From 8f82a064a7de81a5744848eac23428a09559ae76 Mon Sep 17 00:00:00 2001 From: ChrsMark Date: Mon, 23 Sep 2024 11:36:47 +0300 Subject: [PATCH] [mdatagen] Generate documentation for components with resource attributes only Signed-off-by: ChrsMark --- .../metagen_resource_attrs_only_doc.yaml | 25 +++ cmd/mdatagen/go.mod | 10 ++ cmd/mdatagen/internal/command.go | 2 +- cmd/mdatagen/internal/command_test.go | 32 ++-- .../internal/sampleprocessor/README.md | 22 +++ cmd/mdatagen/internal/sampleprocessor/doc.go | 10 ++ .../internal/sampleprocessor/documentation.md | 16 ++ .../internal/sampleprocessor/factory.go | 61 +++++++ .../generated_component_test.go | 151 ++++++++++++++++++ .../sampleprocessor/generated_package_test.go | 13 ++ .../internal/metadata/generated_config.go | 67 ++++++++ .../metadata/generated_config_test.go | 72 +++++++++ .../internal/metadata/generated_resource.go | 92 +++++++++++ .../metadata/generated_resource_test.go | 82 ++++++++++ .../internal/metadata/generated_status.go | 18 +++ .../internal/metadata/testdata/config.yaml | 37 +++++ .../internal/sampleprocessor/metadata.yaml | 68 ++++++++ 17 files changed, 762 insertions(+), 16 deletions(-) create mode 100644 .chloggen/metagen_resource_attrs_only_doc.yaml create mode 100644 cmd/mdatagen/internal/sampleprocessor/README.md create mode 100644 cmd/mdatagen/internal/sampleprocessor/doc.go create mode 100644 cmd/mdatagen/internal/sampleprocessor/documentation.md create mode 100644 cmd/mdatagen/internal/sampleprocessor/factory.go create mode 100644 cmd/mdatagen/internal/sampleprocessor/generated_component_test.go create mode 100644 cmd/mdatagen/internal/sampleprocessor/generated_package_test.go create mode 100644 cmd/mdatagen/internal/sampleprocessor/internal/metadata/generated_config.go create mode 100644 cmd/mdatagen/internal/sampleprocessor/internal/metadata/generated_config_test.go create mode 100644 cmd/mdatagen/internal/sampleprocessor/internal/metadata/generated_resource.go create mode 100644 cmd/mdatagen/internal/sampleprocessor/internal/metadata/generated_resource_test.go create mode 100644 cmd/mdatagen/internal/sampleprocessor/internal/metadata/generated_status.go create mode 100644 cmd/mdatagen/internal/sampleprocessor/internal/metadata/testdata/config.yaml create mode 100644 cmd/mdatagen/internal/sampleprocessor/metadata.yaml diff --git a/.chloggen/metagen_resource_attrs_only_doc.yaml b/.chloggen/metagen_resource_attrs_only_doc.yaml new file mode 100644 index 00000000000..2d999bff83d --- /dev/null +++ b/.chloggen/metagen_resource_attrs_only_doc.yaml @@ -0,0 +1,25 @@ +# Use this changelog template to create an entry for release notes. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver) +component: mdatagen + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Generate documentation for components with resource attributes only + +# One or more tracking issues or pull requests related to the change +issues: [10705] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: + +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [] diff --git a/cmd/mdatagen/go.mod b/cmd/mdatagen/go.mod index ae99b74fae3..bfe9372cfd8 100644 --- a/cmd/mdatagen/go.mod +++ b/cmd/mdatagen/go.mod @@ -14,6 +14,7 @@ require ( go.opentelemetry.io/collector/consumer/consumertest v0.111.0 go.opentelemetry.io/collector/filter v0.111.0 go.opentelemetry.io/collector/pdata v1.17.0 + go.opentelemetry.io/collector/processor v0.111.0 go.opentelemetry.io/collector/receiver v0.111.0 go.opentelemetry.io/collector/semconv v0.111.0 go.opentelemetry.io/otel/metric v1.30.0 @@ -42,10 +43,13 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + go.opentelemetry.io/collector/component/componentstatus v0.111.0 // indirect go.opentelemetry.io/collector/consumer/consumerprofiles v0.111.0 // indirect go.opentelemetry.io/collector/internal/globalsignal v0.111.0 // indirect go.opentelemetry.io/collector/pdata/pprofile v0.111.0 // indirect + go.opentelemetry.io/collector/pdata/testdata v0.111.0 // indirect go.opentelemetry.io/collector/pipeline v0.111.0 // indirect + go.opentelemetry.io/collector/processor/processorprofiles v0.111.0 // indirect go.opentelemetry.io/collector/receiver/receiverprofiles v0.111.0 // indirect go.opentelemetry.io/otel v1.30.0 // indirect go.opentelemetry.io/otel/sdk v1.30.0 // indirect @@ -95,3 +99,9 @@ replace go.opentelemetry.io/collector/receiver/receiverprofiles => ../../receive replace go.opentelemetry.io/collector/pipeline => ../../pipeline replace go.opentelemetry.io/collector/internal/globalsignal => ../../internal/globalsignal + +replace go.opentelemetry.io/collector/processor/processorprofiles => ../../processor/processorprofiles + +replace go.opentelemetry.io/collector/component/componentstatus => ../../component/componentstatus + +replace go.opentelemetry.io/collector/processor => ../../processor diff --git a/cmd/mdatagen/internal/command.go b/cmd/mdatagen/internal/command.go index fbd4088a34f..1c1d84287db 100644 --- a/cmd/mdatagen/internal/command.go +++ b/cmd/mdatagen/internal/command.go @@ -116,7 +116,7 @@ func run(ymlPath string) error { toGenerate[filepath.Join(tmplDir, "telemetry_test.go.tmpl")] = filepath.Join(codeDir, "generated_telemetry_test.go") } - if len(md.Metrics) != 0 || len(md.Telemetry.Metrics) != 0 { // if there's metrics or internal metrics, generate documentation for them + if len(md.Metrics) != 0 || len(md.Telemetry.Metrics) != 0 || len(md.ResourceAttributes) != 0 { // if there's metrics or internal metrics, generate documentation for them toGenerate[filepath.Join(tmplDir, "documentation.md.tmpl")] = filepath.Join(ymlDir, "documentation.md") } diff --git a/cmd/mdatagen/internal/command_test.go b/cmd/mdatagen/internal/command_test.go index b1d82b55f58..b19bef13296 100644 --- a/cmd/mdatagen/internal/command_test.go +++ b/cmd/mdatagen/internal/command_test.go @@ -19,17 +19,18 @@ import ( func TestRunContents(t *testing.T) { tests := []struct { - yml string - wantMetricsGenerated bool - wantMetricsContext bool - wantConfigGenerated bool - wantTelemetryGenerated bool - wantStatusGenerated bool - wantGoleakIgnore bool - wantGoleakSkip bool - wantGoleakSetup bool - wantGoleakTeardown bool - wantErr bool + yml string + wantMetricsGenerated bool + wantMetricsContext bool + wantConfigGenerated bool + wantTelemetryGenerated bool + wantResourceAttributesGenerated bool + wantStatusGenerated bool + wantGoleakIgnore bool + wantGoleakSkip bool + wantGoleakSetup bool + wantGoleakTeardown bool + wantErr bool }{ { yml: "invalid.yaml", @@ -42,9 +43,10 @@ func TestRunContents(t *testing.T) { wantStatusGenerated: true, }, { - yml: "resource_attributes_only.yaml", - wantConfigGenerated: true, - wantStatusGenerated: true, + yml: "resource_attributes_only.yaml", + wantConfigGenerated: true, + wantStatusGenerated: true, + wantResourceAttributesGenerated: true, }, { yml: "status_only.yaml", @@ -168,7 +170,7 @@ foo require.NoFileExists(t, filepath.Join(tmpdir, "internal/metadata/generated_telemetry_test.go")) } - if !tt.wantMetricsGenerated && !tt.wantTelemetryGenerated { + if !tt.wantMetricsGenerated && !tt.wantTelemetryGenerated && !tt.wantResourceAttributesGenerated { require.NoFileExists(t, filepath.Join(tmpdir, "documentation.md")) } diff --git a/cmd/mdatagen/internal/sampleprocessor/README.md b/cmd/mdatagen/internal/sampleprocessor/README.md new file mode 100644 index 00000000000..57d79c1f915 --- /dev/null +++ b/cmd/mdatagen/internal/sampleprocessor/README.md @@ -0,0 +1,22 @@ +# Sample Processor +This processor is used for testing purposes to check the output of mdatagen. + +| Status | | +| ------------- |-----------| +| Stability | [development]: logs | +| | [beta]: traces | +| | [stable]: metrics | +| Unsupported Platforms | freebsd, illumos | +| Distributions | [] | +| Warnings | [Any additional information that should be brought to the consumer's attention](#warnings) | +| Issues | [![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector?query=is%3Aissue%20is%3Aopen%20label%3Aprocessor%2Fsample%20&label=open&color=orange&logo=opentelemetry)](https://github.com/open-telemetry/opentelemetry-collector/issues?q=is%3Aopen+is%3Aissue+label%3Aprocessor%2Fsample) [![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector?query=is%3Aissue%20is%3Aclosed%20label%3Aprocessor%2Fsample%20&label=closed&color=blue&logo=opentelemetry)](https://github.com/open-telemetry/opentelemetry-collector/issues?q=is%3Aclosed+is%3Aissue+label%3Aprocessor%2Fsample) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@some](https://www.github.com/some) | + +[development]: https://github.com/open-telemetry/opentelemetry-collector#development +[beta]: https://github.com/open-telemetry/opentelemetry-collector#beta +[stable]: https://github.com/open-telemetry/opentelemetry-collector#stable + + +## Warnings + +This is where warnings are described. diff --git a/cmd/mdatagen/internal/sampleprocessor/doc.go b/cmd/mdatagen/internal/sampleprocessor/doc.go new file mode 100644 index 00000000000..0fc1c748f91 --- /dev/null +++ b/cmd/mdatagen/internal/sampleprocessor/doc.go @@ -0,0 +1,10 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// Generate a test metrics builder from a sample metrics set covering all configuration options. +//go:generate mdatagen metadata.yaml + +// Deprecated: This package is moving to https://github.com/open-telemetry/opentelemetry-collector and will eventually be removed. +// Please see https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/30497 +// This is a sample receiver package used to showcase how mdatagen is applied. +package sampleprocessor // import "go.opentelemetry.io/collector/cmd/mdatagen/internal/sampleprocessor" diff --git a/cmd/mdatagen/internal/sampleprocessor/documentation.md b/cmd/mdatagen/internal/sampleprocessor/documentation.md new file mode 100644 index 00000000000..5c1d70aa3d5 --- /dev/null +++ b/cmd/mdatagen/internal/sampleprocessor/documentation.md @@ -0,0 +1,16 @@ +[comment]: <> (Code generated by mdatagen. DO NOT EDIT.) + +# sample + +## Resource Attributes + +| Name | Description | Values | Enabled | +| ---- | ----------- | ------ | ------- | +| map.resource.attr | Resource attribute with a map value. | Any Map | true | +| optional.resource.attr | Explicitly disabled ResourceAttribute. | Any Str | false | +| slice.resource.attr | Resource attribute with a slice value. | Any Slice | true | +| string.enum.resource.attr | Resource attribute with a known set of string values. | Str: ``one``, ``two`` | true | +| string.resource.attr | Resource attribute with any string value. | Any Str | true | +| string.resource.attr_disable_warning | Resource attribute with any string value. | Any Str | true | +| string.resource.attr_remove_warning | Resource attribute with any string value. | Any Str | false | +| string.resource.attr_to_be_removed | Resource attribute with any string value. | Any Str | true | diff --git a/cmd/mdatagen/internal/sampleprocessor/factory.go b/cmd/mdatagen/internal/sampleprocessor/factory.go new file mode 100644 index 00000000000..a6f2814b3dd --- /dev/null +++ b/cmd/mdatagen/internal/sampleprocessor/factory.go @@ -0,0 +1,61 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package sampleprocessor // import "go.opentelemetry.io/collector/cmd/mdatagen/internal/sampleprocessor" + +import ( + "context" + + "go.opentelemetry.io/collector/cmd/mdatagen/internal/sampleprocessor/internal/metadata" + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/consumer" + "go.opentelemetry.io/collector/pdata/plog" + "go.opentelemetry.io/collector/pdata/pmetric" + "go.opentelemetry.io/collector/pdata/ptrace" + "go.opentelemetry.io/collector/processor" +) + +// NewFactory returns a receiver.Factory for sample receiver. +func NewFactory() processor.Factory { + return processor.NewFactory( + metadata.Type, + func() component.Config { return &struct{}{} }, + processor.WithTraces(createTracesProcessor, metadata.TracesStability), + processor.WithMetrics(createMetricsProcessor, metadata.MetricsStability), + processor.WithLogs(createLogsProcessor, metadata.LogsStability)) +} + +func createTracesProcessor(context.Context, processor.Settings, component.Config, consumer.Traces) (processor.Traces, error) { + return nopInstance, nil +} + +func createMetricsProcessor(context.Context, processor.Settings, component.Config, consumer.Metrics) (processor.Metrics, error) { + return nopInstance, nil +} + +func createLogsProcessor(context.Context, processor.Settings, component.Config, consumer.Logs) (processor.Logs, error) { + return nopInstance, nil +} + +var nopInstance = &nopProcessor{} + +type nopProcessor struct { + component.StartFunc + component.ShutdownFunc +} + +func (n nopProcessor) ConsumeTraces(context.Context, ptrace.Traces) error { + return nil +} + +func (n nopProcessor) ConsumeLogs(context.Context, plog.Logs) error { + return nil +} + +func (n nopProcessor) Capabilities() consumer.Capabilities { + return consumer.Capabilities{MutatesData: true} +} + +func (n nopProcessor) ConsumeMetrics(context.Context, pmetric.Metrics) error { + return nil +} diff --git a/cmd/mdatagen/internal/sampleprocessor/generated_component_test.go b/cmd/mdatagen/internal/sampleprocessor/generated_component_test.go new file mode 100644 index 00000000000..e42e4bac50c --- /dev/null +++ b/cmd/mdatagen/internal/sampleprocessor/generated_component_test.go @@ -0,0 +1,151 @@ +// Code generated by mdatagen. DO NOT EDIT. +//go:build !freebsd && !illumos + +package sampleprocessor + +import ( + "context" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/component/componenttest" + "go.opentelemetry.io/collector/confmap/confmaptest" + "go.opentelemetry.io/collector/consumer/consumertest" + "go.opentelemetry.io/collector/pdata/pcommon" + "go.opentelemetry.io/collector/pdata/plog" + "go.opentelemetry.io/collector/pdata/pmetric" + "go.opentelemetry.io/collector/pdata/ptrace" + "go.opentelemetry.io/collector/processor" + "go.opentelemetry.io/collector/processor/processortest" +) + +func TestComponentFactoryType(t *testing.T) { + require.Equal(t, "sample", NewFactory().Type().String()) +} + +func TestComponentConfigStruct(t *testing.T) { + require.NoError(t, componenttest.CheckConfigStruct(NewFactory().CreateDefaultConfig())) +} + +func TestComponentLifecycle(t *testing.T) { + factory := NewFactory() + + tests := []struct { + name string + createFn func(ctx context.Context, set processor.Settings, cfg component.Config) (component.Component, error) + }{ + + { + name: "logs", + createFn: func(ctx context.Context, set processor.Settings, cfg component.Config) (component.Component, error) { + return factory.CreateLogs(ctx, set, cfg, consumertest.NewNop()) + }, + }, + + { + name: "metrics", + createFn: func(ctx context.Context, set processor.Settings, cfg component.Config) (component.Component, error) { + return factory.CreateMetrics(ctx, set, cfg, consumertest.NewNop()) + }, + }, + + { + name: "traces", + createFn: func(ctx context.Context, set processor.Settings, cfg component.Config) (component.Component, error) { + return factory.CreateTraces(ctx, set, cfg, consumertest.NewNop()) + }, + }, + } + + cm, err := confmaptest.LoadConf("metadata.yaml") + require.NoError(t, err) + cfg := factory.CreateDefaultConfig() + sub, err := cm.Sub("tests::config") + require.NoError(t, err) + require.NoError(t, sub.Unmarshal(&cfg)) + + for _, tt := range tests { + t.Run(tt.name+"-shutdown", func(t *testing.T) { + c, err := tt.createFn(context.Background(), processortest.NewNopSettings(), cfg) + require.NoError(t, err) + err = c.Shutdown(context.Background()) + require.NoError(t, err) + }) + t.Run(tt.name+"-lifecycle", func(t *testing.T) { + c, err := tt.createFn(context.Background(), processortest.NewNopSettings(), cfg) + require.NoError(t, err) + host := componenttest.NewNopHost() + err = c.Start(context.Background(), host) + require.NoError(t, err) + require.NotPanics(t, func() { + switch tt.name { + case "logs": + e, ok := c.(processor.Logs) + require.True(t, ok) + logs := generateLifecycleTestLogs() + if !e.Capabilities().MutatesData { + logs.MarkReadOnly() + } + err = e.ConsumeLogs(context.Background(), logs) + case "metrics": + e, ok := c.(processor.Metrics) + require.True(t, ok) + metrics := generateLifecycleTestMetrics() + if !e.Capabilities().MutatesData { + metrics.MarkReadOnly() + } + err = e.ConsumeMetrics(context.Background(), metrics) + case "traces": + e, ok := c.(processor.Traces) + require.True(t, ok) + traces := generateLifecycleTestTraces() + if !e.Capabilities().MutatesData { + traces.MarkReadOnly() + } + err = e.ConsumeTraces(context.Background(), traces) + } + }) + require.NoError(t, err) + err = c.Shutdown(context.Background()) + require.NoError(t, err) + }) + } +} + +func generateLifecycleTestLogs() plog.Logs { + logs := plog.NewLogs() + rl := logs.ResourceLogs().AppendEmpty() + rl.Resource().Attributes().PutStr("resource", "R1") + l := rl.ScopeLogs().AppendEmpty().LogRecords().AppendEmpty() + l.Body().SetStr("test log message") + l.SetTimestamp(pcommon.NewTimestampFromTime(time.Now())) + return logs +} + +func generateLifecycleTestMetrics() pmetric.Metrics { + metrics := pmetric.NewMetrics() + rm := metrics.ResourceMetrics().AppendEmpty() + rm.Resource().Attributes().PutStr("resource", "R1") + m := rm.ScopeMetrics().AppendEmpty().Metrics().AppendEmpty() + m.SetName("test_metric") + dp := m.SetEmptyGauge().DataPoints().AppendEmpty() + dp.Attributes().PutStr("test_attr", "value_1") + dp.SetIntValue(123) + dp.SetTimestamp(pcommon.NewTimestampFromTime(time.Now())) + return metrics +} + +func generateLifecycleTestTraces() ptrace.Traces { + traces := ptrace.NewTraces() + rs := traces.ResourceSpans().AppendEmpty() + rs.Resource().Attributes().PutStr("resource", "R1") + span := rs.ScopeSpans().AppendEmpty().Spans().AppendEmpty() + span.Attributes().PutStr("test_attr", "value_1") + span.SetName("test_span") + span.SetStartTimestamp(pcommon.NewTimestampFromTime(time.Now().Add(-1 * time.Second))) + span.SetEndTimestamp(pcommon.NewTimestampFromTime(time.Now())) + return traces +} diff --git a/cmd/mdatagen/internal/sampleprocessor/generated_package_test.go b/cmd/mdatagen/internal/sampleprocessor/generated_package_test.go new file mode 100644 index 00000000000..6abd0d88121 --- /dev/null +++ b/cmd/mdatagen/internal/sampleprocessor/generated_package_test.go @@ -0,0 +1,13 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package sampleprocessor + +import ( + "testing" + + "go.uber.org/goleak" +) + +func TestMain(m *testing.M) { + goleak.VerifyTestMain(m) +} diff --git a/cmd/mdatagen/internal/sampleprocessor/internal/metadata/generated_config.go b/cmd/mdatagen/internal/sampleprocessor/internal/metadata/generated_config.go new file mode 100644 index 00000000000..42e1b6f641a --- /dev/null +++ b/cmd/mdatagen/internal/sampleprocessor/internal/metadata/generated_config.go @@ -0,0 +1,67 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "go.opentelemetry.io/collector/confmap" +) + +// ResourceAttributeConfig provides common config for a particular resource attribute. +type ResourceAttributeConfig struct { + Enabled bool `mapstructure:"enabled"` + + enabledSetByUser bool +} + +func (rac *ResourceAttributeConfig) Unmarshal(parser *confmap.Conf) error { + if parser == nil { + return nil + } + err := parser.Unmarshal(rac) + if err != nil { + return err + } + rac.enabledSetByUser = parser.IsSet("enabled") + return nil +} + +// ResourceAttributesConfig provides config for sample resource attributes. +type ResourceAttributesConfig struct { + MapResourceAttr ResourceAttributeConfig `mapstructure:"map.resource.attr"` + OptionalResourceAttr ResourceAttributeConfig `mapstructure:"optional.resource.attr"` + SliceResourceAttr ResourceAttributeConfig `mapstructure:"slice.resource.attr"` + StringEnumResourceAttr ResourceAttributeConfig `mapstructure:"string.enum.resource.attr"` + StringResourceAttr ResourceAttributeConfig `mapstructure:"string.resource.attr"` + StringResourceAttrDisableWarning ResourceAttributeConfig `mapstructure:"string.resource.attr_disable_warning"` + StringResourceAttrRemoveWarning ResourceAttributeConfig `mapstructure:"string.resource.attr_remove_warning"` + StringResourceAttrToBeRemoved ResourceAttributeConfig `mapstructure:"string.resource.attr_to_be_removed"` +} + +func DefaultResourceAttributesConfig() ResourceAttributesConfig { + return ResourceAttributesConfig{ + MapResourceAttr: ResourceAttributeConfig{ + Enabled: true, + }, + OptionalResourceAttr: ResourceAttributeConfig{ + Enabled: false, + }, + SliceResourceAttr: ResourceAttributeConfig{ + Enabled: true, + }, + StringEnumResourceAttr: ResourceAttributeConfig{ + Enabled: true, + }, + StringResourceAttr: ResourceAttributeConfig{ + Enabled: true, + }, + StringResourceAttrDisableWarning: ResourceAttributeConfig{ + Enabled: true, + }, + StringResourceAttrRemoveWarning: ResourceAttributeConfig{ + Enabled: false, + }, + StringResourceAttrToBeRemoved: ResourceAttributeConfig{ + Enabled: true, + }, + } +} diff --git a/cmd/mdatagen/internal/sampleprocessor/internal/metadata/generated_config_test.go b/cmd/mdatagen/internal/sampleprocessor/internal/metadata/generated_config_test.go new file mode 100644 index 00000000000..7b14c1b960e --- /dev/null +++ b/cmd/mdatagen/internal/sampleprocessor/internal/metadata/generated_config_test.go @@ -0,0 +1,72 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "path/filepath" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/stretchr/testify/require" + + "go.opentelemetry.io/collector/confmap/confmaptest" +) + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + MapResourceAttr: ResourceAttributeConfig{Enabled: true}, + OptionalResourceAttr: ResourceAttributeConfig{Enabled: true}, + SliceResourceAttr: ResourceAttributeConfig{Enabled: true}, + StringEnumResourceAttr: ResourceAttributeConfig{Enabled: true}, + StringResourceAttr: ResourceAttributeConfig{Enabled: true}, + StringResourceAttrDisableWarning: ResourceAttributeConfig{Enabled: true}, + StringResourceAttrRemoveWarning: ResourceAttributeConfig{Enabled: true}, + StringResourceAttrToBeRemoved: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + MapResourceAttr: ResourceAttributeConfig{Enabled: false}, + OptionalResourceAttr: ResourceAttributeConfig{Enabled: false}, + SliceResourceAttr: ResourceAttributeConfig{Enabled: false}, + StringEnumResourceAttr: ResourceAttributeConfig{Enabled: false}, + StringResourceAttr: ResourceAttributeConfig{Enabled: false}, + StringResourceAttrDisableWarning: ResourceAttributeConfig{Enabled: false}, + StringResourceAttrRemoveWarning: ResourceAttributeConfig{Enabled: false}, + StringResourceAttrToBeRemoved: ResourceAttributeConfig{Enabled: false}, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, tt.name) + if diff := cmp.Diff(tt.want, cfg, cmpopts.IgnoreUnexported(ResourceAttributeConfig{})); diff != "" { + t.Errorf("Config mismatch (-expected +actual):\n%s", diff) + } + }) + } +} + +func loadResourceAttributesConfig(t *testing.T, name string) ResourceAttributesConfig { + cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config.yaml")) + require.NoError(t, err) + sub, err := cm.Sub(name) + require.NoError(t, err) + sub, err = sub.Sub("resource_attributes") + require.NoError(t, err) + cfg := DefaultResourceAttributesConfig() + require.NoError(t, sub.Unmarshal(&cfg)) + return cfg +} diff --git a/cmd/mdatagen/internal/sampleprocessor/internal/metadata/generated_resource.go b/cmd/mdatagen/internal/sampleprocessor/internal/metadata/generated_resource.go new file mode 100644 index 00000000000..da69b3c0841 --- /dev/null +++ b/cmd/mdatagen/internal/sampleprocessor/internal/metadata/generated_resource.go @@ -0,0 +1,92 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "go.opentelemetry.io/collector/pdata/pcommon" +) + +// ResourceBuilder is a helper struct to build resources predefined in metadata.yaml. +// The ResourceBuilder is not thread-safe and must not to be used in multiple goroutines. +type ResourceBuilder struct { + config ResourceAttributesConfig + res pcommon.Resource +} + +// NewResourceBuilder creates a new ResourceBuilder. This method should be called on the start of the application. +func NewResourceBuilder(rac ResourceAttributesConfig) *ResourceBuilder { + return &ResourceBuilder{ + config: rac, + res: pcommon.NewResource(), + } +} + +// SetMapResourceAttr sets provided value as "map.resource.attr" attribute. +func (rb *ResourceBuilder) SetMapResourceAttr(val map[string]any) { + if rb.config.MapResourceAttr.Enabled { + rb.res.Attributes().PutEmptyMap("map.resource.attr").FromRaw(val) + } +} + +// SetOptionalResourceAttr sets provided value as "optional.resource.attr" attribute. +func (rb *ResourceBuilder) SetOptionalResourceAttr(val string) { + if rb.config.OptionalResourceAttr.Enabled { + rb.res.Attributes().PutStr("optional.resource.attr", val) + } +} + +// SetSliceResourceAttr sets provided value as "slice.resource.attr" attribute. +func (rb *ResourceBuilder) SetSliceResourceAttr(val []any) { + if rb.config.SliceResourceAttr.Enabled { + rb.res.Attributes().PutEmptySlice("slice.resource.attr").FromRaw(val) + } +} + +// SetStringEnumResourceAttrOne sets "string.enum.resource.attr=one" attribute. +func (rb *ResourceBuilder) SetStringEnumResourceAttrOne() { + if rb.config.StringEnumResourceAttr.Enabled { + rb.res.Attributes().PutStr("string.enum.resource.attr", "one") + } +} + +// SetStringEnumResourceAttrTwo sets "string.enum.resource.attr=two" attribute. +func (rb *ResourceBuilder) SetStringEnumResourceAttrTwo() { + if rb.config.StringEnumResourceAttr.Enabled { + rb.res.Attributes().PutStr("string.enum.resource.attr", "two") + } +} + +// SetStringResourceAttr sets provided value as "string.resource.attr" attribute. +func (rb *ResourceBuilder) SetStringResourceAttr(val string) { + if rb.config.StringResourceAttr.Enabled { + rb.res.Attributes().PutStr("string.resource.attr", val) + } +} + +// SetStringResourceAttrDisableWarning sets provided value as "string.resource.attr_disable_warning" attribute. +func (rb *ResourceBuilder) SetStringResourceAttrDisableWarning(val string) { + if rb.config.StringResourceAttrDisableWarning.Enabled { + rb.res.Attributes().PutStr("string.resource.attr_disable_warning", val) + } +} + +// SetStringResourceAttrRemoveWarning sets provided value as "string.resource.attr_remove_warning" attribute. +func (rb *ResourceBuilder) SetStringResourceAttrRemoveWarning(val string) { + if rb.config.StringResourceAttrRemoveWarning.Enabled { + rb.res.Attributes().PutStr("string.resource.attr_remove_warning", val) + } +} + +// SetStringResourceAttrToBeRemoved sets provided value as "string.resource.attr_to_be_removed" attribute. +func (rb *ResourceBuilder) SetStringResourceAttrToBeRemoved(val string) { + if rb.config.StringResourceAttrToBeRemoved.Enabled { + rb.res.Attributes().PutStr("string.resource.attr_to_be_removed", val) + } +} + +// Emit returns the built resource and resets the internal builder state. +func (rb *ResourceBuilder) Emit() pcommon.Resource { + r := rb.res + rb.res = pcommon.NewResource() + return r +} diff --git a/cmd/mdatagen/internal/sampleprocessor/internal/metadata/generated_resource_test.go b/cmd/mdatagen/internal/sampleprocessor/internal/metadata/generated_resource_test.go new file mode 100644 index 00000000000..162e83a991a --- /dev/null +++ b/cmd/mdatagen/internal/sampleprocessor/internal/metadata/generated_resource_test.go @@ -0,0 +1,82 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, tt := range []string{"default", "all_set", "none_set"} { + t.Run(tt, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, tt) + rb := NewResourceBuilder(cfg) + rb.SetMapResourceAttr(map[string]any{"key1": "map.resource.attr-val1", "key2": "map.resource.attr-val2"}) + rb.SetOptionalResourceAttr("optional.resource.attr-val") + rb.SetSliceResourceAttr([]any{"slice.resource.attr-item1", "slice.resource.attr-item2"}) + rb.SetStringEnumResourceAttrOne() + rb.SetStringResourceAttr("string.resource.attr-val") + rb.SetStringResourceAttrDisableWarning("string.resource.attr_disable_warning-val") + rb.SetStringResourceAttrRemoveWarning("string.resource.attr_remove_warning-val") + rb.SetStringResourceAttrToBeRemoved("string.resource.attr_to_be_removed-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return empty Resource + + switch tt { + case "default": + assert.Equal(t, 6, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 8, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", tt) + } + + val, ok := res.Attributes().Get("map.resource.attr") + assert.True(t, ok) + if ok { + assert.EqualValues(t, map[string]any{"key1": "map.resource.attr-val1", "key2": "map.resource.attr-val2"}, val.Map().AsRaw()) + } + val, ok = res.Attributes().Get("optional.resource.attr") + assert.Equal(t, tt == "all_set", ok) + if ok { + assert.EqualValues(t, "optional.resource.attr-val", val.Str()) + } + val, ok = res.Attributes().Get("slice.resource.attr") + assert.True(t, ok) + if ok { + assert.EqualValues(t, []any{"slice.resource.attr-item1", "slice.resource.attr-item2"}, val.Slice().AsRaw()) + } + val, ok = res.Attributes().Get("string.enum.resource.attr") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "one", val.Str()) + } + val, ok = res.Attributes().Get("string.resource.attr") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "string.resource.attr-val", val.Str()) + } + val, ok = res.Attributes().Get("string.resource.attr_disable_warning") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "string.resource.attr_disable_warning-val", val.Str()) + } + val, ok = res.Attributes().Get("string.resource.attr_remove_warning") + assert.Equal(t, tt == "all_set", ok) + if ok { + assert.EqualValues(t, "string.resource.attr_remove_warning-val", val.Str()) + } + val, ok = res.Attributes().Get("string.resource.attr_to_be_removed") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "string.resource.attr_to_be_removed-val", val.Str()) + } + }) + } +} diff --git a/cmd/mdatagen/internal/sampleprocessor/internal/metadata/generated_status.go b/cmd/mdatagen/internal/sampleprocessor/internal/metadata/generated_status.go new file mode 100644 index 00000000000..7f86f1d8fc1 --- /dev/null +++ b/cmd/mdatagen/internal/sampleprocessor/internal/metadata/generated_status.go @@ -0,0 +1,18 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "go.opentelemetry.io/collector/component" +) + +var ( + Type = component.MustNewType("sample") + ScopeName = "go.opentelemetry.io/collector/internal/receiver/samplereceiver" +) + +const ( + LogsStability = component.StabilityLevelDevelopment + TracesStability = component.StabilityLevelBeta + MetricsStability = component.StabilityLevelStable +) diff --git a/cmd/mdatagen/internal/sampleprocessor/internal/metadata/testdata/config.yaml b/cmd/mdatagen/internal/sampleprocessor/internal/metadata/testdata/config.yaml new file mode 100644 index 00000000000..bcc1a519f60 --- /dev/null +++ b/cmd/mdatagen/internal/sampleprocessor/internal/metadata/testdata/config.yaml @@ -0,0 +1,37 @@ +default: +all_set: + resource_attributes: + map.resource.attr: + enabled: true + optional.resource.attr: + enabled: true + slice.resource.attr: + enabled: true + string.enum.resource.attr: + enabled: true + string.resource.attr: + enabled: true + string.resource.attr_disable_warning: + enabled: true + string.resource.attr_remove_warning: + enabled: true + string.resource.attr_to_be_removed: + enabled: true +none_set: + resource_attributes: + map.resource.attr: + enabled: false + optional.resource.attr: + enabled: false + slice.resource.attr: + enabled: false + string.enum.resource.attr: + enabled: false + string.resource.attr: + enabled: false + string.resource.attr_disable_warning: + enabled: false + string.resource.attr_remove_warning: + enabled: false + string.resource.attr_to_be_removed: + enabled: false diff --git a/cmd/mdatagen/internal/sampleprocessor/metadata.yaml b/cmd/mdatagen/internal/sampleprocessor/metadata.yaml new file mode 100644 index 00000000000..521bd62c452 --- /dev/null +++ b/cmd/mdatagen/internal/sampleprocessor/metadata.yaml @@ -0,0 +1,68 @@ +# Sample metadata file with all available configurations for a receiver. + +type: sample +scope_name: go.opentelemetry.io/collector/internal/receiver/samplereceiver +github_project: open-telemetry/opentelemetry-collector + +sem_conv_version: 1.9.0 + +status: + class: processor + stability: + development: [logs] + beta: [traces] + stable: [metrics] + distributions: [] + unsupported_platforms: [freebsd, illumos] + codeowners: + active: [some] + warnings: + - Any additional information that should be brought to the consumer's attention + +resource_attributes: + string.resource.attr: + description: Resource attribute with any string value. + type: string + enabled: true + + string.enum.resource.attr: + description: Resource attribute with a known set of string values. + type: string + enum: [one, two] + enabled: true + + optional.resource.attr: + description: Explicitly disabled ResourceAttribute. + type: string + enabled: false + + slice.resource.attr: + description: Resource attribute with a slice value. + type: slice + enabled: true + + map.resource.attr: + description: Resource attribute with a map value. + type: map + enabled: true + + string.resource.attr_disable_warning: + description: Resource attribute with any string value. + type: string + enabled: true + warnings: + if_enabled_not_set: This resource_attribute will be disabled by default soon. + + string.resource.attr_remove_warning: + description: Resource attribute with any string value. + type: string + enabled: false + warnings: + if_configured: This resource_attribute is deprecated and will be removed soon. + + string.resource.attr_to_be_removed: + description: Resource attribute with any string value. + type: string + enabled: true + warnings: + if_enabled: This resource_attribute is deprecated and will be removed soon.