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
Fixes #15874 - added logging of 'X_REQUEST_ID' http headers #475
Fixes #15874 - added logging of 'X_REQUEST_ID' http headers #475
Conversation
Some notes:
|
Format = "%s, [%s%s] %5s -- %s: %s\n".freeze | ||
|
||
def call(severity, time, progname, msg) | ||
Format % [severity, format_datetime(time), request_id[0..5], severity, progname, msg2str(msg)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The first severity
field used to be a single letter (severity[0..0]
in stdlib) so it's now duplicated and affects the indentation. Previously:
D, [2016-11-10T13:34:04.946305 #20953] DEBUG -- : require_ssl_client_verification: skipping, non-HTTPS request I, [2016-11-10T13:34:04.946767 #20953] INFO -- : 192.168.122.1 - - [10/Nov/2016 13:34:04] "GET /tftp/serverName HTTP/1.1" 200 30 0.0007
Now:
DEBUG, [2016-11-15T13:12:52.052872 ] DEBUG -- : Rack::Handler::WEBrick is mounted on /. INFO, [2016-11-15T13:12:52.052942 ] INFO -- : WEBrick::HTTPServer#start: pid=4326 port=8443
time.strftime("%Y-%m-%dT%H:%M:%S.%6N ".freeze) | ||
end | ||
|
||
def msg2str(msg) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this inherit Logger::Formatter to avoid copying this implementation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No point, as the methods that I need access to are private (grrr).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A subclass should be able to call the private method (without needing send
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are indeed correct.
@@ -14,6 +14,7 @@ class Proxy::RootApi < Sinatra::Base | |||
|
|||
get "/version" do | |||
begin | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not needed?
def call(env) | ||
Thread.current.thread_variable_set(:request_id, env['HTTP_X_REQUEST_ID']) if env.has_key?('HTTP_X_REQUEST_ID') | ||
to_ret = @app.call(env) | ||
Thread.current.thread_variable_set(:request_id, nil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to break logging of the request ID in a default WEBrick configuration, I can't see the request ID at all in the logs.
It appears from adding debug that the thread var's being cleared by this line before the log formatter's called, so the thread variable is always nil. Commenting it out fixes the logging, but will obviously lead to data leaking between requests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't going to work for logging outside of rack app: the middleware is injected after webrick passes control to it, but before the controller code is invoked. There isn't much I can about this short of changing webrick, which I'd like to avoid.
What I could do however is to log the request (probably via additional middleware) and disable debug logging of requests in webrick/rack?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think I see the issue now, that the Rack::CommonLogger defers logging until the very last minute by using a BodyProxy class. The CommonLogger middleware passes back a BodyProxy class wrapping the original body
with a block that logs when the body is closed. By this point, this RequestIdMiddleware has long since completed.
While I'm not completely adverse to reimplementing request logging, it might be simpler to either:
- Use Rack::BodyProxy here too - pass a BodyProxy with block back out of
call
that will wipe the thread variable, which should then be after CommonLogger. - Subclass Rack::CommonLogger, override
log
to wipe the thread variable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for looking into this -- I didn't think to look into BodyProxy, but it explains why it's always one of the last thing to get logged. I also think using BodyProxy to clear the thread variable is probably the best approach.
I don't think so, it seems fine to me as-is. |
Note: I should point out that only the first 6 digits of the request id are logged, the whole thing (64 digits) would take too much space. |
Format = "%s, [%s%s] %5s -- %s: %s\n".freeze | ||
|
||
def call(severity, time, progname, msg) | ||
Format % [severity[0..0], format_datetime(time), request_id[0..5], severity, progname, msg2str(msg)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you use eight characters of the request ID? Mostly to match what Foreman currently logs - if the same ID is used then it'll be identical in both log files.
Eight characters of the request id are now being logged. Rebased. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still using the first six rather than eight characters?
Actually pushed the change now. |
Thanks, that's better There's a comment on the ticket stating:
Would you be able to add this? |
Request_ids are now being stored when available in the log buffer. |
Thank you @witlessbird, merged. |
No description provided.