solution: [optionally] provide request/response value with access log

This commit is contained in:
Igor Artamonov
2022-02-10 20:58:43 -05:00
parent 8b6fc0c5d6
commit 94289399d5
7 changed files with 46 additions and 10 deletions

View File

@@ -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

View 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"

View File

@@ -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
}

View File

@@ -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() {

View File

@@ -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(

View File

@@ -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,
)
}
}

View File

@@ -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)