1package dev.rafex.ether.http.jetty12;
29import java.time.Instant;
31import org.eclipse.jetty.server.Handler;
32import org.eclipse.jetty.server.Request;
33import org.eclipse.jetty.server.Response;
34import org.eclipse.jetty.util.Callback;
36import dev.rafex.ether.observability.core.request.RequestIdGenerator;
37import dev.rafex.ether.observability.core.timing.TimingRecorder;
38import dev.rafex.ether.observability.core.timing.TimingSample;
40final class JettyObservabilityHandler
extends Handler.Wrapper {
42 static final String REQUEST_ID_ATTRIBUTE =
"ether.request.id";
43 private static final String REQUEST_ID_HEADER =
"X-Request-Id";
45 private final RequestIdGenerator requestIdGenerator;
46 private final TimingRecorder timingRecorder;
48 JettyObservabilityHandler(
final Handler next,
final RequestIdGenerator requestIdGenerator,
49 final TimingRecorder timingRecorder) {
51 this.requestIdGenerator = requestIdGenerator;
52 this.timingRecorder = timingRecorder;
56 public boolean handle(
final Request request,
final Response response,
final Callback callback)
throws Exception {
57 final var requestId = resolveRequestId(request);
58 request.setAttribute(REQUEST_ID_ATTRIBUTE, requestId);
59 response.getHeaders().put(REQUEST_ID_HEADER, requestId);
61 final var startedAt = Instant.now();
62 Request.addCompletionListener(request, failure -> timingRecorder.record(
new TimingSample(
63 request.getMethod() +
" " + request.getHttpURI().getPath(), startedAt, Instant.now())));
64 return super.handle(request, response, callback);
67 private String resolveRequestId(
final Request request) {
68 final var incoming = request.getHeaders().get(REQUEST_ID_HEADER);
69 if (incoming !=
null && !incoming.isBlank()) {
72 return requestIdGenerator.nextId();
record TimingSample(String name, Instant startedAt, Instant finishedAt)
Muestra de tiempo para medir la duración de una operación.