From 0d144a44a9b19e27a215e021c46038a6d922c6ce Mon Sep 17 00:00:00 2001 From: Igor Artamonov Date: Mon, 5 Jul 2021 21:51:15 -0400 Subject: [PATCH] problem: NativeCall replies are logged only on complete solution: add to the log at the moment of reply --- .../monitoring/accesslog/AccessHandler.kt | 31 ++++----- .../monitoring/accesslog/EventsBuilder.kt | 35 ++++------ .../accesslog/EventsBaseBuilderSpec.groovy | 68 ++++++++----------- 3 files changed, 54 insertions(+), 80 deletions(-) diff --git a/src/main/kotlin/io/emeraldpay/dshackle/monitoring/accesslog/AccessHandler.kt b/src/main/kotlin/io/emeraldpay/dshackle/monitoring/accesslog/AccessHandler.kt index 210623b7..47efb4be 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/monitoring/accesslog/AccessHandler.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/monitoring/accesslog/AccessHandler.kt @@ -110,13 +110,14 @@ class AccessHandler( .start(headers, call.attributes) val callWrapper: ServerCall = OnNativeCallResponse( - call as ServerCall, builder + call as ServerCall, + builder, + accessLogWriter ) as ServerCall return OnNativeCall( next.startCall(callWrapper, headers) as ServerCall.Listener, - builder) { logs -> - accessLogWriter.submit(logs) - } as ServerCall.Listener + builder + ) as ServerCall.Listener } @Suppress("UNCHECKED_CAST") @@ -205,29 +206,18 @@ class AccessHandler( class OnNativeCall( val next: ServerCall.Listener, - val builder: EventsBuilder.NativeCall, - val done: (List) -> Unit + val builder: EventsBuilder.NativeCall ) : ForwardingServerCallListener() { override fun onMessage(message: BlockchainOuterClass.NativeCallRequest) { val chain = message.chain builder.withChain(chain.number) message.itemsList.forEach { item -> - builder.onItem(item) + builder.onRequest(item) } super.onMessage(message) } - override fun onCancel() { - super.onCancel() - done(builder.build()) - } - - override fun onComplete() { - super.onComplete() - done(builder.build()) - } - override fun delegate(): ServerCall.Listener { return next } @@ -279,11 +269,14 @@ class AccessHandler( class OnNativeCallResponse( next: ServerCall, - val builder: EventsBuilder.NativeCall + val builder: EventsBuilder.NativeCall, + val accessLogWriter: AccessLogWriter ) : BaseCallResponse(next) { override fun sendMessage(message: BlockchainOuterClass.NativeCallReplyItem) { - builder.onItemReply(message) + accessLogWriter.submit( + builder.onReply(message) + ) super.sendMessage(message) } } diff --git a/src/main/kotlin/io/emeraldpay/dshackle/monitoring/accesslog/EventsBuilder.kt b/src/main/kotlin/io/emeraldpay/dshackle/monitoring/accesslog/EventsBuilder.kt index 520fe06f..8428c298 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/monitoring/accesslog/EventsBuilder.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/monitoring/accesslog/EventsBuilder.kt @@ -186,12 +186,13 @@ class EventsBuilder { class NativeCall : Base() { val items = ArrayList() val replies = HashMap() + private var index = 0 override fun getT(): NativeCall { return this } - fun onItem(item: BlockchainOuterClass.NativeCallItem): NativeCall { + fun onRequest(item: BlockchainOuterClass.NativeCallItem): NativeCall { this.items.add( Events.NativeCallItemDetails( item.method, @@ -202,30 +203,20 @@ class EventsBuilder { return this } - fun onItemReply(reply: BlockchainOuterClass.NativeCallReplyItem): NativeCall { - this.replies[reply.id] = Events.NativeCallReplyDetails( - reply.id, - reply.succeed, - reply.payload?.size()?.toLong() ?: 0L + fun onReply(reply: BlockchainOuterClass.NativeCallReplyItem): Events.NativeCall { + val item = items.find { it.id == reply.id }!! + return Events.NativeCall( + request = requestDetails, + total = items.size, + index = index++, + succeed = reply.succeed, + blockchain = chain, + nativeCall = item, + payloadSizeBytes = item.payloadSizeBytes, + id = UUID.randomUUID() ) - return this } - fun build(): List { - return items.mapIndexed { index, item -> - val reply = replies[item.id] - Events.NativeCall( - request = requestDetails, - total = items.size, - index = index, - succeed = reply?.succeed ?: false, - blockchain = chain, - nativeCall = item, - payloadSizeBytes = item.payloadSizeBytes, - id = UUID.randomUUID() - ) - } - } } class Describe : Base() { diff --git a/src/test/groovy/io/emeraldpay/dshackle/monitoring/accesslog/EventsBaseBuilderSpec.groovy b/src/test/groovy/io/emeraldpay/dshackle/monitoring/accesslog/EventsBaseBuilderSpec.groovy index b72ec97e..49c1fce8 100644 --- a/src/test/groovy/io/emeraldpay/dshackle/monitoring/accesslog/EventsBaseBuilderSpec.groovy +++ b/src/test/groovy/io/emeraldpay/dshackle/monitoring/accesslog/EventsBaseBuilderSpec.groovy @@ -35,18 +35,15 @@ class EventsBaseBuilderSpec extends Specification { def act = new EventsBuilder.NativeCall() .start(metadata, attributes) .withChain(Chain.ETHEREUM.id) - .onItem(BlockchainOuterClass.NativeCallItem.getDefaultInstance()) - .build() + .onRequest(BlockchainOuterClass.NativeCallItem.getDefaultInstance()) + .onReply(BlockchainOuterClass.NativeCallReplyItem.getDefaultInstance()) then: - act.size() == 1 - with(act[0]) { - it.request != null - it.request.remote != null - with(it.request.remote) { - ips == ["127.0.0.1"] - userAgent == "grpc-go/1.30.0" - ip == "127.0.0.1" - } + act.request != null + act.request.remote != null + with(act.request.remote) { + ips == ["127.0.0.1"] + userAgent == "grpc-go/1.30.0" + ip == "127.0.0.1" } } @@ -62,11 +59,10 @@ class EventsBaseBuilderSpec extends Specification { def act = new EventsBuilder.NativeCall() .start(metadata, attributes) .withChain(Chain.ETHEREUM.id) - .onItem(BlockchainOuterClass.NativeCallItem.getDefaultInstance()) - .build() + .onRequest(BlockchainOuterClass.NativeCallItem.getDefaultInstance()) + .onReply(BlockchainOuterClass.NativeCallReplyItem.getDefaultInstance()) then: - act.size() == 1 - with(act[0].request.remote) { + with(act.request.remote) { ips == ["30.56.100.15", "127.0.0.1"] ip == "30.56.100.15" } @@ -84,11 +80,10 @@ class EventsBaseBuilderSpec extends Specification { def act = new EventsBuilder.NativeCall() .start(metadata, attributes) .withChain(Chain.ETHEREUM.id) - .onItem(BlockchainOuterClass.NativeCallItem.getDefaultInstance()) - .build() + .onRequest(BlockchainOuterClass.NativeCallItem.getDefaultInstance()) + .onReply(BlockchainOuterClass.NativeCallReplyItem.getDefaultInstance()) then: - act.size() == 1 - with(act[0].request.remote) { + with(act.request.remote) { ips == ["192.168.1.1", "30.56.100.15"] userAgent == "grpc-go/1.30.0" ip == "30.56.100.15" @@ -107,11 +102,10 @@ class EventsBaseBuilderSpec extends Specification { def act = new EventsBuilder.NativeCall() .start(metadata, attributes) .withChain(Chain.ETHEREUM.id) - .onItem(BlockchainOuterClass.NativeCallItem.getDefaultInstance()) - .build() + .onRequest(BlockchainOuterClass.NativeCallItem.getDefaultInstance()) + .onReply(BlockchainOuterClass.NativeCallReplyItem.getDefaultInstance()) then: - act.size() == 1 - with(act[0].request.remote) { + with(act.request.remote) { ips == ["30.56.100.15"] userAgent == "grpc-go/1.30.0" ip == "30.56.100.15" @@ -130,11 +124,10 @@ class EventsBaseBuilderSpec extends Specification { def act = new EventsBuilder.NativeCall() .start(metadata, attributes) .withChain(Chain.ETHEREUM.id) - .onItem(BlockchainOuterClass.NativeCallItem.getDefaultInstance()) - .build() + .onRequest(BlockchainOuterClass.NativeCallItem.getDefaultInstance()) + .onReply(BlockchainOuterClass.NativeCallReplyItem.getDefaultInstance()) then: - act.size() == 1 - with(act[0].request.remote) { + with(act.request.remote) { ips == ["30.56.100.15"] userAgent == "grpc-go/1.30.0" ip == "30.56.100.15" @@ -153,11 +146,10 @@ class EventsBaseBuilderSpec extends Specification { def act = new EventsBuilder.NativeCall() .start(metadata, attributes) .withChain(Chain.ETHEREUM.id) - .onItem(BlockchainOuterClass.NativeCallItem.getDefaultInstance()) - .build() + .onRequest(BlockchainOuterClass.NativeCallItem.getDefaultInstance()) + .onReply(BlockchainOuterClass.NativeCallReplyItem.getDefaultInstance()) then: - act.size() == 1 - with(act[0].request.remote) { + with(act.request.remote) { ips == ["2001:db8:0:0:0:ff00:42:8329", "0:0:0:0:0:0:0:1"] ip == "2001:db8:0:0:0:ff00:42:8329" } @@ -174,11 +166,10 @@ class EventsBaseBuilderSpec extends Specification { def act = new EventsBuilder.NativeCall() .start(metadata, attributes) .withChain(Chain.ETHEREUM.id) - .onItem(BlockchainOuterClass.NativeCallItem.getDefaultInstance()) - .build() + .onRequest(BlockchainOuterClass.NativeCallItem.getDefaultInstance()) + .onReply(BlockchainOuterClass.NativeCallReplyItem.getDefaultInstance()) then: - act.size() == 1 - with(act[0].request.remote) { + with(act.request.remote) { userAgent == "grpc-go/1.30.0 xss" } } @@ -195,11 +186,10 @@ class EventsBaseBuilderSpec extends Specification { def act = new EventsBuilder.NativeCall() .start(metadata, attributes) .withChain(Chain.ETHEREUM.id) - .onItem(BlockchainOuterClass.NativeCallItem.getDefaultInstance()) - .build() + .onRequest(BlockchainOuterClass.NativeCallItem.getDefaultInstance()) + .onReply(BlockchainOuterClass.NativeCallReplyItem.getDefaultInstance()) then: - act.size() == 1 - with(act[0].request.remote) { + with(act.request.remote) { userAgent.length() == 128 userAgent == "0123456_1_0123456_2_0123456_3_0123456_4_0123456_5_0123456_6_0123456_7_0123456_8_0123456_9_0123456_0_0123456_1_0123456_2_0123456_" }