solution: [optionally] provide request/response value with access log
This commit is contained in:
@@ -430,6 +430,12 @@ accessLog:
|
||||
| `false`
|
||||
| Enable/Disable Access logging
|
||||
|
||||
| `include-messages`
|
||||
| `false`
|
||||
| Include request params and response result/error (i.e., a JSON) in access log.
|
||||
It's an expensive operation, use it for debugging only.
|
||||
Note that for errors it provides only error message, not the error response itself.
|
||||
|
||||
| `filename`
|
||||
| `access_log.jsonl`
|
||||
| Path to the access log file
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package io.emeraldpay.dshackle.config
|
||||
|
||||
class AccessLogConfig(
|
||||
val enabled: Boolean = false
|
||||
val enabled: Boolean = false,
|
||||
val includeMessages: Boolean = false
|
||||
) {
|
||||
|
||||
var filename: String = "./access_log.jsonl"
|
||||
|
||||
@@ -15,7 +15,8 @@ class AccessLogReader : YamlConfigReader(), ConfigReader<AccessLogConfig> {
|
||||
if (!enabled) {
|
||||
AccessLogConfig.disabled()
|
||||
} else {
|
||||
val config = AccessLogConfig(true)
|
||||
val includeMessages = getValueAsBool(node, "include-messages") ?: false
|
||||
val config = AccessLogConfig(true, includeMessages)
|
||||
getValueAsString(node, "filename")?.let {
|
||||
config.filename = it
|
||||
}
|
||||
|
||||
@@ -63,6 +63,9 @@ class AccessLogWriter(
|
||||
}
|
||||
log.info("Writing Access Log to ${filename.absolutePath}")
|
||||
scheduler.schedule(runner, START_SLEEP_MS, TimeUnit.MILLISECONDS)
|
||||
|
||||
//propagate current config to the Event Builder, so it knows which details to include
|
||||
EventsBuilder.accessLogConfig = config
|
||||
}
|
||||
|
||||
private fun flushRunner() {
|
||||
|
||||
@@ -108,7 +108,9 @@ class Events {
|
||||
val succeed: Boolean,
|
||||
val rpcError: Int? = null,
|
||||
val payloadSizeBytes: Long,
|
||||
val nativeCall: NativeCallItemDetails
|
||||
val nativeCall: NativeCallItemDetails,
|
||||
val responseBody: String? = null,
|
||||
val errorMessage: String? = null
|
||||
) : ChainBase(blockchain, "NativeCall", id, channel)
|
||||
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
@@ -120,7 +122,8 @@ class Events {
|
||||
// info about the initial request, that may include several native calls
|
||||
val request: StreamRequestDetails,
|
||||
val payloadSizeBytes: Long,
|
||||
val nativeSubscribe: NativeSubscribeItemDetails
|
||||
val nativeSubscribe: NativeSubscribeItemDetails,
|
||||
val responseBody: String? = null,
|
||||
) : ChainBase(blockchain, "NativeSubscribe", id, channel)
|
||||
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
@@ -159,7 +162,8 @@ class Events {
|
||||
data class NativeCallItemDetails(
|
||||
val method: String,
|
||||
val id: Int,
|
||||
val payloadSizeBytes: Long
|
||||
val payloadSizeBytes: Long,
|
||||
val requestParams: String? = null
|
||||
)
|
||||
|
||||
data class NativeCallReplyDetails(
|
||||
|
||||
@@ -17,6 +17,9 @@ package io.emeraldpay.dshackle.monitoring.accesslog
|
||||
|
||||
import io.emeraldpay.api.proto.BlockchainOuterClass
|
||||
import io.emeraldpay.api.proto.Common
|
||||
import io.emeraldpay.dshackle.Global
|
||||
import io.emeraldpay.dshackle.config.AccessLogConfig
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcError
|
||||
import io.emeraldpay.grpc.Chain
|
||||
import io.grpc.Attributes
|
||||
import io.grpc.Grpc
|
||||
@@ -36,6 +39,10 @@ class EventsBuilder {
|
||||
|
||||
companion object {
|
||||
private val log = LoggerFactory.getLogger(EventsBuilder::class.java)
|
||||
|
||||
// A reference to the config for current _running instance_.
|
||||
// Initialized by AccessLogWriter
|
||||
var accessLogConfig: AccessLogConfig = AccessLogConfig.default()
|
||||
}
|
||||
|
||||
interface StartingHttp2Request {
|
||||
@@ -306,7 +313,10 @@ class EventsBuilder {
|
||||
Events.NativeCallItemDetails(
|
||||
item.method,
|
||||
item.id,
|
||||
item.payload.size().toLong()
|
||||
item.payload.size().toLong(),
|
||||
if (accessLogConfig.includeMessages) {
|
||||
if (item.payload != null && !item.payload.isEmpty && item.payload.isValidUtf8) item.payload.toStringUtf8() else ""
|
||||
} else null
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -323,7 +333,11 @@ class EventsBuilder {
|
||||
nativeCall = item,
|
||||
payloadSizeBytes = item.payloadSizeBytes,
|
||||
id = UUID.randomUUID(),
|
||||
channel = Events.Channel.GRPC
|
||||
channel = Events.Channel.GRPC,
|
||||
responseBody = if (accessLogConfig.includeMessages) {
|
||||
if (msg.payload != null && !msg.payload.isEmpty && msg.payload.isValidUtf8) msg.payload.toStringUtf8() else ""
|
||||
} else null,
|
||||
errorMessage = if (accessLogConfig.includeMessages) msg.errorMessage else null,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -341,7 +355,13 @@ class EventsBuilder {
|
||||
nativeCall = item,
|
||||
payloadSizeBytes = item.payloadSizeBytes,
|
||||
id = UUID.randomUUID(),
|
||||
channel = channel
|
||||
channel = channel,
|
||||
responseBody = if (accessLogConfig.includeMessages) (reply.result?.let { String(it) } ?: "") else null,
|
||||
errorMessage = if (accessLogConfig.includeMessages) {
|
||||
reply.error?.let {
|
||||
it.upstreamError?.message ?: it.message
|
||||
} ?: ""
|
||||
} else null
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -373,7 +393,8 @@ class EventsBuilder {
|
||||
nativeSubscribe = item!!,
|
||||
payloadSizeBytes = msg.payload?.size()?.toLong() ?: 0L,
|
||||
id = UUID.randomUUID(),
|
||||
channel = Events.Channel.GRPC
|
||||
channel = Events.Channel.GRPC,
|
||||
responseBody = if (accessLogConfig.includeMessages) (msg.payload?.toStringUtf8() ?: "") else null,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ class AccessLogWriterSpec extends Specification {
|
||||
File accessLog = new File(dir, "accesslog.jsonl")
|
||||
println("Write access log to $accessLog.absolutePath")
|
||||
MainConfig config = new MainConfig()
|
||||
config.accessLogConfig = new AccessLogConfig(true).tap {
|
||||
config.accessLogConfig = new AccessLogConfig(true, false).tap {
|
||||
it.filename = accessLog.absolutePath
|
||||
}
|
||||
AccessLogWriter logWriter = new AccessLogWriter(config)
|
||||
|
||||
Reference in New Issue
Block a user