-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Logging with request context #405
Comments
Where are you invoking your error logging? |
I registered logger using Of course I can log errors via custom error logging middleware. But it will miss request encoding/decoding errors. |
After review the code and your use case, I think if you explicitly want rich error logging, the correct place to do that is in a custom error encoder. The ErrorEncoder is meant for basic diagnostics, and may even be a candidate for deletion. But the error encoder will always be called in case of error, it has access to everything you want, and I think it's the right place for this kind of logic. In #408 I've clarified this in the docs and also added ServerFinalizer, which is a function that can do arbitrary work (including logging) once a request is complete. If you rather want comprehensive logging or instrumentation of the HTTP transport layer, you can also use that mechanism. |
Ok, so the only way to get both error and context is to use custom error encoder. My point about error encoder was that, without looking into the code, its' contract is not entirely obvious. Judging by the name I would expect that it should convert errors to http responses and have no side effects. Having something like Another solution would be to add context to already existing logging functionality. I think that enriching log messages with request context is a pretty common use case. |
I think you are giving the transport layer too much responsibility. Ideally, package transport would be responsible for request/response de/serialization and nothing more. Certain out-of-band metadata e.g. distributed tracing IDs require additional facilities to move information to/from the context i.e. Server{Before,After}Func — but anything more sophisticated than that belongs in your business logic. Transport-layer middlewares would be a big step in the wrong direction. More concretely, you probably ought to move the loggable details from the HTTP request into the context via a BeforeFunc, potentially even into a request-scoped logger object. Then, extract/use those details in your business logic when your error condition is encountered, rather than waiting until the request returns to the transport layer on the way out. Your business logic error to HTTP status code mapping should be well-defined in your business logic — the clean architecture and inward-facing dependencies require it — so you can even determine status code a priori and log it there, too. And thus let the transport layer be mechanical, concerned with rote shuffling of data. Can you say a bit more about the specific error conditions you're trying to enrich with this information? I'd be happy to consult a bit, or offer another solution if I'm overlooking something... |
Actually, that's similar to how I do logging now. The problem is that this does not catch transport decoding errors. One of my microservices was sending invalid requests that failed at request decoding step. |
Or, to put it short, I would like transport errors to be logged in the same way the business logic errors are. |
What's wrong with supporting transport-level middlewares? |
I'm giving this a think. |
I mean you don't need explicit support for middlewares in package transport/http, you can just use them. var handler http.Handler
handler = httptransport.NewServer(...)
handler = myBasicMiddleware(handler)
handler = myParameterizedMiddleware(...)(handler)
mux.Method("GET").Path("/foo").Handler(handler) |
I've also added PopulateRequestContext helper, to get HTTP request details into the context. Hopefully this is enough to help you build something that works :) |
With "classic" middleware I don't have errors and i don't have context. Ok, I will stick to ErrorEncoder |
You do have context, with the Context method on http.Request. (I'll upgrade Go kit to support that more fully when 1.8 is released.) And you can get errors, by intercepting the http.ResponseWriter. |
#421 for using stdlib context, currently pending changes in gRPC (argh). |
I would like to add some request information to my error log messages (http url / endpoint name / request params)
What is the proper way to do this? With
http.ServerErrorLogger()
I have no access to contextThe text was updated successfully, but these errors were encountered: