forked from open-telemetry/opentelemetry-collector-contrib
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add comments, README, metadata.yaml relative to open-telemetry#24811
- Loading branch information
Showing
13 changed files
with
1,743 additions
and
0 deletions.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# pkg/sampling | ||
|
||
## Overview | ||
|
||
This package contains utilities for parsing and interpreting the W3C | ||
[TraceState](https://www.w3.org/TR/trace-context/#tracestate-header) | ||
and all sampling-relevant fields specified by OpenTelemetry that may | ||
be found in the OpenTelemetry section of the W3C TraceState. | ||
|
||
This package implements the draft specification in [OTEP | ||
235](https://github.com/open-telemetry/oteps/pull/235), which | ||
specifies two fields used by the OpenTelemetry consistent probability | ||
sampling scheme. | ||
|
||
These are: | ||
|
||
- `th`: the Threshold used to determine whether a TraceID is sampled | ||
- `rv`: an explicit randomness value, which overrides randomness in the TraceID | ||
|
||
[OTEP 235](https://github.com/open-telemetry/oteps/pull/235) contains | ||
details on how to interpret these fields. The are not meant to be | ||
human readable, with a few exceptions. The tracestate entry `ot=th:0` | ||
indicates 100% sampling. |
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,127 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package sampling | ||
|
||
import ( | ||
"errors" | ||
"io" | ||
"strings" | ||
|
||
"go.uber.org/multierr" | ||
) | ||
|
||
// KV represents a key-value parsed from a section of the TraceState. | ||
type KV struct { | ||
Key string | ||
Value string | ||
} | ||
|
||
var ( | ||
// ErrTraceStateSize is returned when a TraceState is over its | ||
// size limit, as specified by W3C. | ||
ErrTraceStateSize = errors.New("invalid tracestate size") | ||
) | ||
|
||
// keyValueScanner defines distinct scanner behaviors for lists of | ||
// key-values. | ||
type keyValueScanner struct { | ||
// maxItems is 32 or -1 | ||
maxItems int | ||
// trim is set if OWS (optional whitespace) should be removed | ||
trim bool | ||
// separator is , or ; | ||
separator byte | ||
// equality is = or : | ||
equality byte | ||
} | ||
|
||
// commonTraceState is embedded in both W3C and OTel trace states. | ||
type commonTraceState struct { | ||
kvs []KV | ||
} | ||
|
||
func (cts commonTraceState) HasExtraValues() bool { | ||
return len(cts.kvs) != 0 | ||
} | ||
|
||
func (cts commonTraceState) ExtraValues() []KV { | ||
return cts.kvs | ||
} | ||
|
||
// trimOws removes optional whitespace on both ends of a string. | ||
func trimOws(input string) string { | ||
// Hard-codes the value of owsCharset | ||
for len(input) > 0 && (input[0] == ' ' || input[0] == '\t') { | ||
input = input[1:] | ||
} | ||
for len(input) > 0 && (input[len(input)-1] == ' ' || input[len(input)-1] == '\t') { | ||
input = input[:len(input)-1] | ||
} | ||
return input | ||
} | ||
|
||
// scanKeyValues is common code to scan either W3C or OTel tracestate | ||
// entries, as parameterized in the keyValueScanner struct. | ||
func (s keyValueScanner) scanKeyValues(input string, f func(key, value string) error) error { | ||
var rval error | ||
items := 0 | ||
for input != "" { | ||
items++ | ||
if s.maxItems > 0 && items >= s.maxItems { | ||
// W3C specifies max 32 entries, tested here | ||
// instead of via the regexp. | ||
return ErrTraceStateSize | ||
} | ||
|
||
sep := strings.IndexByte(input, s.separator) | ||
|
||
var member string | ||
if sep < 0 { | ||
member = input | ||
input = "" | ||
} else { | ||
member = input[:sep] | ||
input = input[sep+1:] | ||
} | ||
|
||
if s.trim { | ||
// Trim only required for W3C; OTel does not | ||
// specify whitespace for its value encoding. | ||
member = trimOws(member) | ||
} | ||
|
||
if member == "" { | ||
// W3C allows empty list members. | ||
continue | ||
} | ||
|
||
eq := strings.IndexByte(member, s.equality) | ||
if eq < 0 { | ||
// A regexp should have rejected this input. | ||
continue | ||
} | ||
if err := f(member[:eq], member[eq+1:]); err != nil { | ||
rval = multierr.Append(rval, err) | ||
} | ||
} | ||
return rval | ||
} | ||
|
||
// serializer assists with checking and combining errors from | ||
// (io.StringWriter).WriteString(). | ||
type serializer struct { | ||
writer io.StringWriter | ||
err error | ||
} | ||
|
||
// write handles errors from io.StringWriter. | ||
func (ser *serializer) write(str string) { | ||
_, err := ser.writer.WriteString(str) | ||
ser.check(err) | ||
} | ||
|
||
// check handles errors (e.g., from another serializer). | ||
func (ser *serializer) check(err error) { | ||
ser.err = multierr.Append(ser.err, err) | ||
} |
Oops, something went wrong.