-
Notifications
You must be signed in to change notification settings - Fork 690
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
internal/envoy: configurable access log format #3694
Conversation
This is a work-in-progress for requesting comments. The PR lacks e.g. validation, tests, documentation... Example use in contour.yaml configuration file accesslog-format-string: "[%START_TIME%] \"%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%\" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% \"%REQ(X-FORWARDED-FOR)%\" \"%REQ(USER-AGENT)%\" \"%REQ(X-REQUEST-ID)%\" \"%REQ(:AUTHORITY)%\" \"%UPSTREAM_HOST%\"\n" Motivation would be to allow user to set custom access log format and also utilize Envoy access log formatter command extensions. Example extension envoyproxy/envoy#15711. Access log format extensions could be optionally built into Envoy binary and in theory they might be even out-of-tree code that was added into a custom build of Envoy. The list of valid access log commands cannot be anymore known in advance - full validation within Contour would not be possible. I would appreciate your opinion about this feature! |
Codecov Report
@@ Coverage Diff @@
## main #3694 +/- ##
==========================================
- Coverage 76.96% 75.88% -1.09%
==========================================
Files 109 107 -2
Lines 8475 7361 -1114
==========================================
- Hits 6523 5586 -937
+ Misses 1818 1654 -164
+ Partials 134 121 -13
|
5f7a1df
to
fd6283d
Compare
@tsaarni sorry we've been slow to provide feedback here. In principle I think this feature makes sense. With regard to the command operators, I'm not sure if you've seen but we've accepted a contribution to do something similar for headers: https://projectcontour.io/docs/v1.16.0/config/request-rewriting/#dynamic-header-values and https://github.com/projectcontour/contour/blob/main/internal/dag/policy.go#L262-L305. With that feature, we included an allow-list of possible command operators in the Contour code. That makes me wonder, do you know what Envoy's behavior is if a malformed access log format string is passed? Will it NACK the config update, or ignore invalid command operators, or something else? That may inform how paranoid we need to be about ensuring the passed value is valid. |
Thanks @skriss for responding!
Yes, I think I would need to do that anyways: my underlying goal #3576 would require use of Envoy's (forthcoming) log format command operator extension. These formatter extension needs to be enabled explicitly before use. For Contour to allow using such command operator, it would need to recognize the command enable the corresponding extension like this #3576 (comment). On the other hand, if the command is not used, the extension would not need to be enabled (or it could be always enabled, but this would mean Envoy needs to be always compiled with that extension). The JSON access log validation does bit more: it checks the command operator syntax with regex but I'm bit uncertain how far to go? It can only capture some specific errors, e.g. it cannot validate if header name in If letting Envoy to do the validation, one gets quite good error message in NACK, at least in this case. I guess the biggest difference is that when Contour is validating, it will If new command operators are introduced, maintaining allow-list will always mean code impact on Contour. Though it seems that Envoy encourages to implement new command operators as formatter extensions, so it would mean code impact anyways - for maintaining a list of extensions to enable.
It will NACK the config update, and give error message which will be visible both in Contour and Envoy logs, example here #3576 (comment). |
96cb7fa
to
04cd6c0
Compare
I've now adapted the existing validation code from JSON access log fields so that the same validation is also done for text access log format configuration. Meanwhile, the access log formatter extension which I was working in Envoy was merged envoyproxy/envoy#15711. I uplifted |
04cd6c0
to
58e2efa
Compare
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 PR @tsaarni - I think this looks pretty reasonable. I had some minor inline comments. I still need to look at the tests in some more detail as well.
It'd also be nice to find some place to document this more thoroughly than the config reference docs. One option would be to expand the JSON access logging guide (https://projectcontour.io/guides/structured-logs/) to cover non-JSON access logging as well, and to include the new operator / extension there. We could do that in a separate PR that we don't merge until the next release, since the guides aren't versioned so any changes are "live" immediately (xref #3829 for changing that, I don't see any reason why we shouldn't version the guides).
@@ -5,7 +5,7 @@ go 1.15 | |||
require ( | |||
github.com/ahmetb/gen-crd-api-reference-docs v0.3.0 | |||
github.com/bombsimon/logrusr v1.0.0 | |||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210111201334-f1f47757da33 | |||
github.com/envoyproxy/go-control-plane v0.9.10-0.20210614203518-782de910ff04 |
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.
need to decide if we're comfortable shipping with this commit, or if we want to wait for an official v0.9.10.
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've done this in the past as well, but not sure how quickly go-control-plane is releasing. Could even pull this out as a separate commit to verify tests, etc.
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.
I think as long as tests are passing (which they are currently), I'm OK with shipping with a specific commit here.
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.
I need to do some real tests with this. Would be super nice to have some E2E tests or follow up with some in another PR. The only downside is we need to test against an unreleased version of Envoy at the moment.
@@ -54,6 +54,10 @@ data: | |||
### Logging options | |||
# Default setting | |||
accesslog-format: envoy | |||
# The default access log format is defined by Envoy but it can be customized by setting following 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.
This might need to be docs on the site. I worry we're getting too many comments in the config file.
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.
I've shortened the text by removing the link to Envoy docs and the full example (still leaving short example value accesslog-format-string: "...\n"
)
The config file is bit hard to read in general. Maybe one small improvement would be changing indentation of fields-vs-comments, see e.g. sshd_config
# first comment
#first-field:
# second comment
#second-field:
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.
d'oh, it obviously fails anyways to be readable due to structs having indentations :-D
# first comment
#first-field:
# sub-field:
# second comment
maybe double-hash for comments:
## first comment
#first-field:
# sub-field:
## second 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.
Yeah, this formatting is not great. I filed #3843 to make some improvements here.
@@ -5,7 +5,7 @@ go 1.15 | |||
require ( | |||
github.com/ahmetb/gen-crd-api-reference-docs v0.3.0 | |||
github.com/bombsimon/logrusr v1.0.0 | |||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210111201334-f1f47757da33 | |||
github.com/envoyproxy/go-control-plane v0.9.10-0.20210614203518-782de910ff04 |
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've done this in the past as well, but not sure how quickly go-control-plane is releasing. Could even pull this out as a separate commit to verify tests, etc.
Format: &envoy_config_core_v3.SubstitutionFormatString_TextFormatSource{ | ||
TextFormatSource: &envoy_config_core_v3.DataSource{ | ||
Specifier: &envoy_config_core_v3.DataSource_InlineString{ | ||
InlineString: format, |
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.
Will Envoy blow up if the format is invalid? Or just not log properly?
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.
Oh I see there's a parser below.
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, the same parser is now used for both JSON and text based logs. If for some reason invalid format would still get through parser, I've tested how Envoy would react, for results see #3576 (comment).
There is also one very common error that could be validated: there needs to be \n
at the end of the line.
When it is not included, logs are not flushed until certain amount of logs have been written. And obviously, everything comes as one long line. I think I saw old discussions about automatically adding this, but it is still not done today.
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.
Oof, yeah, that \n
one is a great candidate for us to check, as you probably would never actually want that behavior.
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.
Yeah, I think I'm a 👍 to enforcing/adding the \n
.
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.
I've now added check for \n
.
a1fcd1f
to
0c9e075
Compare
0c9e075
to
a28de3e
Compare
I believe I have covered current comments for now. Please take a look. I'll create another issue for updating https://projectcontour.io/guides/structured-logs/ (or some other page) with detailed usage docs. One question regarding API: I guess adding third option ( |
I think leaving it as |
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 further comments from me, LGTM. thanks @tsaarni!
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 LGTM, but before we merge, I just need to check: @tsaarni, what version of Envoy is the required extension available in? Do we need to hold this PR until after v1.17.0 to wait for the new Envoy version?
If it works with v1.18.3, then we're good to go, if not, we should hold off merging, since 1.17.0 is due out tomorrow (my time).
Otherwise it will work but if user adds the new command operator extension |
Hmm, okay, thanks. While I know it's the reason you're making the change, I don't think that we can introduce this feature with a known-not-working field in it, given the current level of Envoy support. In that case, we have two options:
@tsaarni, what do you think? |
Yes, lets wait for the Envoy release first. It will avoid some extra work. |
I'll add the do not merge tag for now so we dont accidentally merge this |
Marking this PR stale since there has been no activity for 14 days. It will be closed if there is no activity for another 30 days. |
Just merged #3887, so I think this is ready to go now, just need a quick rebase to fix merge conflicts. |
a28de3e
to
be32c62
Compare
I've now rebased and run manual test with the current Envoy version. I did not look yet how this could be fully automated in the integration tests but I've written manual test procedure here https://gist.github.com/tsaarni/6e8be52179d775bf2a90b6e009e5ef94 |
This is ready to merge from my perspective now that we've updated Envoy, cc @youngnick to confirm |
Sorry @tsaarni, needs another rebase. |
* Adds new configuration option that allows setting the format string for Envoy's text based access log. * Adds support for Envoy's REQ_WITHOUT_QUERY command operator, which can be used to avoid writing query string to access log. Signed-off-by: Tero Saarni <[email protected]>
be32c62
to
be9c0a8
Compare
@skriss no problem, rebase done! |
Awesome, thanks. I''ll merge this first thing next week unless I hear otherwise from @youngnick |
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.
Envoy 1.19 is out now, so I thnk we are good to go.
* configurable access log format Signed-off-by: Tero Saarni <[email protected]>
This change adds following features:
Fixes #3576
Signed-off-by: Tero Saarni [email protected]