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
contrib/internal/httptrace: record errors in span tags while retrieving client IP #1346
Conversation
…te span tags directly
e3ea201
to
6d1c0dc
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.
I think there's still a few corner cases here that give strange results and still think this can be greatly simplified.
I'm proposing something more along these lines:
// clientIPTags generates the client IP related tags. If there is exactly one, valid IP header, the
// IP will be set in the ext.HTTPClientIP tag. Otherwise, any IP headers will be added as tags with
// ext.HTTPRequestHeaders.<header> keys. If there are no IP headers, the request's RemoteAddr field
// will be used if valid.
func clientIPTags(r *http.Request) []ddtrace.StartSpanOption {
ipHeaders := defaultIPHeaders
if len(clientIPHeader) > 0 {
ipHeaders = []string{clientIPHeader}
}
var ips []string
var tags []ddtrace.StartSpanOption
for _, hdr := range ipHeaders {
if v := r.Header.Get(hdr); v != "" {
ips = append(ips, v)
tags = append(tags, tracer.Tag(ext.HTTPRequestHeaders+"."+hdr, v))
}
}
if len(ips) == 0 {
// Only use the server-detected remote address if the client didn't provide any ip headers.
ips = append(ips, r.RemoteAddr)
}
if len(ips) == 1 {
for _, s := range strings.Split(ips[0], ",") {
ip := parseIP(strings.TrimSpace(s))
if ip.IsValid() && isGlobal(ip) {
return []ddtrace.StartSpanOption{tracer.Tag(ext.HTTPClientIP, ip.String())}
}
}
return tags
}
return append(tags, tracer.Tag(ext.MultipleIPHeaders, strings.Join(ips, ",")))
}
I still question why we should return the ext.HTTPRequestHeaders
list only when there is not a valid IP. Is the name of the header not important when the IP is valid?
Similarly, why do we handle r.RemoteAddr
so differently? It can only ever appear in the ext.HTTPClientIP
tag, but never anywhere else.
@Hellzy My previous review was posted before I saw the new changes. I'll review the new changes once this is ready. |
5f70211
to
24e9d7b
Compare
24e9d7b
to
9c3ff4b
Compare
Pending approval from @katiehockman |
Checked w/ Katie, merging. |
This change follows the RFC update: https://datadoghq.atlassian.net/wiki/spaces/APS/pages/2118779066/Client+IP+addresses+resolution.
In case multiple IP related headers are found in a request, we need to record information for the backend in the span tags.
Added tags:
Changes:
getClientIP
so that it builds the list of IP headers encountered while retrieving the client IP.getClientIP
holds more than one element, the new tags are set with information from this listgenClientIPSpanTags
abstracts this decision logic and returns a map of tag key/values to set for the span