line / armeria

Your go-to microservice framework for any situation, from the creator of Netty et al. You can build any type of microservice leveraging your favorite technologies, including gRPC, Thrift, Kotlin, Retrofit, Reactive Streams, Spring Boot and Dropwizard.
https://armeria.dev
Apache License 2.0
4.82k stars 915 forks source link

Allow customizing log message format for `Logging{Client,Service}`? #3040

Open trustin opened 4 years ago

trustin commented 4 years ago

Related conversation: https://line-armeria.slack.com/archives/C1NGPBUH2/p1598877787005400

Hello everyone!

We are using com.linecorp.armeria.server.logging.LoggingService but we have a little problem. We are trying to change the order of ctx logging and our custom request/response message logging. But now it's seems to be impossible because of LoggingDecorators and its three default ways of logging:

private static final String REQUEST_FORMAT = "{} Request: {}";
private static final String RESPONSE_FORMAT = "{} Response: {}";
private static final String RESPONSE_FORMAT2 = "{} Response: {}, cause: {}";

Is it possible to log request/response first, and then log ctx information? Just for visual usability.

Our log message looks like:

requestId=..., traceId=..., 1 million more headers, [sreqId=..., chanId=..., raddr=127.0.0.1:port, laddr=127.0.0.1:8080]h2c://url/service/method#POST, Request: {...}...

And our admins wants to see service and method first. So I need something like ctx sanitizer to remove [sreqId=..., chanId=..., raddr=127.0.0.1:port, laddr=127.0.0.1:8080] and only stay h2c://url/service/method#POST, Request: {...}...

anuraaga commented 4 years ago

IIRC we used to have dedicated structural logging but removed it since logback / log4j can generally restructure the log well enough based on the information in the context. Is that right?

https://github.com/line/armeria/blob/master/site/src/pages/docs/advanced-structured-logging.mdx

trustin commented 4 years ago

IIRC we used to have dedicated structural logging but removed it since logback / log4j can generally restructure the log well enough based on the information in the context. Is that right?

It was removed because AccessLogWriter or just a custom callback on RequestLog.whenComplete() will do the same job.

I guess what the user is asking is more about the ways to customize the traditional log messages. For the case shown in the conversion, the user could achieve the goal by:

It's doable by writing one's own decorator instead of using Logging{Client,Service}, but the user will have to reimplement/fork some useful functionalities like sampling and sanitization.

Would it make sense to add one more extension point like this?

interface RequestLogMessageFormatter { // name tbd
    String formatRequest(RequestContext ctx, Object sanitizedRequest);
    String formatResponse(RequestContext ctx, Object sanitizedResponse);
    String formatResponse(RequestContext ctx, Object sanitizedResponse, Throwable cause);
}

I'm not sure if it's a good idea or not yet, though. Just exploring.

anuraaga commented 4 years ago

I see - it feels unfortunate to have to add a formatter interface since the logging libraries provide their own and is sort of duplicate functionality. But I guess since slf4j doesn't provide a way to do structured logging until 2.0, it might be the only way to allow reformatting of our log messages.