From d262f8d4c0b9a891d5fafb5efe0f777cedcd49b0 Mon Sep 17 00:00:00 2001 From: alex boten <223565+codeboten@users.noreply.github.com> Date: Fri, 31 Oct 2025 15:46:06 -0700 Subject: [PATCH 1/3] otelconf: add unmarshalers for otlp exporters Adding unmarshalers and tests for otlp http/grpc exporters. Also added a missing test for createHeaders. Part of splitting #8026 Signed-off-by: alex boten <223565+codeboten@users.noreply.github.com> --- CHANGELOG.md | 1 + otelconf/config_common.go | 17 ++- otelconf/config_json.go | 102 ++++++++++++- otelconf/config_test.go | 307 +++++++++++++++++++++++++++++++++++++- otelconf/config_yaml.go | 74 ++++++++- 5 files changed, 484 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 39479c4cc31..404fba45574 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Add unmarshaling and validation for `CardinalityLimits` and `SpanLimits` to v1.0.0 model in `go.opentelemetry.io/contrib/otelconf`. (#8043) - Add unmarshaling and validation for `BatchLogRecordProcessor`, `BatchSpanProcessor`, and `PeriodicMetricReader` to v1.0.0 model in `go.opentelemetry.io/contrib/otelconf`. (#8049) - Add unmarshaling and validation for `TextMapPropagator` to v1.0.0 model in `go.opentelemetry.io/contrib/otelconf`. (#8052) +- Add unmarshaling and validation for `OTLPHttpExporter`, `OTLPGrpcExporter`, `OTLPGrpcMetricExporter` and `OTLPHttpMetricExporter` to v1.0.0 model in `go.opentelemetry.io/contrib/otelconf`. (#) ### Changed diff --git a/otelconf/config_common.go b/otelconf/config_common.go index 40c2890d18e..c5b8ea6456e 100644 --- a/otelconf/config_common.go +++ b/otelconf/config_common.go @@ -52,16 +52,17 @@ func (e *errBound) Is(target error) bool { return e.Field == t.Field && e.Bound == t.Bound && e.Op == t.Op } -type errRequiredExporter struct { +type errRequired struct { Object any + Field string } -func (e *errRequiredExporter) Error() string { - return fmt.Sprintf("field exporter in %s: required", reflect.TypeOf(e.Object)) +func (e *errRequired) Error() string { + return fmt.Sprintf("field %s in %s: required", e.Field, reflect.TypeOf(e.Object)) } -func (e *errRequiredExporter) Is(target error) bool { - t, ok := target.(*errRequiredExporter) +func (e *errRequired) Is(target error) bool { + t, ok := target.(*errRequired) if !ok { return false } @@ -96,9 +97,9 @@ func newErrGreaterThanZero(field string) error { return &errBound{Field: field, Bound: 0, Op: ">"} } -// newErrRequiredExporter creates a new error indicating that the exporter field is required. -func newErrRequiredExporter(object any) error { - return &errRequiredExporter{Object: object} +// newErrRequired creates a new error indicating that the exporter field is required. +func newErrRequired(object any, field string) error { + return &errRequired{Object: object, Field: field} } // newErrUnmarshal creates a new error indicating that an error occurred during unmarshaling. diff --git a/otelconf/config_json.go b/otelconf/config_json.go index 373cbd11b6d..13be55c6cad 100644 --- a/otelconf/config_json.go +++ b/otelconf/config_json.go @@ -273,7 +273,7 @@ func (j *BatchLogRecordProcessor) UnmarshalJSON(b []byte) error { return errors.Join(newErrUnmarshal(j), err) } if sh.Exporter == nil { - return newErrRequiredExporter(j) + return newErrRequired(j, "exporter") } // Hydrate the exporter into the underlying field. if err := json.Unmarshal(sh.Exporter, &sh.Plain.Exporter); err != nil { @@ -299,7 +299,7 @@ func (j *BatchSpanProcessor) UnmarshalJSON(b []byte) error { return errors.Join(newErrUnmarshal(j), err) } if sh.Exporter == nil { - return newErrRequiredExporter(j) + return newErrRequired(j, "exporter") } // Hydrate the exporter into the underlying field. if err := json.Unmarshal(sh.Exporter, &sh.Plain.Exporter); err != nil { @@ -325,7 +325,7 @@ func (j *PeriodicMetricReader) UnmarshalJSON(b []byte) error { return errors.Join(newErrUnmarshal(j), err) } if sh.Exporter == nil { - return newErrRequiredExporter(j) + return newErrRequired(j, "exporter") } // Hydrate the exporter into the underlying field. if err := json.Unmarshal(sh.Exporter, &sh.Plain.Exporter); err != nil { @@ -366,3 +366,99 @@ func (j *SpanLimits) UnmarshalJSON(value []byte) error { *j = SpanLimits(plain) return nil } + +// UnmarshalJSON implements json.Unmarshaler. +func (j *OTLPHttpMetricExporter) UnmarshalJSON(b []byte) error { + type Plain OTLPHttpMetricExporter + type shadow struct { + Plain + Endpoint json.RawMessage `json:"endpoint"` + } + var sh shadow + if err := json.Unmarshal(b, &sh); err != nil { + return errors.Join(newErrUnmarshal(j), err) + } + if sh.Endpoint == nil { + return newErrRequired(j, "endpoint") + } + if err := json.Unmarshal(sh.Endpoint, &sh.Plain.Endpoint); err != nil { + return err + } + if sh.Plain.Timeout != nil && 0 > *sh.Plain.Timeout { + return newErrGreaterOrEqualZero("timeout") + } + *j = OTLPHttpMetricExporter(sh.Plain) + return nil +} + +// UnmarshalJSON implements json.Unmarshaler. +func (j *OTLPGrpcMetricExporter) UnmarshalJSON(b []byte) error { + type Plain OTLPGrpcMetricExporter + type shadow struct { + Plain + Endpoint json.RawMessage `json:"endpoint"` + } + var sh shadow + if err := json.Unmarshal(b, &sh); err != nil { + return errors.Join(newErrUnmarshal(j), err) + } + if sh.Endpoint == nil { + return newErrRequired(j, "endpoint") + } + if err := json.Unmarshal(sh.Endpoint, &sh.Plain.Endpoint); err != nil { + return err + } + if sh.Plain.Timeout != nil && 0 > *sh.Plain.Timeout { + return newErrGreaterOrEqualZero("timeout") + } + *j = OTLPGrpcMetricExporter(sh.Plain) + return nil +} + +// UnmarshalJSON implements json.Unmarshaler. +func (j *OTLPHttpExporter) UnmarshalJSON(b []byte) error { + type Plain OTLPHttpExporter + type shadow struct { + Plain + Endpoint json.RawMessage `json:"endpoint"` + } + var sh shadow + if err := json.Unmarshal(b, &sh); err != nil { + return errors.Join(newErrUnmarshal(j), err) + } + if sh.Endpoint == nil { + return newErrRequired(j, "endpoint") + } + if err := json.Unmarshal(sh.Endpoint, &sh.Plain.Endpoint); err != nil { + return err + } + if sh.Plain.Timeout != nil && 0 > *sh.Plain.Timeout { + return newErrGreaterOrEqualZero("timeout") + } + *j = OTLPHttpExporter(sh.Plain) + return nil +} + +// UnmarshalJSON implements json.Unmarshaler. +func (j *OTLPGrpcExporter) UnmarshalJSON(b []byte) error { + type Plain OTLPGrpcExporter + type shadow struct { + Plain + Endpoint json.RawMessage `json:"endpoint"` + } + var sh shadow + if err := json.Unmarshal(b, &sh); err != nil { + return errors.Join(newErrUnmarshal(j), err) + } + if sh.Endpoint == nil { + return newErrRequired(j, "endpoint") + } + if err := json.Unmarshal(sh.Endpoint, &sh.Plain.Endpoint); err != nil { + return err + } + if sh.Plain.Timeout != nil && 0 > *sh.Plain.Timeout { + return newErrGreaterOrEqualZero("timeout") + } + *j = OTLPGrpcExporter(sh.Plain) + return nil +} diff --git a/otelconf/config_test.go b/otelconf/config_test.go index f9306f7ad4a..dee0dff0509 100644 --- a/otelconf/config_test.go +++ b/otelconf/config_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "go.yaml.in/yaml/v3" ) @@ -185,7 +186,7 @@ func TestUnmarshalBatchLogRecordProcessor(t *testing.T) { name: "missing required exporter field", jsonConfig: []byte(`{}`), yamlConfig: []byte("{}"), - wantErrT: newErrRequiredExporter(&BatchLogRecordProcessor{}), + wantErrT: newErrRequired(&BatchLogRecordProcessor{}, "exporter"), }, { name: "invalid data", @@ -286,7 +287,7 @@ func TestUnmarshalBatchSpanProcessor(t *testing.T) { name: "missing required exporter field", jsonConfig: []byte(`{}`), yamlConfig: []byte("{}"), - wantErrT: newErrRequiredExporter(&BatchSpanProcessor{}), + wantErrT: newErrRequired(&BatchSpanProcessor{}, "exporter"), }, { name: "invalid data", @@ -387,7 +388,7 @@ func TestUnmarshalPeriodicMetricReader(t *testing.T) { name: "missing required exporter field", jsonConfig: []byte(`{}`), yamlConfig: []byte("{}"), - wantErrT: newErrRequiredExporter(&PeriodicMetricReader{}), + wantErrT: newErrRequired(&PeriodicMetricReader{}, "exporter"), }, { name: "invalid data", @@ -559,6 +560,94 @@ func TestUnmarshalCardinalityLimits(t *testing.T) { } } +func TestCreateHeadersConfig(t *testing.T) { + tests := []struct { + name string + headers []NameStringValuePair + headersList *string + wantHeaders map[string]string + wantErr error + }{ + { + name: "no headers", + headers: []NameStringValuePair{}, + headersList: nil, + wantHeaders: map[string]string{}, + }, + { + name: "headerslist only", + headers: []NameStringValuePair{}, + headersList: ptr("a=b,c=d"), + wantHeaders: map[string]string{ + "a": "b", + "c": "d", + }, + }, + { + name: "headers only", + headers: []NameStringValuePair{ + { + Name: "a", + Value: ptr("b"), + }, + { + Name: "c", + Value: ptr("d"), + }, + }, + headersList: nil, + wantHeaders: map[string]string{ + "a": "b", + "c": "d", + }, + }, + { + name: "both headers and headerslist", + headers: []NameStringValuePair{ + { + Name: "a", + Value: ptr("b"), + }, + }, + headersList: ptr("c=d"), + wantHeaders: map[string]string{ + "a": "b", + "c": "d", + }, + }, + { + name: "headers supersedes headerslist", + headers: []NameStringValuePair{ + { + Name: "a", + Value: ptr("b"), + }, + { + Name: "c", + Value: ptr("override"), + }, + }, + headersList: ptr("c=d"), + wantHeaders: map[string]string{ + "a": "b", + "c": "override", + }, + }, + { + name: "invalid headerslist", + headersList: ptr("==="), + wantErr: newErrInvalid("invalid headers_list"), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + headersMap, err := createHeadersConfig(tt.headers, tt.headersList) + require.ErrorIs(t, err, tt.wantErr) + require.Equal(t, tt.wantHeaders, headersMap) + }) + } +} + func TestUnmarshalSpanLimits(t *testing.T) { for _, tt := range []struct { name string @@ -635,3 +724,215 @@ func TestUnmarshalSpanLimits(t *testing.T) { }) } } + +func TestUnmarshalOTLPHttpExporter(t *testing.T) { + for _, tt := range []struct { + name string + yamlConfig []byte + jsonConfig []byte + wantErrT error + wantExporter OTLPHttpExporter + }{ + { + name: "valid with exporter", + jsonConfig: []byte(`{"endpoint":"localhost:4318"}`), + yamlConfig: []byte("endpoint: localhost:4318\n"), + wantExporter: OTLPHttpExporter{Endpoint: ptr("localhost:4318")}, + }, + { + name: "missing required endpoint field", + jsonConfig: []byte(`{}`), + yamlConfig: []byte("{}"), + wantErrT: newErrRequired(&OTLPHttpExporter{}, "endpoint"), + }, + { + name: "valid with zero timeout", + jsonConfig: []byte(`{"endpoint":"localhost:4318", "timeout":0}`), + yamlConfig: []byte("endpoint: localhost:4318\ntimeout: 0"), + wantExporter: OTLPHttpExporter{Endpoint: ptr("localhost:4318"), Timeout: ptr(0)}, + }, + { + name: "invalid data", + jsonConfig: []byte(`{:2000}`), + yamlConfig: []byte("endpoint: localhost:4318\ntimeout: !!str str"), + wantErrT: newErrUnmarshal(&OTLPHttpExporter{}), + }, + { + name: "invalid timeout negative", + jsonConfig: []byte(`{"endpoint":"localhost:4318", "timeout":-1}`), + yamlConfig: []byte("endpoint: localhost:4318\ntimeout: -1"), + wantErrT: newErrGreaterOrEqualZero("timeout"), + }, + } { + t.Run(tt.name, func(t *testing.T) { + cl := OTLPHttpExporter{} + err := cl.UnmarshalJSON(tt.jsonConfig) + assert.ErrorIs(t, err, tt.wantErrT) + assert.Equal(t, tt.wantExporter, cl) + + cl = OTLPHttpExporter{} + err = yaml.Unmarshal(tt.yamlConfig, &cl) + assert.ErrorIs(t, err, tt.wantErrT) + assert.Equal(t, tt.wantExporter, cl) + }) + } +} + +func TestUnmarshalOTLPGrpcExporter(t *testing.T) { + for _, tt := range []struct { + name string + yamlConfig []byte + jsonConfig []byte + wantErrT error + wantExporter OTLPGrpcExporter + }{ + { + name: "valid with exporter", + jsonConfig: []byte(`{"endpoint":"localhost:4318"}`), + yamlConfig: []byte("endpoint: localhost:4318\n"), + wantExporter: OTLPGrpcExporter{Endpoint: ptr("localhost:4318")}, + }, + { + name: "missing required endpoint field", + jsonConfig: []byte(`{}`), + yamlConfig: []byte("{}"), + wantErrT: newErrRequired(&OTLPGrpcExporter{}, "endpoint"), + }, + { + name: "valid with zero timeout", + jsonConfig: []byte(`{"endpoint":"localhost:4318", "timeout":0}`), + yamlConfig: []byte("endpoint: localhost:4318\ntimeout: 0"), + wantExporter: OTLPGrpcExporter{Endpoint: ptr("localhost:4318"), Timeout: ptr(0)}, + }, + { + name: "invalid data", + jsonConfig: []byte(`{:2000}`), + yamlConfig: []byte("endpoint: localhost:4318\ntimeout: !!str str"), + wantErrT: newErrUnmarshal(&OTLPGrpcExporter{}), + }, + { + name: "invalid timeout negative", + jsonConfig: []byte(`{"endpoint":"localhost:4318", "timeout":-1}`), + yamlConfig: []byte("endpoint: localhost:4318\ntimeout: -1"), + wantErrT: newErrGreaterOrEqualZero("timeout"), + }, + } { + t.Run(tt.name, func(t *testing.T) { + cl := OTLPGrpcExporter{} + err := cl.UnmarshalJSON(tt.jsonConfig) + assert.ErrorIs(t, err, tt.wantErrT) + assert.Equal(t, tt.wantExporter, cl) + + cl = OTLPGrpcExporter{} + err = yaml.Unmarshal(tt.yamlConfig, &cl) + assert.ErrorIs(t, err, tt.wantErrT) + assert.Equal(t, tt.wantExporter, cl) + }) + } +} + +func TestUnmarshalOTLPHttpMetricExporter(t *testing.T) { + for _, tt := range []struct { + name string + yamlConfig []byte + jsonConfig []byte + wantErrT error + wantExporter OTLPHttpMetricExporter + }{ + { + name: "valid with exporter", + jsonConfig: []byte(`{"endpoint":"localhost:4318"}`), + yamlConfig: []byte("endpoint: localhost:4318\n"), + wantExporter: OTLPHttpMetricExporter{Endpoint: ptr("localhost:4318")}, + }, + { + name: "missing required endpoint field", + jsonConfig: []byte(`{}`), + yamlConfig: []byte("{}"), + wantErrT: newErrRequired(&OTLPHttpMetricExporter{}, "endpoint"), + }, + { + name: "valid with zero timeout", + jsonConfig: []byte(`{"endpoint":"localhost:4318", "timeout":0}`), + yamlConfig: []byte("endpoint: localhost:4318\ntimeout: 0"), + wantExporter: OTLPHttpMetricExporter{Endpoint: ptr("localhost:4318"), Timeout: ptr(0)}, + }, + { + name: "invalid data", + jsonConfig: []byte(`{:2000}`), + yamlConfig: []byte("endpoint: localhost:4318\ntimeout: !!str str"), + wantErrT: newErrUnmarshal(&OTLPHttpMetricExporter{}), + }, + { + name: "invalid timeout negative", + jsonConfig: []byte(`{"endpoint":"localhost:4318", "timeout":-1}`), + yamlConfig: []byte("endpoint: localhost:4318\ntimeout: -1"), + wantErrT: newErrGreaterOrEqualZero("timeout"), + }, + } { + t.Run(tt.name, func(t *testing.T) { + cl := OTLPHttpMetricExporter{} + err := cl.UnmarshalJSON(tt.jsonConfig) + assert.ErrorIs(t, err, tt.wantErrT) + assert.Equal(t, tt.wantExporter, cl) + + cl = OTLPHttpMetricExporter{} + err = yaml.Unmarshal(tt.yamlConfig, &cl) + assert.ErrorIs(t, err, tt.wantErrT) + assert.Equal(t, tt.wantExporter, cl) + }) + } +} + +func TestUnmarshalOTLPGrpcMetricExporter(t *testing.T) { + for _, tt := range []struct { + name string + yamlConfig []byte + jsonConfig []byte + wantErrT error + wantExporter OTLPGrpcMetricExporter + }{ + { + name: "valid with exporter", + jsonConfig: []byte(`{"endpoint":"localhost:4318"}`), + yamlConfig: []byte("endpoint: localhost:4318\n"), + wantExporter: OTLPGrpcMetricExporter{Endpoint: ptr("localhost:4318")}, + }, + { + name: "missing required endpoint field", + jsonConfig: []byte(`{}`), + yamlConfig: []byte("{}"), + wantErrT: newErrRequired(&OTLPGrpcMetricExporter{}, "endpoint"), + }, + { + name: "valid with zero timeout", + jsonConfig: []byte(`{"endpoint":"localhost:4318", "timeout":0}`), + yamlConfig: []byte("endpoint: localhost:4318\ntimeout: 0"), + wantExporter: OTLPGrpcMetricExporter{Endpoint: ptr("localhost:4318"), Timeout: ptr(0)}, + }, + { + name: "invalid data", + jsonConfig: []byte(`{:2000}`), + yamlConfig: []byte("endpoint: localhost:4318\ntimeout: !!str str"), + wantErrT: newErrUnmarshal(&OTLPGrpcMetricExporter{}), + }, + { + name: "invalid timeout negative", + jsonConfig: []byte(`{"endpoint":"localhost:4318", "timeout":-1}`), + yamlConfig: []byte("endpoint: localhost:4318\ntimeout: -1"), + wantErrT: newErrGreaterOrEqualZero("timeout"), + }, + } { + t.Run(tt.name, func(t *testing.T) { + cl := OTLPGrpcMetricExporter{} + err := cl.UnmarshalJSON(tt.jsonConfig) + assert.ErrorIs(t, err, tt.wantErrT) + assert.Equal(t, tt.wantExporter, cl) + + cl = OTLPGrpcMetricExporter{} + err = yaml.Unmarshal(tt.yamlConfig, &cl) + assert.ErrorIs(t, err, tt.wantErrT) + assert.Equal(t, tt.wantExporter, cl) + }) + } +} diff --git a/otelconf/config_yaml.go b/otelconf/config_yaml.go index c29e8126ebf..cf57eeda5d1 100644 --- a/otelconf/config_yaml.go +++ b/otelconf/config_yaml.go @@ -107,7 +107,7 @@ func (j *TextMapPropagator) UnmarshalYAML(node *yaml.Node) error { // UnmarshalYAML implements yaml.Unmarshaler. func (j *BatchLogRecordProcessor) UnmarshalYAML(node *yaml.Node) error { if !hasYAMLMapKey(node, "exporter") { - return newErrRequiredExporter(j) + return newErrRequired(j, "exporter") } type Plain BatchLogRecordProcessor var plain Plain @@ -124,7 +124,7 @@ func (j *BatchLogRecordProcessor) UnmarshalYAML(node *yaml.Node) error { // UnmarshalYAML implements yaml.Unmarshaler. func (j *BatchSpanProcessor) UnmarshalYAML(node *yaml.Node) error { if !hasYAMLMapKey(node, "exporter") { - return newErrRequiredExporter(j) + return newErrRequired(j, "exporter") } type Plain BatchSpanProcessor var plain Plain @@ -141,7 +141,7 @@ func (j *BatchSpanProcessor) UnmarshalYAML(node *yaml.Node) error { // UnmarshalYAML implements yaml.Unmarshaler. func (j *PeriodicMetricReader) UnmarshalYAML(node *yaml.Node) error { if !hasYAMLMapKey(node, "exporter") { - return newErrRequiredExporter(j) + return newErrRequired(j, "exporter") } type Plain PeriodicMetricReader var plain Plain @@ -182,3 +182,71 @@ func (j *SpanLimits) UnmarshalYAML(node *yaml.Node) error { *j = SpanLimits(plain) return nil } + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *OTLPHttpMetricExporter) UnmarshalYAML(node *yaml.Node) error { + if !hasYAMLMapKey(node, "endpoint") { + return newErrRequired(j, "endpoint") + } + type Plain OTLPHttpMetricExporter + var plain Plain + if err := node.Decode(&plain); err != nil { + return errors.Join(newErrUnmarshal(j), err) + } + if plain.Timeout != nil && 0 > *plain.Timeout { + return newErrGreaterOrEqualZero("timeout") + } + *j = OTLPHttpMetricExporter(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *OTLPGrpcMetricExporter) UnmarshalYAML(node *yaml.Node) error { + if !hasYAMLMapKey(node, "endpoint") { + return newErrRequired(j, "endpoint") + } + type Plain OTLPGrpcMetricExporter + var plain Plain + if err := node.Decode(&plain); err != nil { + return errors.Join(newErrUnmarshal(j), err) + } + if plain.Timeout != nil && 0 > *plain.Timeout { + return newErrGreaterOrEqualZero("timeout") + } + *j = OTLPGrpcMetricExporter(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *OTLPHttpExporter) UnmarshalYAML(node *yaml.Node) error { + if !hasYAMLMapKey(node, "endpoint") { + return newErrRequired(j, "endpoint") + } + type Plain OTLPHttpExporter + var plain Plain + if err := node.Decode(&plain); err != nil { + return errors.Join(newErrUnmarshal(j), err) + } + if plain.Timeout != nil && 0 > *plain.Timeout { + return newErrGreaterOrEqualZero("timeout") + } + *j = OTLPHttpExporter(plain) + return nil +} + +// UnmarshalYAML implements yaml.Unmarshaler. +func (j *OTLPGrpcExporter) UnmarshalYAML(node *yaml.Node) error { + if !hasYAMLMapKey(node, "endpoint") { + return newErrRequired(j, "endpoint") + } + type Plain OTLPGrpcExporter + var plain Plain + if err := node.Decode(&plain); err != nil { + return errors.Join(newErrUnmarshal(j), err) + } + if plain.Timeout != nil && 0 > *plain.Timeout { + return newErrGreaterOrEqualZero("timeout") + } + *j = OTLPGrpcExporter(plain) + return nil +} From 3818c819c07635fc46910638c50dcda5c975ef25 Mon Sep 17 00:00:00 2001 From: Alex Boten <223565+codeboten@users.noreply.github.com> Date: Fri, 31 Oct 2025 15:47:51 -0700 Subject: [PATCH 2/3] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 404fba45574..bca07614b54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Add unmarshaling and validation for `CardinalityLimits` and `SpanLimits` to v1.0.0 model in `go.opentelemetry.io/contrib/otelconf`. (#8043) - Add unmarshaling and validation for `BatchLogRecordProcessor`, `BatchSpanProcessor`, and `PeriodicMetricReader` to v1.0.0 model in `go.opentelemetry.io/contrib/otelconf`. (#8049) - Add unmarshaling and validation for `TextMapPropagator` to v1.0.0 model in `go.opentelemetry.io/contrib/otelconf`. (#8052) -- Add unmarshaling and validation for `OTLPHttpExporter`, `OTLPGrpcExporter`, `OTLPGrpcMetricExporter` and `OTLPHttpMetricExporter` to v1.0.0 model in `go.opentelemetry.io/contrib/otelconf`. (#) +- Add unmarshaling and validation for `OTLPHttpExporter`, `OTLPGrpcExporter`, `OTLPGrpcMetricExporter` and `OTLPHttpMetricExporter` to v1.0.0 model in `go.opentelemetry.io/contrib/otelconf`. (#8112) ### Changed From 247bf3b0e64c152d40631f352b0ce913525f9fda Mon Sep 17 00:00:00 2001 From: alex boten <223565+codeboten@users.noreply.github.com> Date: Mon, 3 Nov 2025 06:59:40 -0800 Subject: [PATCH 3/3] fix Signed-off-by: alex boten <223565+codeboten@users.noreply.github.com> --- otelconf/config_json.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/otelconf/config_json.go b/otelconf/config_json.go index 13be55c6cad..a02ad603776 100644 --- a/otelconf/config_json.go +++ b/otelconf/config_json.go @@ -384,7 +384,7 @@ func (j *OTLPHttpMetricExporter) UnmarshalJSON(b []byte) error { if err := json.Unmarshal(sh.Endpoint, &sh.Plain.Endpoint); err != nil { return err } - if sh.Plain.Timeout != nil && 0 > *sh.Plain.Timeout { + if sh.Timeout != nil && 0 > *sh.Timeout { return newErrGreaterOrEqualZero("timeout") } *j = OTLPHttpMetricExporter(sh.Plain) @@ -408,7 +408,7 @@ func (j *OTLPGrpcMetricExporter) UnmarshalJSON(b []byte) error { if err := json.Unmarshal(sh.Endpoint, &sh.Plain.Endpoint); err != nil { return err } - if sh.Plain.Timeout != nil && 0 > *sh.Plain.Timeout { + if sh.Timeout != nil && 0 > *sh.Timeout { return newErrGreaterOrEqualZero("timeout") } *j = OTLPGrpcMetricExporter(sh.Plain) @@ -432,7 +432,7 @@ func (j *OTLPHttpExporter) UnmarshalJSON(b []byte) error { if err := json.Unmarshal(sh.Endpoint, &sh.Plain.Endpoint); err != nil { return err } - if sh.Plain.Timeout != nil && 0 > *sh.Plain.Timeout { + if sh.Timeout != nil && 0 > *sh.Timeout { return newErrGreaterOrEqualZero("timeout") } *j = OTLPHttpExporter(sh.Plain) @@ -456,7 +456,7 @@ func (j *OTLPGrpcExporter) UnmarshalJSON(b []byte) error { if err := json.Unmarshal(sh.Endpoint, &sh.Plain.Endpoint); err != nil { return err } - if sh.Plain.Timeout != nil && 0 > *sh.Plain.Timeout { + if sh.Timeout != nil && 0 > *sh.Timeout { return newErrGreaterOrEqualZero("timeout") } *j = OTLPGrpcExporter(sh.Plain)