3232import org .reactivestreams .Publisher ;
3333import reactor .core .publisher .Flux ;
3434import reactor .core .publisher .Mono ;
35+ import reactor .util .annotation .Nullable ;
3536import reactor .util .context .ContextView ;
3637
3738/**
4344 */
4445public class ObservationRequesterRSocketProxy extends RSocketProxy {
4546
47+ /** Aligned with ObservationThreadLocalAccessor#KEY */
48+ private static final String MICROMETER_OBSERVATION_KEY = "micrometer.observation" ;
49+
4650 private final ObservationRegistry observationRegistry ;
4751
48- private RSocketRequesterObservationConvention observationConvention ;
52+ @ Nullable private final RSocketRequesterObservationConvention observationConvention ;
4953
5054 public ObservationRequesterRSocketProxy (RSocket source , ObservationRegistry observationRegistry ) {
55+ this (source , observationRegistry , null );
56+ }
57+
58+ public ObservationRequesterRSocketProxy (
59+ RSocket source ,
60+ ObservationRegistry observationRegistry ,
61+ RSocketRequesterObservationConvention observationConvention ) {
5162 super (source );
5263 this .observationRegistry = observationRegistry ;
64+ this .observationConvention = observationConvention ;
5365 }
5466
5567 @ Override
@@ -76,15 +88,7 @@ <T> Mono<T> setObservation(
7688 FrameType frameType ,
7789 ObservationDocumentation observation ) {
7890 return Mono .deferContextual (
79- contextView -> {
80- if (contextView .hasKey (Observation .class )) {
81- Observation parent = contextView .get (Observation .class );
82- try (Observation .Scope scope = parent .openScope ()) {
83- return observe (input , payload , frameType , observation );
84- }
85- }
86- return observe (input , payload , frameType , observation );
87- });
91+ contextView -> observe (input , payload , frameType , observation , contextView ));
8892 }
8993
9094 private String route (Payload payload ) {
@@ -107,45 +111,40 @@ private <T> Mono<T> observe(
107111 Function <Payload , Mono <T >> input ,
108112 Payload payload ,
109113 FrameType frameType ,
110- ObservationDocumentation obs ) {
114+ ObservationDocumentation obs ,
115+ ContextView contextView ) {
111116 String route = route (payload );
112117 RSocketContext rSocketContext =
113118 new RSocketContext (
114119 payload , payload .sliceMetadata (), frameType , route , RSocketContext .Side .REQUESTER );
120+ Observation parentObservation = contextView .getOrDefault (MICROMETER_OBSERVATION_KEY , null );
115121 Observation observation =
116- obs .start (
117- this .observationConvention ,
118- new DefaultRSocketRequesterObservationConvention (rSocketContext ),
119- () -> rSocketContext ,
120- observationRegistry );
122+ obs .observation (
123+ this .observationConvention ,
124+ new DefaultRSocketRequesterObservationConvention (rSocketContext ),
125+ () -> rSocketContext ,
126+ observationRegistry )
127+ .parentObservation (parentObservation );
121128 setContextualName (frameType , route , observation );
129+ observation .start ();
122130 Payload newPayload = payload ;
123131 if (rSocketContext .modifiedPayload != null ) {
124132 newPayload = rSocketContext .modifiedPayload ;
125133 }
126134 return input
127135 .apply (newPayload )
128136 .doOnError (observation ::error )
129- .doFinally (signalType -> observation .stop ());
130- }
131-
132- private Observation observation (ContextView contextView ) {
133- if (contextView .hasKey (Observation .class )) {
134- return contextView .get (Observation .class );
135- }
136- return null ;
137+ .doFinally (signalType -> observation .stop ())
138+ .contextWrite (context -> context .put (MICROMETER_OBSERVATION_KEY , observation ));
137139 }
138140
139141 @ Override
140142 public Flux <Payload > requestStream (Payload payload ) {
141- return Flux .deferContextual (
142- contextView ->
143- setObservation (
144- super ::requestStream ,
145- payload ,
146- contextView ,
147- FrameType .REQUEST_STREAM ,
148- RSocketObservationDocumentation .RSOCKET_REQUESTER_REQUEST_STREAM ));
143+ return observationFlux (
144+ super ::requestStream ,
145+ payload ,
146+ FrameType .REQUEST_STREAM ,
147+ RSocketObservationDocumentation .RSOCKET_REQUESTER_REQUEST_STREAM );
149148 }
150149
151150 @ Override
@@ -155,32 +154,16 @@ public Flux<Payload> requestChannel(Publisher<Payload> inbound) {
155154 (firstSignal , flux ) -> {
156155 final Payload firstPayload = firstSignal .get ();
157156 if (firstPayload != null ) {
158- return setObservation (
157+ return observationFlux (
159158 p -> super .requestChannel (flux .skip (1 ).startWith (p )),
160159 firstPayload ,
161- firstSignal .getContextView (),
162160 FrameType .REQUEST_CHANNEL ,
163161 RSocketObservationDocumentation .RSOCKET_REQUESTER_REQUEST_CHANNEL );
164162 }
165163 return flux ;
166164 });
167165 }
168166
169- private Flux <Payload > setObservation (
170- Function <Payload , Flux <Payload >> input ,
171- Payload payload ,
172- ContextView contextView ,
173- FrameType frameType ,
174- ObservationDocumentation obs ) {
175- Observation parentObservation = observation (contextView );
176- if (parentObservation == null ) {
177- return observationFlux (input , payload , frameType , obs );
178- }
179- try (Observation .Scope scope = parentObservation .openScope ()) {
180- return observationFlux (input , payload , frameType , obs );
181- }
182- }
183-
184167 private Flux <Payload > observationFlux (
185168 Function <Payload , Flux <Payload >> input ,
186169 Payload payload ,
@@ -196,17 +179,22 @@ private Flux<Payload> observationFlux(
196179 frameType ,
197180 route ,
198181 RSocketContext .Side .REQUESTER );
182+ Observation parentObservation =
183+ contextView .getOrDefault (MICROMETER_OBSERVATION_KEY , null );
199184 Observation newObservation =
200- obs .start (
201- this .observationConvention ,
202- new DefaultRSocketRequesterObservationConvention (rSocketContext ),
203- () -> rSocketContext ,
204- this .observationRegistry );
185+ obs .observation (
186+ this .observationConvention ,
187+ new DefaultRSocketRequesterObservationConvention (rSocketContext ),
188+ () -> rSocketContext ,
189+ this .observationRegistry )
190+ .parentObservation (parentObservation );
205191 setContextualName (frameType , route , newObservation );
192+ newObservation .start ();
206193 return input
207194 .apply (rSocketContext .modifiedPayload )
208195 .doOnError (newObservation ::error )
209- .doFinally (signalType -> newObservation .stop ());
196+ .doFinally (signalType -> newObservation .stop ())
197+ .contextWrite (context -> context .put (MICROMETER_OBSERVATION_KEY , newObservation ));
210198 });
211199 }
212200
@@ -217,8 +205,4 @@ private void setContextualName(FrameType frameType, String route, Observation ne
217205 newObservation .contextualName (frameType .name ());
218206 }
219207 }
220-
221- public void setObservationConvention (RSocketRequesterObservationConvention convention ) {
222- this .observationConvention = convention ;
223- }
224208}
0 commit comments