Skip to content

Commit c7618cf

Browse files
committed
Flatten JSON structure of log messages
1 parent 6a78a63 commit c7618cf

File tree

8 files changed

+89
-108
lines changed

8 files changed

+89
-108
lines changed

pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/logging/LogMessageContent.kt

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,32 +29,53 @@ sealed class LogMessageContent {
2929
* Error message with type, message, and stack trace.
3030
*/
3131
data class Error(
32+
@SerializedName("type")
33+
val type: String? = null,
3234
@SerializedName("message")
33-
val message: ErrorDetails
35+
val message: String,
36+
@SerializedName("stack")
37+
val stack: List<String>? = null
3438
) : LogMessageContent()
3539

3640
/**
3741
* Network request message.
3842
*/
3943
data class NetworkRequest(
40-
@SerializedName("message")
41-
val message: NetworkLog.Request
44+
@SerializedName("origin")
45+
val origin: String,
46+
@SerializedName("path")
47+
val path: String,
48+
@SerializedName("query")
49+
val query: Map<String, String>? = null,
50+
@SerializedName("method")
51+
val method: HttpMethod,
52+
@SerializedName("headers")
53+
val headers: Map<String, String>? = null,
54+
@SerializedName("formData")
55+
val formData: Map<String, String>? = null,
56+
@SerializedName("body")
57+
val body: String? = null,
58+
@SerializedName("timeout")
59+
val timeout: Long? = null,
60+
@SerializedName("identifier")
61+
val identifier: String? = null,
62+
@SerializedName("canceled")
63+
val canceled: Boolean = false,
64+
@SerializedName("failed")
65+
val failed: Boolean = false
4266
) : LogMessageContent()
4367

4468
/**
4569
* Network response message.
4670
*/
4771
data class NetworkResponse(
48-
@SerializedName("message")
49-
val message: NetworkLog.Response
72+
@SerializedName("url")
73+
val url: String,
74+
@SerializedName("status")
75+
val status: Int,
76+
@SerializedName("headers")
77+
val headers: Map<String, String>? = null,
78+
@SerializedName("body")
79+
val body: String? = null
5080
) : LogMessageContent()
5181
}
52-
53-
data class ErrorDetails(
54-
@SerializedName("type")
55-
val type: String? = null,
56-
@SerializedName("message")
57-
val message: String,
58-
@SerializedName("stack")
59-
val stack: List<String>? = null
60-
)

pubnub-kotlin/pubnub-kotlin-core-api/src/jvmMain/kotlin/com/pubnub/api/logging/NetworkLog.kt

Lines changed: 0 additions & 19 deletions
This file was deleted.

pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/PubNubImpl.kt

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ import com.pubnub.api.endpoints.push.RemoveAllPushChannelsForDevice
5252
import com.pubnub.api.endpoints.push.RemoveChannelsFromPush
5353
import com.pubnub.api.enums.PNPushEnvironment
5454
import com.pubnub.api.enums.PNPushType
55-
import com.pubnub.api.logging.ErrorDetails
5655
import com.pubnub.api.logging.LogConfig
5756
import com.pubnub.api.logging.LogMessage
5857
import com.pubnub.api.logging.LogMessageContent
@@ -257,10 +256,9 @@ open class PubNubImpl(
257256
logger.error(
258257
LogMessage(
259258
message = LogMessageContent.Error(
260-
message = ErrorDetails(
261-
type = e.javaClass.simpleName,
262-
message = "Failed calling getCryptoModuleWithLogConfig"
263-
)
259+
type = e.javaClass.simpleName,
260+
message = "Failed calling getCryptoModuleWithLogConfig",
261+
stack = null
264262
),
265263
details = "details",
266264
)

pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/logging/CompositeLogger.kt

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package com.pubnub.internal.logging
22

3+
import com.google.gson.Gson
4+
import com.google.gson.GsonBuilder
35
import com.pubnub.api.logging.CustomLogger
4-
import com.pubnub.api.logging.ErrorDetails
56
import com.pubnub.api.logging.LogMessage
67
import com.pubnub.api.logging.LogMessageContent
78
import com.pubnub.api.logging.LogMessageType
@@ -38,6 +39,11 @@ class CompositeLogger(
3839
}
3940

4041
override fun debug(message: LogMessage) {
42+
// todo remove
43+
val prettyGson: Gson = GsonBuilder().setPrettyPrinting().create()
44+
val toJson = prettyGson.toJson(message)
45+
println("-=JSON:\n$toJson")
46+
4147
val enhancedLogMessage = LogMessage(
4248
message = message.message,
4349
details = message.details,
@@ -146,10 +152,9 @@ class CompositeLogger(
146152
try {
147153
val logMessage = LogMessage(
148154
message = LogMessageContent.Error(
149-
ErrorDetails(
150-
type = this::class.java.simpleName,
151-
message = "Custom logger ${logger.name} failed: ${e.message}",
152-
)
155+
type = this::class.java.simpleName,
156+
message = "Custom logger ${logger.name} failed: ${e.message}",
157+
stack = null
153158
),
154159
type = LogMessageType.ERROR,
155160
location = "CompositeLogger",

pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/logging/networkLogging/CustomPnHttpLoggingInterceptor.kt

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
11
package com.pubnub.internal.logging.networkLogging
22

33
import com.pubnub.api.enums.PNLogVerbosity
4-
import com.pubnub.api.logging.ErrorDetails
54
import com.pubnub.api.logging.HttpMethod
65
import com.pubnub.api.logging.LogMessage
76
import com.pubnub.api.logging.LogMessageContent
8-
import com.pubnub.api.logging.NetworkLog
9-
import com.pubnub.api.logging.NetworkRequestMessage
10-
import com.pubnub.api.logging.NetworkResponseMessage
117
import com.pubnub.internal.logging.PNLogger
128
import com.pubnub.internal.managers.MapperManager
139
import okhttp3.Interceptor
@@ -62,7 +58,7 @@ class CustomPnHttpLoggingInterceptor(
6258
// Parse headers
6359
val headers = request.headers.toMap()
6460

65-
val networkRequest = NetworkRequestMessage(
61+
val networkRequest = LogMessageContent.NetworkRequest(
6662
origin = origin,
6763
path = path,
6864
query = queryParams.takeIf { it.isNotEmpty() },
@@ -71,16 +67,13 @@ class CustomPnHttpLoggingInterceptor(
7167
formData = null, // TODO: Parse form data if needed
7268
body = request.body.toString(),
7369
timeout = null, // TODO: Extract from request if available
74-
)
75-
76-
val requestLog = NetworkLog.Request(
77-
message = networkRequest,
70+
identifier = null,
7871
canceled = false,
7972
failed = false
8073
)
8174

8275
val logMessage = LogMessage(
83-
message = LogMessageContent.NetworkRequest(requestLog),
76+
message = networkRequest,
8477
details = "HTTP Request",
8578
location = location,
8679
)
@@ -121,17 +114,13 @@ class CustomPnHttpLoggingInterceptor(
121114
}
122115
} ?: (null to response)
123116

124-
val networkResponse = NetworkResponseMessage(
125-
url = url,
126-
status = status,
127-
headers = headers.takeIf { it.isNotEmpty() },
128-
body = body
129-
)
130-
131-
val responseLog = NetworkLog.Response(message = networkResponse)
132-
133117
val logMessage = LogMessage(
134-
message = LogMessageContent.NetworkResponse(responseLog),
118+
message = LogMessageContent.NetworkResponse(
119+
url = url,
120+
status = status,
121+
headers = headers.takeIf { it.isNotEmpty() },
122+
body = body
123+
),
135124
details = "HTTP Response",
136125
location = location,
137126
)
@@ -150,11 +139,9 @@ class CustomPnHttpLoggingInterceptor(
150139
val duration = System.currentTimeMillis() - requestStartTime
151140

152141
val errorDetails = LogMessageContent.Error(
153-
message = ErrorDetails(
154-
type = error.javaClass.simpleName,
155-
message = error.message ?: "Unknown error",
156-
stack = error.stackTrace.take(10).map { it.toString() }
157-
)
142+
type = error.javaClass.simpleName,
143+
message = error.message ?: "Unknown error",
144+
stack = error.stackTrace.take(10).map { it.toString() }
158145
)
159146

160147
val logMessage = LogMessage(

pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/logging/networkLogging/LogMessageFormatter.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,13 @@ object LogMessageFormatter {
2323
is LogMessageContent.Text -> content.message
2424
is LogMessageContent.Object -> prettyGson.toJson(mapOf("operation" to content.operation, "arguments" to content.arguments))
2525
is LogMessageContent.Error -> {
26-
val err = content.message
27-
"Error(type=${err.type}, message=${err.message}, stack=${err.stack?.joinToString("\n")})"
26+
"Error(type=${content.type}, message=${content.message}, stack=${content.stack?.joinToString("\n")})"
2827
}
2928
is LogMessageContent.NetworkRequest -> {
30-
"NetworkRequest:\n${prettyGson.toJson(content.message)}"
29+
"NetworkRequest:\n${prettyGson.toJson(content)}"
3130
}
3231
is LogMessageContent.NetworkResponse -> {
33-
"NetworkResponse:\n${prettyGson.toJson(content.message)}"
32+
"NetworkResponse:\n${prettyGson.toJson(content)}"
3433
}
3534
else -> content.toString()
3635
}

pubnub-kotlin/pubnub-kotlin-impl/src/main/kotlin/com/pubnub/internal/managers/MapperManager.kt

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import com.google.gson.stream.JsonToken
1919
import com.google.gson.stream.JsonWriter
2020
import com.pubnub.api.PubNubError
2121
import com.pubnub.api.PubNubException
22-
import com.pubnub.api.logging.ErrorDetails
2322
import com.pubnub.api.logging.LogConfig
2423
import com.pubnub.api.logging.LogMessage
2524
import com.pubnub.api.logging.LogMessageContent
@@ -270,10 +269,9 @@ class MapperManager(private val logConfig: LogConfig) {
270269
log.error(
271270
LogMessage(
272271
message = LogMessageContent.Error(
273-
ErrorDetails(
274-
type = e.javaClass.simpleName,
275-
message = "Serialization of content failed due to: ${e.message}"
276-
)
272+
type = e.javaClass.simpleName,
273+
message = "Serialization of content failed due to: ${e.message}",
274+
stack = null
277275
)
278276
)
279277
)

pubnub-kotlin/pubnub-kotlin-impl/src/test/kotlin/com/pubnub/internal/logging/networkLogging/LogMessageFormatterTest.kt

Lines changed: 23 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
11
package com.pubnub.internal.logging.networkLogging
22

3-
import com.pubnub.api.logging.ErrorDetails
43
import com.pubnub.api.logging.HttpMethod
54
import com.pubnub.api.logging.LogMessage
65
import com.pubnub.api.logging.LogMessageContent
76
import com.pubnub.api.logging.LogMessageType
8-
import com.pubnub.api.logging.NetworkLog
9-
import com.pubnub.api.logging.NetworkRequestMessage
10-
import com.pubnub.api.logging.NetworkResponseMessage
117
import org.junit.jupiter.api.Assertions.assertEquals
128
import org.junit.jupiter.api.Assertions.assertFalse
139
import org.junit.jupiter.api.Assertions.assertTrue
@@ -44,15 +40,14 @@ class LogMessageFormatterTest {
4440

4541
@Test
4642
fun `should format error message content with stack trace`() {
47-
val errorDetails = ErrorDetails(
43+
val errorContent = LogMessageContent.Error(
4844
type = "RuntimeException",
4945
message = "Something went wrong",
5046
stack = listOf(
5147
"at com.example.Test.method1(Test.java:10)",
5248
"at com.example.Test.method2(Test.java:20)"
5349
)
5450
)
55-
val errorContent = LogMessageContent.Error(errorDetails)
5651

5752
val result = LogMessageFormatter.formatMessageContent(errorContent)
5853

@@ -64,12 +59,11 @@ class LogMessageFormatterTest {
6459

6560
@Test
6661
fun `should format error message content without stack trace`() {
67-
val errorDetails = ErrorDetails(
62+
val errorContent = LogMessageContent.Error(
6863
type = "IOException",
6964
message = "Network error",
7065
stack = null
7166
)
72-
val errorContent = LogMessageContent.Error(errorDetails)
7367

7468
val result = LogMessageFormatter.formatMessageContent(errorContent)
7569

@@ -80,7 +74,7 @@ class LogMessageFormatterTest {
8074

8175
@Test
8276
fun `should format network request message content as JSON`() {
83-
val networkRequest = NetworkRequestMessage(
77+
val requestContent = LogMessageContent.NetworkRequest(
8478
origin = "https://ps.pndsn.com",
8579
path = "/v2/subscribe/demo/my-channel/0",
8680
query = mapOf("uuid" to "test-uuid"),
@@ -89,10 +83,10 @@ class LogMessageFormatterTest {
8983
formData = null,
9084
body = """{"message": "hello"}""",
9185
timeout = 5000,
92-
identifier = "req-123"
86+
identifier = "req-123",
87+
canceled = false,
88+
failed = false
9389
)
94-
val requestLog = NetworkLog.Request(networkRequest, canceled = false, failed = false)
95-
val requestContent = LogMessageContent.NetworkRequest(requestLog)
9690

9791
val result = LogMessageFormatter.formatMessageContent(requestContent)
9892

@@ -108,14 +102,12 @@ class LogMessageFormatterTest {
108102

109103
@Test
110104
fun `should format network response message content as JSON`() {
111-
val networkResponse = NetworkResponseMessage(
105+
val responseContent = LogMessageContent.NetworkResponse(
112106
url = "https://ps.pndsn.com/v2/subscribe/demo/my-channel/0",
113107
status = 200,
114108
headers = mapOf("Content-Type" to "application/json"),
115109
body = """{"status": 200, "message": "OK"}"""
116110
)
117-
val responseLog = NetworkLog.Response(networkResponse)
118-
val responseContent = LogMessageContent.NetworkResponse(responseLog)
119111

120112
val result = LogMessageFormatter.formatMessageContent(responseContent)
121113

@@ -178,23 +170,23 @@ class LogMessageFormatterTest {
178170

179171
@Test
180172
fun `simplified extension function should format complex network request`() {
181-
val networkRequest = NetworkRequestMessage(
182-
origin = "https://ps.pndsn.com",
183-
path = "/publish/demo/my-channel/0",
184-
query = mapOf("pnsdk" to "kotlin/1.0.0", "uuid" to "user-123"),
185-
method = HttpMethod.POST,
186-
headers = mapOf(
187-
"Content-Type" to "application/json",
188-
"Authorization" to "Bearer token123"
189-
),
190-
formData = null,
191-
body = """{"text": "Hello World!", "meta": {"timestamp": 1234567890}}""",
192-
timeout = 10000,
193-
identifier = "publish-req-789"
194-
)
195-
val requestLog = NetworkLog.Request(networkRequest, canceled = false, failed = false)
196173
val logMessage = LogMessage(
197-
message = LogMessageContent.NetworkRequest(requestLog),
174+
message = LogMessageContent.NetworkRequest(
175+
origin = "https://ps.pndsn.com",
176+
path = "/publish/demo/my-channel/0",
177+
query = mapOf("pnsdk" to "kotlin/1.0.0", "uuid" to "user-123"),
178+
method = HttpMethod.POST,
179+
headers = mapOf(
180+
"Content-Type" to "application/json",
181+
"Authorization" to "Bearer token123"
182+
),
183+
formData = null,
184+
body = """{"text": "Hello World!", "meta": {"timestamp": 1234567890}}""",
185+
timeout = 10000,
186+
identifier = "publish-req-789",
187+
canceled = false,
188+
failed = false
189+
),
198190
details = "Publishing message to channel",
199191
type = LogMessageType.NETWORK_REQUEST,
200192
location = "PublishEndpoint",

0 commit comments

Comments
 (0)