-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Improvement for log_format directive configuration #845
Conversation
Hi @alxmsl Thanks for the PR, we'll review it shortly and get back to you. |
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.
@alxmsl thanks for the PR!
It's nice that now it is possible to support the json escaping without any workaround.
Additionally, I like how now we can split the log format definition across multiple lines.
However, let's consider the following case, where the user wants to split the definition across multiple lines (so that the log format is easier to read/maintain):
log-format: |
remote_addr - $remote_user [$time_local] "$request"
$status $body_bytes_sent "$http_referer"
"$http_user_agent" "$http_x_forwarded_for"
As a result, the following config will be generated:
log_format main 'remote_addr - $remote_user [$time_local] "$request"'
'$status $body_bytes_sent "$http_referer"'
'"$http_user_agent" "$http_x_forwarded_for"'
''
;
Now if the user looks at the logs, they will see:
. . . "POST /coffee HTTP/1.1"200 158 "-""curl/7.54.0" "-"
As you can see, there are no space character between the request and the status, the http refer and the user agent.
Would it be possible to ensure that the IC insert the spaces?
Please also see additional comments.
Also, could you rebase against the master?
internal/configs/version1/nginx.tmpl
Outdated
@@ -34,7 +34,11 @@ http { | |||
{{- end}} | |||
|
|||
{{if .LogFormat -}} | |||
log_format main '{{.LogFormat}}'; | |||
log_format main {{if .LogFormat -}} |
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 {{if .LogFormat -}} ... {{end}}
is not required here - using just range is enough.
the same applies for the stream log format.
Thanks for your fast reply, @pleshakov! And I think it will be better to pipe log format configuration "as is". For example, if log-format: |
'remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'
log_format main 'remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'
; This sample looks much obvious. And additionally, users are allowed to use all power of string values. For example, log format could be defined using these ways:
In this solution I can see just one problem - it doesn't have back-compatibility: users who defined log format like presented below will have error data:
log-format: '{ "@timestamp": "$time_iso8601"}' I don't like that users will have an error and I can omit it using small hack: |
Hi @alxmsl
Agree with that.
While this option gives users the maximum control, I don't think it is necessary and also could lead to errors because of hunting for unmatched If we go back to the original problem -- supporting json escaping - perhaps a slightly different way of implementing that can do that job. What if we have a ConfigMap key The option of supporting multiple lines in the log format is a nice bonus, but considering the original problem, it could be left out of the scope. At the same time, I wonder what you think about a simpler solution for handling multi-line strings- concatenating the strings with the space character. For example (note there are no trailing spaces here): log-format: |
$remote_addr - $remote_user [$time_local] "$request"
$status $body_bytes_sent "$http_referer"
"$http_user_agent" "$http_x_forwarded_for" Becomes log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for"'; Thanks |
Hi @pleshakov
I found this solution as a little bit redundant, but I agree it, because - you're completely right - it solves initial problem and it keeps back-compatibility without any code which can be unclear. So, let me modify this PR to support
I thought about this simple solution before in flow of the maximum control for users. At this moment, I think, this is also well 👍 |
af835e6
to
c0664de
Compare
@pleshakov , I've completed suggested changes. Commits also have been rebased. kind: ConfigMap
apiVersion: v1
metadata:
...
data:
log-format-escaping: "json"
log-format: |
{
"remote_addr": "$remote_addr",
"remote_user": "$remote_user",
"request": "$request"
} Nginx log module is configured like this: log_format main escape=json '{ '
' "remote_addr": "$remote_addr", '
' "remote_user": "$remote_user", '
' "request": "$request" '
'} '
; And log message looks like: { "remote_addr": "127.0.0.1", "remote_user": "", "request": "GET /\" HTTP/1.1" } |
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 the changes!
I left a small comment about readability of the template.
The PR looks good!
I have a small concern regarding the trailing space that will always be present in the logs now, because of the space in the template:
{{with $value }}'{{ $value }} '
However, I can't think how the new behavior can break any existing users. I wonder what you think about it?
@@ -35,7 +35,9 @@ http { | |||
{{- end}} | |||
|
|||
{{if .LogFormat -}} | |||
log_format main '{{.LogFormat}}'; | |||
log_format main {{if .LogFormatEscaping}}escape={{ .LogFormatEscaping }} {{end}}{{range $value := .LogFormat -}} |
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.
for readability of the template, could you put the range loop one line below. For example:
log_format main {{if .LogFormatEscaping}}escape={{ .LogFormatEscaping }} {{end}}
{{range $value := .LogFormat -}}
{{with $value }}'{{ $value }} '{{end}}
{{end}};
Thank you, @pleshakov About the trailing space I can see exactly one much serious problem: now logs is bigger at 1 byte per line. Because I don't see any commonly used cases of calling, for example, And I have made small improvement which looks gracefully, I think: log_format main {{if .LogFormatEscaping}}escape={{ .LogFormatEscaping }} {{end}}
{{range $i, $value := .LogFormat -}}
{{with $value }}'{{if $i}} {{end}}{{ $value }}'
{{end}}{{end}}; If you think, this is over-engineering, of course, I can revert it back |
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.
@alxmsl
The PR looks good! Thanks for the additional investigation around the trailing space problem.
I will ask a coworker to take a final look and we should merge it shortly!
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.
lgtm, did a few tests, couldn't find any problem.
Kudos for the addition of the fields in template_tests
Also it seems this doesn't introduce any breaking change 🎉
Proposed changes
I've found configuration of log_format directive doesn't support
escape
parameter clearly at this moment.For example, if I'd like to have
json
escaping I have to createConfigMap
like this, using fake space-apostrophe substring' '
:This PR contains improvement to solve this problem. Now
log_format
can be configured this way:Additionally, I've kept back-compatibility with previous solution, if somebody is using it...
Checklist
Before creating a PR, run through this checklist and mark each as complete.