Open AleksanderBrzozowski opened 5 months ago
So we have GRPC and Kotlin here. Can you try to isolate the problem e.g. only to Grpc or Kotlin?
I can't reproduce this issue using gRPC or Kotlin coroutines, unfortunately π
I added additional logging, and I found scope which is not being closed:
11:39:54.875 [grpc-default-executor-0] INFO i.m.o.ObservationTextPublisher - START - name='grpc.server', contextualName='null', error='null', lowCardinalityKeyValues=[rpc.method='UnaryRpc', rpc.service='grpc.testing.SimpleService', rpc.type='UNARY'], highCardinalityKeyValues=[], map=[], parentObservation=null
11:39:54.878 [grpc-default-executor-0] INFO i.m.o.SimpleObservation$SimpleScope - Scope opened: io.micrometer.observation.SimpleObservation$SimpleScope@5f9d2dc9
11:39:54.878 [grpc-default-executor-0] INFO i.m.o.ObservationTextPublisher - OPEN - name='grpc.server', contextualName='null', error='null', lowCardinalityKeyValues=[rpc.method='UnaryRpc', rpc.service='grpc.testing.SimpleService', rpc.type='UNARY'], highCardinalityKeyValues=[], map=[], parentObservation=null
11:39:54.901 [grpc-default-executor-0] DEBUG i.m.o.SimpleObservation$SimpleScope - Closing scope: io.micrometer.observation.SimpleObservation$SimpleScope@5f9d2dc9
11:39:54.902 [single-thread] INFO i.m.o.SimpleObservation$SimpleScope - Scope opened: io.micrometer.observation.SimpleObservation$SimpleScope@335435f0
11:39:54.902 [grpc-default-executor-0] INFO i.m.o.ObservationTextPublisher - CLOSE - name='grpc.server', contextualName='null', error='null', lowCardinalityKeyValues=[rpc.method='UnaryRpc', rpc.service='grpc.testing.SimpleService', rpc.type='UNARY'], highCardinalityKeyValues=[], map=[], parentObservation=null
11:39:54.902 [single-thread] INFO i.m.o.ObservationTextPublisher - OPEN - name='grpc.server', contextualName='null', error='null', lowCardinalityKeyValues=[rpc.method='UnaryRpc', rpc.service='grpc.testing.SimpleService', rpc.type='UNARY'], highCardinalityKeyValues=[], map=[], parentObservation=null
11:39:54.903 [grpc-default-executor-0] INFO i.m.o.SimpleObservation$SimpleScope - Scope opened: io.micrometer.observation.SimpleObservation$SimpleScope@2018ec54
11:39:54.903 [grpc-default-executor-0] INFO i.m.o.ObservationTextPublisher - OPEN - name='grpc.server', contextualName='null', error='null', lowCardinalityKeyValues=[rpc.method='UnaryRpc', rpc.service='grpc.testing.SimpleService', rpc.type='UNARY'], highCardinalityKeyValues=[], map=[], parentObservation=null
11:39:54.904 [grpc-default-executor-0] DEBUG i.m.o.SimpleObservation$SimpleScope - Closing scope: io.micrometer.observation.SimpleObservation$SimpleScope@2018ec54
11:39:54.904 [grpc-default-executor-0] INFO i.m.o.ObservationTextPublisher - CLOSE - name='grpc.server', contextualName='null', error='null', lowCardinalityKeyValues=[rpc.method='UnaryRpc', rpc.service='grpc.testing.SimpleService', rpc.type='UNARY'], highCardinalityKeyValues=[], map=[], parentObservation=null
11:39:54.912 [grpc-default-executor-0] INFO i.m.o.ObservationTextPublisher - EVENT - MESSAGE_RECEIVED, name='grpc.server', contextualName='null', error='null', lowCardinalityKeyValues=[rpc.method='UnaryRpc', rpc.service='grpc.testing.SimpleService', rpc.type='UNARY'], highCardinalityKeyValues=[], map=[], parentObservation=null
11:39:54.912 [grpc-default-executor-0] INFO i.m.o.SimpleObservation$SimpleScope - Scope opened: io.micrometer.observation.SimpleObservation$SimpleScope@4fe8e027
11:39:54.912 [grpc-default-executor-0] INFO i.m.o.ObservationTextPublisher - OPEN - name='grpc.server', contextualName='null', error='null', lowCardinalityKeyValues=[rpc.method='UnaryRpc', rpc.service='grpc.testing.SimpleService', rpc.type='UNARY'], highCardinalityKeyValues=[], map=[], parentObservation=null
11:39:54.912 [single-thread] DEBUG i.m.o.SimpleObservation$SimpleScope - Closing scope: io.micrometer.observation.SimpleObservation$SimpleScope@335435f0
11:39:54.913 [single-thread] INFO i.m.o.ObservationTextPublisher - CLOSE - name='grpc.server', contextualName='null', error='null', lowCardinalityKeyValues=[rpc.method='UnaryRpc', rpc.service='grpc.testing.SimpleService', rpc.type='UNARY'], highCardinalityKeyValues=[], map=[], parentObservation=null
11:39:54.913 [single-thread] INFO i.m.o.SimpleObservation$SimpleScope - Scope opened: io.micrometer.observation.SimpleObservation$SimpleScope@33f78a04
11:39:54.913 [grpc-default-executor-0] DEBUG i.m.o.SimpleObservation$SimpleScope - Closing scope: io.micrometer.observation.SimpleObservation$SimpleScope@4fe8e027
11:39:54.913 [single-thread] INFO i.m.o.ObservationTextPublisher - OPEN - name='grpc.server', contextualName='null', error='null', lowCardinalityKeyValues=[rpc.method='UnaryRpc', rpc.service='grpc.testing.SimpleService', rpc.type='UNARY'], highCardinalityKeyValues=[], map=[], parentObservation=null
11:39:54.913 [grpc-default-executor-0] INFO i.m.o.ObservationTextPublisher - CLOSE - name='grpc.server', contextualName='null', error='null', lowCardinalityKeyValues=[rpc.method='UnaryRpc', rpc.service='grpc.testing.SimpleService', rpc.type='UNARY'], highCardinalityKeyValues=[], map=[], parentObservation=null
11:39:54.913 [grpc-default-executor-0] INFO i.m.o.SimpleObservation$SimpleScope - Scope opened: io.micrometer.observation.SimpleObservation$SimpleScope@1df02ef1
11:39:54.913 [grpc-default-executor-0] INFO i.m.o.ObservationTextPublisher - OPEN - name='grpc.server', contextualName='null', error='null', lowCardinalityKeyValues=[rpc.method='UnaryRpc', rpc.service='grpc.testing.SimpleService', rpc.type='UNARY'], highCardinalityKeyValues=[], map=[], parentObservation=null
11:39:54.914 [grpc-default-executor-0] DEBUG i.m.o.SimpleObservation$SimpleScope - Closing scope: io.micrometer.observation.SimpleObservation$SimpleScope@1df02ef1
11:39:54.914 [grpc-default-executor-0] INFO i.m.o.ObservationTextPublisher - CLOSE - name='grpc.server', contextualName='null', error='null', lowCardinalityKeyValues=[rpc.method='UnaryRpc', rpc.service='grpc.testing.SimpleService', rpc.type='UNARY'], highCardinalityKeyValues=[], map=[], parentObservation=null
11:39:54.915 [single-thread @coroutine#1] INFO i.m.o.ObservationTextPublisher - START - name='test', contextualName='null', error='null', lowCardinalityKeyValues=[], highCardinalityKeyValues=[], map=[], parentObservation={name=grpc.server(null), error=null, context=name='grpc.server', contextualName='null', error='null', lowCardinalityKeyValues=[rpc.method='UnaryRpc', rpc.service='grpc.testing.SimpleService', rpc.type='UNARY'], highCardinalityKeyValues=[], map=[], parentObservation=null}
11:39:54.915 [single-thread @coroutine#1] INFO i.m.o.SimpleObservation$SimpleScope - Scope opened: io.micrometer.observation.SimpleObservation$SimpleScope@77b3ffa1
11:39:54.915 [single-thread @coroutine#1] INFO i.m.o.ObservationTextPublisher - OPEN - name='test', contextualName='null', error='null', lowCardinalityKeyValues=[], highCardinalityKeyValues=[], map=[], parentObservation={name=grpc.server(null), error=null, context=name='grpc.server', contextualName='null', error='null', lowCardinalityKeyValues=[rpc.method='UnaryRpc', rpc.service='grpc.testing.SimpleService', rpc.type='UNARY'], highCardinalityKeyValues=[], map=[], parentObservation=null}
11:39:54.917 [single-thread] DEBUG i.m.o.SimpleObservation$SimpleScope - Closing scope: io.micrometer.observation.SimpleObservation$SimpleScope@77b3ffa1
11:39:54.917 [single-thread] INFO i.m.o.ObservationTextPublisher - CLOSE - name='test', contextualName='null', error='null', lowCardinalityKeyValues=[], highCardinalityKeyValues=[], map=[], parentObservation={name=grpc.server(null), error=null, context=name='grpc.server', contextualName='null', error='null', lowCardinalityKeyValues=[rpc.method='UnaryRpc', rpc.service='grpc.testing.SimpleService', rpc.type='UNARY'], highCardinalityKeyValues=[], map=[], parentObservation=null}
11:39:54.918 [single-thread] INFO i.m.o.SimpleObservation$SimpleScope - Scope opened: io.micrometer.observation.SimpleObservation$SimpleScope@1629599e
11:39:54.918 [single-thread] INFO i.m.o.ObservationTextPublisher - OPEN - name='grpc.server', contextualName='null', error='null', lowCardinalityKeyValues=[rpc.method='UnaryRpc', rpc.service='grpc.testing.SimpleService', rpc.type='UNARY'], highCardinalityKeyValues=[], map=[], parentObservation=null
11:39:54.918 [single-thread @coroutine#1] DEBUG i.m.o.SimpleObservation$SimpleScope - Closing scope: io.micrometer.observation.SimpleObservation$SimpleScope@77b3ffa1
11:39:54.918 [single-thread @coroutine#1] INFO i.m.o.ObservationTextPublisher - CLOSE - name='test', contextualName='null', error='null', lowCardinalityKeyValues=[], highCardinalityKeyValues=[], map=[], parentObservation={name=grpc.server(null), error=null, context=name='grpc.server', contextualName='null', error='null', lowCardinalityKeyValues=[rpc.method='UnaryRpc', rpc.service='grpc.testing.SimpleService', rpc.type='UNARY'], highCardinalityKeyValues=[], map=[], parentObservation=null}
11:39:54.919 [single-thread @coroutine#1] INFO i.m.o.ObservationTextPublisher - STOP - name='test', contextualName='null', error='null', lowCardinalityKeyValues=[], highCardinalityKeyValues=[], map=[], parentObservation={name=grpc.server(null), error=null, context=name='grpc.server', contextualName='null', error='null', lowCardinalityKeyValues=[rpc.method='UnaryRpc', rpc.service='grpc.testing.SimpleService', rpc.type='UNARY'], highCardinalityKeyValues=[], map=[], parentObservation=null}
11:39:54.920 [single-thread @coroutine#1] INFO i.m.o.ObservationTextPublisher - EVENT - MESSAGE_SENT, name='grpc.server', contextualName='null', error='null', lowCardinalityKeyValues=[rpc.method='UnaryRpc', rpc.service='grpc.testing.SimpleService', rpc.type='UNARY'], highCardinalityKeyValues=[], map=[], parentObservation=null
11:39:54.921 [grpc-default-executor-0] INFO i.m.o.SimpleObservation$SimpleScope - Scope opened: io.micrometer.observation.SimpleObservation$SimpleScope@45459493
11:39:54.922 [grpc-default-executor-0] INFO i.m.o.ObservationTextPublisher - OPEN - name='grpc.server', contextualName='null', error='null', lowCardinalityKeyValues=[rpc.method='UnaryRpc', rpc.service='grpc.testing.SimpleService', rpc.type='UNARY'], highCardinalityKeyValues=[], map=[], parentObservation=null
11:39:54.922 [grpc-default-executor-0] DEBUG i.m.o.SimpleObservation$SimpleScope - Closing scope: io.micrometer.observation.SimpleObservation$SimpleScope@45459493
11:39:54.922 [grpc-default-executor-0] INFO i.m.o.ObservationTextPublisher - CLOSE - name='grpc.server', contextualName='null', error='null', lowCardinalityKeyValues=[rpc.method='UnaryRpc', rpc.service='grpc.testing.SimpleService', rpc.type='UNARY'], highCardinalityKeyValues=[], map=[], parentObservation=null
11:39:54.922 [grpc-default-executor-0] INFO i.m.o.ObservationTextPublisher - STOP - name='grpc.server', contextualName='grpc.testing.SimpleService/UnaryRpc', error='null', lowCardinalityKeyValues=[grpc.status_code='OK', rpc.method='UnaryRpc', rpc.service='grpc.testing.SimpleService', rpc.type='UNARY'], highCardinalityKeyValues=[], map=[], parentObservation=null
11:39:54.922 [single-thread] WARN i.m.o.c.ObservationThreadLocalAccessor - Observation <{name=grpc.server(grpc.testing.SimpleService/UnaryRpc), error=null, context=name='grpc.server', contextualName='grpc.testing.SimpleService/UnaryRpc', error='null', lowCardinalityKeyValues=[grpc.status_code='OK', rpc.method='UnaryRpc', rpc.service='grpc.testing.SimpleService', rpc.type='UNARY'], highCardinalityKeyValues=[], map=[], parentObservation=null}> to which we're restoring is not the same as the one set as this scope's parent observation <null>. Most likely a manually created Observation has a scope opened that was never closed. This may lead to thread polluting and memory leaks.
This is the one:
11:39:54.918 [single-thread] INFO i.m.o.SimpleObservation$SimpleScope - Scope opened: io.micrometer.observation.SimpleObservation$SimpleScope@1629599e
@marcingrzejszczak Any ideas what we can do to debug this issue? I am happy to help, but I need to know where to start π
These kind of problems are the most difficult ones to debug. What you can do is to put a breakpoint inside the SimpleScope that will print the stacktrace when reached. That way you will know who opened the scope and not closed it.
Describe the bug
Some time ago, I added a change to the micrometer that allowed to pass Observation to a gRPC server using kotlin coroutines, see here.
Recently, a new spring boot was released that contains latest changes in micrometer. I tried to use the new Observation propagation feature, but I observed this strange error:
Unfortunately, it seems that the changes that I made are not working as expected. I've prepared a commit that reproduces the issue, see here.
Here are the logs from test execution:
Environment
java -version
]To Reproduce How to reproduce the bug:
see [commit]((https://github.com/micrometer-metrics/micrometer/compare/main...AleksanderBrzozowski:micrometer:support-observation-propagation-for-kotlin-coroutines-grpc-server)
Expected behavior
Seems that the issue is related to
ObservationThreadLocalAccessor.restore
function.Additional context
When observation is not being restored, because a coroutine is not restored, but a new one is started, the issue doesn't happen, see below logs: