Skip to content

Commit 5e6a33d

Browse files
committed
Introduce RequestLogListener
Motivation: A single `RequestLogProperty` can be received through `RequestLog.whenAvailable()`, but it is not straightforward to receive all events published by `RequestLog` using `.whenAvailable()`. To address the limitation, I propose introducing an interface that listens to all events by adding it to `RequestLog`. This will also simplify the integration of other implmentations used for collecting metrics. Motifications: - Introduced `RequestLogListener` API that can be attached to `RequestLog`. - `RequestLogAccess.addListener()` API was added and `DefaultRequestLog` implmemeted it. - The listener will be notified whenever a new property is set to `RequestLog`. If some properties have already been set, they will notified of them immediately. - Add `REQUEST_COMPLETE`, `RESPONSE_COMPLETE` and `ALL_COMPLETE` to `RequestLogProperty`. - Previously, there were APIs such as `whenRequestComplete()` and `whenComplete()` that computed and signaled request or response completion and but no explicit properties exists for them. `RequestLogProperty` should represent all states in `RequestLogListener`, I added the new completion properties. - Simplied child log propagation in `DefaultRequestLog` and the `Observation{Service,Client} implementations by using `RequestLogListener`. Result: You can now use `RequestLogListener` to observe all `RequestLog` events.
1 parent b97b391 commit 5e6a33d

File tree

8 files changed

+532
-188
lines changed

8 files changed

+532
-188
lines changed

core/src/main/java/com/linecorp/armeria/client/observation/ObservationClient.java

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import com.linecorp.armeria.common.RequestHeadersBuilder;
3030
import com.linecorp.armeria.common.annotation.Nullable;
3131
import com.linecorp.armeria.common.annotation.UnstableApi;
32-
import com.linecorp.armeria.common.logging.RequestLogProperty;
3332
import com.linecorp.armeria.internal.common.RequestContextExtension;
3433
import com.linecorp.armeria.server.observation.ObservationService;
3534

@@ -138,24 +137,26 @@ public HttpResponse execute(ClientRequestContext ctx, HttpRequest req) throws Ex
138137
private static void enrichObservation(ClientRequestContext ctx,
139138
ClientObservationContext clientObservationContext,
140139
Observation observation) {
141-
ctx.log()
142-
.whenAvailable(RequestLogProperty.REQUEST_FIRST_BYTES_TRANSFERRED_TIME)
143-
.thenAccept(requestLog -> observation.event(Events.WIRE_SEND));
144-
145-
ctx.log()
146-
.whenAvailable(RequestLogProperty.RESPONSE_FIRST_BYTES_TRANSFERRED_TIME)
147-
.thenAccept(requestLog -> {
148-
if (requestLog.responseFirstBytesTransferredTimeNanos() != null) {
149-
observation.event(Events.WIRE_RECEIVE);
150-
}
151-
});
152-
153-
ctx.log().whenComplete()
154-
.thenAccept(requestLog -> {
155-
// TODO: ClientConnectionTimings - there is no way to record events
156-
// with a specific timestamp for an observation
157-
clientObservationContext.setResponse(requestLog);
158-
observation.stop();
159-
});
140+
ctx.log().addListener((property, log) -> {
141+
switch (property) {
142+
case REQUEST_FIRST_BYTES_TRANSFERRED_TIME:
143+
observation.event(Events.WIRE_SEND);
144+
break;
145+
case RESPONSE_FIRST_BYTES_TRANSFERRED_TIME:
146+
if (log.responseFirstBytesTransferredTimeNanos() != null) {
147+
observation.event(Events.WIRE_RECEIVE);
148+
}
149+
break;
150+
case ALL_COMPLETE:
151+
// TODO: ClientConnectionTimings - there is no way to record events
152+
// with a specific timestamp for an observation
153+
clientObservationContext.setResponse(log);
154+
observation.stop();
155+
break;
156+
default:
157+
// Do nothing.
158+
break;
159+
}
160+
});
160161
}
161162
}

0 commit comments

Comments
 (0)