Skip to content

add response code details to stream info#6530

Merged
mattklein123 merged 5 commits intoenvoyproxy:masterfrom
eziskind:rcdetails
Apr 15, 2019
Merged

add response code details to stream info#6530
mattklein123 merged 5 commits intoenvoyproxy:masterfrom
eziskind:rcdetails

Conversation

@eziskind
Copy link
Contributor

@eziskind eziskind commented Apr 9, 2019

Description: add a response code field to the StreamInfo object with a helper class to hold well-known constants. For now this just has 1 value which lets access logs tell if the response is coming from the upstream vs from the envoy itself (in the case of a sendLocalReply), but many more values will added in future PRs. Making this a string rather than an enum so that 3rd parties can extend it.
Risk Level: low
Testing: unit tests

Signed-off-by: Elisha Ziskind eziskind@google.com

Signed-off-by: Elisha Ziskind <eziskind@google.com>
@eziskind
Copy link
Contributor Author

eziskind commented Apr 9, 2019

@alyssawilk, could you take a look?

Copy link
Contributor

@alyssawilk alyssawilk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, thanks for tackling this!

/**
* @param rc_details the response code details string to set for this request.
*/
virtual void setResponseCodeDetails(const std::string& rc_details) PURE;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about absl::string_view?

Some of the details I'd like to see in future include things like passing the http_errno_name from the H1 codec, and those come as char*s, so it'd be nice to avoid stringifying and then copying.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, changed the signature but I left the StreamInfo field as absl::optionalstd::string so there's still going to be a copy. Do you think I should change the field to absl::string_view as well? For that to be safe we'd need to be sure that the actual storage of the string will outlive the StreamInfo object.

virtual void setResponseFlag(ResponseFlag response_flag) PURE;

