-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Add new tail sampling processor policy: status_code #3754
Merged
Merged
Changes from 9 commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
018af94
Refactor tail sampling processor policies
6fb15cc
Add license
5b5f0d2
tailsamplingprocessor: add status code policy
7450b12
Improve tests status_code tail sampling policy
31f775b
Refactor using util helper function
154460d
Add new tail sampling processor latency to changelog
9c63ad4
Add new tail sampling processor status_code to changelog
30bfe7f
Merge branch 'main' into status_code
4836eff
Update processor/tailsamplingprocessor/sampling/status_code.go
b376ad2
Fix error handling
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package sampling | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
|
||
"go.opentelemetry.io/collector/consumer/pdata" | ||
"go.uber.org/zap" | ||
) | ||
|
||
type statusCodeFilter struct { | ||
logger *zap.Logger | ||
statusCodes []pdata.StatusCode | ||
} | ||
|
||
var _ PolicyEvaluator = (*statusCodeFilter)(nil) | ||
|
||
// NewStatusCodeFilter creates a policy evaluator that samples all traces with | ||
// a given status code. | ||
func NewStatusCodeFilter(logger *zap.Logger, statusCodeString []string) (PolicyEvaluator, error) { | ||
if len(statusCodeString) == 0 { | ||
return nil, errors.New("expected at least one status code to filter on") | ||
} | ||
|
||
statusCodes := make([]pdata.StatusCode, len(statusCodeString)) | ||
|
||
for i := range statusCodeString { | ||
switch statusCodeString[i] { | ||
case "OK": | ||
statusCodes[i] = pdata.StatusCodeOk | ||
case "ERROR": | ||
statusCodes[i] = pdata.StatusCodeError | ||
case "UNSET": | ||
statusCodes[i] = pdata.StatusCodeUnset | ||
default: | ||
return nil, fmt.Errorf("unknown status code %q, supported: OK, ERROR, UNSET", statusCodeString) | ||
} | ||
} | ||
|
||
return &statusCodeFilter{ | ||
logger: logger, | ||
statusCodes: statusCodes, | ||
}, nil | ||
} | ||
|
||
// OnLateArrivingSpans notifies the evaluator that the given list of spans arrived | ||
// after the sampling decision was already taken for the trace. | ||
// This gives the evaluator a chance to log any message/metrics and/or update any | ||
// related internal state. | ||
func (r *statusCodeFilter) OnLateArrivingSpans(Decision, []*pdata.Span) error { | ||
r.logger.Debug("Triggering action for late arriving spans in status code filter") | ||
return nil | ||
} | ||
|
||
// Evaluate looks at the trace data and returns a corresponding SamplingDecision. | ||
func (r *statusCodeFilter) Evaluate(_ pdata.TraceID, trace *TraceData) (Decision, error) { | ||
r.logger.Debug("Evaluating spans in status code filter") | ||
|
||
trace.Lock() | ||
batches := trace.ReceivedBatches | ||
trace.Unlock() | ||
|
||
return hasSpanWithCondition(batches, func(span pdata.Span) bool { | ||
for _, statusCode := range r.statusCodes { | ||
if span.Status().Code() == statusCode { | ||
return true | ||
} | ||
} | ||
return false | ||
}), nil | ||
} |
101 changes: 101 additions & 0 deletions
101
processor/tailsamplingprocessor/sampling/status_code_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package sampling | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"go.opentelemetry.io/collector/consumer/pdata" | ||
"go.uber.org/zap" | ||
) | ||
|
||
func TestNewStatusCodeFilter_errorHandling(t *testing.T) { | ||
_, err := NewStatusCodeFilter(zap.NewNop(), []string{}) | ||
assert.Error(t, err, "expected at least one status code to filter on") | ||
|
||
_, err = NewStatusCodeFilter(zap.NewNop(), []string{"OK", "ERR"}) | ||
assert.Error(t, err, "unknown status code ERR, supported: OK, ERROR, UNSET") | ||
} | ||
|
||
func TestPercentageSampling(t *testing.T) { | ||
traceID := pdata.NewTraceID([16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}) | ||
|
||
cases := []struct { | ||
Desc string | ||
StatusCodesToFilterOn []string | ||
StatusCodesPresent []pdata.StatusCode | ||
Decision Decision | ||
}{ | ||
{ | ||
Desc: "filter on ERROR - none match", | ||
StatusCodesToFilterOn: []string{"ERROR"}, | ||
StatusCodesPresent: []pdata.StatusCode{pdata.StatusCodeOk, pdata.StatusCodeUnset, pdata.StatusCodeOk}, | ||
Decision: NotSampled, | ||
}, | ||
{ | ||
Desc: "filter on OK and ERROR - none match", | ||
StatusCodesToFilterOn: []string{"OK", "ERROR"}, | ||
StatusCodesPresent: []pdata.StatusCode{pdata.StatusCodeUnset, pdata.StatusCodeUnset}, | ||
Decision: NotSampled, | ||
}, | ||
{ | ||
Desc: "filter on UNSET - matches", | ||
StatusCodesToFilterOn: []string{"UNSET"}, | ||
StatusCodesPresent: []pdata.StatusCode{pdata.StatusCodeUnset}, | ||
Decision: Sampled, | ||
}, | ||
{ | ||
Desc: "filter on OK and UNSET - matches", | ||
StatusCodesToFilterOn: []string{"OK", "UNSET"}, | ||
StatusCodesPresent: []pdata.StatusCode{pdata.StatusCodeError, pdata.StatusCodeOk}, | ||
Decision: Sampled, | ||
}, | ||
} | ||
|
||
for _, c := range cases { | ||
t.Run(c.Desc, func(t *testing.T) { | ||
traces := pdata.NewTraces() | ||
rs := traces.ResourceSpans().AppendEmpty() | ||
ils := rs.InstrumentationLibrarySpans().AppendEmpty() | ||
|
||
for _, statusCode := range c.StatusCodesPresent { | ||
span := ils.Spans().AppendEmpty() | ||
span.Status().SetCode(statusCode) | ||
span.SetTraceID(pdata.NewTraceID([16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16})) | ||
span.SetSpanID(pdata.NewSpanID([8]byte{1, 2, 3, 4, 5, 6, 7, 8})) | ||
} | ||
|
||
trace := &TraceData{ | ||
ReceivedBatches: []pdata.Traces{traces}, | ||
} | ||
|
||
statusCodeFilter, err := NewStatusCodeFilter(zap.NewNop(), c.StatusCodesToFilterOn) | ||
assert.NoError(t, err) | ||
|
||
decision, err := statusCodeFilter.Evaluate(traceID, trace) | ||
assert.NoError(t, err) | ||
assert.Equal(t, c.Decision, decision) | ||
}) | ||
} | ||
} | ||
|
||
func TestOnLateArrivingSpans_PercentageSampling(t *testing.T) { | ||
statusCode, err := NewStatusCodeFilter(zap.NewNop(), []string{"ERROR"}) | ||
assert.Nil(t, err) | ||
|
||
err = statusCode.OnLateArrivingSpans(NotSampled, nil) | ||
assert.Nil(t, err) | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 guess the latency made it to 0.29.0, no?
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.
Actually... 0.29.0 hasn't been released for contrib yet. I heard yesterday that the release train has departed already, though (#3863).
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.
Is it still possible to get this PR in 0.29 or is the release already cut?
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'm not sure how to avoid a merge conflict with the release PR, should I wait until #3863 is merged to rebase and update the changelog?
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 @bogdandrutu mentioned yesterday that they were having build problems, blocking the release. I don't expect any new features to be included for 0.29.0. Wait for the release, then rebase and update the changelog.