-
Notifications
You must be signed in to change notification settings - Fork 82
[RFC] Rest logging improvements #978
base: master
Are you sure you want to change the base?
[RFC] Rest logging improvements #978
Conversation
It is useful to log the request as it is being made to the server rather than relying entirely on logging generated after the request. Logging before the request is processed can help a person debugging with understanding when the client first made the request. Log the client's user agent string. Signed-off-by: John Mulligan <[email protected]>
Support having the rest client library send a more specific user agent string to the server. Provide a mechanism for tools built upon that library to add more specific user agent information. Use the api in the glusercli command line tool to specify itself. Signed-off-by: John Mulligan <[email protected]>
Extend the cli such that it can send it's original command line arguments to the server so that the server may log the original command that initiated the api call. Signed-off-by: John Mulligan <[email protected]>
I like the overall approach. It'll be great if changes such as this come with a sample output. I pulled this to local repo to see how it looks like: curl -s -X GET http://127.0.0.1:24007/v1/peers
glustercli peer list
Some observations and suggestion:
That is okay for now as it helps in debugging if it's in the same logfile. It's easier to track timelines. |
@@ -14,8 +14,16 @@ import ( | |||
// Apache Common Log Format (CLF) | |||
func LogRequest(next http.Handler) http.Handler { | |||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | |||
entry := log.WithField("reqid", gdctx.GetReqID(r.Context()).String()) | |||
entry := log.WithFields(log.Fields{ | |||
"subsys": "rest", |
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.
Is subsys
an Apache log term with a specific meaning ?
If it's a general term that expands to "subsystem", we don't have other subsystems and this field can be removed.
@@ -114,6 +123,8 @@ func (c *Client) do(method string, url string, data interface{}, expectStatusCod | |||
req.Header.Set("Authorization", "bearer "+getAuthToken(c.username, c.password)) | |||
} | |||
|
|||
c.sendOriginArgs(req) |
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.
Suggestion: this can be named to setOriginArgs
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.
We have a c.SetOriginArgs
which does a different job to sendOriginArgs
. The suggested rename makes the code more confusing.
I'd suggest that it be renamed to addOriginArgs
, but that would take away the consistent naming with the other "set" methods being called. Maybe also rename 'c.setAgentto
c.addAgent`?
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.
Perhaps we keep SetOriginArgs and rename this to addOriginArgsToHeaders ?
"reqid": gdctx.GetReqID(r.Context()).String(), | ||
} | ||
if origin := r.Header.Get("X-Gluster-Origin-Args"); origin != "" { | ||
f["origin"] = origin |
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.
TRIVIAL: IMO origin seems a bit ambiguous, a better variable name can be chosen, something like orgnArgs.
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.
Sounds good.
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.
Looks good, some minor comments
@@ -20,6 +21,8 @@ var ( | |||
|
|||
func initRESTClient(hostname, user, secret, cacert string, insecure bool) { | |||
client = restclient.New(hostname, user, secret, cacert, insecure) | |||
client.ExtendAgent( | |||
fmt.Sprintf("glustercli/%v", version.GlusterdVersion)) |
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.
nit: We can have cli version instead of glusterd version. For now it is same, but it can change in future. @prashanthpai your thoughts?
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.
IMO, this should be okay. glustercli and glusterd are almost always built together. We can quickly identify if older/outdated clients connect to more recent glusterd2 by looking at the version if they follow same versioning. A separate version for CLI will makes more sense if it's a separate repo/project.
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.
makes sense. we can update later if that happens.
// by prefixing it to the existing agent information. | ||
// This allows client programs to identify themselves more than | ||
// just something using the rest client api. | ||
func (c *Client) ExtendAgent(a string) { |
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.
please rename "a" to something meaningful.
// inform the server what arguments were provided to generate | ||
// the api call(s). The contents of the array are meant only for | ||
// human interpretation but will generally be command line args. | ||
func (c *Client) SetOriginArgs(a []string) { |
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.
same here, please rename "a"
|
||
func (c *Client) sendOriginArgs(req *http.Request) { | ||
if len(c.originArgs) != 0 { | ||
req.Header.Set("X-Gluster-Origin-Args", |
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 is nice. is this logged? I don't see this detail in output @prashanthpai posted #978 (comment)
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.
It should be, but only if the client sends it. I'm not exactly sure exactly how @prashanthpai got his examples, but when I incorporate the other feedback for these changes I'll include examples of the logging as well.
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.
My bad. I think I did make glusterd2
as I usually do. I can see it after I recompiled the CLI.
INFO[2018-07-17 10:03:37.209081] HTTP Request client="glustercli/v4.1.0-97.git987fac1 GlusterD2-rest-client/v4.1.0-97.git987fac1 (Go-http-client/1.1)" method=GET origin="1:\"glustercli peer list\"" reqid=817c7683-37dd-4b04-a589-16136deaf766 source="[request_logging.go:29:middleware.LogRequest.func1]" subsys=rest url=/v1/peers
INFO[2018-07-17 10:03:37.209832] 127.0.0.1 - - [17/Jul/2018:10:03:37 +0530] "GET /v1/peers HTTP/1.1" 401 71 "" "glustercli/v4.1.0-97.git987fac1 GlusterD2-rest-client/v4.1.0-97.git987fac1 (Go-http-client/1.1)" origin="1:\"glustercli peer list\"" reqid=817c7683-37dd-4b04-a589-16136deaf766 subsys=rest
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.
nice, thanks for the update
Do we need this to extend to sprint 2? Or we can close it in a day's time? |
Subsys was going to be how I redirected some of the logging into an special purpose log file equivalent to what @atinmu orginally requested. Additionally, I actually think the general approach is good; tag subsystems so that you can easily grep a logfile for the subsystem you care about. Note I'm not deeply in love with the 'subsys' name, but I think there's some value here.
When I was working on this change orginally, I was wondering why this was one of the only places that didn't log the source. I tried to make it so that the logging that was originally there continued to skip the If you really want it gone I think we'll need to tweak the hook that generates the source item rather than
Good point. Will do.
Sure, based on the original issue I was going to add an additional option like `--accesslog [/path/to/file | STDOUT] that would start a seperate "logging stream" for certain log entries (see above). When deployed as a container this could certainly be off by default but in the more traditional deployment the service file might specify --accesslog to create the gd2 equivalent of the command log. |
@phlogistonjohn would you mind refreshing this? |
Sorry for the long delay. I will try to get around to this soon. |
Issue #887 requests a few improvements to the logging, based on that discussion I've done the following:
Still to-do is the ability to log these items to an additional/separate log file.
I figured I'd throw an RFC PR out to get some feedback on the approaches I took here. I do not expect this PR to be merged in this state, just looking for discussion.