armeria icon indicating copy to clipboard operation
armeria copied to clipboard

ContentPreviewingService logs are inserted after custom logs

Open sedax90 opened this issue 10 months ago • 2 comments

I've added some decorators to my ServerBuilder:

        sb.decorator(LoggingService.newDecorator());

        // Add request/response preview data to logs
        sb.decorator(ContentPreviewingService.newDecorator(Integer.MAX_VALUE));

        // Add trace ID to every request/response
        sb.decorator(TraceIdDecorator::new);

        return sb.build();

With these decorators I would expect log output like this:

REQUEST LOG
MY CUSTOM LOGS...
RESPONSE LOG

but the output that i optain is:

MY CUSTOM LOGS...
REQUEST LOG
RESPONSE LOG

and request/response do not contain the traceId value that I added as a custom decorator (while all the others do).

How can I get the logs to be written in the correct order?

sedax90 avatar Feb 28 '25 09:02 sedax90

request/response do not contain the traceId value that I added as a custom decorator (while all the others do).

Did you set the trace ID using MDC? If so, I recommend using RequestScopedMdc as requests in Armeria are served asynchronously in an event loop.

How can I get the logs to be written in the correct order?

The request and response logs are written together, so it is difficult to inject add MY CUSTOM LOGS using a decorator. https://github.com/line/armeria/blob/ed16bf6f8846415fdadd70d46afc364376669058/core/src/main/java/com/linecorp/armeria/internal/common/logging/LoggingUtils.java#L41-L50 One possible workaround is implementing a custom LogWriter and composing it with the default LogWriter using .andThen().

LogWriter logWriter = LogWriter.of().andThen(new LogWriter() {
    @Override
    public void logRequest(RequestOnlyLog log) {
        logger.info("MY CUSTOM LOGS...");
    }

    @Override
    public void logResponse(RequestLog log) {
        // DO NOTHING
    }
});
LoggingService.builder()
              .logWriter(logWriter)
              .newDecorator();

ikhoon avatar Mar 04 '25 04:03 ikhoon

thanks for your response, TraceID is added like this:

public class TraceIdDecorator extends SimpleDecoratingHttpService {

    public TraceIdDecorator(HttpService delegate) {
        super(delegate);
    }

    @Override
    public HttpResponse serve(ServiceRequestContext ctx, HttpRequest req) throws Exception {
        final String traceId = UUID.randomUUID().toString();

        // Salva il traceId nel contesto della richiesta
        ctx.setAttr(AttributeKey.valueOf("traceId"), traceId);

        // Aggiungi il traceId nei log
        MDC.put("traceId", traceId);

        // Esegui la richiesta
        HttpResponse response = unwrap().serve(ctx, req);

        // Rimuovi il traceId dal MDC alla fine della richiesta
        response.whenComplete().thenRun(() -> MDC.remove("traceId"));

        // Propaga il traceId nella response
        return response.mapHeaders(headers -> headers.toBuilder().set("X-Trace-ID", traceId).build());
    }
}

an my custom logs are not added via decorator but directly in my services, so inside my post/get/etc methods... and before the return

sedax90 avatar Mar 04 '25 07:03 sedax90