/**
* @param rc_details the response code details string to set for this request.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe some details here about what response code details are?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}

callbacks_->streamInfo().setResponseCodeDetails(
StreamInfo::ResponseCodeDetails::get().RC_SET_BY_UPSTREAM);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this PR would be a bit more correct if you also did the work to set the string to nothing in sendLocalReply.

I don't think we have any response filters that pause on encodeHeaders, but if we did it could be the case that while that encoder filter were doing its RPC, it took too long and for example triggered an idle timeout where the HCM would sendLocalReply. Because that could transform, say, a 200 from upstream to a 408 where the details would eventually be "stream timeout" but for today would be "" rather than "response_code_set_by_upstream"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Signed-off-by: Elisha Ziskind <eziskind@google.com>
@eziskind
Copy link
Contributor Author

/retest

@repokitteh-read-only
Copy link

🔨 rebuilding ci/circleci: api (failed build)

🐱

Caused by: a #6530 (comment) was created by @eziskind.

see: more, trace.

Copy link
Contributor

@alyssawilk alyssawilk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM modulo one final nit. @junr03 up for doing the cross company pass since I think you have more context?

/**
* Constants for the response code details field of StreamInfo.
*
* These provide details about the stream state such as whether the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One other minor nit - do you think it's worth clarifying what's done now vs what this will do?
These will provide such details, but right now they only do rc_set_by_upstream

I'd be fine with a tracking issue assigned my way for actually setting values in sendLocalReply and referencing the issue here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filed #6542 to track this. I'll add a reference to this in the code.

Signed-off-by: Elisha Ziskind <eziskind@google.com>
alyssawilk
alyssawilk previously approved these changes Apr 10, 2019
@eziskind
Copy link
Contributor Author

/retest

@repokitteh-read-only
Copy link

🔨 rebuilding ci/circleci: build_image (failed build)
🔨 rebuilding ci/circleci: ipv6_tests (failed build)

🐱

Caused by: a #6530 (comment) was created by @eziskind.

see: more, trace.

@eziskind
Copy link
Contributor Author

/retest

@repokitteh-read-only
Copy link

🔨 rebuilding ci/circleci: build_image (failed build)
🔨 rebuilding ci/circleci: ipv6_tests (failed build)
🔨 rebuilding ci/circleci: docker (failed build)

🐱

Caused by: a #6530 (comment) was created by @eziskind.

see: more, trace.

Copy link
Member

@junr03 junr03 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eziskind are you also going to have subsequent PRs to surface this information out, e.g to make this accessible in access logs?

return response_code_details_;
}

void setResponseCodeDetails(absl::string_view rc_details) override {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it up to the caller on how to enrich this information? Or do you imagine codifying this somehow, i.e a comma delimited list of details?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My thinking was that this will be just one of the string constants defined in ResponseCodeDetailValues. That currently only has 1 value but that will change soon (#6542). Also, since this is a string, 3rd party extensions can add additional values if it doesn't make sense to add it to OSS envoy. I don't see a need for making this an array (or comma-separated list). @alyssawilk wdyt?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to add another point - I think the idea is that there should be enough distinct strings available to uniquely specify why envoy is returning an error code (more or less one for each time sendLocalReply is called). So a list of strings should not be necessary.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with it as-is.

For single-hop responses we only need one rc-details. It might be useful to have a full trace of what happened somewhere (500-retried, timeout-retries, gave up and sent 500) but I think that's better off via some other trace mechanism where we can put arbitrary information about how much time was spent in each filter etc. etc.

For multi-hop responses while we might want both layers captured in access logs (e.g. layer-2 envoy had timeout, layer-1 envoy proxied response code sent by upstream) I think that the information from prior hops would be transmitted via headers, and could be sent to access logs via logging the proxy-status header. SG?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, thanks!

* scoped to avoid collisions.
*/
struct ResponseCodeDetailValues {
const std::string RC_SET_BY_UPSTREAM = "response_code_set_by_upstream";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I wonder if we have to prefix RC here given the structs name?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the RC_ prefix

@eziskind
Copy link
Contributor Author

@eziskind are you also going to have subsequent PRs to surface this information out, e.g to make this accessible in access logs?

Access logs already get a reference to the StreamInfo object so they will be able to get the response code details from that.

@junr03
Copy link
Member

junr03 commented Apr 11, 2019

@eziskind are you also going to have subsequent PRs to surface this information out, e.g to make this accessible in access logs?

Access logs already get a reference to the StreamInfo object so they will be able to get the response code details from that.

Right, I know that the access log already has a reference. I am just wondering if you are also going to add functionality to be able to write this new information the stream info has. So for instance in the access log case are you planning on adding it to the formatter:

StreamInfoFormatter::StreamInfoFormatter(const std::string& field_name) {

Just wondering how you are planning to surface the additional info we are adding, the access log just being a concrete place where it could happen.

@eziskind
Copy link
Contributor Author

Just wondering how you are planning to surface the additional info we are adding, the access log just being a concrete place where it could happen.

Thanks for the pointer - I'll add support for logging this field to access_log_formatter.cc

@junr03
Copy link
Member

junr03 commented Apr 11, 2019

Yep! No need to add in this PR if that wasn't the plan. I think this PR stands on itself functionally. I was just wondering how you were thinking about surfacing this information to the system's observability layer.

Signed-off-by: Elisha Ziskind <eziskind@google.com>
@eziskind
Copy link
Contributor Author

Yep! No need to add in this PR if that wasn't the plan. I think this PR stands on itself functionally. I was just wondering how you were thinking about surfacing this information to the system's observability layer.

Sounds good - I'll add this change in a followup PR.

@eziskind
Copy link
Contributor Author

@junr03 can you take another look? Thanks!

junr03
junr03 previously approved these changes Apr 12, 2019
Copy link
Member

@junr03 junr03 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, thanks!

Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, looks good with small nit. Looking forward to seeing this info exposed in access logs and eventually optionally in the actual response body if configured to do so.

/wait

* scoped to avoid collisions.
*/
struct ResponseCodeDetailValues {
const std::string SET_BY_UPSTREAM = "set_by_upstream";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: "set_by_upstream" is a bit vague to me in terms of what it means given we have lots of info in stream info. Perhaps "via_upstream" ? Any other ideas? Also nit, SetByUpstream (trying to avoid capitals for new constants).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"proxied_from_upstream" or "forwarded_from_upstream"? "via_upstream" is fine too and shorter so I'll go with that :)

Signed-off-by: Elisha Ziskind <eziskind@google.com>
Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@mattklein123 mattklein123 merged commit d0f992c into envoyproxy:master Apr 15, 2019
@eziskind eziskind deleted the rcdetails branch April 15, 2019 21:01
lizan pushed a commit that referenced this pull request Apr 19, 2019
)

Description: add formatting for the "response code details" string recently added to the StreamInfo (#6530)
Risk Level: low
Testing: unit tests
Docs Changes: updated
Release Notes: updated

Signed-off-by: Elisha Ziskind <eziskind@google.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants