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

Added support for Trace name truncation for traces #3689

Merged
merged 8 commits into from
Jul 31, 2018

Conversation

aantono
Copy link
Contributor

@aantono aantono commented Jul 27, 2018

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

  • Added/updated tests
  • Added/updated documentation

Copy link
Contributor

@timoreimann timoreimann left a 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?

@aantono
Copy link
Contributor Author

aantono commented Jul 30, 2018

@timoreimann You are right, changed the default to be no truncation.

@mmatur mmatur added kind/enhancement a new or improved feature. kind/bug/fix a bug fix and removed contributor/waiting-for-corrections kind/enhancement a new or improved feature. labels Jul 30, 2018
Copy link
Member

@mmatur mmatur left a 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

opNameFunc := func(r *http.Request) string {
return fmt.Sprintf("Entrypoint %s %s", e.entryPoint, r.Host)
}
//opNameFunc := func(r *http.Request) string {
Copy link
Member

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"
Copy link
Member

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 {
Copy link
Member

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()
Copy link
Member

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

Copy link
Contributor Author

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 {
Copy link
Member

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

}
for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
if got := ComputeHash(tt.text); got != tt.want {
Copy link
Member

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

want: "f9b0078b",
},
}
for _, tt := range tests {
Copy link
Member

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

want: "some-service-100.slug.namespace.envi...",
},
}
for _, tt := range tests {
Copy link
Member

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

want: "some-service-100.slug.namespace.envi...",
},
}
for _, tt := range tests {
Copy link
Member

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

}
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 {
Copy link
Member

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

Copy link
Member

@mmatur mmatur left a comment

Choose a reason for hiding this comment

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

Thanks for your fix @aantono
I created a PR aantono#1 on your fork to improve tests. Could you have a look please

Copy link
Member

@mmatur mmatur left a 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 :)

Copy link
Member

@juliens juliens left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Contributor

@dtomcej dtomcej left a 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
:shipit:

@aantono
Copy link
Contributor Author

aantono commented Jul 31, 2018

Rebased against latest v1.7

Copy link
Contributor

@timoreimann timoreimann left a 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?


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)
Copy link
Contributor

Choose a reason for hiding this comment

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

Grammar: then -> than

@@ -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 '_'
Copy link
Contributor

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?

// 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 '_'
Copy link
Contributor

Choose a reason for hiding this comment

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

Colon here too please.

@@ -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 {
Copy link
Contributor

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",
Copy link
Contributor

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.

@@ -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
Copy link
Contributor

Choose a reason for hiding this comment

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

Trailing punctuation missing.

@@ -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 {
Copy link
Contributor

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?

return text
}

// ComputeHash returns the first TraceNameHashLength character of the sha256 hash for 'name' argument
Copy link
Contributor

Choose a reason for hiding this comment

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

Trailing punctuation missing.

data := []byte(name)
hash := sha256.New()
_, err := hash.Write(data)
if err != nil {
Copy link
Contributor

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 {

expected: "some ve...",
},
{
desc: "short text less than limit 10",
Copy link
Contributor

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.

@@ -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
Copy link
Contributor

Choose a reason for hiding this comment

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

Trailing punctuation missing.

}
hash := ComputeHash(name)
limit := (spanLimit - ForwardMaxLengthNumber) / 2
name = fmt.Sprintf("forward %s/%s/%s", TruncateString(frontend, limit), TruncateString(backend, limit), hash)
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

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.
Copy link
Contributor

Choose a reason for hiding this comment

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

Unexport?

}

return name
}
Copy link
Contributor

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
Copy link
Contributor

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.

Copy link
Contributor

@timoreimann timoreimann left a comment

Choose a reason for hiding this comment

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

LGTM. 👏

let-the-truncation-begin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants