Skip to content
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

fix(logging): allow X-Cloud-Trace-Context fields to be optional #3062

Merged
merged 7 commits into from Oct 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
30 changes: 14 additions & 16 deletions logging/logging.go
Expand Up @@ -873,33 +873,31 @@ func (l *Logger) writeLogEntries(entries []*logpb.LogEntry) {
// (for example by calling SetFlags or SetPrefix).
func (l *Logger) StandardLogger(s Severity) *log.Logger { return l.stdLoggers[s] }

var reCloudTraceContext = regexp.MustCompile(`([a-f\d]+)/([a-f\d]+);o=(\d)`)
var reCloudTraceContext = regexp.MustCompile(
// Matches on "TRACE_ID"
`([a-f\d]+)?` +
// Matches on "/SPAN_ID"
`(?:/([a-f\d]+))?` +
// Matches on ";0=TRACE_TRUE"
`(?:;o=(\d))?`)

func deconstructXCloudTraceContext(s string) (traceID, spanID string, traceSampled bool) {
// As per the format described at https://cloud.google.com/trace/docs/troubleshooting#force-trace
// As per the format described at https://cloud.google.com/trace/docs/setup#force-trace
// "X-Cloud-Trace-Context: TRACE_ID/SPAN_ID;o=TRACE_TRUE"
// for example:
// "X-Cloud-Trace-Context: 105445aa7843bc8bf206b120001000/0;o=1"
// "X-Cloud-Trace-Context: 105445aa7843bc8bf206b120001000/1;o=1"
//
// We expect:
// * traceID: "105445aa7843bc8bf206b120001000"
// * spanID: ""
// * traceSampled: true
matches := reCloudTraceContext.FindAllStringSubmatch(s, -1)
if len(matches) != 1 {
return
}
// * traceID (optional): "105445aa7843bc8bf206b120001000"
// * spanID (optional): "1"
// * traceSampled (optional): true
matches := reCloudTraceContext.FindStringSubmatch(s)

sub := matches[0]
if len(sub) != 4 {
return
}
traceID, spanID, traceSampled = matches[1], matches[2], matches[3] == "1"

traceID, spanID = sub[1], sub[2]
if spanID == "0" {
spanID = ""
}
traceSampled = sub[3] == "1"

return
}
Expand Down
38 changes: 37 additions & 1 deletion logging/logging_unexported_test.go
Expand Up @@ -288,18 +288,54 @@ func TestToLogEntryTrace(t *testing.T) {
},
logging.LogEntry{Trace: "projects/P/traces/105445aa7843bc8bf206b120001000", SpanId: "000000000000004a", TraceSampled: true},
},
{
"X-Trace-Context header with blank trace",
Entry{
HTTPRequest: &HTTPRequest{
Request: &http.Request{
URL: u,
Header: http.Header{"X-Cloud-Trace-Context": {"/0;o=1"}},
},
},
},
logging.LogEntry{TraceSampled: true},
},
{
"X-Trace-Context header with blank span",
Entry{
HTTPRequest: &HTTPRequest{
Request: &http.Request{
URL: u,
Header: http.Header{"X-Cloud-Trace-Context": {"105445aa7843bc8bf206b120001000/0;o=0"}},
Header: http.Header{"X-Cloud-Trace-Context": {"105445aa7843bc8bf206b120001000/;o=0"}},
},
},
},
logging.LogEntry{Trace: "projects/P/traces/105445aa7843bc8bf206b120001000"},
},
{
"X-Trace-Context header with missing traceSampled aka ?o=*",
Entry{
HTTPRequest: &HTTPRequest{
Request: &http.Request{
URL: u,
Header: http.Header{"X-Cloud-Trace-Context": {"105445aa7843bc8bf206b120001000/0"}},
},
},
},
logging.LogEntry{Trace: "projects/P/traces/105445aa7843bc8bf206b120001000"},
},
{
"X-Trace-Context header with all blank fields",
Entry{
HTTPRequest: &HTTPRequest{
Request: &http.Request{
URL: u,
Header: http.Header{"X-Cloud-Trace-Context": {""}},
},
},
},
logging.LogEntry{},
},
{
"Invalid X-Trace-Context header but already set TraceID",
Entry{
Expand Down