access log: add response flag filter#3536
Conversation
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: Jose Nino <jnino@lyft.com>
Signed-off-by: Jose Nino <jnino@lyft.com>
| // A list of the response flags can be found | ||
| // in the access log formatter :ref:`documentation<config_access_log_format_response_flags>`. | ||
| message ResponseFlagFilter { | ||
| } |
There was a problem hiding this comment.
alternatively I thought about adding an option to specify the flags you care about. But I think that response flags are important, and infrequent enough to have the filter filter on all of them. Thoughts?
There was a problem hiding this comment.
One way to achieve both settings is have an array field that will specify which response flags to log on and if that field is empty default to all response flags? (or have an enum that says all)
There was a problem hiding this comment.
Yep, that is what I thought, will add.
|
@zuercher can you do a first pass? |
|
Nothing jumps out -- I'll have another look when you update with the requested change. |
|
quick update here: taking a bit longer because I needed to take a wide detour to protoc-gen-validate. I want to add a rule to the flags field like: PR in pgv fixing https://github.com/lyft/protoc-gen-validate/pull/78 |
|
This pull request has been automatically marked as stale because it has not had activity in the last 7 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions! |
|
@zuercher sorry for the delay here. PR is now up to date. |
zuercher
left a comment
There was a problem hiding this comment.
I think it needs some extra testing but otherwise looks good.
| /** | ||
| * @return whether any response flag is set or not. | ||
| */ | ||
| virtual bool getResponseFlag() const PURE; |
There was a problem hiding this comment.
nit: should this be hasResponseFlag()?
There was a problem hiding this comment.
yeah I think that is a better name, and also a better name for the other function getResponseFlag(ResponseFlag response_flag). I wanted to preserve naming. But now that you brought it up again I think it is probably better for clarity to change both names.
| absl::optional<RequestInfo::ResponseFlag> response_flag = | ||
| RequestInfo::ResponseFlagUtils::toResponseFlag(config.flags(i)); | ||
| // The config has been validated. Therefore, every flag in the config will have a mapping. | ||
| RELEASE_ASSERT(response_flag.has_value()); |
There was a problem hiding this comment.
At this point the set of flags is reproduced in a few places:
- RequestInfo::ResponseFlag
- ResponseFlagUtils
- the ResponseFlagFilter proto message's validation
I think it would be good to have a test that validates each response flag to prove that the list in the validation is correct, and a similar test for toResponseFlag to prove that each flag is in the static map there.
There was a problem hiding this comment.
nit, would probably switch this to normal ASSERT
|
Looks good. I'll approve once the merge conflict is fixed. |
Signed-off-by: Jose Nino <jnino@lyft.com>
|
@zuercher thanks. The conflict has been resolved but the build is going to fail because I moved the PGV sha, and we haven't merged the necessary fix yet (https://github.com/lyft/protoc-gen-validate/pull/78). I'll ping you when that gets merged. |
Signed-off-by: Jose Nino <jnino@lyft.com>
mattklein123
left a comment
There was a problem hiding this comment.
LGTM, just a few small comments. Nice!
| // in the access log formatter :ref:`documentation<config_access_log_format_response_flags>`. | ||
| message ResponseFlagFilter { | ||
| // Only responses with the any of the flags listed in this field will be logged. | ||
| // This field is optional if it is not specified, then any response flag will pass |
There was a problem hiding this comment.
nit: "This field is optional. If it ..."
docs/root/intro/version_history.rst
Outdated
| * access log: added ability to format START_TIME. | ||
| * access log: added DYNAMIC_METADATA :ref:`access log formatter <config_access_log_format>`. | ||
| * access log: added :ref:`HeaderFilter <envoy_api_msg_config.filter.accesslog.v2.HeaderFilter>` | ||
| to filter logs based on request headers |
| absl::optional<RequestInfo::ResponseFlag> response_flag = | ||
| RequestInfo::ResponseFlagUtils::toResponseFlag(config.flags(i)); | ||
| // The config has been validated. Therefore, every flag in the config will have a mapping. | ||
| RELEASE_ASSERT(response_flag.has_value()); |
There was a problem hiding this comment.
nit, would probably switch this to normal ASSERT
| const Http::HeaderMap& request_headers) override; | ||
|
|
||
| private: | ||
| RequestInfo::RequestInfoImpl info_; |
There was a problem hiding this comment.
nit: It seems a little odd to me to have a full request info here, but it's probably fine. Just throwing that out there.
There was a problem hiding this comment.
Yeah, it is a little clunky. I guess I could just maintain the uint64_t for the flags and instead of using the setResponseFlag abstraction do the |= myself.
That way I also can get rid of the currentResponseFlags() method and add less stuff to that api.
wdyt?
There was a problem hiding this comment.
yeah I would probably do that...
Signed-off-by: Jose Nino <jnino@lyft.com>
|
@mattklein123 comments are addressed. |
docs/root/intro/version_history.rst
Outdated
| 1.8.0 (Pending) | ||
| =============== | ||
| * access log: added :ref:`response flag filter <envoy_api_msg_config.filter.accesslog.v2.ResponseFlagFilter>` to filter based on the presence of Envoy response flags. | ||
| to filter logs based on request headers. |
There was a problem hiding this comment.
duplicated text / please break on 100 chars
|
|
||
| #include "common/http/header_utility.h" | ||
| #include "common/protobuf/protobuf.h" | ||
| #include "common/request_info/request_info_impl.h" |
There was a problem hiding this comment.
This header change can be reverted I believe here and above.
| /** | ||
| * @return whether any response flag is set or not. | ||
| */ | ||
| virtual bool hasResponseFlag() const PURE; |
There was a problem hiding this comment.
IMO this function name is a little strange given the other overload of same name Can we call it hasAnyResponseFlag() or something similar?
|
@mattklein123 updated |
access log: add response flag filter
After #3299 merged log lines for gRPC requests that would have resulted in non-200 HTTP status codes in the past (for instance an unroutable request 404 and NR response flag), now result in a 200 HTTP status code. This can potentially filter out log lines that were previously being logged.
This PR adds an access log filter, that prints log lines if an Envoy response flag is set.
Testing: unit tests for the access log filter, and a new API call for the request info class.
Docs Changes:
Added documentation to the filter. And release notes.
Release Notes:
Added release notes.