-
Notifications
You must be signed in to change notification settings - Fork 5k
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
Added support for Trace name truncation for traces #3689
Conversation
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.
As discussed on Slack, we decided to introduce an option that allows users to define the span name length threshold, with the default being that no truncation happens. We also need this to ensure that we don't break existing clients.
The outlined behavior isn't reflected in the PR yet, or is it?
@timoreimann You are right, changed the default to be no truncation. |
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 your contribution @aantono.
First quick review
middlewares/tracing/entrypoint.go
Outdated
opNameFunc := func(r *http.Request) string { | ||
return fmt.Sprintf("Entrypoint %s %s", e.entryPoint, r.Host) | ||
} | ||
//opNameFunc := func(r *http.Request) string { |
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.
Could you remove these comments please
package tracing | ||
|
||
import ( | ||
"github.com/opentracing/opentracing-go/ext" |
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.
Please sort your imports
r *http.Request | ||
next http.HandlerFunc | ||
} | ||
tests := []struct { |
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.
Could you please rename tests
into testCases
} | ||
for _, tt := range tests { | ||
t.Run(tt.desc, func(t *testing.T) { | ||
defaultMockSpan.Reset() |
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.
Could you please run in parallel
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.
Those are run serial on purpose, as the Mock tracer is static and otherwise would be having race conditions.
}, | ||
}, | ||
} | ||
for _, tt := range tests { |
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.
Could you please rename tt
in test
middlewares/tracing/tracing_test.go
Outdated
} | ||
for _, tt := range tests { | ||
t.Run(tt.desc, func(t *testing.T) { | ||
if got := ComputeHash(tt.text); got != tt.want { |
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.
Could you please run your test in parallel
middlewares/tracing/tracing_test.go
Outdated
want: "f9b0078b", | ||
}, | ||
} | ||
for _, tt := range tests { |
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.
Could you please add a new line before
middlewares/tracing/tracing_test.go
Outdated
want: "some-service-100.slug.namespace.envi...", | ||
}, | ||
} | ||
for _, tt := range tests { |
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.
Could you please add a new line before
middlewares/tracing/tracing_test.go
Outdated
want: "some-service-100.slug.namespace.envi...", | ||
}, | ||
} | ||
for _, tt := range tests { |
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.
Could you please rename tt
into test
middlewares/tracing/tracing_test.go
Outdated
} | ||
for _, tt := range tests { | ||
t.Run(tt.desc, func(t *testing.T) { | ||
if got := TruncateString(tt.text, tt.limit); got != tt.want || len(got) > tt.limit { |
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.
Could you please run testCases in parallel
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.
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.
LGTM :)
Great PR @aantono :)
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.
LGTM
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.
HASH ALL THE THINGS
LGTM
Rebased against latest v1.7 |
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.
Left some comments.
Shouldn't we need to update some documentation as well?
middlewares/tracing/entrypoint.go
Outdated
|
||
if spanLimit > 0 && len(name) > spanLimit { | ||
if spanLimit < EntryPointMaxLengthNumber { | ||
log.Warnf("SpanNameLimit is set to be less then required static number of characters, defaulting to %d + 3", EntryPointMaxLengthNumber) |
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.
Grammar: then -> than
middlewares/tracing/tracing.go
Outdated
@@ -13,13 +14,23 @@ import ( | |||
"github.com/opentracing/opentracing-go/ext" | |||
) | |||
|
|||
// ForwardMaxLengthNumber defines the number of static characters in the Forwarding Span Trace name - 8 chars for 'forward ' + 8 chars for hash + 2 chars for '_' |
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.
My brain mistook the -
in Trace name - 8
for a minus shortly due to the other arithmetic operator (+
) used here. Can we use a colon (:
) instead?
middlewares/tracing/tracing.go
Outdated
// ForwardMaxLengthNumber defines the number of static characters in the Forwarding Span Trace name - 8 chars for 'forward ' + 8 chars for hash + 2 chars for '_' | ||
const ForwardMaxLengthNumber = 18 | ||
|
||
// EntryPointMaxLengthNumber defines the number of static characters in the Entrypoint Span Trace name - 11 chars for 'Entrypoint ' + 8 chars for hash + 2 chars for '_' |
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.
Colon here too please.
middlewares/tracing/entrypoint.go
Outdated
@@ -40,3 +38,19 @@ func (e *entryPointMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request, | |||
LogResponseCode(span, recorder.Status()) | |||
span.Finish() | |||
} | |||
|
|||
func generateEntryPointSpanName(r *http.Request, entryPoint string, spanLimit int) string { |
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.
Can we please add a GoDoc to the function explaining what it does, along with an example?
Please include why we do + 3
when we hit the spanLimit < EntryPointMaxLengthNumber
case.
expectedName: "Entrypoint te... ww... 39b97e58", | ||
}, | ||
{ | ||
desc: "no truncation test", |
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'd put this test case first: reading it first helps to understand the other cases.
middlewares/tracing/tracing.go
Outdated
@@ -160,3 +171,28 @@ func SetErrorAndWarnLog(r *http.Request, format string, args ...interface{}) { | |||
log.Warnf(format, args...) | |||
LogEventf(r, format, args...) | |||
} | |||
|
|||
// TruncateString reduces the length of the 'str' argument to 'num' - 3 and adds a '...' suffix to the tail |
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.
Trailing punctuation missing.
middlewares/tracing/tracing.go
Outdated
@@ -160,3 +171,28 @@ func SetErrorAndWarnLog(r *http.Request, format string, args ...interface{}) { | |||
log.Warnf(format, args...) | |||
LogEventf(r, format, args...) | |||
} | |||
|
|||
// TruncateString reduces the length of the 'str' argument to 'num' - 3 and adds a '...' suffix to the tail | |||
func TruncateString(str string, num int) string { |
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.
The function does not need to be exported, does it?
middlewares/tracing/tracing.go
Outdated
return text | ||
} | ||
|
||
// ComputeHash returns the first TraceNameHashLength character of the sha256 hash for 'name' argument |
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.
Trailing punctuation missing.
middlewares/tracing/tracing.go
Outdated
data := []byte(name) | ||
hash := sha256.New() | ||
_, err := hash.Write(data) | ||
if err != nil { |
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.
Can be merged with previous line:
if err := has.Write(data); err != nil {
middlewares/tracing/tracing_test.go
Outdated
expected: "some ve...", | ||
}, | ||
{ | ||
desc: "short text less than limit 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.
Please put this test case first.
middlewares/tracing/entrypoint.go
Outdated
@@ -40,3 +38,20 @@ func (e *entryPointMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request, | |||
LogResponseCode(span, recorder.Status()) | |||
span.Finish() | |||
} | |||
|
|||
// generateEntryPointSpanName will return a Span name of an appropriate lenth based on the 'spanLimit' argument. If needed, it will be truncated, but will not be less than 24 characters |
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.
Trailing punctuation missing.
middlewares/tracing/forwarder.go
Outdated
} | ||
hash := ComputeHash(name) | ||
limit := (spanLimit - ForwardMaxLengthNumber) / 2 | ||
name = fmt.Sprintf("forward %s/%s/%s", TruncateString(frontend, limit), TruncateString(backend, limit), hash) |
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.
👍
middlewares/tracing/tracing.go
Outdated
func SetErrorAndWarnLog(r *http.Request, format string, args ...interface{}) { | ||
SetError(r) | ||
log.Warnf(format, args...) | ||
LogEventf(r, format, args...) | ||
} | ||
|
||
// TruncateString reduces the length of the 'str' argument to 'num' - 3 and adds a '...' suffix to the tail. |
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.
Unexport?
middlewares/tracing/forwarder.go
Outdated
} | ||
|
||
return name | ||
} |
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.
Gotcha, fine with me. 👍
@@ -22,6 +22,12 @@ Træfik supports two backends: Jaeger and Zipkin. | |||
# Default: "traefik" | |||
# | |||
serviceName = "traefik" | |||
|
|||
# Span name limit allows for name truncation in case of very long Frontend/Backend names |
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.
Can we append something like
"This can prevent certain tracing providers from dropping such traces."
?
Similar 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.
What does this PR do?
In many situations the trace name gets pretty large (over 100 chars, especially when using k8s provider). This provides an option to truncate the name to a configurable length to avoid dropped traces.
More