diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8f239644b69..cfc6f13ae7f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -124,8 +124,10 @@ jobs: arch: "386" - os: ubuntu-latest arch: amd64 - - os: macos-latest + - os: macos-13 arch: amd64 + - os: macos-latest + arch: arm64 - os: windows-latest arch: "386" - os: windows-latest diff --git a/.github/workflows/protect-released-changelog.yml b/.github/workflows/protect-released-changelog.yml new file mode 100644 index 00000000000..c5c8730299a --- /dev/null +++ b/.github/workflows/protect-released-changelog.yml @@ -0,0 +1,20 @@ +# This action against that any PR targeting the main branch touches released +# sections in CHANGELOG file. If change to released CHANGELOG is required, like +# doing a release, add the \"Unlock Released Changelog\" label to disable this action. + +name: Protect released changelog + +on: + pull_request: + types: [opened, synchronize, reopened, labeled, unlabeled] +jobs: + protect-released-changelog: + runs-on: ubuntu-latest + if: ${{ !contains(github.event.pull_request.labels.*.name, 'Unlock Released Changelog')}} + + steps: + - uses: actions/checkout@v4 + + - name: Protect the released changelog + run: | + ./verify_released_changelog.sh ${{ github.base_ref }} diff --git a/CHANGELOG.md b/CHANGELOG.md index c01e6998e0b..b976608c708 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,17 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## [Unreleased] +### Added + +- Add macOS ARM64 platform to the compatibility testing suite. (#5577) + +### Fixed + +- Correct comments for the priority of the `WithEndpoint` and `WithEndpointURL` options and their corresponding environment variables in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#5584) + + + + ## [1.28.0/0.50.0/0.4.0] 2024-07-02 ### Added @@ -49,6 +60,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Fix stale timestamps reported by the last-value aggregation. (#5517) - Indicate the `Exporter` in `go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp` must be created by the `New` method. (#5521) - Improved performance in all `{Bool,Int64,Float64,String}SliceValue` functions of `go.opentelemetry.io/attributes` by reducing the number of allocations. (#5549) +- Replace invalid percent-encoded octet sequences with replacement char in `go.opentelemetry.io/otel/baggage`. (#5528) ## [1.27.0/0.49.0/0.3.0] 2024-05-21 @@ -175,7 +187,7 @@ The next release will require at least [Go 1.21]. This module includes OpenTelemetry Go's implementation of the Logs Bridge API. This module is in an alpha state, it is subject to breaking changes. See our [versioning policy](./VERSIONING.md) for more info. (#4961) -- ARM64 platform to the compatibility testing suite. (#4994) +- Add ARM64 platform to the compatibility testing suite. (#4994) ### Fixed @@ -3086,6 +3098,8 @@ It contains api and sdk for trace and meter. [0.1.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.1.1 [0.1.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.1.0 + + [Go 1.22]: https://go.dev/doc/go1.22 [Go 1.21]: https://go.dev/doc/go1.21 [Go 1.20]: https://go.dev/doc/go1.20 diff --git a/README.md b/README.md index 5a890931731..51b91526158 100644 --- a/README.md +++ b/README.md @@ -47,20 +47,22 @@ stop ensuring compatibility with these versions in the following manner: Currently, this project supports the following environments. -| OS | Go Version | Architecture | -|---------|------------|--------------| -| Ubuntu | 1.22 | amd64 | -| Ubuntu | 1.21 | amd64 | -| Ubuntu | 1.22 | 386 | -| Ubuntu | 1.21 | 386 | -| Linux | 1.22 | arm64 | -| Linux | 1.21 | arm64 | -| MacOS | 1.22 | amd64 | -| MacOS | 1.21 | amd64 | -| Windows | 1.22 | amd64 | -| Windows | 1.21 | amd64 | -| Windows | 1.22 | 386 | -| Windows | 1.21 | 386 | +| OS | Go Version | Architecture | +|----------|------------|--------------| +| Ubuntu | 1.22 | amd64 | +| Ubuntu | 1.21 | amd64 | +| Ubuntu | 1.22 | 386 | +| Ubuntu | 1.21 | 386 | +| Linux | 1.22 | arm64 | +| Linux | 1.21 | arm64 | +| macOS 13 | 1.22 | amd64 | +| macOS 13 | 1.21 | amd64 | +| macOS | 1.22 | arm64 | +| macOS | 1.21 | arm64 | +| Windows | 1.22 | amd64 | +| Windows | 1.21 | amd64 | +| Windows | 1.22 | 386 | +| Windows | 1.21 | 386 | While this project should work for other systems, no compatibility guarantees are made for those systems currently. diff --git a/RELEASING.md b/RELEASING.md index 940f57f3d87..59992984d42 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -69,6 +69,7 @@ Update go.mod for submodules to depend on the new release which will happen in t ``` - Move all the `Unreleased` changes into a new section following the title scheme (`[] - `). + - Make sure the new section is under the comment for released section, like ``, so it is protected from being overwritten in the future. - Update all the appropriate links at the bottom. 4. Push the changes to upstream and create a Pull Request on GitHub. diff --git a/baggage/baggage.go b/baggage/baggage.go index c40c896cc66..42cd46d842d 100644 --- a/baggage/baggage.go +++ b/baggage/baggage.go @@ -294,19 +294,45 @@ func parseMember(member string) (Member, error) { return newInvalidMember(), fmt.Errorf("%w: %q", errInvalidKey, key) } - val := strings.TrimSpace(v) - if !validateValue(val) { + rawVal := strings.TrimSpace(v) + if !validateValue(rawVal) { return newInvalidMember(), fmt.Errorf("%w: %q", errInvalidValue, v) } // Decode a percent-encoded value. - value, err := url.PathUnescape(val) + unescapeVal, err := url.PathUnescape(rawVal) if err != nil { return newInvalidMember(), fmt.Errorf("%w: %w", errInvalidValue, err) } + + value := replaceInvalidUTF8Sequences(len(rawVal), unescapeVal) return Member{key: key, value: value, properties: props, hasData: true}, nil } +// replaceInvalidUTF8Sequences replaces invalid UTF-8 sequences with '�'. +func replaceInvalidUTF8Sequences(cap int, unescapeVal string) string { + if utf8.ValidString(unescapeVal) { + return unescapeVal + } + // W3C baggage spec: + // https://github.com/w3c/baggage/blob/8c215efbeebd3fa4b1aceb937a747e56444f22f3/baggage/HTTP_HEADER_FORMAT.md?plain=1#L69 + + var b strings.Builder + b.Grow(cap) + for i := 0; i < len(unescapeVal); { + r, size := utf8.DecodeRuneInString(unescapeVal[i:]) + if r == utf8.RuneError && size == 1 { + // Invalid UTF-8 sequence found, replace it with '�' + _, _ = b.WriteString("�") + } else { + _, _ = b.WriteRune(r) + } + i += size + } + + return b.String() +} + // validate ensures m conforms to the W3C Baggage specification. // A key must be an ASCII string, returning an error otherwise. func (m Member) validate() error { @@ -607,10 +633,12 @@ func parsePropertyInternal(s string) (p Property, ok bool) { } // Decode a percent-encoded value. - value, err := url.PathUnescape(s[valueStart:valueEnd]) + rawVal := s[valueStart:valueEnd] + unescapeVal, err := url.PathUnescape(rawVal) if err != nil { return } + value := replaceInvalidUTF8Sequences(len(rawVal), unescapeVal) ok = true p.key = s[keyStart:keyEnd] diff --git a/baggage/baggage_test.go b/baggage/baggage_test.go index 30150e4f92d..146673846fc 100644 --- a/baggage/baggage_test.go +++ b/baggage/baggage_test.go @@ -9,6 +9,7 @@ import ( "slices" "strings" "testing" + "unicode/utf8" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -469,6 +470,18 @@ func TestBaggageParse(t *testing.T) { in: tooManyMembers, err: errMemberNumber, }, + { + name: "percent-encoded octet sequences do not match the UTF-8 encoding scheme", + in: "k=aa%ffcc;p=d%fff", + want: baggage.List{ + "k": { + Value: "aa�cc", + Properties: []baggage.Property{ + {Key: "p", Value: "d�f", HasValue: true}, + }, + }, + }, + }, } for _, tc := range testcases { @@ -480,6 +493,53 @@ func TestBaggageParse(t *testing.T) { } } +func TestBaggageParseValue(t *testing.T) { + testcases := []struct { + name string + in string + valueWant string + valueWantSize int + }{ + { + name: "percent encoded octet sequence matches UTF-8 encoding scheme", + in: "k=aa%26cc", + valueWant: "aa&cc", + valueWantSize: 5, + }, + { + name: "percent encoded octet sequence doesn't match UTF-8 encoding scheme", + in: "k=aa%ffcc", + valueWant: "aa�cc", + valueWantSize: 7, + }, + { + name: "multiple percent encoded octet sequences don't match UTF-8 encoding scheme", + in: "k=aa%ffcc%fedd%fa", + valueWant: "aa�cc�dd�", + valueWantSize: 15, + }, + { + name: "raw value", + in: "k=aacc", + valueWant: "aacc", + valueWantSize: 4, + }, + } + + for _, tc := range testcases { + t.Run(tc.name, func(t *testing.T) { + b, err := Parse(tc.in) + assert.Empty(t, err) + + val := b.Members()[0].Value() + + assert.EqualValues(t, val, tc.valueWant) + assert.Equal(t, len(val), tc.valueWantSize) + assert.True(t, utf8.ValidString(val)) + }) + } +} + func TestBaggageString(t *testing.T) { testcases := []struct { name string @@ -979,7 +1039,7 @@ func BenchmarkParse(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { - benchBaggage, _ = Parse(`userId=alice,serverNode = DF28 , isProduction = false,hasProp=stuff;propKey;propWValue=value`) + benchBaggage, _ = Parse("userId=alice,serverNode = DF28 , isProduction = false,hasProp=stuff;propKey;propWValue=value, invalidUtf8=pr%ffo%ffp%fcValue") } } diff --git a/bridge/opentracing/test/go.mod b/bridge/opentracing/test/go.mod index 1ca3cadc980..a27c35cdb90 100644 --- a/bridge/opentracing/test/go.mod +++ b/bridge/opentracing/test/go.mod @@ -28,7 +28,7 @@ require ( golang.org/x/net v0.27.0 // indirect golang.org/x/sys v0.22.0 // indirect golang.org/x/text v0.16.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/bridge/opentracing/test/go.sum b/bridge/opentracing/test/go.sum index 890ef718bf0..8645e2f1f29 100644 --- a/bridge/opentracing/test/go.sum +++ b/bridge/opentracing/test/go.sum @@ -49,8 +49,8 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= diff --git a/example/otel-collector/docker-compose.yaml b/example/otel-collector/docker-compose.yaml index 81565fcab3a..c9bd107a86c 100644 --- a/example/otel-collector/docker-compose.yaml +++ b/example/otel-collector/docker-compose.yaml @@ -11,13 +11,13 @@ services: - 4317:4317 prometheus: - image: prom/prometheus:v2.53.0 + image: prom/prometheus:v2.53.1 volumes: - ./prometheus.yaml:/etc/prometheus/prometheus.yml ports: - 9090:9090 jaeger: - image: jaegertracing/all-in-one:1.58 + image: jaegertracing/all-in-one:1.59 ports: - 16686:16686 diff --git a/example/otel-collector/go.mod b/example/otel-collector/go.mod index 281e793641a..0630b9ee245 100644 --- a/example/otel-collector/go.mod +++ b/example/otel-collector/go.mod @@ -29,8 +29,8 @@ require ( golang.org/x/net v0.27.0 // indirect golang.org/x/sys v0.22.0 // indirect golang.org/x/text v0.16.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/example/otel-collector/go.sum b/example/otel-collector/go.sum index 87358c7ef53..e1851503a08 100644 --- a/example/otel-collector/go.sum +++ b/example/otel-collector/go.sum @@ -27,10 +27,10 @@ golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 h1:0+ozOGcrp+Y8Aq8TLNN2Aliibms5LEzsq99ZZmAGYm0= -google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094/go.mod h1:fJ/e3If/Q67Mj99hin0hMhiNyCRmt6BQ2aWIJshUSJw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= diff --git a/exporters/otlp/otlplog/otlploggrpc/client_test.go b/exporters/otlp/otlplog/otlploggrpc/client_test.go index 11326fe424c..004a6f4131d 100644 --- a/exporters/otlp/otlplog/otlploggrpc/client_test.go +++ b/exporters/otlp/otlplog/otlploggrpc/client_test.go @@ -451,6 +451,7 @@ func (c *grpcCollector) Collect() *storage { } func clientFactory(t *testing.T, rCh <-chan exportResult) (*client, *grpcCollector) { + t.Helper() coll, err := newGRPCCollector("", rCh) require.NoError(t, err) diff --git a/exporters/otlp/otlplog/otlploggrpc/exporter.go b/exporters/otlp/otlplog/otlploggrpc/exporter.go index 659846bb6b4..dcd6b9ecf9f 100644 --- a/exporters/otlp/otlplog/otlploggrpc/exporter.go +++ b/exporters/otlp/otlplog/otlploggrpc/exporter.go @@ -32,6 +32,9 @@ type Exporter struct { var _ log.Exporter = (*Exporter)(nil) // New returns a new [Exporter]. +// +// It is recommended to use it with a [BatchProcessor] +// or other processor exporting records asynchronously. func New(_ context.Context, options ...Option) (*Exporter, error) { cfg := newConfig(options) c, err := newClient(cfg) @@ -51,7 +54,7 @@ var transformResourceLogs = transform.ResourceLogs // Export transforms and transmits log records to an OTLP receiver. // -// This method returns nil error if called after Shutdown. +// This method returns nil and drops records if called after Shutdown. // This method returns an error if the method is canceled by the passed context. func (e *Exporter) Export(ctx context.Context, records []log.Record) error { if e.stopped.Load() { diff --git a/exporters/otlp/otlplog/otlploggrpc/exporter_test.go b/exporters/otlp/otlplog/otlploggrpc/exporter_test.go index 5888ba9332d..427c2c69ed9 100644 --- a/exporters/otlp/otlplog/otlploggrpc/exporter_test.go +++ b/exporters/otlp/otlplog/otlploggrpc/exporter_test.go @@ -19,6 +19,8 @@ import ( "go.opentelemetry.io/otel/log" sdklog "go.opentelemetry.io/otel/sdk/log" collogpb "go.opentelemetry.io/proto/otlp/collector/logs/v1" + "go.opentelemetry.io/otel/log" + sdklog "go.opentelemetry.io/otel/sdk/log" logpb "go.opentelemetry.io/proto/otlp/logs/v1" ) @@ -50,6 +52,8 @@ func (m *mockClient) Shutdown(context.Context) error { } func TestExporterExport(t *testing.T) { + errClient := errors.New("client") + testCases := []struct { name string logs []sdklog.Record @@ -66,8 +70,8 @@ func TestExporterExport(t *testing.T) { { name: "Error", logs: make([]sdklog.Record, 2), - err: errors.New("test"), - wantErr: errors.New("test"), + err: errClient, + wantErr: errClient, }, } diff --git a/exporters/otlp/otlplog/otlploggrpc/go.mod b/exporters/otlp/otlplog/otlploggrpc/go.mod index 6f24d33aa8f..16cfe3c5e57 100644 --- a/exporters/otlp/otlplog/otlploggrpc/go.mod +++ b/exporters/otlp/otlplog/otlploggrpc/go.mod @@ -12,7 +12,7 @@ require ( go.opentelemetry.io/otel/sdk/log v0.4.0 go.opentelemetry.io/otel/trace v1.28.0 go.opentelemetry.io/proto/otlp v1.3.1 - google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 + google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d google.golang.org/grpc v1.65.0 google.golang.org/protobuf v1.34.2 ) @@ -30,7 +30,7 @@ require ( golang.org/x/net v0.27.0 // indirect golang.org/x/sys v0.22.0 // indirect golang.org/x/text v0.16.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/exporters/otlp/otlplog/otlploggrpc/go.sum b/exporters/otlp/otlplog/otlploggrpc/go.sum index eed02789f1c..fed342fd00b 100644 --- a/exporters/otlp/otlplog/otlploggrpc/go.sum +++ b/exporters/otlp/otlplog/otlploggrpc/go.sum @@ -32,10 +32,10 @@ golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 h1:0+ozOGcrp+Y8Aq8TLNN2Aliibms5LEzsq99ZZmAGYm0= -google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094/go.mod h1:fJ/e3If/Q67Mj99hin0hMhiNyCRmt6BQ2aWIJshUSJw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= diff --git a/exporters/otlp/otlplog/otlploghttp/exporter.go b/exporters/otlp/otlplog/otlploghttp/exporter.go index deee36c001c..f1c8d3ae0a7 100644 --- a/exporters/otlp/otlplog/otlploghttp/exporter.go +++ b/exporters/otlp/otlplog/otlploghttp/exporter.go @@ -23,6 +23,9 @@ type Exporter struct { var _ log.Exporter = (*Exporter)(nil) // New returns a new [Exporter]. +// +// It is recommended to use it with a [BatchProcessor] +// or other processor exporting records asynchronously. func New(_ context.Context, options ...Option) (*Exporter, error) { cfg := newConfig(options) c, err := newHTTPClient(cfg) diff --git a/exporters/otlp/otlplog/otlploghttp/go.mod b/exporters/otlp/otlplog/otlploghttp/go.mod index 87d997d9dbf..902d80b7318 100644 --- a/exporters/otlp/otlplog/otlploghttp/go.mod +++ b/exporters/otlp/otlplog/otlploghttp/go.mod @@ -28,8 +28,8 @@ require ( golang.org/x/net v0.27.0 // indirect golang.org/x/sys v0.22.0 // indirect golang.org/x/text v0.16.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect google.golang.org/grpc v1.65.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/exporters/otlp/otlplog/otlploghttp/go.sum b/exporters/otlp/otlplog/otlploghttp/go.sum index eed02789f1c..fed342fd00b 100644 --- a/exporters/otlp/otlplog/otlploghttp/go.sum +++ b/exporters/otlp/otlplog/otlploghttp/go.sum @@ -32,10 +32,10 @@ golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 h1:0+ozOGcrp+Y8Aq8TLNN2Aliibms5LEzsq99ZZmAGYm0= -google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094/go.mod h1:fJ/e3If/Q67Mj99hin0hMhiNyCRmt6BQ2aWIJshUSJw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= diff --git a/exporters/otlp/otlpmetric/otlpmetricgrpc/go.mod b/exporters/otlp/otlpmetric/otlpmetricgrpc/go.mod index 76d881331c2..50f51661935 100644 --- a/exporters/otlp/otlpmetric/otlpmetricgrpc/go.mod +++ b/exporters/otlp/otlpmetric/otlpmetricgrpc/go.mod @@ -12,7 +12,7 @@ require ( go.opentelemetry.io/otel/sdk v1.28.0 go.opentelemetry.io/otel/sdk/metric v1.28.0 go.opentelemetry.io/proto/otlp v1.3.1 - google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 + google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d google.golang.org/grpc v1.65.0 google.golang.org/protobuf v1.34.2 ) @@ -31,7 +31,7 @@ require ( golang.org/x/net v0.27.0 // indirect golang.org/x/sys v0.22.0 // indirect golang.org/x/text v0.16.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/exporters/otlp/otlpmetric/otlpmetricgrpc/go.sum b/exporters/otlp/otlpmetric/otlpmetricgrpc/go.sum index eed02789f1c..fed342fd00b 100644 --- a/exporters/otlp/otlpmetric/otlpmetricgrpc/go.sum +++ b/exporters/otlp/otlpmetric/otlpmetricgrpc/go.sum @@ -32,10 +32,10 @@ golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 h1:0+ozOGcrp+Y8Aq8TLNN2Aliibms5LEzsq99ZZmAGYm0= -google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094/go.mod h1:fJ/e3If/Q67Mj99hin0hMhiNyCRmt6BQ2aWIJshUSJw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= diff --git a/exporters/otlp/otlpmetric/otlpmetrichttp/go.mod b/exporters/otlp/otlpmetric/otlpmetrichttp/go.mod index 16592effb5d..7c5dd840ca5 100644 --- a/exporters/otlp/otlpmetric/otlpmetrichttp/go.mod +++ b/exporters/otlp/otlpmetric/otlpmetrichttp/go.mod @@ -30,8 +30,8 @@ require ( golang.org/x/net v0.27.0 // indirect golang.org/x/sys v0.22.0 // indirect golang.org/x/text v0.16.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/exporters/otlp/otlpmetric/otlpmetrichttp/go.sum b/exporters/otlp/otlpmetric/otlpmetrichttp/go.sum index eed02789f1c..fed342fd00b 100644 --- a/exporters/otlp/otlpmetric/otlpmetrichttp/go.sum +++ b/exporters/otlp/otlpmetric/otlpmetrichttp/go.sum @@ -32,10 +32,10 @@ golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 h1:0+ozOGcrp+Y8Aq8TLNN2Aliibms5LEzsq99ZZmAGYm0= -google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094/go.mod h1:fJ/e3If/Q67Mj99hin0hMhiNyCRmt6BQ2aWIJshUSJw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= diff --git a/exporters/otlp/otlptrace/otlptracegrpc/go.mod b/exporters/otlp/otlptrace/otlptracegrpc/go.mod index 81db240da21..c15c0aff6bc 100644 --- a/exporters/otlp/otlptrace/otlptracegrpc/go.mod +++ b/exporters/otlp/otlptrace/otlptracegrpc/go.mod @@ -11,7 +11,7 @@ require ( go.opentelemetry.io/otel/trace v1.28.0 go.opentelemetry.io/proto/otlp v1.3.1 go.uber.org/goleak v1.3.0 - google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 + google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d google.golang.org/grpc v1.65.0 google.golang.org/protobuf v1.34.2 ) @@ -28,7 +28,7 @@ require ( golang.org/x/net v0.27.0 // indirect golang.org/x/sys v0.22.0 // indirect golang.org/x/text v0.16.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/exporters/otlp/otlptrace/otlptracegrpc/go.sum b/exporters/otlp/otlptrace/otlptracegrpc/go.sum index 303b38d0db4..53736949bd0 100644 --- a/exporters/otlp/otlptrace/otlptracegrpc/go.sum +++ b/exporters/otlp/otlptrace/otlptracegrpc/go.sum @@ -34,10 +34,10 @@ golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 h1:0+ozOGcrp+Y8Aq8TLNN2Aliibms5LEzsq99ZZmAGYm0= -google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094/go.mod h1:fJ/e3If/Q67Mj99hin0hMhiNyCRmt6BQ2aWIJshUSJw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= diff --git a/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/options_test.go b/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/options_test.go index 715c04fd6b3..46d0d105fb4 100644 --- a/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/options_test.go +++ b/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig/options_test.go @@ -127,6 +127,26 @@ func TestConfigs(t *testing.T) { assert.Equal(t, "/v1/traces", c.Traces.URLPath) }, }, + { + name: "Test With Endpoint last used", + opts: []GenericOption{ + WithEndpointURL("https://someendpoint/somepath"), + WithEndpoint("someendpoint2"), + }, + asserts: func(t *testing.T, c *Config, grpcOption bool) { + assert.Equal(t, "someendpoint2", c.Traces.Endpoint) + }, + }, + { + name: "Test With WithEndpointURL last used", + opts: []GenericOption{ + WithEndpoint("someendpoint2"), + WithEndpointURL("https://someendpoint/somepath"), + }, + asserts: func(t *testing.T, c *Config, grpcOption bool) { + assert.Equal(t, "someendpoint", c.Traces.Endpoint) + }, + }, { name: "Test Environment Endpoint", env: map[string]string{ @@ -159,15 +179,31 @@ func TestConfigs(t *testing.T) { { name: "Test Mixed Environment and With Endpoint", opts: []GenericOption{ + WithEndpointURL("https://traces_endpoint2/somepath"), WithEndpoint("traces_endpoint"), }, env: map[string]string{ - "OTEL_EXPORTER_OTLP_ENDPOINT": "env_endpoint", + "OTEL_EXPORTER_OTLP_ENDPOINT": "env_endpoint", + "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT": "env_endpoint2", }, asserts: func(t *testing.T, c *Config, grpcOption bool) { assert.Equal(t, "traces_endpoint", c.Traces.Endpoint) }, }, + { + name: "Test Mixed Environment and With Endpoint", + opts: []GenericOption{ + WithEndpoint("traces_endpoint"), + WithEndpointURL("https://traces_endpoint2/somepath"), + }, + env: map[string]string{ + "OTEL_EXPORTER_OTLP_ENDPOINT": "env_endpoint", + "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT": "env_endpoint2", + }, + asserts: func(t *testing.T, c *Config, grpcOption bool) { + assert.Equal(t, "traces_endpoint2", c.Traces.Endpoint) + }, + }, { name: "Test Environment Endpoint with HTTP scheme", env: map[string]string{ diff --git a/exporters/otlp/otlptrace/otlptracehttp/go.mod b/exporters/otlp/otlptrace/otlptracehttp/go.mod index 45ace56381c..8dbf543a269 100644 --- a/exporters/otlp/otlptrace/otlptracehttp/go.mod +++ b/exporters/otlp/otlptrace/otlptracehttp/go.mod @@ -26,8 +26,8 @@ require ( golang.org/x/net v0.27.0 // indirect golang.org/x/sys v0.22.0 // indirect golang.org/x/text v0.16.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/exporters/otlp/otlptrace/otlptracehttp/go.sum b/exporters/otlp/otlptrace/otlptracehttp/go.sum index eed02789f1c..fed342fd00b 100644 --- a/exporters/otlp/otlptrace/otlptracehttp/go.sum +++ b/exporters/otlp/otlptrace/otlptracehttp/go.sum @@ -32,10 +32,10 @@ golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 h1:0+ozOGcrp+Y8Aq8TLNN2Aliibms5LEzsq99ZZmAGYm0= -google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094/go.mod h1:fJ/e3If/Q67Mj99hin0hMhiNyCRmt6BQ2aWIJshUSJw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY= +google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d h1:JU0iKnSg02Gmb5ZdV8nYsKEKsP6o/FGVWTrw4i1DA9A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240711142825-46eb208f015d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= diff --git a/exporters/otlp/otlptrace/otlptracehttp/internal/otlpconfig/options_test.go b/exporters/otlp/otlptrace/otlptracehttp/internal/otlpconfig/options_test.go index 1a4e5aab110..7ac0711d0eb 100644 --- a/exporters/otlp/otlptrace/otlptracehttp/internal/otlpconfig/options_test.go +++ b/exporters/otlp/otlptrace/otlptracehttp/internal/otlpconfig/options_test.go @@ -127,6 +127,26 @@ func TestConfigs(t *testing.T) { assert.Equal(t, "/v1/traces", c.Traces.URLPath) }, }, + { + name: "Test With Endpoint last used", + opts: []GenericOption{ + WithEndpointURL("https://someendpoint/somepath"), + WithEndpoint("someendpoint2"), + }, + asserts: func(t *testing.T, c *Config, grpcOption bool) { + assert.Equal(t, "someendpoint2", c.Traces.Endpoint) + }, + }, + { + name: "Test With WithEndpointURL last used", + opts: []GenericOption{ + WithEndpoint("someendpoint2"), + WithEndpointURL("https://someendpoint/somepath"), + }, + asserts: func(t *testing.T, c *Config, grpcOption bool) { + assert.Equal(t, "someendpoint", c.Traces.Endpoint) + }, + }, { name: "Test Environment Endpoint", env: map[string]string{ @@ -159,15 +179,31 @@ func TestConfigs(t *testing.T) { { name: "Test Mixed Environment and With Endpoint", opts: []GenericOption{ + WithEndpointURL("https://traces_endpoint2/somepath"), WithEndpoint("traces_endpoint"), }, env: map[string]string{ - "OTEL_EXPORTER_OTLP_ENDPOINT": "env_endpoint", + "OTEL_EXPORTER_OTLP_ENDPOINT": "env_endpoint", + "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT": "env_endpoint2", }, asserts: func(t *testing.T, c *Config, grpcOption bool) { assert.Equal(t, "traces_endpoint", c.Traces.Endpoint) }, }, + { + name: "Test Mixed Environment and With Endpoint", + opts: []GenericOption{ + WithEndpoint("traces_endpoint"), + WithEndpointURL("https://traces_endpoint2/somepath"), + }, + env: map[string]string{ + "OTEL_EXPORTER_OTLP_ENDPOINT": "env_endpoint", + "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT": "env_endpoint2", + }, + asserts: func(t *testing.T, c *Config, grpcOption bool) { + assert.Equal(t, "traces_endpoint2", c.Traces.Endpoint) + }, + }, { name: "Test Environment Endpoint with HTTP scheme", env: map[string]string{ diff --git a/exporters/otlp/otlptrace/otlptracehttp/options.go b/exporters/otlp/otlptrace/otlptracehttp/options.go index 6497f3ccdd0..3559c5664f4 100644 --- a/exporters/otlp/otlptrace/otlptracehttp/options.go +++ b/exporters/otlp/otlptrace/otlptracehttp/options.go @@ -62,8 +62,10 @@ func (w wrappedOption) applyHTTPOption(cfg otlpconfig.Config) otlpconfig.Config // // If the OTEL_EXPORTER_OTLP_ENDPOINT or OTEL_EXPORTER_OTLP_TRACES_ENDPOINT // environment variable is set, and this option is not passed, that variable -// value will be used. If both are set, OTEL_EXPORTER_OTLP_TRACES_ENDPOINT -// will take precedence. Note, both environment variables include the full +// value will be used. If both environment variables are set, +// OTEL_EXPORTER_OTLP_TRACES_ENDPOINT will take precedence. If an environment +// variable is set, and this option is passed, this option will take precedence. +// Note, both environment variables include the full // scheme and path, while WithEndpoint sets only the host and port. // // If both this option and WithEndpointURL are used, the last used option will @@ -82,8 +84,9 @@ func WithEndpoint(endpoint string) Option { // // If the OTEL_EXPORTER_OTLP_ENDPOINT or OTEL_EXPORTER_OTLP_TRACES_ENDPOINT // environment variable is set, and this option is not passed, that variable -// value will be used. If both are set, OTEL_EXPORTER_OTLP_TRACES_ENDPOINT -// will take precedence. +// value will be used. If both environment variables are set, +// OTEL_EXPORTER_OTLP_TRACES_ENDPOINT will take precedence. If an environment +// variable is set, and this option is passed, this option will take precedence. // // If both this option and WithEndpoint are used, the last used option will // take precedence. diff --git a/internal/shared/otlp/otlptrace/otlpconfig/options_test.go.tmpl b/internal/shared/otlp/otlptrace/otlpconfig/options_test.go.tmpl index 8d670a5aa9a..2688db9db51 100644 --- a/internal/shared/otlp/otlptrace/otlpconfig/options_test.go.tmpl +++ b/internal/shared/otlp/otlptrace/otlpconfig/options_test.go.tmpl @@ -127,6 +127,26 @@ func TestConfigs(t *testing.T) { assert.Equal(t, "/v1/traces", c.Traces.URLPath) }, }, + { + name: "Test With Endpoint last used", + opts: []GenericOption{ + WithEndpointURL("https://someendpoint/somepath"), + WithEndpoint("someendpoint2"), + }, + asserts: func(t *testing.T, c *Config, grpcOption bool) { + assert.Equal(t, "someendpoint2", c.Traces.Endpoint) + }, + }, + { + name: "Test With WithEndpointURL last used", + opts: []GenericOption{ + WithEndpoint("someendpoint2"), + WithEndpointURL("https://someendpoint/somepath"), + }, + asserts: func(t *testing.T, c *Config, grpcOption bool) { + assert.Equal(t, "someendpoint", c.Traces.Endpoint) + }, + }, { name: "Test Environment Endpoint", env: map[string]string{ @@ -159,15 +179,31 @@ func TestConfigs(t *testing.T) { { name: "Test Mixed Environment and With Endpoint", opts: []GenericOption{ + WithEndpointURL("https://traces_endpoint2/somepath"), WithEndpoint("traces_endpoint"), }, env: map[string]string{ - "OTEL_EXPORTER_OTLP_ENDPOINT": "env_endpoint", + "OTEL_EXPORTER_OTLP_ENDPOINT": "env_endpoint", + "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT": "env_endpoint2", }, asserts: func(t *testing.T, c *Config, grpcOption bool) { assert.Equal(t, "traces_endpoint", c.Traces.Endpoint) }, }, + { + name: "Test Mixed Environment and With Endpoint", + opts: []GenericOption{ + WithEndpoint("traces_endpoint"), + WithEndpointURL("https://traces_endpoint2/somepath"), + }, + env: map[string]string{ + "OTEL_EXPORTER_OTLP_ENDPOINT": "env_endpoint", + "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT": "env_endpoint2", + }, + asserts: func(t *testing.T, c *Config, grpcOption bool) { + assert.Equal(t, "traces_endpoint2", c.Traces.Endpoint) + }, + }, { name: "Test Environment Endpoint with HTTP scheme", env: map[string]string{ diff --git a/internal/tools/go.mod b/internal/tools/go.mod index 9e8415500cd..e82dfcca611 100644 --- a/internal/tools/go.mod +++ b/internal/tools/go.mod @@ -9,12 +9,12 @@ require ( github.com/itchyny/gojq v0.12.16 github.com/jcchavezs/porto v0.6.0 github.com/wadey/gocovmerge v0.0.0-20160331181800-b5bfa59ec0ad - go.opentelemetry.io/build-tools/crosslink v0.13.0 - go.opentelemetry.io/build-tools/gotmpl v0.13.0 - go.opentelemetry.io/build-tools/multimod v0.13.0 - go.opentelemetry.io/build-tools/semconvgen v0.13.0 - golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 - golang.org/x/tools v0.22.0 + go.opentelemetry.io/build-tools/crosslink v0.14.0 + go.opentelemetry.io/build-tools/gotmpl v0.14.0 + go.opentelemetry.io/build-tools/multimod v0.14.0 + go.opentelemetry.io/build-tools/semconvgen v0.14.0 + golang.org/x/exp v0.0.0-20240707233637-46b078467d37 + golang.org/x/tools v0.23.0 golang.org/x/vuln v1.1.2 ) @@ -34,7 +34,7 @@ require ( github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/OpenPeeDeeP/depguard/v2 v2.2.0 // indirect - github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect + github.com/ProtonMail/go-crypto v1.0.0 // indirect github.com/alecthomas/go-check-sumtype v0.1.4 // indirect github.com/alexkohler/nakedret/v2 v2.0.4 // indirect github.com/alexkohler/prealloc v1.0.0 // indirect @@ -72,7 +72,7 @@ require ( github.com/go-critic/go-critic v0.11.4 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.5.0 // indirect - github.com/go-git/go-git/v5 v5.11.0 // indirect + github.com/go-git/go-git/v5 v5.12.0 // indirect github.com/go-toolsmith/astcast v1.1.0 // indirect github.com/go-toolsmith/astcopy v1.1.0 // indirect github.com/go-toolsmith/astequal v1.2.0 // indirect @@ -161,20 +161,20 @@ require ( github.com/sashamelentyev/interfacebloat v1.1.0 // indirect github.com/sashamelentyev/usestdlibvars v1.26.0 // indirect github.com/securego/gosec/v2 v2.20.1-0.20240525090044-5f0084eb01a9 // indirect - github.com/sergi/go-diff v1.2.0 // indirect + github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/sivchari/containedctx v1.0.3 // indirect github.com/sivchari/tenv v1.7.1 // indirect - github.com/skeema/knownhosts v1.2.1 // indirect + github.com/skeema/knownhosts v1.2.2 // indirect github.com/sonatard/noctx v0.0.2 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/sourcegraph/go-diff v0.7.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect - github.com/spf13/cobra v1.8.0 // indirect + github.com/spf13/cobra v1.8.1 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.18.2 // indirect + github.com/spf13/viper v1.19.0 // indirect github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect github.com/stretchr/objx v0.5.2 // indirect @@ -198,16 +198,16 @@ require ( gitlab.com/bosi/decorder v0.4.2 // indirect go-simpler.org/musttag v0.12.2 // indirect go-simpler.org/sloglint v0.7.1 // indirect - go.opentelemetry.io/build-tools v0.13.0 // indirect + go.opentelemetry.io/build-tools v0.14.0 // indirect go.uber.org/automaxprocs v1.5.3 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.24.0 // indirect + golang.org/x/crypto v0.25.0 // indirect golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f // indirect - golang.org/x/mod v0.18.0 // indirect - golang.org/x/net v0.26.0 // indirect + golang.org/x/mod v0.19.0 // indirect + golang.org/x/net v0.27.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.21.0 // indirect + golang.org/x/sys v0.22.0 // indirect golang.org/x/telemetry v0.0.0-20240522233618-39ace7a40ae7 // indirect golang.org/x/text v0.16.0 // indirect google.golang.org/protobuf v1.34.0 // indirect diff --git a/internal/tools/go.sum b/internal/tools/go.sum index 246f6065210..296c4073dff 100644 --- a/internal/tools/go.sum +++ b/internal/tools/go.sum @@ -29,8 +29,8 @@ github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migc github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/OpenPeeDeeP/depguard/v2 v2.2.0 h1:vDfG60vDtIuf0MEOhmLlLLSzqaRM8EMcgJPdp74zmpA= github.com/OpenPeeDeeP/depguard/v2 v2.2.0/go.mod h1:CIzddKRvLBC4Au5aYP/i3nyaWQ+ClszLIuVocRiCYFQ= -github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg= -github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78= +github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/alecthomas/assert/v2 v2.2.2 h1:Z/iVC0xZfWTaFNE6bA3z07T86hd45Xe2eLt6WVy2bbk= github.com/alecthomas/assert/v2 v2.2.2/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ= github.com/alecthomas/go-check-sumtype v0.1.4 h1:WCvlB3l5Vq5dZQTFmodqL2g68uHiSwwlWcT5a2FGK0c= @@ -85,7 +85,7 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/curioswitch/go-reassign v0.2.0 h1:G9UZyOcpk/d7Gd6mqYgd8XYWFMw/znxwGDUstnC9DIo= github.com/curioswitch/go-reassign v0.2.0/go.mod h1:x6OpXuWvgfQaMGks2BZybTngWjT84hqJfKoO8Tt/Roc= github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= @@ -118,8 +118,8 @@ github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo= github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= github.com/ghostiam/protogetter v0.3.6 h1:R7qEWaSgFCsy20yYHNIJsU9ZOb8TziSRRxuAOTVKeOk= github.com/ghostiam/protogetter v0.3.6/go.mod h1:7lpeDnEJ1ZjL/YtyoN99ljO4z0pd3H0d18/t2dPBxHw= -github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY= -github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4= +github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE= +github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8= github.com/go-critic/go-critic v0.11.4 h1:O7kGOCx0NDIni4czrkRIXTnit0mkyKOCePh3My6OyEU= github.com/go-critic/go-critic v0.11.4/go.mod h1:2QAdo4iuLik5S9YG0rT4wcZ8QxwHYkrr6/2MWAiv/vc= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= @@ -128,8 +128,8 @@ github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+ github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4= -github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY= +github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= +github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= @@ -372,8 +372,8 @@ github.com/sashamelentyev/usestdlibvars v1.26.0 h1:LONR2hNVKxRmzIrZR0PhSF3mhCAzv github.com/sashamelentyev/usestdlibvars v1.26.0/go.mod h1:9nl0jgOfHKWNFS43Ojw0i7aRoS4j6EBye3YBhmAIRF8= github.com/securego/gosec/v2 v2.20.1-0.20240525090044-5f0084eb01a9 h1:rnO6Zp1YMQwv8AyxzuwsVohljJgp4L0ZqiCgtACsPsc= github.com/securego/gosec/v2 v2.20.1-0.20240525090044-5f0084eb01a9/go.mod h1:dg7lPlu/xK/Ut9SedURCoZbVCR4yC7fM65DtH9/CDHs= -github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= -github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= @@ -385,8 +385,8 @@ github.com/sivchari/containedctx v1.0.3 h1:x+etemjbsh2fB5ewm5FeLNi5bUjK0V8n0RB+W github.com/sivchari/containedctx v1.0.3/go.mod h1:c1RDvCbnJLtH4lLcYD/GqwiBSSf4F5Qk0xld2rBqzJ4= github.com/sivchari/tenv v1.7.1 h1:PSpuD4bu6fSmtWMxSGWcvqUUgIn7k3yOJhOIzVWn8Ak= github.com/sivchari/tenv v1.7.1/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg= -github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ= -github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= +github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= +github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= github.com/sonatard/noctx v0.0.2 h1:L7Dz4De2zDQhW8S0t+KUjY0MAQJd6SgVwhzNIc4ok00= github.com/sonatard/noctx v0.0.2/go.mod h1:kzFz+CzWSjQ2OzIm46uJZoXuBpa2+0y3T36U18dWqIo= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= @@ -397,12 +397,12 @@ github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= -github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= +github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= +github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= github.com/ssgreg/nlreturn/v2 v2.2.1 h1:X4XDI7jstt3ySqGU86YGAURbxw3oTDPK9sPEi6YEwQ0= github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= github.com/stbenjam/no-sprintf-host-port v0.1.1 h1:tYugd/yrm1O0dV+ThCbaKZh195Dfm07ysF0U6JQXczc= @@ -476,16 +476,16 @@ go-simpler.org/musttag v0.12.2 h1:J7lRc2ysXOq7eM8rwaTYnNrHd5JwjppzB6mScysB2Cs= go-simpler.org/musttag v0.12.2/go.mod h1:uN1DVIasMTQKk6XSik7yrJoEysGtR2GRqvWnI9S7TYM= go-simpler.org/sloglint v0.7.1 h1:qlGLiqHbN5islOxjeLXoPtUdZXb669RW+BDQ+xOSNoU= go-simpler.org/sloglint v0.7.1/go.mod h1:OlaVDRh/FKKd4X4sIMbsz8st97vomydceL146Fthh/c= -go.opentelemetry.io/build-tools v0.13.0 h1:0I3jJQ2zcJU8k4ZjyHNqUBX2Len1UvBIOzVP4b50g9A= -go.opentelemetry.io/build-tools v0.13.0/go.mod h1:PEtg5iWjNI9WAlKXP/xll/hgbq/Cp4Ma4T1ssKB2T0Q= -go.opentelemetry.io/build-tools/crosslink v0.13.0 h1:R0V89bTYzoJpasiOIYiQo6txL/ZTzMdEuthJ4gLUTF8= -go.opentelemetry.io/build-tools/crosslink v0.13.0/go.mod h1:aYIwOj9b3Nmgm6nIZZk28tF/JjpicI8xenEVUeoVNp0= -go.opentelemetry.io/build-tools/gotmpl v0.13.0 h1:JSNKw7dg2RNTxVREYL0nlmdL6eH22xKGj6s1V2gAC+Y= -go.opentelemetry.io/build-tools/gotmpl v0.13.0/go.mod h1:oNosRsW9ExQDrRd2YTd4U20Jt5AD9CG+Ef3EPyjOTE4= -go.opentelemetry.io/build-tools/multimod v0.13.0 h1:HGAP3zCM8vOTNJSQbjQ5VbKZSctIZxppPBxRTzye7ic= -go.opentelemetry.io/build-tools/multimod v0.13.0/go.mod h1:CxZp68c4PIN+bYlVOGB2FvE5zZMBuGz7cGSHv2L7pSc= -go.opentelemetry.io/build-tools/semconvgen v0.13.0 h1:gGCCXzAQa4/9osvjQr/twTSiPFloxJOz01/segikweI= -go.opentelemetry.io/build-tools/semconvgen v0.13.0/go.mod h1:Xwolx7cXWG3QYYLvDMeO4+IkZGna+4SkI6qadeLDkW4= +go.opentelemetry.io/build-tools v0.14.0 h1:fcnriXRUVpnVIFXtdlc1fTn9g+YRxzOV0xhw4nN919c= +go.opentelemetry.io/build-tools v0.14.0/go.mod h1:pxTqOr0uL/0s9+xnpuKTAhmVFDssF3O4UUUuWKQqThE= +go.opentelemetry.io/build-tools/crosslink v0.14.0 h1:yxCsELb3A81W4p8RSDjPSg9WcCTkM3+X+tYUzaaJ3uU= +go.opentelemetry.io/build-tools/crosslink v0.14.0/go.mod h1:QJ+E5i4+CCg40jlOYQsfBq4lVe2cKCyhftEXDsqNlhg= +go.opentelemetry.io/build-tools/gotmpl v0.14.0 h1:oCDzQvs78J0r311JZ60lcHmZ6xAK0O4F7gIHN8jeB2A= +go.opentelemetry.io/build-tools/gotmpl v0.14.0/go.mod h1:jO5X6iTySwb3UMbiC380ZgwLPCdKyQwxEraFh4dYYF8= +go.opentelemetry.io/build-tools/multimod v0.14.0 h1:AaM06mlSga3IaCj6eM+Kg9tei062qsU6Z+x6ENmfBWI= +go.opentelemetry.io/build-tools/multimod v0.14.0/go.mod h1:lY7ZccnZ6dg4uRcghXa4p9v4IDvI9Yf/XFdlpPO84AA= +go.opentelemetry.io/build-tools/semconvgen v0.14.0 h1:lOHKG4Tc/mfc6yb0an4hdi9oLbIrf/mUUIF3U8HbM8Q= +go.opentelemetry.io/build-tools/semconvgen v0.14.0/go.mod h1:JRu+X6WMMK1fvo9toZM5hb7p6Pug7NXLjbq5J0WcS18= go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -502,10 +502,10 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= -golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= -golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= -golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= +golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= +golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= +golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f h1:phY1HzDcf18Aq9A8KkmRtY9WvOFIxN8wgfvy6Zm1DV8= @@ -520,8 +520,8 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= -golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= +golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -538,8 +538,8 @@ golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -574,8 +574,8 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240522233618-39ace7a40ae7 h1:FemxDzfMUcK2f3YY4H+05K9CDzbSVr2+q/JKN45pey0= golang.org/x/telemetry v0.0.0-20240522233618-39ace7a40ae7/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -585,8 +585,8 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= -golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= +golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= +golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -623,8 +623,8 @@ golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= -golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= +golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= +golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= golang.org/x/vuln v1.1.2 h1:UkLxe+kAMcrNBpGrFbU0Mc5l7cX97P2nhy21wx5+Qbk= golang.org/x/vuln v1.1.2/go.mod h1:2o3fRKD8Uz9AraAL3lwd/grWBv+t+SeJnPcqBUJrY24= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -642,7 +642,6 @@ gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/log/keyvalue.go b/log/keyvalue.go index 8258defe360..296840a4468 100644 --- a/log/keyvalue.go +++ b/log/keyvalue.go @@ -351,16 +351,19 @@ func Bool(key string, value bool) KeyValue { } // Bytes returns a KeyValue for a []byte value. +// The passed slice must not be changed after it is passed. func Bytes(key string, value []byte) KeyValue { return KeyValue{key, BytesValue(value)} } // Slice returns a KeyValue for a []Value value. +// The passed slice must not be changed after it is passed. func Slice(key string, value ...Value) KeyValue { return KeyValue{key, SliceValue(value...)} } // Map returns a KeyValue for a map value. +// The passed slice must not be changed after it is passed. func Map(key string, value ...KeyValue) KeyValue { return KeyValue{key, MapValue(value...)} } diff --git a/sdk/log/DESIGN.md b/sdk/log/DESIGN.md index 6d73150db5d..cda06511203 100644 --- a/sdk/log/DESIGN.md +++ b/sdk/log/DESIGN.md @@ -5,13 +5,28 @@ `go.opentelemetry.io/otel/sdk/log` provides Logs SDK compliant with the [specification](https://opentelemetry.io/docs/specs/otel/logs/sdk/). -The main and recommended use case is to configure the SDK to use an OTLP -exporter with a batch processor.[^1] Therefore, the design aims to be -high-performant in this scenario. - The prototype was created in [#4955](https://github.com/open-telemetry/opentelemetry-go/pull/4955). +## Background + +The goal is to design the exported API of the SDK would have low performance +overhead. Most importantly, have a design that reduces the amount of heap +allocations and even make it possible to have a zero-allocation implementation. +Eliminating the amount of heap allocations reduces the GC pressure which can +produce some of the largest improvements in performance.[^1] + +The main and recommended use case is to configure the SDK to use an OTLP +exporter with a batch processor.[^2] Therefore, the implementation aims to be +high-performant in this scenario. Some users that require high throughput may +also want to use e.g. an [user_events](https://docs.kernel.org/trace/user_events.html), +[LLTng](https://lttng.org/docs/v2.13/#doc-tracing-your-own-user-application) +or [ETW](https://learn.microsoft.com/en-us/windows/win32/etw/about-event-tracing) +exporter with a simple processor. Users may also want to use +[OTLP File](https://opentelemetry.io/docs/specs/otel/protocol/file-exporter/) +or [Standard Output](https://opentelemetry.io/docs/specs/otel/logs/sdk_exporters/stdout/) +exporter in order to emit logs to standard output/error or files. + ## Modules structure The SDK is published as a single `go.opentelemetry.io/otel/sdk/log` Go module. @@ -112,10 +127,10 @@ The benchmark results can be found in [the prototype](https://github.com/open-te Because the [LogRecordProcessor](https://opentelemetry.io/docs/specs/otel/logs/sdk/#logrecordprocessor) and the [LogRecordProcessor](https://opentelemetry.io/docs/specs/otel/logs/sdk/#logrecordexporter) abstractions are so similar, there was a proposal to unify them under -single `Expoter` interface.[^2] +single `Expoter` interface.[^3] However, introducing a `Processor` interface makes it easier -to create custom processor decorators[^3] +to create custom processor decorators[^4] and makes the design more aligned with the specification. ### Embed log.Record @@ -131,6 +146,7 @@ provided via API. Moreover it is safer to have these abstraction decoupled. E.g. there can be a need for some fields that can be set via API and cannot be modified by the processors. -[^1]: [OpenTelemetry Logging](https://opentelemetry.io/docs/specs/otel/logs) -[^2]: [Conversation on representing LogRecordProcessor and LogRecordExporter via a single Expoter interface](https://github.com/open-telemetry/opentelemetry-go/pull/4954#discussion_r1515050480) -[^3]: [Introduce Processor](https://github.com/pellared/opentelemetry-go/pull/9) +[^1]: [A Guide to the Go Garbage Collector](https://tip.golang.org/doc/gc-guide) +[^2]: [OpenTelemetry Logging](https://opentelemetry.io/docs/specs/otel/logs) +[^3]: [Conversation on representing LogRecordProcessor and LogRecordExporter via a single Expoter interface](https://github.com/open-telemetry/opentelemetry-go/pull/4954#discussion_r1515050480) +[^4]: [Introduce Processor](https://github.com/pellared/opentelemetry-go/pull/9) diff --git a/sdk/log/bench_test.go b/sdk/log/bench_test.go index ff5d6fe2bfa..8147418ef7e 100644 --- a/sdk/log/bench_test.go +++ b/sdk/log/bench_test.go @@ -31,27 +31,39 @@ func BenchmarkProcessor(b *testing.B) { }, }, { - name: "ModifyTimestampSimple", + name: "SetTimestampSimple", f: func() Processor { return timestampDecorator{NewSimpleProcessor(noopExporter{})} }, }, { - name: "ModifyTimestampBatch", + name: "SetTimestampBatch", f: func() Processor { return timestampDecorator{NewBatchProcessor(noopExporter{})} }, }, { - name: "ModifyAttributesSimple", + name: "AddAttributesSimple", f: func() Processor { - return attrDecorator{NewSimpleProcessor(noopExporter{})} + return attrAddDecorator{NewSimpleProcessor(noopExporter{})} }, }, { - name: "ModifyAttributesBatch", + name: "AddAttributesBatch", f: func() Processor { - return attrDecorator{NewBatchProcessor(noopExporter{})} + return attrAddDecorator{NewBatchProcessor(noopExporter{})} + }, + }, + { + name: "SetAttributesSimple", + f: func() Processor { + return attrSetDecorator{NewSimpleProcessor(noopExporter{})} + }, + }, + { + name: "SetAttributesBatch", + f: func() Processor { + return attrSetDecorator{NewBatchProcessor(noopExporter{})} }, }, } { @@ -89,11 +101,21 @@ func (e timestampDecorator) OnEmit(ctx context.Context, r Record) error { return e.Processor.OnEmit(ctx, r) } -type attrDecorator struct { +type attrAddDecorator struct { + Processor +} + +func (e attrAddDecorator) OnEmit(ctx context.Context, r Record) error { + r = r.Clone() + r.AddAttributes(log.String("add", "me")) + return e.Processor.OnEmit(ctx, r) +} + +type attrSetDecorator struct { Processor } -func (e attrDecorator) OnEmit(ctx context.Context, r Record) error { +func (e attrSetDecorator) OnEmit(ctx context.Context, r Record) error { r = r.Clone() r.SetAttributes(log.String("replace", "me")) return e.Processor.OnEmit(ctx, r) diff --git a/sdk/log/example_test.go b/sdk/log/example_test.go index 4210a7fe54b..71b99921528 100644 --- a/sdk/log/example_test.go +++ b/sdk/log/example_test.go @@ -5,16 +5,55 @@ package log_test import ( "context" + "fmt" "strings" - "go.opentelemetry.io/otel/log" - logsdk "go.opentelemetry.io/otel/sdk/log" + logapi "go.opentelemetry.io/otel/log" + "go.opentelemetry.io/otel/log/global" + "go.opentelemetry.io/otel/sdk/log" ) +// Initialize OpenTelemetry Logs SDK and setup logging using a log bridge. +func Example() { + // Create an exporter that will emit log records. + // E.g. use go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp + // to send logs using OTLP over HTTP: + // exporter, err := otlploghttp.New(ctx) + var exporter log.Exporter + + // Create a log record processor pipeline. + processor := log.NewBatchProcessor(exporter) + + // Create a logger provider. + // You can pass this instance directly when creating a log bridge. + provider := log.NewLoggerProvider( + log.WithProcessor(processor), + ) + + // Handle shutdown properly so that nothing leaks. + defer func() { + err := provider.Shutdown(context.Background()) + if err != nil { + fmt.Println(err) + } + }() + + // Register as global logger provider so that it can be used via global.Meter + // and accessed using global.GetMeterProvider. + // Most log bridges use the global logger provider as default. + // If the global logger provider is not set then a no-op implementation + // is used, which fails to generate data. + global.SetLoggerProvider(provider) + + // Use a bridge so that you can emit logs using your Go logging library of preference. + // E.g. use go.opentelemetry.io/contrib/bridges/otelslog so that you can use log/slog: + // slog.SetDefault(otelslog.NewLogger("my/pkg/name", otelslog.WithLoggerProvider(provider))) +} + // Use a processor that filters out records based on the provided context. func ExampleProcessor_filtering() { // Existing processor that emits telemetry. - var processor logsdk.Processor = logsdk.NewBatchProcessor(nil) + var processor log.Processor = log.NewBatchProcessor(nil) // Wrap the processor so that it ignores processing log records // when a context deriving from WithIgnoreLogs is passed @@ -23,8 +62,8 @@ func ExampleProcessor_filtering() { // The created processor can then be registered with // the OpenTelemetry Logs SDK using the WithProcessor option. - _ = logsdk.NewLoggerProvider( - logsdk.WithProcessor(processor), + _ = log.NewLoggerProvider( + log.WithProcessor(processor), ) } @@ -41,17 +80,17 @@ func WithIgnoreLogs(ctx context.Context) context.Context { // ContextFilterProcessor filters out logs when a context deriving from // [WithIgnoreLogs] is passed to its methods. type ContextFilterProcessor struct { - logsdk.Processor + log.Processor } -func (p *ContextFilterProcessor) OnEmit(ctx context.Context, record logsdk.Record) error { +func (p *ContextFilterProcessor) OnEmit(ctx context.Context, record log.Record) error { if ignoreLogs(ctx) { return nil } return p.Processor.OnEmit(ctx, record) } -func (p *ContextFilterProcessor) Enabled(ctx context.Context, record logsdk.Record) bool { +func (p *ContextFilterProcessor) Enabled(ctx context.Context, record log.Record) bool { return !ignoreLogs(ctx) && p.Processor.Enabled(ctx, record) } @@ -63,35 +102,35 @@ func ignoreLogs(ctx context.Context) bool { // Use a processor which redacts sensitive data from some attributes. func ExampleProcessor_redact() { // Existing processor that emits telemetry. - var processor logsdk.Processor = logsdk.NewBatchProcessor(nil) + var processor log.Processor = log.NewBatchProcessor(nil) // Wrap the processor so that it redacts values from token attributes. processor = &RedactTokensProcessor{processor} // The created processor can then be registered with // the OpenTelemetry Logs SDK using the WithProcessor option. - _ = logsdk.NewLoggerProvider( - logsdk.WithProcessor(processor), + _ = log.NewLoggerProvider( + log.WithProcessor(processor), ) } -// RedactTokensProcessor is a [logsdk.Processor] decorator that redacts values +// RedactTokensProcessor is a [log.Processor] decorator that redacts values // from attributes containing "token" in the key. type RedactTokensProcessor struct { - logsdk.Processor + log.Processor } // OnEmit redacts values from attributes containing "token" in the key // by replacing them with a REDACTED value. -func (p *RedactTokensProcessor) OnEmit(ctx context.Context, record logsdk.Record) error { +func (p *RedactTokensProcessor) OnEmit(ctx context.Context, record log.Record) error { cloned := false - record.WalkAttributes(func(kv log.KeyValue) bool { + record.WalkAttributes(func(kv logapi.KeyValue) bool { if strings.Contains(strings.ToLower(kv.Key), "token") { if !cloned { record = record.Clone() cloned = true } - record.AddAttributes(log.String(kv.Key, "REDACTED")) + record.AddAttributes(logapi.String(kv.Key, "REDACTED")) } return true }) diff --git a/sdk/log/simple.go b/sdk/log/simple.go index fc5690b22d5..4d2bb412045 100644 --- a/sdk/log/simple.go +++ b/sdk/log/simple.go @@ -18,11 +18,12 @@ type SimpleProcessor struct { // NewSimpleProcessor is a simple Processor adapter. // -// This Processor is not recommended for production use. The synchronous -// nature of this Processor make it good for testing, debugging, or -// showing examples of other features, but it can be slow and have a high -// computation resource usage overhead. [NewBatchProcessor] is recommended -// for production use instead. +// This Processor is not recommended for production use due to its synchronous +// nature, which makes it suitable for testing, debugging, or demonstrating +// other features, but can lead to slow performance and high computational +// overhead. For production environments, it is recommended to use +// [NewBatchProcessor] instead. However, there may be exceptions where certain +// [Exporter] implementations perform better with this Processor. func NewSimpleProcessor(exporter Exporter, _ ...SimpleProcessorOption) *SimpleProcessor { if exporter == nil { // Do not panic on nil exporter. diff --git a/trace/config_test.go b/trace/config_test.go index da341d06eb8..9a613ace2c9 100644 --- a/trace/config_test.go +++ b/trace/config_test.go @@ -163,6 +163,19 @@ func TestNewSpanConfig(t *testing.T) { } } +func TestSpanStartConfigAttributeMutability(t *testing.T) { + a := attribute.String("a", "val") + b := attribute.String("b", "val") + attrs := []attribute.KeyValue{a, b} + conf := NewSpanStartConfig(WithAttributes(attrs...)) + + // Mutating passed arg should not change configured attributes. + attrs[0] = attribute.String("c", "val") + + want := SpanConfig{attributes: []attribute.KeyValue{a, b}} + assert.Equal(t, want, conf) +} + func TestEndSpanConfig(t *testing.T) { timestamp := time.Unix(0, 0) @@ -227,61 +240,174 @@ var ( ) func BenchmarkNewTracerConfig(b *testing.B) { - opts := []TracerOption{ - WithInstrumentationVersion("testing version"), - WithSchemaURL("testing URL"), - } - - b.ReportAllocs() - b.ResetTimer() + for _, bb := range []struct { + name string + options []TracerOption + }{ + { + name: "with no options", + }, + { + name: "with an instrumentation version", + options: []TracerOption{ + WithInstrumentationVersion("testing version"), + }, + }, + { + name: "with a schema url", + options: []TracerOption{ + WithSchemaURL("testing URL"), + }, + }, + } { + b.Run(bb.name, func(b *testing.B) { + b.ReportAllocs() + b.ResetTimer() - for i := 0; i < b.N; i++ { - tracerConfig = NewTracerConfig(opts...) + for i := 0; i < b.N; i++ { + tracerConfig = NewTracerConfig(bb.options...) + } + }) } } func BenchmarkNewSpanStartConfig(b *testing.B) { - opts := []SpanStartOption{ - WithAttributes(attribute.Bool("key", true)), - WithTimestamp(time.Now()), - WithLinks(Link{}), - WithNewRoot(), - WithSpanKind(SpanKindClient), - } - - b.ReportAllocs() - b.ResetTimer() + for _, bb := range []struct { + name string + options []SpanStartOption + }{ + { + name: "with no options", + }, + { + name: "with attributes", + options: []SpanStartOption{ + WithAttributes(attribute.Bool("key", true)), + }, + }, + { + name: "with attributes set multiple times", + options: []SpanStartOption{ + WithAttributes(attribute.Bool("key", true)), + WithAttributes(attribute.Bool("secondKey", false)), + }, + }, + { + name: "with a timestamp", + options: []SpanStartOption{ + WithTimestamp(time.Now()), + }, + }, + { + name: "with links", + options: []SpanStartOption{ + WithLinks(Link{}), + }, + }, + { + name: "with links set multiple times", + options: []SpanStartOption{ + WithLinks(Link{}), + WithLinks(Link{}), + }, + }, + { + name: "with new root", + options: []SpanStartOption{ + WithNewRoot(), + }, + }, + { + name: "with span kind", + options: []SpanStartOption{ + WithSpanKind(SpanKindClient), + }, + }, + } { + b.Run(bb.name, func(b *testing.B) { + b.ReportAllocs() + b.ResetTimer() - for i := 0; i < b.N; i++ { - spanConfig = NewSpanStartConfig(opts...) + for i := 0; i < b.N; i++ { + spanConfig = NewSpanStartConfig(bb.options...) + } + }) } } func BenchmarkNewSpanEndConfig(b *testing.B) { - opts := []SpanEndOption{ - WithTimestamp(time.Now()), - WithStackTrace(true), - } - - b.ReportAllocs() - b.ResetTimer() + for _, bb := range []struct { + name string + options []SpanEndOption + }{ + { + name: "with no options", + }, + { + name: "with a timestamp", + options: []SpanEndOption{ + WithTimestamp(time.Now()), + }, + }, + { + name: "with stack trace", + options: []SpanEndOption{ + WithStackTrace(true), + }, + }, + } { + b.Run(bb.name, func(b *testing.B) { + b.ReportAllocs() + b.ResetTimer() - for i := 0; i < b.N; i++ { - spanConfig = NewSpanEndConfig(opts...) + for i := 0; i < b.N; i++ { + spanConfig = NewSpanEndConfig(bb.options...) + } + }) } } func BenchmarkNewEventConfig(b *testing.B) { - opts := []EventOption{ - WithAttributes(attribute.Bool("key", true)), - WithTimestamp(time.Now()), - WithStackTrace(true), - } - - b.ReportAllocs() - b.ResetTimer() + for _, bb := range []struct { + name string + options []EventOption + }{ + { + name: "with no options", + }, + { + name: "with attributes", + options: []EventOption{ + WithAttributes(attribute.Bool("key", true)), + }, + }, + { + name: "with attributes set multiple times", + options: []EventOption{ + WithAttributes(attribute.Bool("key", true)), + WithAttributes(attribute.Bool("secondKey", false)), + }, + }, + { + name: "with a timestamp", + options: []EventOption{ + WithTimestamp(time.Now()), + }, + }, + { + name: "with a stacktrace", + options: []EventOption{ + WithStackTrace(true), + }, + }, + } { + b.Run(bb.name, func(b *testing.B) { + b.ReportAllocs() + b.ResetTimer() - for i := 0; i < b.N; i++ { - eventConfig = NewEventConfig(opts...) + for i := 0; i < b.N; i++ { + eventConfig = NewEventConfig(bb.options...) + } + }) } } diff --git a/trace/trace_test.go b/trace/trace_test.go index 73ee3ce49bc..8e51df33dd5 100644 --- a/trace/trace_test.go +++ b/trace/trace_test.go @@ -643,3 +643,21 @@ func TestLinkFromContext(t *testing.T) { } assert.Equal(t, link.Attributes[0], k1v1) } + +func TestConfigLinkMutability(t *testing.T) { + sc0 := NewSpanContext(SpanContextConfig{TraceID: [16]byte{1}}) + sc1 := NewSpanContext(SpanContextConfig{TraceID: [16]byte{2}}) + sc2 := NewSpanContext(SpanContextConfig{TraceID: [16]byte{3}}) + l0 := Link{SpanContext: sc0} + l1 := Link{SpanContext: sc1} + l2 := Link{SpanContext: sc2} + + links := []Link{l0, l1} + conf := NewSpanStartConfig(WithLinks(links...)) + + // Mutating passed arg should not change configured links. + links[0] = l2 + + want := SpanConfig{links: []Link{l0, l1}} + assert.Equal(t, want, conf) +} diff --git a/verify_released_changelog.sh b/verify_released_changelog.sh new file mode 100755 index 00000000000..77e6b95d48a --- /dev/null +++ b/verify_released_changelog.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +set -euo pipefail + +TARGET="${1:?Must provide target ref}" + +FILE="CHANGELOG.md" +TEMP_DIR=$(mktemp -d) +echo "Temp folder: $TEMP_DIR" + +# Only the latest commit of the feature branch is available +# automatically. To diff with the base branch, we need to +# fetch that too (and we only need its latest commit). +git fetch origin "${TARGET}" --depth=1 + +# Checkout the previous version on the base branch of the changelog to tmpfolder +git --work-tree="$TEMP_DIR" checkout FETCH_HEAD $FILE + +PREVIOUS_FILE="$TEMP_DIR/$FILE" +CURRENT_FILE="$FILE" +PREVIOUS_LOCKED_FILE="$TEMP_DIR/previous_locked_section.md" +CURRENT_LOCKED_FILE="$TEMP_DIR/current_locked_section.md" + +# Extract released sections from the previous version +awk '/^\