From 788af04e63e4c37f9a02b447af0782ab9951ed0a Mon Sep 17 00:00:00 2001 From: Antoine Toulme Date: Thu, 20 Jul 2023 17:12:27 -0700 Subject: [PATCH 01/42] [chore] add ecsobserver codeowners (#24406) --- .github/CODEOWNERS | 1 + .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + .github/ISSUE_TEMPLATE/feature_request.yaml | 1 + .github/ISSUE_TEMPLATE/other.yaml | 1 + 4 files changed, 4 insertions(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index f3a40a641c0a..b9e411edcb9b 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -96,6 +96,7 @@ extension/jaegerremotesampling/ @open-telemetry/collect extension/oauth2clientauthextension/ @open-telemetry/collector-contrib-approvers @pavankrish123 @jpkrohling extension/observer/ @open-telemetry/collector-contrib-approvers @dmitryax @rmfitzpatrick extension/observer/dockerobserver/ @open-telemetry/collector-contrib-approvers @MovieStoreGuy +extension/observer/ecsobserver/ @open-telemetry/collector-contrib-approvers @dmitryax @rmfitzpatrick extension/observer/ecstaskobserver/ @open-telemetry/collector-contrib-approvers @rmfitzpatrick extension/observer/hostobserver/ @open-telemetry/collector-contrib-approvers @MovieStoreGuy extension/observer/k8sobserver/ @open-telemetry/collector-contrib-approvers @rmfitzpatrick @dmitryax diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 06e4b1f88e8f..bf0e8f5a1d5f 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -89,6 +89,7 @@ body: - extension/oauth2clientauth - extension/observer - extension/observer/dockerobserver + - extension/observer/ecsobserver - extension/observer/ecstaskobserver - extension/observer/hostobserver - extension/observer/k8sobserver diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml index 0afd837a8e2b..605c885e070c 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yaml +++ b/.github/ISSUE_TEMPLATE/feature_request.yaml @@ -83,6 +83,7 @@ body: - extension/oauth2clientauth - extension/observer - extension/observer/dockerobserver + - extension/observer/ecsobserver - extension/observer/ecstaskobserver - extension/observer/hostobserver - extension/observer/k8sobserver diff --git a/.github/ISSUE_TEMPLATE/other.yaml b/.github/ISSUE_TEMPLATE/other.yaml index a7614d86b8a6..10b214f3db07 100644 --- a/.github/ISSUE_TEMPLATE/other.yaml +++ b/.github/ISSUE_TEMPLATE/other.yaml @@ -83,6 +83,7 @@ body: - extension/oauth2clientauth - extension/observer - extension/observer/dockerobserver + - extension/observer/ecsobserver - extension/observer/ecstaskobserver - extension/observer/hostobserver - extension/observer/k8sobserver From 68a9da824436ca86c61899869ff059e57a01878e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=81=93=E5=90=9B?= Date: Fri, 21 Jul 2023 23:29:05 +0800 Subject: [PATCH 02/42] update pulsar receiver/exporter CODEOWNERS (#24424) Update pulsar receiver/exporter codeowner from @tjiuming to @dao-jun Fixes #23406 --- .github/CODEOWNERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index b9e411edcb9b..d93bc9039b30 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -72,7 +72,7 @@ exporter/opencensusexporter/ @open-telemetry/collect exporter/parquetexporter/ @open-telemetry/collector-contrib-approvers @atoulme exporter/prometheusexporter/ @open-telemetry/collector-contrib-approvers @Aneurysm9 exporter/prometheusremotewriteexporter/ @open-telemetry/collector-contrib-approvers @Aneurysm9 @rapphil -exporter/pulsarexporter/ @open-telemetry/collector-contrib-approvers @dmitryax @tjiuming +exporter/pulsarexporter/ @open-telemetry/collector-contrib-approvers @dmitryax @dao-jun exporter/sapmexporter/ @open-telemetry/collector-contrib-approvers @dmitryax @atoulme exporter/sentryexporter/ @open-telemetry/collector-contrib-approvers @AbhiPrasad exporter/signalfxexporter/ @open-telemetry/collector-contrib-approvers @dmitryax @crobert-1 @@ -222,7 +222,7 @@ receiver/podmanreceiver/ @open-telemetry/collect receiver/postgresqlreceiver/ @open-telemetry/collector-contrib-approvers @djaglowski receiver/prometheusexecreceiver/ @open-telemetry/collector-contrib-approvers @dmitryax receiver/prometheusreceiver/ @open-telemetry/collector-contrib-approvers @Aneurysm9 @dashpole -receiver/pulsarreceiver/ @open-telemetry/collector-contrib-approvers @dmitryax @tjiuming +receiver/pulsarreceiver/ @open-telemetry/collector-contrib-approvers @dmitryax @dao-jun receiver/purefareceiver/ @open-telemetry/collector-contrib-approvers @jpkrohling @dgoscn @chrroberts-pure receiver/purefbreceiver/ @open-telemetry/collector-contrib-approvers @jpkrohling @dgoscn @chrroberts-pure receiver/rabbitmqreceiver/ @open-telemetry/collector-contrib-approvers @djaglowski @cpheps From edff046aa82e372abf0b8755d047f0d929f6a5b2 Mon Sep 17 00:00:00 2001 From: Mike Dame Date: Fri, 21 Jul 2023 11:30:27 -0400 Subject: [PATCH 03/42] [chore] [exporter/googlecloud] add note on metric label collisions to readme (#24390) Adds a section to the readme on using the transform processor to avoid metric label collisions when the exporter adds labels to metrics. **Link to tracking Issue:** https://github.com/GoogleCloudPlatform/opentelemetry-operations-go/issues/352 --- exporter/googlecloudexporter/README.md | 48 ++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/exporter/googlecloudexporter/README.md b/exporter/googlecloudexporter/README.md index 68e9b0b06cf3..5fe584de1a43 100644 --- a/exporter/googlecloudexporter/README.md +++ b/exporter/googlecloudexporter/README.md @@ -235,6 +235,54 @@ following proxy environment variables: If set at Collector start time then exporters, regardless of protocol, will or will not proxy traffic as defined by these environment variables. +### Preventing metric label collisions + +The metrics exporter can add metric labels to timeseries, such as when setting +`metric.service_resource_labels`, `metric.instrumentation_library_labels` (both +on by default), or when using `metric.resource_filters` to convert resource +attributes to metric labels. + +However, if your metrics already contain any of these labels they will fail to +export to Google Cloud with a `Duplicate label key encountered` error. Such +labels from the default features above include: + +* `service_name` +* `service_namespace` +* `service_instance_id` +* `instrumentation_source` +* `instrumentation_version` + +*(Note that these are the sanitized versions of OpenTelemetry attributes, with `.` replaced by `_` to be compatible with Cloud Monitoring. For example, `service_name` comes from the [`service.name` resource attribute](https://github.com/open-telemetry/opentelemetry-specification/blob/dc78006c12d9767fd2e35b691706c7572a76fd43/specification/resource/semantic_conventions/README.md#service).)* + +To prevent this, it's recommended to use the [transform processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/c7bd50ce773e66be327ef7618775a884a774e5d1/processor/transformprocessor) in your collector config to rename existing metric labels to preserve them, for example: + +```yaml +processors: + transform: + metric_statements: + - context: datapoint + statements: + - set(attributes["exported_service_name"], attributes["service_name"]) + - delete_key(attributes, "service_name") + - set(attributes["exported_service_namespace"], attributes["service_namespace"]) + - delete_key(attributes, "service_namespace") + - set(attributes["exported_service_instance_id"], attributes["service_instance_id"]) + - delete_key(attributes, "service_instance_id") + - set(attributes["exported_instrumentation_source"], attributes["instrumentation_source"]) + - delete_key(attributes, "instrumentation_source") + - set(attributes["exported_instrumentation_version"], attributes["instrumentation_version"]) + - delete_key(attributes, "instrumentation_version") +``` + +The same method can be used for any resource attributes being filtered to metric +labels, or metric labels which might collide with the GCP monitored resource +used with resource detection. + +Keep in mind that your conflicting attributes may contain dots instead of +underscores (eg, `service.name`), but these will still collide once all +attributes are normalized to metric labels. In this case you will need to update +the collector config above appropriately. + ### Logging Example The logging exporter processes OpenTelemetry log entries and exports them to GCP Cloud Logging. Logs can be collected using one From 1c36f057be5f97e712974973c92d1b57dca4324c Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Fri, 21 Jul 2023 11:43:14 -0400 Subject: [PATCH 04/42] [receiver/k8sclusterreceiver] Begin emitting entity events as logs (#24419) Resolves https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24400 This is part 3 of the work to move to entity events-as-log-records in K8s cluster receiver: https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/19741 Overall design document: https://docs.google.com/document/d/1Tg18sIck3Nakxtd3TFFcIjrmRO_0GLMdHXylVqBQmJA/ Example log record emitted when a pod changes: ``` ObservedTimestamp: 1970-01-01 00:00:00 +0000 UTC Timestamp: 1970-01-01 00:00:00 +0000 UTC SeverityText: SeverityNumber: Unspecified(0) Body: Empty() Attributes: -> otel.entity.id: Map({"k8s.pod.uid":"07cc87d9-8e76-4472-b5ee-c9ecbad94ea9"}) -> otel.entity.event.type: Str(entity_state) -> otel.entity.type: Str(k8s.pod) -> otel.entity.attributes: Map({"k8s-app":"kubernetes-dashboard","k8s.deployment.name":"kubernetes-dashboard","k8s.deployment.uid":"4c1ee765-906b-498b-80b5-bea67a714fce","k8s.replicaset.name":"kubernetes-dashboard-6c7ccbcf87","k8s.replicasetuid":"e8c052b4-c1db-43bd-806d-f85d8a861f5b","k8s.service.kubernetes-dashboard":"","k8s.workload.kind":"Deployment","k8s.workload.name":"kubernetes-dashboard","pod-template-hash":"6c7ccbcf87","podcreation_timestamp":"2023-06-30T11:32:00-04:00"}) Trace ID: Span ID: Flags: 0 ``` --- ...k8scluster-receiver-emit-entityevents.yaml | 20 +++++ .../entity_events.go | 18 +++++ .../entity_events_test.go | 54 ++++++++++++++ receiver/k8sclusterreceiver/README.md | 11 ++- receiver/k8sclusterreceiver/factory.go | 11 ++- receiver/k8sclusterreceiver/factory_test.go | 28 ++++++- receiver/k8sclusterreceiver/go.mod | 3 + .../internal/metadata/generated_status.go | 1 + receiver/k8sclusterreceiver/metadata.yaml | 1 + receiver/k8sclusterreceiver/receiver.go | 73 +++++++++++++++---- receiver/k8sclusterreceiver/receiver_test.go | 36 ++++++--- receiver/k8sclusterreceiver/watcher.go | 54 ++++++++++++-- receiver/k8sclusterreceiver/watcher_test.go | 73 +++++++++++++++++++ 13 files changed, 349 insertions(+), 34 deletions(-) create mode 100644 .chloggen/k8scluster-receiver-emit-entityevents.yaml diff --git a/.chloggen/k8scluster-receiver-emit-entityevents.yaml b/.chloggen/k8scluster-receiver-emit-entityevents.yaml new file mode 100644 index 000000000000..5a46871ec80f --- /dev/null +++ b/.chloggen/k8scluster-receiver-emit-entityevents.yaml @@ -0,0 +1,20 @@ +# Use this changelog template to create an entry for release notes. +# If your change doesn't affect end users, such as a test fix or a tooling change, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. + +# 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. filelogreceiver) +component: k8sclusterreceiver + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: k8sclusterreceiver - Begin emitting entity events as logs + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [24400] + +# (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: diff --git a/pkg/experimentalmetricmetadata/entity_events.go b/pkg/experimentalmetricmetadata/entity_events.go index acaa6d76e078..5edb703cc8aa 100644 --- a/pkg/experimentalmetricmetadata/entity_events.go +++ b/pkg/experimentalmetricmetadata/entity_events.go @@ -19,6 +19,8 @@ const ( semconvOtelEntityID = "otel.entity.id" semconvOtelEntityType = "otel.entity.type" semconvOtelEntityAttributes = "otel.entity.attributes" + + semconvOtelEntityEventAsScope = "otel.entity.event_as_log" ) // EntityEventsSlice is a slice of EntityEvent. @@ -52,6 +54,22 @@ func (s EntityEventsSlice) At(i int) EntityEvent { return EntityEvent{orig: s.orig.At(i)} } +// ConvertAndMoveToLogs converts entity events to log representation and moves them +// from this EntityEventsSlice into plog.Logs. This slice becomes empty after this call. +func (s EntityEventsSlice) ConvertAndMoveToLogs() plog.Logs { + logs := plog.NewLogs() + + scopeLogs := logs.ResourceLogs().AppendEmpty().ScopeLogs().AppendEmpty() + + // Set the scope marker. + scopeLogs.Scope().Attributes().PutBool(semconvOtelEntityEventAsScope, true) + + // Move all events. Note that this remove all + s.orig.MoveAndAppendTo(scopeLogs.LogRecords()) + + return logs +} + // EntityEvent is an entity event. type EntityEvent struct { orig plog.LogRecord diff --git a/pkg/experimentalmetricmetadata/entity_events_test.go b/pkg/experimentalmetricmetadata/entity_events_test.go index 83a00fbee142..7ded1c7bb503 100644 --- a/pkg/experimentalmetricmetadata/entity_events_test.go +++ b/pkg/experimentalmetricmetadata/entity_events_test.go @@ -58,6 +58,60 @@ func Test_EntityEventsSlice(t *testing.T) { assert.Equal(t, 1, slice.Len()) } +func Test_EntityEventsSlice_ConvertAndMoveToLogs(t *testing.T) { + // Prepare an event slice. + slice := NewEntityEventsSlice() + event := slice.AppendEmpty() + + event.ID().PutStr("k8s.pod.uid", "123") + state := event.SetEntityState() + state.SetEntityType("k8s.pod") + state.Attributes().PutStr("label1", "value1") + + event = slice.AppendEmpty() + event.ID().PutStr("k8s.node.uid", "abc") + event.SetEntityDelete() + + // Convert to logs. + logs := slice.ConvertAndMoveToLogs() + + // Check that all 2 events are moved. + assert.Equal(t, 0, slice.Len()) + assert.Equal(t, 2, logs.LogRecordCount()) + + assert.Equal(t, 1, logs.ResourceLogs().Len()) + + scopeLogs := logs.ResourceLogs().At(0).ScopeLogs().At(0) + + // Check the Scope + v, ok := scopeLogs.Scope().Attributes().Get(semconvOtelEntityEventAsScope) + assert.True(t, ok) + assert.Equal(t, true, v.Bool()) + + records := scopeLogs.LogRecords() + assert.Equal(t, 2, records.Len()) + + // Check the first event. + attrs := records.At(0).Attributes().AsRaw() + assert.EqualValues( + t, map[string]any{ + semconvOtelEntityEventName: semconvEventEntityEventState, + semconvOtelEntityType: "k8s.pod", + semconvOtelEntityID: map[string]any{"k8s.pod.uid": "123"}, + semconvOtelEntityAttributes: map[string]any{"label1": "value1"}, + }, attrs, + ) + + // Check the second event. + attrs = records.At(1).Attributes().AsRaw() + assert.EqualValues( + t, map[string]any{ + semconvOtelEntityEventName: semconvEventEntityEventDelete, + semconvOtelEntityID: map[string]any{"k8s.node.uid": "abc"}, + }, attrs, + ) +} + func Test_EntityEventType(t *testing.T) { lr := plog.NewLogRecord() e := EntityEvent{lr} diff --git a/receiver/k8sclusterreceiver/README.md b/receiver/k8sclusterreceiver/README.md index d5a75f52c228..e82292bd8b71 100644 --- a/receiver/k8sclusterreceiver/README.md +++ b/receiver/k8sclusterreceiver/README.md @@ -4,17 +4,19 @@ | Status | | | ------------- |-----------| | Stability | [beta]: metrics | +| | [development]: logs | | Distributions | [contrib], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fk8scluster%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fk8scluster%20&label=closed&color=blue&logo=opentelemetry) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta +[development]: https://github.com/open-telemetry/opentelemetry-collector#development [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib [observiq]: https://github.com/observIQ/observiq-otel-collector [splunk]: https://github.com/signalfx/splunk-otel-collector [sumo]: https://github.com/SumoLogic/sumologic-otel-collector -The Kubernetes Cluster receiver collects cluster-level metrics from the Kubernetes +The Kubernetes Cluster receiver collects cluster-level metrics and entity events from the Kubernetes API server. It uses the K8s API to listen for updates. A single instance of this receiver can be used to monitor a cluster. @@ -107,6 +109,10 @@ type MetadataDelta struct { See [here](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/pkg/experimentalmetricmetadata/metadata.go) for details about the above types. +The same metadata will be also emitted as entity events in the form of log records if +this receiver is connected to a logs pipeline. +See [here](https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/23565) +for the format of emitted log records. ## Example @@ -139,6 +145,9 @@ data: metrics: receivers: [k8s_cluster] exporters: [logging] + logs/entity_events: + receivers: [k8s_cluster] + exporters: [logging] EOF ``` diff --git a/receiver/k8sclusterreceiver/factory.go b/receiver/k8sclusterreceiver/factory.go index d72c515301fd..bc516001c6d0 100644 --- a/receiver/k8sclusterreceiver/factory.go +++ b/receiver/k8sclusterreceiver/factory.go @@ -10,6 +10,7 @@ import ( "go.opentelemetry.io/collector/receiver" "github.com/open-telemetry/opentelemetry-collector-contrib/internal/k8sconfig" + "github.com/open-telemetry/opentelemetry-collector-contrib/internal/sharedcomponent" "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/metadata" ) @@ -41,5 +42,13 @@ func NewFactory() receiver.Factory { return receiver.NewFactory( metadata.Type, createDefaultConfig, - receiver.WithMetrics(newReceiver, metadata.MetricsStability)) + receiver.WithMetrics(newMetricsReceiver, metadata.MetricsStability), + receiver.WithLogs(newLogsReceiver, metadata.MetricsStability), + ) } + +// This is the map of already created k8scluster receivers for particular configurations. +// We maintain this map because the Factory is asked log and metric receivers separately +// when it gets CreateLogsReceiver() and CreateMetricsReceiver() but they must not +// create separate objects, they must use one receiver object per configuration. +var receivers = sharedcomponent.NewSharedComponents() diff --git a/receiver/k8sclusterreceiver/factory_test.go b/receiver/k8sclusterreceiver/factory_test.go index a1c4128bd7d1..13677bbfd1d9 100644 --- a/receiver/k8sclusterreceiver/factory_test.go +++ b/receiver/k8sclusterreceiver/factory_test.go @@ -10,6 +10,7 @@ import ( quotaclientset "github.com/openshift/client-go/quota/clientset/versioned" fakeQuota "github.com/openshift/client-go/quota/clientset/versioned/fake" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/component/componenttest" @@ -19,6 +20,7 @@ import ( "k8s.io/client-go/kubernetes/fake" "github.com/open-telemetry/opentelemetry-collector-contrib/internal/k8sconfig" + "github.com/open-telemetry/opentelemetry-collector-contrib/internal/sharedcomponent" ) func TestFactory(t *testing.T) { @@ -80,7 +82,7 @@ func TestFactoryDistributions(t *testing.T) { } func newTestReceiver(t *testing.T, cfg *Config) *kubernetesReceiver { - r, err := newReceiver(context.Background(), receivertest.NewNopCreateSettings(), cfg, consumertest.NewNop()) + r, err := newReceiver(context.Background(), receivertest.NewNopCreateSettings(), cfg) require.NoError(t, err) require.NotNil(t, r) rcvr, ok := r.(*kubernetesReceiver) @@ -111,3 +113,27 @@ func (n *nopHostWithExporters) GetExporters() map[component.DataType]map[compone }, } } + +func TestNewSharedReceiver(t *testing.T) { + f := NewFactory() + cfg := f.CreateDefaultConfig() + + mc := consumertest.NewNop() + mr, err := newMetricsReceiver(context.Background(), receivertest.NewNopCreateSettings(), cfg, mc) + require.NoError(t, err) + + // Verify that the metric consumer is correctly set. + kr := mr.(*sharedcomponent.SharedComponent).Unwrap().(*kubernetesReceiver) + assert.Equal(t, mc, kr.metricsConsumer) + + lc := consumertest.NewNop() + lr, err := newLogsReceiver(context.Background(), receivertest.NewNopCreateSettings(), cfg, lc) + require.NoError(t, err) + + // Verify that the log consumer is correct set. + kr = lr.(*sharedcomponent.SharedComponent).Unwrap().(*kubernetesReceiver) + assert.Equal(t, lc, kr.resourceWatcher.entityLogConsumer) + + // Make sure only one receiver is created both for metrics and logs. + assert.Equal(t, mr, lr) +} diff --git a/receiver/k8sclusterreceiver/go.mod b/receiver/k8sclusterreceiver/go.mod index b7dadf3b6d6e..6a9fd3b9c257 100644 --- a/receiver/k8sclusterreceiver/go.mod +++ b/receiver/k8sclusterreceiver/go.mod @@ -11,6 +11,7 @@ require ( github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.81.0 github.com/open-telemetry/opentelemetry-collector-contrib/internal/k8sconfig v0.81.0 github.com/open-telemetry/opentelemetry-collector-contrib/internal/k8stest v0.81.0 + github.com/open-telemetry/opentelemetry-collector-contrib/internal/sharedcomponent v0.81.0 github.com/open-telemetry/opentelemetry-collector-contrib/pkg/experimentalmetricmetadata v0.81.0 github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest v0.81.0 github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/opencensus v0.81.0 @@ -160,3 +161,5 @@ replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil replace github.com/openshift/api v3.9.0+incompatible => github.com/openshift/api v0.0.0-20180801171038-322a19404e37 replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/k8stest => ../../internal/k8stest + +replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/sharedcomponent => ../../internal/sharedcomponent diff --git a/receiver/k8sclusterreceiver/internal/metadata/generated_status.go b/receiver/k8sclusterreceiver/internal/metadata/generated_status.go index 2b55ed15641c..1eaeb822b837 100644 --- a/receiver/k8sclusterreceiver/internal/metadata/generated_status.go +++ b/receiver/k8sclusterreceiver/internal/metadata/generated_status.go @@ -9,4 +9,5 @@ import ( const ( Type = "k8s_cluster" MetricsStability = component.StabilityLevelBeta + LogsStability = component.StabilityLevelDevelopment ) diff --git a/receiver/k8sclusterreceiver/metadata.yaml b/receiver/k8sclusterreceiver/metadata.yaml index e88c6fd31027..b27e538518f9 100644 --- a/receiver/k8sclusterreceiver/metadata.yaml +++ b/receiver/k8sclusterreceiver/metadata.yaml @@ -4,5 +4,6 @@ status: class: receiver stability: beta: [metrics] + development: [logs] distributions: [contrib, splunk, observiq, sumo] diff --git a/receiver/k8sclusterreceiver/receiver.go b/receiver/k8sclusterreceiver/receiver.go index e2c040acc7a7..ea8977b35683 100644 --- a/receiver/k8sclusterreceiver/receiver.go +++ b/receiver/k8sclusterreceiver/receiver.go @@ -27,11 +27,11 @@ var _ receiver.Metrics = (*kubernetesReceiver)(nil) type kubernetesReceiver struct { resourceWatcher *resourceWatcher - config *Config - settings receiver.CreateSettings - consumer consumer.Metrics - cancel context.CancelFunc - obsrecv *obsreport.Receiver + config *Config + settings receiver.CreateSettings + metricsConsumer consumer.Metrics + cancel context.CancelFunc + obsrecv *obsreport.Receiver } func (kr *kubernetesReceiver) Start(ctx context.Context, host component.Host) error { @@ -97,25 +97,69 @@ func (kr *kubernetesReceiver) Shutdown(context.Context) error { } func (kr *kubernetesReceiver) dispatchMetrics(ctx context.Context) { + if kr.metricsConsumer == nil { + // Metric collection is not enabled. + return + } + now := time.Now() mds := kr.resourceWatcher.dataCollector.CollectMetricData(now) c := kr.obsrecv.StartMetricsOp(ctx) numPoints := mds.DataPointCount() - err := kr.consumer.ConsumeMetrics(c, mds) + err := kr.metricsConsumer.ConsumeMetrics(c, mds) kr.obsrecv.EndMetricsOp(c, metadata.Type, numPoints, err) } -// newReceiver creates the Kubernetes cluster receiver with the given configuration. -func newReceiver(_ context.Context, set receiver.CreateSettings, cfg component.Config, consumer consumer.Metrics) (receiver.Metrics, error) { - rCfg := cfg.(*Config) +// newMetricsReceiver creates the Kubernetes cluster receiver with the given configuration. +func newMetricsReceiver( + ctx context.Context, set receiver.CreateSettings, cfg component.Config, consumer consumer.Metrics, +) (receiver.Metrics, error) { + var err error + r := receivers.GetOrAdd( + cfg, func() component.Component { + var rcv component.Component + rcv, err = newReceiver(ctx, set, cfg) + return rcv + }, + ) + if err != nil { + return nil, err + } + r.Unwrap().(*kubernetesReceiver).metricsConsumer = consumer + return r, nil +} - obsrecv, err := obsreport.NewReceiver(obsreport.ReceiverSettings{ - ReceiverID: set.ID, - Transport: transport, - ReceiverCreateSettings: set, - }) +// newMetricsReceiver creates the Kubernetes cluster receiver with the given configuration. +func newLogsReceiver( + ctx context.Context, set receiver.CreateSettings, cfg component.Config, consumer consumer.Logs, +) (receiver.Logs, error) { + var err error + r := receivers.GetOrAdd( + cfg, func() component.Component { + var rcv component.Component + rcv, err = newReceiver(ctx, set, cfg) + return rcv + }, + ) + if err != nil { + return nil, err + } + r.Unwrap().(*kubernetesReceiver).resourceWatcher.entityLogConsumer = consumer + return r, nil +} + +// newMetricsReceiver creates the Kubernetes cluster receiver with the given configuration. +func newReceiver(_ context.Context, set receiver.CreateSettings, cfg component.Config) (component.Component, error) { + rCfg := cfg.(*Config) + obsrecv, err := obsreport.NewReceiver( + obsreport.ReceiverSettings{ + ReceiverID: set.ID, + Transport: transport, + ReceiverCreateSettings: set, + }, + ) if err != nil { return nil, err } @@ -123,7 +167,6 @@ func newReceiver(_ context.Context, set receiver.CreateSettings, cfg component.C resourceWatcher: newResourceWatcher(set, rCfg), settings: set, config: rCfg, - consumer: consumer, obsrecv: obsrecv, }, nil } diff --git a/receiver/k8sclusterreceiver/receiver_test.go b/receiver/k8sclusterreceiver/receiver_test.go index 4419f49c6e3e..b82bb286e4a0 100644 --- a/receiver/k8sclusterreceiver/receiver_test.go +++ b/receiver/k8sclusterreceiver/receiver_test.go @@ -39,7 +39,7 @@ func TestReceiver(t *testing.T) { osQuotaClient := fakeQuota.NewSimpleClientset() sink := new(consumertest.MetricsSink) - r := setupReceiver(client, osQuotaClient, sink, 10*time.Second, tt) + r := setupReceiver(client, osQuotaClient, sink, nil, 10*time.Second, tt) // Setup k8s resources. numPods := 2 @@ -87,7 +87,7 @@ func TestReceiverTimesOutAfterStartup(t *testing.T) { client := newFakeClientWithAllResources() // Mock initial cache sync timing out, using a small timeout. - r := setupReceiver(client, nil, consumertest.NewNop(), 1*time.Millisecond, tt) + r := setupReceiver(client, nil, consumertest.NewNop(), nil, 1*time.Millisecond, tt) createPods(t, client, 1) @@ -110,7 +110,7 @@ func TestReceiverWithManyResources(t *testing.T) { osQuotaClient := fakeQuota.NewSimpleClientset() sink := new(consumertest.MetricsSink) - r := setupReceiver(client, osQuotaClient, sink, 10*time.Second, tt) + r := setupReceiver(client, osQuotaClient, sink, nil, 10*time.Second, tt) numPods := 1000 numQuotas := 2 @@ -145,10 +145,12 @@ func TestReceiverWithMetadata(t *testing.T) { }() client := newFakeClientWithAllResources() - next := &mockExporterWithK8sMetadata{MetricsSink: new(consumertest.MetricsSink)} + metricsConsumer := &mockExporterWithK8sMetadata{MetricsSink: new(consumertest.MetricsSink)} numCalls = &atomic.Int32{} - r := setupReceiver(client, nil, next, 10*time.Second, tt) + logsConsumer := new(consumertest.LogsSink) + + r := setupReceiver(client, nil, metricsConsumer, logsConsumer, 10*time.Second, tt) r.config.MetadataExporters = []string{"nop/withmetadata"} // Setup k8s resources. @@ -163,18 +165,29 @@ func TestReceiverWithMetadata(t *testing.T) { updatedPod := getUpdatedPod(pods[0]) r.resourceWatcher.onUpdate(pods[0], updatedPod) - // Should not result in ConsumerKubernetesMetadata invocation. - r.resourceWatcher.onUpdate(pods[0], pods[0]) + // Should not result in ConsumerKubernetesMetadata invocation since the pod + // is not changed. Should result in entity event because they are emitted even + // if the entity is not changed. + r.resourceWatcher.onUpdate(updatedPod, updatedPod) deletePods(t, client, 1) // Ensure ConsumeKubernetesMetadata is called twice, once for the add and - // then for the update. + // then for the update. Note the second update does not result in metatada call + // since the pod is not changed. require.Eventually(t, func() bool { return int(numCalls.Load()) == 2 }, 10*time.Second, 100*time.Millisecond, "metadata not collected") + // Must have 3 entity events: once for the add, followed by an update and + // then another update, which unlike metadata calls actually happens since + // even unchanged entities trigger an event. + require.Eventually(t, func() bool { + return logsConsumer.LogRecordCount() == 3 + }, 10*time.Second, 100*time.Millisecond, + "entity events not collected") + require.NoError(t, r.Shutdown(ctx)) } @@ -194,7 +207,8 @@ func getUpdatedPod(pod *corev1.Pod) interface{} { func setupReceiver( client *fake.Clientset, osQuotaClient quotaclientset.Interface, - consumer consumer.Metrics, + metricsConsumer consumer.Metrics, + logsConsumer consumer.Logs, initialSyncTimeout time.Duration, tt obsreporttest.TestTelemetry) *kubernetesReceiver { @@ -210,8 +224,9 @@ func setupReceiver( Distribution: distribution, } - r, _ := newReceiver(context.Background(), tt.ToReceiverCreateSettings(), config, consumer) + r, _ := newReceiver(context.Background(), tt.ToReceiverCreateSettings(), config) kr := r.(*kubernetesReceiver) + kr.metricsConsumer = metricsConsumer kr.resourceWatcher.makeClient = func(_ k8sconfig.APIConfig) (kubernetes.Interface, error) { return client, nil } @@ -219,6 +234,7 @@ func setupReceiver( return osQuotaClient, nil } kr.resourceWatcher.initialTimeout = initialSyncTimeout + kr.resourceWatcher.entityLogConsumer = logsConsumer return kr } diff --git a/receiver/k8sclusterreceiver/watcher.go b/receiver/k8sclusterreceiver/watcher.go index 029cacd56c81..ada240927c60 100644 --- a/receiver/k8sclusterreceiver/watcher.go +++ b/receiver/k8sclusterreceiver/watcher.go @@ -13,8 +13,10 @@ import ( quotaclientset "github.com/openshift/client-go/quota/clientset/versioned" quotainformersv1 "github.com/openshift/client-go/quota/informers/externalversions" "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/receiver" "go.uber.org/zap" + "go.uber.org/zap/zapcore" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/informers" @@ -40,11 +42,13 @@ type resourceWatcher struct { informerFactories []sharedInformer dataCollector *collection.DataCollector logger *zap.Logger + sampledLogger *zap.Logger metadataConsumers []metadataConsumer initialTimeout time.Duration initialSyncDone *atomic.Bool initialSyncTimedOut *atomic.Bool config *Config + entityLogConsumer consumer.Logs // For mocking. makeClient func(apiConf k8sconfig.APIConfig) (kubernetes.Interface, error) @@ -55,8 +59,18 @@ type metadataConsumer func(metadata []*experimentalmetricmetadata.MetadataUpdate // newResourceWatcher creates a Kubernetes resource watcher. func newResourceWatcher(set receiver.CreateSettings, cfg *Config) *resourceWatcher { + // Create a sampled logger for error messages. + core := zapcore.NewSamplerWithOptions( + set.Logger.Core(), + 1*time.Second, + 1, // 1 per second initially + 1000, // then 1/1000 of messages + ) + sampledLogger := zap.New(core) + return &resourceWatcher{ logger: set.Logger, + sampledLogger: sampledLogger, dataCollector: collection.NewDataCollector(set, cfg.NodeConditionTypesToReport, cfg.AllocatableTypesToReport), initialSyncDone: &atomic.Bool{}, initialSyncTimedOut: &atomic.Bool{}, @@ -237,7 +251,7 @@ func (rw *resourceWatcher) onAdd(obj interface{}) { rw.dataCollector.SyncMetrics(obj) // Sync metadata only if there's at least one destination for it to sent. - if len(rw.metadataConsumers) == 0 { + if !rw.hasDestination() { return } @@ -250,13 +264,17 @@ func (rw *resourceWatcher) onDelete(obj interface{}) { rw.dataCollector.RemoveFromMetricsStore(obj) } +func (rw *resourceWatcher) hasDestination() bool { + return len(rw.metadataConsumers) != 0 || rw.entityLogConsumer != nil +} + func (rw *resourceWatcher) onUpdate(oldObj, newObj interface{}) { rw.waitForInitialInformerSync() // Sync metrics from the new object rw.dataCollector.SyncMetrics(newObj) // Sync metadata only if there's at least one destination for it to sent. - if len(rw.metadataConsumers) == 0 { + if !rw.hasDestination() { return } @@ -326,11 +344,35 @@ func validateMetadataExporters(metadataExporters map[string]bool, exporters map[ func (rw *resourceWatcher) syncMetadataUpdate(oldMetadata, newMetadata map[experimentalmetricmetadata.ResourceID]*metadata.KubernetesMetadata) { metadataUpdate := metadata.GetMetadataUpdate(oldMetadata, newMetadata) - if len(metadataUpdate) == 0 { - return + if len(metadataUpdate) != 0 { + for _, consume := range rw.metadataConsumers { + _ = consume(metadataUpdate) + } } - for _, consume := range rw.metadataConsumers { - _ = consume(metadataUpdate) + if rw.entityLogConsumer != nil { + // Represent metadata update as entity events. + // TODO: record the timestamp in the events. + entityEvents := metadata.GetEntityEvents(oldMetadata, newMetadata) + + // Convert entity events to log representation. + logs := entityEvents.ConvertAndMoveToLogs() + + if logs.LogRecordCount() != 0 { + err := rw.entityLogConsumer.ConsumeLogs(context.Background(), logs) + if err != nil { + rw.sampledLogger.Error("Error sending entity events to the consumer", zap.Error(err)) + + // Note: receiver contract says that we need to retry sending if the + // returned error is not Permanent. However, we are not doing it here. + // Instead, we rely on the fact the metadata is collected periodically + // and the entity events will be delivered on the next cycle. This is + // fine because we deliver cumulative entity state. + // This allows us to avoid stressing the Collector or its destination + // unnecessarily (typically non-Permanent errors happen in stressed conditions). + // The periodic collection will be implemented later, see + // https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24413 + } + } } } diff --git a/receiver/k8sclusterreceiver/watcher_test.go b/receiver/k8sclusterreceiver/watcher_test.go index 5639fe2a35f1..28ec630023e1 100644 --- a/receiver/k8sclusterreceiver/watcher_test.go +++ b/receiver/k8sclusterreceiver/watcher_test.go @@ -9,6 +9,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/consumer/consumertest" "go.opentelemetry.io/collector/receiver/receivertest" "go.uber.org/zap" "go.uber.org/zap/zaptest/observer" @@ -220,3 +221,75 @@ func TestSetupInformerForKind(t *testing.T) { assert.Equal(t, 1, logs.Len()) assert.Equal(t, "Could not setup an informer for provided group version kind", logs.All()[0].Entry.Message) } + +func TestSyncMetadataAndEmitEntityEvents(t *testing.T) { + client := newFakeClientWithAllResources() + + logsConsumer := new(consumertest.LogsSink) + + // Setup k8s resources. + pods := createPods(t, client, 1) + + origPod := pods[0] + updatedPod := getUpdatedPod(origPod) + + rw := newResourceWatcher(receivertest.NewNopCreateSettings(), &Config{}) + rw.entityLogConsumer = logsConsumer + + // Make some changes to the pod. Each change should result in an entity event represented + // as a log record. + + // Pod is created. + rw.syncMetadataUpdate(nil, rw.dataCollector.SyncMetadata(origPod)) + + // Pod is updated. + rw.syncMetadataUpdate(rw.dataCollector.SyncMetadata(origPod), rw.dataCollector.SyncMetadata(updatedPod)) + + // Pod is updated again, but nothing changed in the pod. + // Should still result in entity event because they are emitted even + // if the entity is not changed. + rw.syncMetadataUpdate(rw.dataCollector.SyncMetadata(updatedPod), rw.dataCollector.SyncMetadata(updatedPod)) + + // Change pod's state back to original + rw.syncMetadataUpdate(rw.dataCollector.SyncMetadata(updatedPod), rw.dataCollector.SyncMetadata(origPod)) + + // Delete the pod + rw.syncMetadataUpdate(rw.dataCollector.SyncMetadata(origPod), nil) + + // Must have 5 entity events. + require.EqualValues(t, 5, logsConsumer.LogRecordCount()) + + // Event 1 should contain the initial state of the pod. + lr := logsConsumer.AllLogs()[0].ResourceLogs().At(0).ScopeLogs().At(0).LogRecords().At(0) + expected := map[string]any{ + "otel.entity.event.type": "entity_state", + "otel.entity.type": "k8s.pod", + "otel.entity.id": map[string]any{"k8s.pod.uid": "pod0"}, + "otel.entity.attributes": map[string]any{"pod.creation_timestamp": "0001-01-01T00:00:00Z"}, + } + assert.EqualValues(t, expected, lr.Attributes().AsRaw()) + + // Event 2 should contain the updated state of the pod. + lr = logsConsumer.AllLogs()[1].ResourceLogs().At(0).ScopeLogs().At(0).LogRecords().At(0) + attrs := expected["otel.entity.attributes"].(map[string]any) + attrs["key"] = "value" + assert.EqualValues(t, expected, lr.Attributes().AsRaw()) + + // Event 3 should be identical to the previous one since pod state didn't change. + lr = logsConsumer.AllLogs()[2].ResourceLogs().At(0).ScopeLogs().At(0).LogRecords().At(0) + assert.EqualValues(t, expected, lr.Attributes().AsRaw()) + + // Event 4 should contain the reverted state of the pod. + lr = logsConsumer.AllLogs()[3].ResourceLogs().At(0).ScopeLogs().At(0).LogRecords().At(0) + attrs = expected["otel.entity.attributes"].(map[string]any) + delete(attrs, "key") + assert.EqualValues(t, expected, lr.Attributes().AsRaw()) + + // Event 5 should indicate pod deletion. + lr = logsConsumer.AllLogs()[4].ResourceLogs().At(0).ScopeLogs().At(0).LogRecords().At(0) + expected = map[string]any{ + "otel.entity.event.type": "entity_delete", + "otel.entity.id": map[string]any{"k8s.pod.uid": "pod0"}, + } + assert.EqualValues(t, expected, lr.Attributes().AsRaw()) +} From 20b3071eba7fdfd24869cde40601d3c9455cc282 Mon Sep 17 00:00:00 2001 From: David Ashpole Date: Fri, 21 Jul 2023 11:43:47 -0400 Subject: [PATCH 05/42] prometheusreceiver: remove unused buffer_period and buffer_count configuration options (#24257) **Description:** Fixes #24258 Found while adding documentation for https://github.com/open-telemetry/opentelemetry-collector-contrib/pull/24256. The prometheus receiver had two config options that AFAICT have never been used. The config options have existed since the very first commit ever for the Prometheus receiver: https://github.com/open-telemetry/opentelemetry-collector-contrib/commit/7c728eff57374c80141657e5cb4618ee8df6b951 Co-authored-by: Dmitrii Anoshin --- .chloggen/prometheus-config-cleanup.yaml | 20 +++++++++++++++++++ receiver/prometheusreceiver/config.go | 2 -- .../prometheusreceiver/testdata/config.yaml | 2 -- ...onfig-prometheus-unsupported-features.yaml | 2 -- 4 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 .chloggen/prometheus-config-cleanup.yaml diff --git a/.chloggen/prometheus-config-cleanup.yaml b/.chloggen/prometheus-config-cleanup.yaml new file mode 100644 index 000000000000..0be0919db425 --- /dev/null +++ b/.chloggen/prometheus-config-cleanup.yaml @@ -0,0 +1,20 @@ +# Use this changelog template to create an entry for release notes. +# If your change doesn't affect end users, such as a test fix or a tooling change, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: 'breaking' + +# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) +component: prometheusreciever + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Remove unused buffer_period and buffer_count configuration options + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [24258] + +# (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: diff --git a/receiver/prometheusreceiver/config.go b/receiver/prometheusreceiver/config.go index 0827ad3f861e..699452d8f65f 100644 --- a/receiver/prometheusreceiver/config.go +++ b/receiver/prometheusreceiver/config.go @@ -34,8 +34,6 @@ const ( type Config struct { PrometheusConfig *promconfig.Config `mapstructure:"-"` TrimMetricSuffixes bool `mapstructure:"trim_metric_suffixes"` - BufferPeriod time.Duration `mapstructure:"buffer_period"` - BufferCount int `mapstructure:"buffer_count"` // UseStartTimeMetric enables retrieving the start time of all counter metrics // from the process_start_time_seconds metric. This is only correct if all counters on that endpoint // started after the process start time, and the process is the only actor exporting the metric after diff --git a/receiver/prometheusreceiver/testdata/config.yaml b/receiver/prometheusreceiver/testdata/config.yaml index db0876ad0710..e80188728a4c 100644 --- a/receiver/prometheusreceiver/testdata/config.yaml +++ b/receiver/prometheusreceiver/testdata/config.yaml @@ -1,7 +1,5 @@ prometheus: prometheus/customname: - buffer_period: 234 - buffer_count: 45 trim_metric_suffixes: true use_start_time_metric: true start_time_metric_regex: '^(.+_)*process_start_time_seconds$' diff --git a/receiver/prometheusreceiver/testdata/invalid-config-prometheus-unsupported-features.yaml b/receiver/prometheusreceiver/testdata/invalid-config-prometheus-unsupported-features.yaml index 3111f1d38dd1..4ed0892f10b2 100644 --- a/receiver/prometheusreceiver/testdata/invalid-config-prometheus-unsupported-features.yaml +++ b/receiver/prometheusreceiver/testdata/invalid-config-prometheus-unsupported-features.yaml @@ -1,6 +1,4 @@ prometheus: - buffer_period: 234 - buffer_count: 45 use_start_time_metric: true start_time_metric_regex: '^(.+_)*process_start_time_seconds$' config: From 675710dbdff3285fc31b7d1a535c611f7fcce46a Mon Sep 17 00:00:00 2001 From: Mitchell Gale Date: Fri, 21 Jul 2023 08:55:01 -0700 Subject: [PATCH 06/42] [Exporter/OpenSearch] OpenSearch exporter setup (#23819) Adding initial set-up for OpenSearch exporter addition. Future PRs will include adding functionality to the exporter, code coverage and e2e tests. Broken up for easier review. [New component proposal.](https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/23611) Start of resolution of https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/7905. Will come in future PR to 80+% coverage. Break-up of https://github.com/open-telemetry/opentelemetry-collector-contrib/pull/23045 --------- Signed-off-by: Max Ksyunz --- .chloggen/opensearch-exporter.yaml | 9 + .github/CODEOWNERS | 1 + .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + .github/ISSUE_TEMPLATE/feature_request.yaml | 1 + .github/ISSUE_TEMPLATE/other.yaml | 1 + .github/dependabot.yml | 10 +- exporter/opensearchexporter/Makefile | 1 + exporter/opensearchexporter/README.md | 51 ++ exporter/opensearchexporter/config.go | 31 ++ exporter/opensearchexporter/config_test.go | 84 +++ exporter/opensearchexporter/factory.go | 51 ++ exporter/opensearchexporter/go.mod | 63 +++ exporter/opensearchexporter/go.sum | 503 ++++++++++++++++++ .../opensearchexporter/testdata/config.yaml | 22 + versions.yaml | 1 + 15 files changed, 825 insertions(+), 5 deletions(-) create mode 100644 .chloggen/opensearch-exporter.yaml create mode 100644 exporter/opensearchexporter/Makefile create mode 100644 exporter/opensearchexporter/README.md create mode 100644 exporter/opensearchexporter/config.go create mode 100644 exporter/opensearchexporter/config_test.go create mode 100644 exporter/opensearchexporter/factory.go create mode 100644 exporter/opensearchexporter/go.mod create mode 100644 exporter/opensearchexporter/go.sum create mode 100644 exporter/opensearchexporter/testdata/config.yaml diff --git a/.chloggen/opensearch-exporter.yaml b/.chloggen/opensearch-exporter.yaml new file mode 100644 index 000000000000..892ac29cae77 --- /dev/null +++ b/.chloggen/opensearch-exporter.yaml @@ -0,0 +1,9 @@ +change_type: new_component + +component: opensearchexporter + +note: exports OpenTelemetry signals to [OpenSearch](https://opensearch.org/). + +issues: [23611] + +subtext: diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index d93bc9039b30..23637843117f 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -69,6 +69,7 @@ exporter/logzioexporter/ @open-telemetry/collect exporter/lokiexporter/ @open-telemetry/collector-contrib-approvers @gramidt @gouthamve @jpkrohling @kovrus @mar4uk exporter/mezmoexporter/ @open-telemetry/collector-contrib-approvers @dashpole @billmeyer @gjanco exporter/opencensusexporter/ @open-telemetry/collector-contrib-approvers @open-telemetry/collector-approvers +exporter/opensearchexporter/ @open-telemetry/collector-contrib-approvers @Aneurysm9 @MitchellGale @MaxKsyunz @YANG-DB exporter/parquetexporter/ @open-telemetry/collector-contrib-approvers @atoulme exporter/prometheusexporter/ @open-telemetry/collector-contrib-approvers @Aneurysm9 exporter/prometheusremotewriteexporter/ @open-telemetry/collector-contrib-approvers @Aneurysm9 @rapphil diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index bf0e8f5a1d5f..16abddfa66df 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -63,6 +63,7 @@ body: - exporter/loki - exporter/mezmo - exporter/opencensus + - exporter/opensearch - exporter/parquet - exporter/prometheus - exporter/prometheusremotewrite diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml index 605c885e070c..cf1b929682e1 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yaml +++ b/.github/ISSUE_TEMPLATE/feature_request.yaml @@ -57,6 +57,7 @@ body: - exporter/loki - exporter/mezmo - exporter/opencensus + - exporter/opensearch - exporter/parquet - exporter/prometheus - exporter/prometheusremotewrite diff --git a/.github/ISSUE_TEMPLATE/other.yaml b/.github/ISSUE_TEMPLATE/other.yaml index 10b214f3db07..87e43369e987 100644 --- a/.github/ISSUE_TEMPLATE/other.yaml +++ b/.github/ISSUE_TEMPLATE/other.yaml @@ -57,6 +57,7 @@ body: - exporter/loki - exporter/mezmo - exporter/opencensus + - exporter/opensearch - exporter/parquet - exporter/prometheus - exporter/prometheusremotewrite diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 335c9ec01a65..7dafa2a6715f 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -237,6 +237,11 @@ updates: schedule: interval: "weekly" day: "wednesday" + - package-ecosystem: "gomod" + directory: "/exporter/opensearchexporter" + schedule: + interval: "weekly" + day: "wednesday" - package-ecosystem: "gomod" directory: "/exporter/parquetexporter" schedule: @@ -1097,8 +1102,3 @@ updates: schedule: interval: "weekly" day: "wednesday" - - package-ecosystem: "gomod" - directory: "/receiver/sqlserverreceiver" - schedule: - interval: "weekly" - day: "wednesday" diff --git a/exporter/opensearchexporter/Makefile b/exporter/opensearchexporter/Makefile new file mode 100644 index 000000000000..ded7a36092dc --- /dev/null +++ b/exporter/opensearchexporter/Makefile @@ -0,0 +1 @@ +include ../../Makefile.Common diff --git a/exporter/opensearchexporter/README.md b/exporter/opensearchexporter/README.md new file mode 100644 index 000000000000..2ce4a6db96c0 --- /dev/null +++ b/exporter/opensearchexporter/README.md @@ -0,0 +1,51 @@ +# OpenSearch Exporter + +| Status | | +| ------------------------ |-----------| +| Stability | [devel] | +| Supported pipeline types | traces | +| Distributions | [contrib] | + +OpenSearch exporter supports sending OpenTelemetry signals as documents to [OpenSearch](https://www.opensearch.org). + +The documents are sent using [observability catalog](https://github.com/opensearch-project/opensearch-catalog/tree/main/schema/observability) schema. + +## Configuration options +### Indexing Options +- `dataset` (default=`default`) a user-provided label to classify source of telemetry. It is used to construct the name of the destination index or data stream. +- `namespace` (default=`namespace`) a user-provided label to group telemetry. It is used to construct the name of the destination index or data stream. + +### HTTP Connection Options +OpenSearch export supports standard (HTTP client settings](https://github.com/open-telemetry/opentelemetry-collector/tree/main/config/confighttp#client-configuration). +- `endpoint` (required) `:` of OpenSearch node to send data to. + +### TLS settings +Supports standard TLS settings as part of HTTP settings. See [TLS Configuration/Client Settings](https://github.com/open-telemetry/opentelemetry-collector/blob/main/config/configtls/README.md#client-configuration). + +### Retry Options +- `retry_on_failure`: See [retry_on_failure](https://github.com/open-telemetry/opentelemetry-collector/blob/main/exporter/exporterhelper/README.md) + +## Example + +```yaml +extensions: + basicauth/client: + client_auth: + username: username + password: password + +exporters: + opensearch/trace: + endpoint: https://opensearch.example.com:9200 + auth: + authenticator: basicauth/client +# ······ +service: + pipelines: + traces: + receivers: [otlp] + exporters: [opensearch/trace] + processors: [batch] +``` +[devel]:https://github.com/open-telemetry/opentelemetry-collector#development +[contrib]:https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib \ No newline at end of file diff --git a/exporter/opensearchexporter/config.go b/exporter/opensearchexporter/config.go new file mode 100644 index 000000000000..97f7b443c596 --- /dev/null +++ b/exporter/opensearchexporter/config.go @@ -0,0 +1,31 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package opensearchexporter // import "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/opensearchexporter" + +import ( + "errors" + + "go.opentelemetry.io/collector/config/confighttp" + "go.opentelemetry.io/collector/exporter/exporterhelper" +) + +// Config defines configuration for OpenSearch exporter. +type Config struct { + confighttp.HTTPClientSettings `mapstructure:",squash"` + exporterhelper.RetrySettings `mapstructure:"retry_on_failure"` + Namespace string `mapstructure:"namespace"` + Dataset string `mapstructure:"dataset"` +} + +var ( + errConfigNoEndpoint = errors.New("endpoint must be specified") +) + +// Validate validates the opensearch server configuration. +func (cfg *Config) Validate() error { + if len(cfg.Endpoint) == 0 { + return errConfigNoEndpoint + } + return nil +} diff --git a/exporter/opensearchexporter/config_test.go b/exporter/opensearchexporter/config_test.go new file mode 100644 index 000000000000..3f6b2a7c13c1 --- /dev/null +++ b/exporter/opensearchexporter/config_test.go @@ -0,0 +1,84 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package opensearchexporter + +import ( + "path/filepath" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/config/configauth" + "go.opentelemetry.io/collector/config/confighttp" + "go.opentelemetry.io/collector/config/configopaque" + "go.opentelemetry.io/collector/confmap/confmaptest" + "go.opentelemetry.io/collector/exporter/exporterhelper" +) + +func TestLoadConfig(t *testing.T) { + t.Parallel() + + cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config.yaml")) + require.NoError(t, err) + + defaultCfg := newDefaultConfig() + defaultCfg.(*Config).Endpoint = "https://opensearch.example.com:9200" + maxIdleConns := 100 + idleConnTimeout := 90 * time.Second + + tests := []struct { + id component.ID + expected component.Config + configValidateAssert assert.ErrorAssertionFunc + }{ + { + id: component.NewIDWithName(typeStr, ""), + expected: defaultCfg, + configValidateAssert: assert.NoError, + }, + { + id: component.NewIDWithName(typeStr, "trace"), + expected: &Config{ + Dataset: "ngnix", + Namespace: "eu", + HTTPClientSettings: confighttp.HTTPClientSettings{ + Endpoint: "https://opensearch.example.com:9200", + Timeout: 2 * time.Minute, + Headers: map[string]configopaque.String{ + "myheader": "test", + }, + MaxIdleConns: &maxIdleConns, + IdleConnTimeout: &idleConnTimeout, + Auth: &configauth.Authentication{AuthenticatorID: component.NewID("sample_basic_auth")}, + }, + RetrySettings: exporterhelper.RetrySettings{ + Enabled: true, + InitialInterval: 100 * time.Millisecond, + MaxInterval: 30 * time.Second, + MaxElapsedTime: 5 * time.Minute, + Multiplier: 1.5, + RandomizationFactor: 0.5, + }, + }, + configValidateAssert: assert.NoError, + }, + } + + for _, tt := range tests { + t.Run(tt.id.String(), func(t *testing.T) { + factory := NewFactory() + cfg := factory.CreateDefaultConfig() + + sub, err := cm.Sub(tt.id.String()) + require.NoError(t, err) + require.NoError(t, component.UnmarshalConfig(sub, cfg)) + + vv := component.ValidateConfig(cfg) + tt.configValidateAssert(t, vv) + assert.Equal(t, tt.expected, cfg) + }) + } +} diff --git a/exporter/opensearchexporter/factory.go b/exporter/opensearchexporter/factory.go new file mode 100644 index 000000000000..9c2f66a55161 --- /dev/null +++ b/exporter/opensearchexporter/factory.go @@ -0,0 +1,51 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package opensearchexporter // import "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/opensearchexporter" + +import ( + "context" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/config/confighttp" + "go.opentelemetry.io/collector/exporter" + "go.opentelemetry.io/collector/exporter/exporterhelper" + "go.opentelemetry.io/collector/pdata/ptrace" +) + +const ( + // The value of "type" key in configuration. + typeStr = "opensearch" + // The stability level of the exporter. + stability = component.StabilityLevelDevelopment +) + +// NewFactory creates a factory for OpenSearch exporter. +func NewFactory() exporter.Factory { + return exporter.NewFactory( + typeStr, + newDefaultConfig, + exporter.WithTraces(createTracesExporter, stability), + ) +} + +func newDefaultConfig() component.Config { + return &Config{ + HTTPClientSettings: confighttp.NewDefaultHTTPClientSettings(), + Namespace: "namespace", + Dataset: "default", + RetrySettings: exporterhelper.NewDefaultRetrySettings(), + } +} + +func createTracesExporter(ctx context.Context, + set exporter.CreateSettings, + cfg component.Config) (exporter.Traces, error) { + + return exporterhelper.NewTracesExporter(ctx, set, cfg, func(ctx context.Context, ld ptrace.Traces) error { + return nil + }, + exporterhelper.WithShutdown(func(ctx context.Context) error { + return nil + })) +} diff --git a/exporter/opensearchexporter/go.mod b/exporter/opensearchexporter/go.mod new file mode 100644 index 000000000000..9e92e8cee92e --- /dev/null +++ b/exporter/opensearchexporter/go.mod @@ -0,0 +1,63 @@ +module github.com/open-telemetry/opentelemetry-collector-contrib/exporter/opensearchexporter + +go 1.19 + +require ( + github.com/stretchr/testify v1.8.4 + go.opentelemetry.io/collector/component v0.81.0 + go.opentelemetry.io/collector/config/configauth v0.81.0 + go.opentelemetry.io/collector/config/confighttp v0.81.0 + go.opentelemetry.io/collector/config/configopaque v0.81.0 + go.opentelemetry.io/collector/confmap v0.81.0 + go.opentelemetry.io/collector/exporter v0.81.0 + go.opentelemetry.io/collector/pdata v1.0.0-rcv0013 +) + +require ( + github.com/cenkalti/backoff/v4 v4.2.1 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/felixge/httpsnoop v1.0.3 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/go-logr/logr v1.2.4 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/compress v1.16.6 // indirect + github.com/knadh/koanf v1.5.0 // indirect + github.com/knadh/koanf/v2 v2.0.1 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect + github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/rs/cors v1.9.0 // indirect + go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/collector v0.81.0 // indirect + go.opentelemetry.io/collector/config/configcompression v0.81.0 // indirect + go.opentelemetry.io/collector/config/configtelemetry v0.81.0 // indirect + go.opentelemetry.io/collector/config/configtls v0.81.0 // indirect + go.opentelemetry.io/collector/config/internal v0.81.0 // indirect + go.opentelemetry.io/collector/consumer v0.81.0 // indirect + go.opentelemetry.io/collector/extension v0.81.0 // indirect + go.opentelemetry.io/collector/extension/auth v0.81.0 // indirect + go.opentelemetry.io/collector/featuregate v1.0.0-rcv0013 // indirect + go.opentelemetry.io/collector/processor v0.81.0 // indirect + go.opentelemetry.io/collector/receiver v0.81.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0 // indirect + go.opentelemetry.io/otel v1.16.0 // indirect + go.opentelemetry.io/otel/metric v1.16.0 // indirect + go.opentelemetry.io/otel/trace v1.16.0 // indirect + go.uber.org/atomic v1.10.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.24.0 // indirect + golang.org/x/net v0.11.0 // indirect + golang.org/x/sys v0.9.0 // indirect + golang.org/x/text v0.10.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect + google.golang.org/grpc v1.56.1 // indirect + google.golang.org/protobuf v1.31.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/exporter/opensearchexporter/go.sum b/exporter/opensearchexporter/go.sum new file mode 100644 index 000000000000..c476d978a2ae --- /dev/null +++ b/exporter/opensearchexporter/go.sum @@ -0,0 +1,503 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +contrib.go.opencensus.io/exporter/prometheus v0.4.2 h1:sqfsYl5GIY/L570iT+l93ehxaWJs2/OwXtiWwew3oAg= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aws/aws-sdk-go-v2 v1.9.2/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4= +github.com/aws/aws-sdk-go-v2/config v1.8.3/go.mod h1:4AEiLtAb8kLs7vgw2ZV3p2VZ1+hBavOc84hqxVNpCyw= +github.com/aws/aws-sdk-go-v2/credentials v1.4.3/go.mod h1:FNNC6nQZQUuyhq5aE5c7ata8o9e4ECGmS4lAXC7o1mQ= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.6.0/go.mod h1:gqlclDEZp4aqJOancXK6TN24aKhT0W0Ae9MHk3wzTMM= +github.com/aws/aws-sdk-go-v2/internal/ini v1.2.4/go.mod h1:ZcBrrI3zBKlhGFNYWvju0I3TR93I7YIgAfy82Fh4lcQ= +github.com/aws/aws-sdk-go-v2/service/appconfig v1.4.2/go.mod h1:FZ3HkCe+b10uFZZkFdvf98LHW21k49W8o8J366lqVKY= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.3.2/go.mod h1:72HRZDLMtmVQiLG2tLfQcaWLCssELvGl+Zf2WVxMmR8= +github.com/aws/aws-sdk-go-v2/service/sso v1.4.2/go.mod h1:NBvT9R1MEF+Ud6ApJKM0G+IkPchKS7p7c2YPKwHmBOk= +github.com/aws/aws-sdk-go-v2/service/sts v1.7.2/go.mod h1:8EzeIqfWt2wWT4rJVu3f21TfrhJ8AEMzVybRNSb/b4g= +github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= +github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= +github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= +github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= +github.com/go-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/hashicorp/consul/api v1.13.0/go.mod h1:ZlVrynguJKcYr54zGaDbaL3fOvKC9m72FhPvA8T35KQ= +github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= +github.com/hashicorp/go-hclog v0.8.0/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= +github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY= +github.com/hashicorp/go-retryablehttp v0.5.4/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= +github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= +github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= +github.com/hashicorp/vault/api v1.0.4/go.mod h1:gDcqh3WGcR1cpF5AJz/B1UFheUEneMoIospckxBxk6Q= +github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M= +github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +github.com/hjson/hjson-go/v4 v4.0.0/go.mod h1:KaYt3bTw3zhBjYqnXkYywcYctk0A2nxeEFTse3rH13E= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.16.6 h1:91SKEy4K37vkp255cJ8QesJhjyRO0hn9i9G0GoUwLsk= +github.com/klauspost/compress v1.16.6/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/knadh/koanf v1.5.0 h1:q2TSd/3Pyc/5yP9ldIrSdIz26MCcyNQzW0pEAugLPNs= +github.com/knadh/koanf v1.5.0/go.mod h1:Hgyjp4y8v44hpZtPzs7JZfRAW5AhN7KfZcwv1RYggDs= +github.com/knadh/koanf/v2 v2.0.1 h1:1dYGITt1I23x8cfx8ZnldtezdyaZtfAuRtIFOiRzK7g= +github.com/knadh/koanf/v2 v2.0.1/go.mod h1:ZeiIlIDXTE7w1lMT6UVcNiRAS2/rCeLn/GdLNvY1Dus= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= +github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4 h1:BpfhmLKZf+SjVanKKhCgf3bg+511DmU9eDQTen7LLbY= +github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/npillmayer/nestext v0.1.3/go.mod h1:h2lrijH8jpicr25dFY+oAJLyzlya6jhnuG+zWp9L0Uk= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= +github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT1pX2CziuyQR0= +github.com/rhnvrm/simples3 v0.6.1/go.mod h1:Y+3vYm2V7Y4VijFoJHHTrja6OgPrJ2cBti8dPGkC3sA= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE= +github.com/rs/cors v1.9.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= +go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/collector v0.81.0 h1:pF+sB8xNXlg/W0a0QTLz4mUWyool1a9toVj8LmLoFqg= +go.opentelemetry.io/collector v0.81.0/go.mod h1:thuOTBMusXwcTPTwLbs3zwwCOLaaQX2g+Hjf8OObc/w= +go.opentelemetry.io/collector/component v0.81.0 h1:AKsl6bss/SRrW248GFpmGiiI/4kdemW92Ai/X82CCqY= +go.opentelemetry.io/collector/component v0.81.0/go.mod h1:+m6/yPiJ7O7Oc/OLfmgUB2mrY1xoUqRj4BsoOtIVpGs= +go.opentelemetry.io/collector/config/configauth v0.81.0 h1:NIiJuIGOdblN0EIJv64R2mvGhthcYfWuvyCnjk8HRN4= +go.opentelemetry.io/collector/config/configauth v0.81.0/go.mod h1:2KscbmU+8fIzwiSU9Kku0Tf4b4A1plqFIJXR1DWSaTw= +go.opentelemetry.io/collector/config/configcompression v0.81.0 h1:Q725pvVH7tR6BP3WK7Ro3pbqMeQdZEV3KeFVHchBxCc= +go.opentelemetry.io/collector/config/configcompression v0.81.0/go.mod h1:xhHm1sEH7BTECAJo1xn64NMxeIvZGKdVGdSKUUc+YuM= +go.opentelemetry.io/collector/config/confighttp v0.81.0 h1:vIdiepUT7P/WtJRdfh8mjzvSqJRVF8/vl9GWtUNQlHQ= +go.opentelemetry.io/collector/config/confighttp v0.81.0/go.mod h1:I54THsffkpv//O7bUHw+0bXxjYdvyL6IHg5ksgYez8I= +go.opentelemetry.io/collector/config/configopaque v0.81.0 h1:MkCAGh0WydRWydETB9FLnuCj9hDPDiz2g4Wxnl53I0w= +go.opentelemetry.io/collector/config/configopaque v0.81.0/go.mod h1:pM1oy6gasukw3H6jAvc9Q9OtFaaY2IbfeuwCPAjOgXc= +go.opentelemetry.io/collector/config/configtelemetry v0.81.0 h1:j3dhWbAcrfL1n0RmShRJf99X/xIMoPfEShN/5Z8bY0k= +go.opentelemetry.io/collector/config/configtelemetry v0.81.0/go.mod h1:KEYQRiYJdx38iZkvcLKBZWH9fK4NeafxBwGRrRKMgyA= +go.opentelemetry.io/collector/config/configtls v0.81.0 h1:2vt+yOZUvGq5ADqFAxL5ONm1ACuGXDSs87AWT54Ez4M= +go.opentelemetry.io/collector/config/configtls v0.81.0/go.mod h1:HMHTYBMMgqBpTvnNAhQYmjO7XuoBMe2T4qRHcKluB4Q= +go.opentelemetry.io/collector/config/internal v0.81.0 h1:wRV2PBnJygdmKpIdt/xfG7zdQvXvHz9L+z8MhGsOji4= +go.opentelemetry.io/collector/config/internal v0.81.0/go.mod h1:RKcLV1gQxhgwx+6rlPYsvGMq1RZNne3UeOUZkHxJnIg= +go.opentelemetry.io/collector/confmap v0.81.0 h1:AqweoBGdF3jGM2/KgP5GS6bmN+1aVrEiCy4nPf7IBE4= +go.opentelemetry.io/collector/confmap v0.81.0/go.mod h1:iCTnTqGgZZJumhJxpY7rrJz9UQ/0zjPmsJz2Z7Tp4RY= +go.opentelemetry.io/collector/consumer v0.81.0 h1:8R2iCrSzD7T0RtC2Wh4GXxDiqla2vNhDokGW6Bcrfas= +go.opentelemetry.io/collector/consumer v0.81.0/go.mod h1:jS7+gAKdOx3lD3SnaBztBjUVpUYL3ee7fpoqI4p/gT8= +go.opentelemetry.io/collector/exporter v0.81.0 h1:GLhB8WGrBx+zZSB1HIOx2ivFUMahGtAVO2CC5xbCUHQ= +go.opentelemetry.io/collector/exporter v0.81.0/go.mod h1:Di4RTzI8uRooVNATIeApNUgmGdNt8XiikUTQLabmZaA= +go.opentelemetry.io/collector/extension v0.81.0 h1:Ak7AzZzxTFJxGyVbEklsGzqHyOHW5USiifJilCcRyTU= +go.opentelemetry.io/collector/extension v0.81.0/go.mod h1:DU2bX8qulS5+OCJZGfvqIwIT/q3sFnEjI2HjJ2LDI/s= +go.opentelemetry.io/collector/extension/auth v0.81.0 h1:UzVQSG9naJh1hX7hh+HVcvB3n+rpCJXX2BBdUoL/Ybo= +go.opentelemetry.io/collector/extension/auth v0.81.0/go.mod h1:PaBFcFrzXV+UgM4VZKp6Kn1IiRC/MbEYWxTfIalcIwk= +go.opentelemetry.io/collector/featuregate v1.0.0-rcv0013 h1:tiTUG9X/gEDN1oDYQOBVUFYQfhUG2CvgW9VhBc2uk1U= +go.opentelemetry.io/collector/featuregate v1.0.0-rcv0013/go.mod h1:0mE3mDLmUrOXVoNsuvj+7dV14h/9HFl/Fy9YTLoLObo= +go.opentelemetry.io/collector/pdata v1.0.0-rcv0013 h1:4sONXE9hAX+4Di8m0bQ/KaoH3Mi+OPt04cXkZ7A8W3k= +go.opentelemetry.io/collector/pdata v1.0.0-rcv0013/go.mod h1:x09G/4KjEcDKNuWCjC5ZtnuDE0XEqiRwI+yrHSVjIy8= +go.opentelemetry.io/collector/processor v0.81.0 h1:ypyNV5R0bnN3XGMAsH/q5eNARF5vXtFgSOK9rBWzsLc= +go.opentelemetry.io/collector/processor v0.81.0/go.mod h1:ZDwO3DVg1VUSA92g0r/o0jYk+T7r9uxgZZ3LABJbC34= +go.opentelemetry.io/collector/receiver v0.81.0 h1:0c+YtIV7fmd9ev+zmwS9qjx5ASi8cw+gSypu4I7Gugc= +go.opentelemetry.io/collector/receiver v0.81.0/go.mod h1:q80JkMxVLnk0vWxoTRY2J7F4Qx9069Yy5yxDbZ4JVwk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0 h1:pginetY7+onl4qN1vl0xW/V/v6OBZ0vVdH+esuJgvmM= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0/go.mod h1:XiYsayHc36K3EByOO6nbAXnAWbrUxdjUROCEeeROOH8= +go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= +go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= +go.opentelemetry.io/otel/exporters/prometheus v0.39.0 h1:whAaiHxOatgtKd+w0dOi//1KUxj3KoPINZdtDaDj3IA= +go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= +go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= +go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= +go.opentelemetry.io/otel/sdk/metric v0.39.0 h1:Kun8i1eYf48kHH83RucG93ffz0zGV1sh46FAScOTuDI= +go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= +go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= +go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +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-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= +golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= +golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +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-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +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= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc h1:XSJ8Vk1SWuNr8S18z1NZSziL0CPIXLCCMDOEFtHBOFc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.56.1 h1:z0dNfjIl0VpaZ9iSVjA6daGatAYwPGstTjt5vkRMFkQ= +google.golang.org/grpc v1.56.1/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/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= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/exporter/opensearchexporter/testdata/config.yaml b/exporter/opensearchexporter/testdata/config.yaml new file mode 100644 index 000000000000..8cd10bb8f588 --- /dev/null +++ b/exporter/opensearchexporter/testdata/config.yaml @@ -0,0 +1,22 @@ +extensions: + basicauth/sample_basic_auth: + username: test + password: testtoo + +opensearch: + endpoint: https://opensearch.example.com:9200 +opensearch/trace: + dataset: ngnix + namespace: eu + tls: + insecure: false + endpoint: https://opensearch.example.com:9200 + timeout: 2m + headers: + myheader: test + retry_on_failure: + enabled: true + initial_interval: 100000000 + randomization_factor: 0.5 + auth: + authenticator: sample_basic_auth diff --git a/versions.yaml b/versions.yaml index 2765a345da9b..cdabf495e2ca 100644 --- a/versions.yaml +++ b/versions.yaml @@ -242,3 +242,4 @@ excluded-modules: - github.com/open-telemetry/opentelemetry-collector-contrib/cmd/otelcontribcol - github.com/open-telemetry/opentelemetry-collector-contrib/cmd/oteltestbedcol - github.com/open-telemetry/opentelemetry-collector-contrib/internal/tools + - github.com/open-telemetry/opentelemetry-collector-contrib/exporter/opensearchexporter From afbd75255d2c78b2cebff206bff41a6ca9c23cb5 Mon Sep 17 00:00:00 2001 From: Mike Dame Date: Fri, 21 Jul 2023 13:04:59 -0400 Subject: [PATCH 07/42] [exporter/googlemanagedprometheus] support resource filters (#24392) Fixes #21654 Allows GMP exporter to use the same `resource_filters` option as supported by the main GCP exporter. --- .chloggen/gmp-resource-filters.yaml | 20 +++++++++++++++++++ .../googlemanagedprometheusexporter/README.md | 6 ++++++ .../googlemanagedprometheusexporter/config.go | 8 +++++--- 3 files changed, 31 insertions(+), 3 deletions(-) create mode 100755 .chloggen/gmp-resource-filters.yaml diff --git a/.chloggen/gmp-resource-filters.yaml b/.chloggen/gmp-resource-filters.yaml new file mode 100755 index 000000000000..1e69dfce7a04 --- /dev/null +++ b/.chloggen/gmp-resource-filters.yaml @@ -0,0 +1,20 @@ +# Use this changelog template to create an entry for release notes. +# If your change doesn't affect end users, such as a test fix or a tooling change, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. + +# 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. filelogreceiver) +component: googlemanagedprometheusexporter + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: GMP exporter supports filtering resource attributes to metric labels. + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [21654] + +# (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: diff --git a/exporter/googlemanagedprometheusexporter/README.md b/exporter/googlemanagedprometheusexporter/README.md index 9b30e2a99167..d02c7d0d0ae8 100644 --- a/exporter/googlemanagedprometheusexporter/README.md +++ b/exporter/googlemanagedprometheusexporter/README.md @@ -24,6 +24,12 @@ The following configuration options are supported: - `user_agent` (optional): Override the user agent string sent on requests to Cloud Monitoring (currently only applies to metrics). Specify `{{version}}` to include the application version number. Defaults to `opentelemetry-collector-contrib {{version}}`. - `metric`(optional): Configuration for sending metrics to Cloud Monitoring. - `endpoint` (optional): Endpoint where metric data is going to be sent to. Replaces `endpoint`. + - `extra_metrics_config` (optional): Enable or disable additional metrics. + - `enable_target_info` (default=`true`): Add `target_info` metric based on resource. + - `enable_scope_info` (default=`true`): Add `otel_scope_info` metric and `scope_name`/`scope_version` attributes to all other metrics. + - `resource_filters` (optional): Provides a list of filters to match resource attributes which will be included in metric labels. + - `prefix` (optional): Match resource attribute keys by prefix. + - `regex` (optional): Match resource attribute keys by regex. - `use_insecure` (optional): If true, use gRPC as their communication transport. Only has effect if Endpoint is not "". - `retry_on_failure` (optional): Configuration for how to handle retries when sending data to Google Cloud fails. - `enabled` (default = false) diff --git a/exporter/googlemanagedprometheusexporter/config.go b/exporter/googlemanagedprometheusexporter/config.go index 7fbd20efb47b..2d1513f131e9 100644 --- a/exporter/googlemanagedprometheusexporter/config.go +++ b/exporter/googlemanagedprometheusexporter/config.go @@ -32,9 +32,10 @@ type GMPConfig struct { type MetricConfig struct { // Prefix configures the prefix of metrics sent to GoogleManagedPrometheus. Defaults to prometheus.googleapis.com. // Changing this prefix is not recommended, as it may cause metrics to not be queryable with promql in the Cloud Monitoring UI. - Prefix string `mapstructure:"prefix"` - ClientConfig collector.ClientConfig `mapstructure:",squash"` - ExtraMetricsConfig ExtraMetricsConfig `mapstructure:"extra_metrics_config"` + Prefix string `mapstructure:"prefix"` + ClientConfig collector.ClientConfig `mapstructure:",squash"` + ExtraMetricsConfig ExtraMetricsConfig `mapstructure:"extra_metrics_config"` + ResourceFilters []collector.ResourceFilter `mapstructure:"resource_filters"` } // ExtraMetricsConfig controls the inclusion of additional metrics. @@ -64,6 +65,7 @@ func (c *GMPConfig) toCollectorConfig() collector.Config { cfg.ProjectID = c.ProjectID cfg.UserAgent = c.UserAgent cfg.MetricConfig.ClientConfig = c.MetricConfig.ClientConfig + cfg.MetricConfig.ResourceFilters = c.MetricConfig.ResourceFilters // add target_info and scope_info metrics extraMetricsFuncs := make([]func(m pmetric.Metrics), 0) From fa922a5b79e9656cc88c2ebe61fffa25a2e1ab45 Mon Sep 17 00:00:00 2001 From: Lan Date: Sat, 22 Jul 2023 01:09:31 +0800 Subject: [PATCH 08/42] [exporter/pulsar] Fix doc of pulsar exporter for endpoint (#24056) Signed-off-by: Lan Liang --- exporter/pulsarexporter/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exporter/pulsarexporter/README.md b/exporter/pulsarexporter/README.md index 385eb5f6c6b0..1e593a0ec9dc 100644 --- a/exporter/pulsarexporter/README.md +++ b/exporter/pulsarexporter/README.md @@ -80,7 +80,7 @@ Example configuration: ```yaml exporters: pulsar: - service_url: pulsar://localhost:6650 + endpoint: pulsar://localhost:6650 topic: otlp-spans encoding: otlp_proto auth: From 2607ed821391bb03d0ea921c573e04760c5c08cd Mon Sep 17 00:00:00 2001 From: Edwin Date: Fri, 21 Jul 2023 18:45:11 +0100 Subject: [PATCH 09/42] [cmd/telemetrygen] Change span kind from an attribute to top level info (#24303) **Description:** Remove the span attribute `span.kind` and instead set the `Kind` (which is a top level span information) directly using `trace.WithSpanKind`. **Link to tracking Issue:** #24286 **Testing:** Added a rudimentary test to ensure that `Kind` is not `Internal` which is the default when not specified. **Documentation:** None. This is probably the original intention. --- ...4286-telemetrygen-span-kind-attribute.yaml | 20 ++++++++++++++ cmd/telemetrygen/internal/traces/worker.go | 11 ++++---- .../internal/traces/worker_test.go | 26 +++++++++++++++++++ 3 files changed, 52 insertions(+), 5 deletions(-) create mode 100755 .chloggen/issue-24286-telemetrygen-span-kind-attribute.yaml diff --git a/.chloggen/issue-24286-telemetrygen-span-kind-attribute.yaml b/.chloggen/issue-24286-telemetrygen-span-kind-attribute.yaml new file mode 100755 index 000000000000..23cc5a41ae99 --- /dev/null +++ b/.chloggen/issue-24286-telemetrygen-span-kind-attribute.yaml @@ -0,0 +1,20 @@ +# Use this changelog template to create an entry for release notes. +# If your change doesn't affect end users, such as a test fix or a tooling change, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: bug_fix + +# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) +component: cmd/telemetrygen + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Move the span attribute span.kind to the native Kind which is a top level trace information + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [24286] + +# (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: diff --git a/cmd/telemetrygen/internal/traces/worker.go b/cmd/telemetrygen/internal/traces/worker.go index f39eca1484d4..d02b34cf384e 100644 --- a/cmd/telemetrygen/internal/traces/worker.go +++ b/cmd/telemetrygen/internal/traces/worker.go @@ -10,7 +10,6 @@ import ( "time" "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/propagation" semconv "go.opentelemetry.io/otel/semconv/v1.4.0" "go.opentelemetry.io/otel/trace" @@ -40,10 +39,11 @@ func (w worker) simulateTraces() { var i int for w.running.Load() { ctx, sp := tracer.Start(context.Background(), "lets-go", trace.WithAttributes( - attribute.String("span.kind", "client"), // is there a semantic convention for this? semconv.NetPeerIPKey.String(fakeIP), semconv.PeerServiceKey.String("telemetrygen-server"), - )) + ), + trace.WithSpanKind(trace.SpanKindClient), + ) childCtx := ctx if w.propagateContext { @@ -56,10 +56,11 @@ func (w worker) simulateTraces() { } _, child := tracer.Start(childCtx, "okey-dokey", trace.WithAttributes( - attribute.String("span.kind", "server"), semconv.NetPeerIPKey.String(fakeIP), semconv.PeerServiceKey.String("telemetrygen-client"), - )) + ), + trace.WithSpanKind(trace.SpanKindServer), + ) if err := limiter.Wait(context.Background()); err != nil { w.logger.Fatal("limiter waited failed, retry", zap.Error(err)) diff --git a/cmd/telemetrygen/internal/traces/worker_test.go b/cmd/telemetrygen/internal/traces/worker_test.go index e21e98c86ef2..e8b8aa18c136 100644 --- a/cmd/telemetrygen/internal/traces/worker_test.go +++ b/cmd/telemetrygen/internal/traces/worker_test.go @@ -12,6 +12,7 @@ import ( "github.com/stretchr/testify/require" "go.opentelemetry.io/otel" sdktrace "go.opentelemetry.io/otel/sdk/trace" + "go.opentelemetry.io/otel/trace" "go.uber.org/zap" "github.com/open-telemetry/opentelemetry-collector-contrib/cmd/telemetrygen/internal/common" @@ -97,6 +98,31 @@ func TestUnthrottled(t *testing.T) { assert.True(t, len(syncer.spans) > 100, "there should have been more than 100 spans, had %d", len(syncer.spans)) } +func TestSpanKind(t *testing.T) { + // prepare + syncer := &mockSyncer{} + + tracerProvider := sdktrace.NewTracerProvider() + sp := sdktrace.NewSimpleSpanProcessor(syncer) + tracerProvider.RegisterSpanProcessor(sp) + otel.SetTracerProvider(tracerProvider) + + cfg := &Config{ + Config: common.Config{ + WorkerCount: 1, + }, + NumTraces: 1, + } + + // test + require.NoError(t, Run(cfg, zap.NewNop())) + + // verify that the default Span Kind is being overridden + for _, span := range syncer.spans { + assert.NotEqual(t, span.SpanKind(), trace.SpanKindInternal) + } +} + var _ sdktrace.SpanExporter = (*mockSyncer)(nil) type mockSyncer struct { From b6cff39ff5a10dddf3e24fd7f3bab82413fd8ce9 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Fri, 21 Jul 2023 13:50:21 -0400 Subject: [PATCH 10/42] [testbed] Add zstd compression end-to-end tests for OTLP/HTTP (#23456) --- testbed/go.mod | 2 +- testbed/testbed/mock_backend_test.go | 2 +- testbed/testbed/senders.go | 6 +++++- testbed/tests/trace_test.go | 13 +++++++++++-- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/testbed/go.mod b/testbed/go.mod index 906d4ce7c6b0..a0564322862e 100644 --- a/testbed/go.mod +++ b/testbed/go.mod @@ -31,6 +31,7 @@ require ( github.com/stretchr/testify v1.8.4 go.opentelemetry.io/collector v0.81.0 go.opentelemetry.io/collector/component v0.81.0 + go.opentelemetry.io/collector/config/configcompression v0.81.0 go.opentelemetry.io/collector/config/configgrpc v0.81.0 go.opentelemetry.io/collector/config/confighttp v0.81.0 go.opentelemetry.io/collector/config/confignet v0.81.0 @@ -211,7 +212,6 @@ require ( github.com/yusufpapurcu/wmi v1.2.3 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/collector/config/configauth v0.81.0 // indirect - go.opentelemetry.io/collector/config/configcompression v0.81.0 // indirect go.opentelemetry.io/collector/config/configopaque v0.81.0 // indirect go.opentelemetry.io/collector/config/configtelemetry v0.81.0 // indirect go.opentelemetry.io/collector/config/internal v0.81.0 // indirect diff --git a/testbed/testbed/mock_backend_test.go b/testbed/testbed/mock_backend_test.go index 92bc351330dd..d5493cbafb00 100644 --- a/testbed/testbed/mock_backend_test.go +++ b/testbed/testbed/mock_backend_test.go @@ -27,7 +27,7 @@ func TestGeneratorAndBackend(t *testing.T) { { name: "OTLP/HTTP-OTLP/HTTP", receiver: NewOTLPHTTPDataReceiver(port), - sender: NewOTLPHTTPTraceDataSender(DefaultHost, port), + sender: NewOTLPHTTPTraceDataSender(DefaultHost, port, ""), }, } diff --git a/testbed/testbed/senders.go b/testbed/testbed/senders.go index 2bc8691fc51d..1fca0860cedb 100644 --- a/testbed/testbed/senders.go +++ b/testbed/testbed/senders.go @@ -9,6 +9,7 @@ import ( "net" "go.opentelemetry.io/collector/component/componenttest" + "go.opentelemetry.io/collector/config/configcompression" "go.opentelemetry.io/collector/config/configtls" "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/exporter/exportertest" @@ -77,6 +78,7 @@ func (dsb *DataSenderBase) Flush() { type otlpHTTPDataSender struct { DataSenderBase + compression configcompression.CompressionType } func (ods *otlpHTTPDataSender) fillConfig(cfg *otlphttpexporter.Config) *otlphttpexporter.Config { @@ -88,6 +90,7 @@ func (ods *otlpHTTPDataSender) fillConfig(cfg *otlphttpexporter.Config) *otlphtt cfg.TLSSetting = configtls.TLSClientSetting{ Insecure: true, } + cfg.Compression = ods.compression return cfg } @@ -111,13 +114,14 @@ type otlpHTTPTraceDataSender struct { } // NewOTLPHTTPTraceDataSender creates a new TraceDataSender for OTLP/HTTP traces exporter. -func NewOTLPHTTPTraceDataSender(host string, port int) TraceDataSender { +func NewOTLPHTTPTraceDataSender(host string, port int, compression configcompression.CompressionType) TraceDataSender { return &otlpHTTPTraceDataSender{ otlpHTTPDataSender: otlpHTTPDataSender{ DataSenderBase: DataSenderBase{ Port: port, Host: host, }, + compression: compression, }, } } diff --git a/testbed/tests/trace_test.go b/testbed/tests/trace_test.go index 161dc4631c12..5d060867ad95 100644 --- a/testbed/tests/trace_test.go +++ b/testbed/tests/trace_test.go @@ -75,7 +75,7 @@ func TestTrace10kSPS(t *testing.T) { }, { "OTLP-HTTP", - testbed.NewOTLPHTTPTraceDataSender(testbed.DefaultHost, testbed.GetAvailablePort(t)), + testbed.NewOTLPHTTPTraceDataSender(testbed.DefaultHost, testbed.GetAvailablePort(t), ""), testbed.NewOTLPHTTPDataReceiver(testbed.GetAvailablePort(t)), testbed.ResourceSpec{ ExpectedMaxCPU: 20, @@ -84,13 +84,22 @@ func TestTrace10kSPS(t *testing.T) { }, { "OTLP-HTTP-gzip", - testbed.NewOTLPHTTPTraceDataSender(testbed.DefaultHost, testbed.GetAvailablePort(t)), + testbed.NewOTLPHTTPTraceDataSender(testbed.DefaultHost, testbed.GetAvailablePort(t), "gzip"), testbed.NewOTLPHTTPDataReceiver(testbed.GetAvailablePort(t)).WithCompression("gzip"), testbed.ResourceSpec{ ExpectedMaxCPU: 25, ExpectedMaxRAM: 100, }, }, + { + "OTLP-HTTP-zstd", + testbed.NewOTLPHTTPTraceDataSender(testbed.DefaultHost, testbed.GetAvailablePort(t), "zstd"), + testbed.NewOTLPHTTPDataReceiver(testbed.GetAvailablePort(t)).WithCompression("zstd"), + testbed.ResourceSpec{ + ExpectedMaxCPU: 22, + ExpectedMaxRAM: 220, + }, + }, { "SAPM", datasenders.NewSapmDataSender(testbed.GetAvailablePort(t), ""), From a68b3414794a6e7a3749903f017f45324f06007a Mon Sep 17 00:00:00 2001 From: Goutham Veeramachaneni Date: Fri, 21 Jul 2023 20:20:24 +0200 Subject: [PATCH 11/42] [prometheus] Recommend copying resource attrs. into metric labels (#23867) https://docs.google.com/document/d/1gG-eTQ4SxmfbGwkrblnUk97fWQA93umvXHEzQn2Nv7E/edit?disco=AAAAzwSMgJ8 It was recommended to convert this recommendation into a blog-post, but I think making it part of the documentation might be better. Signed-off-by: Goutham --- exporter/prometheusexporter/README.md | 36 +++++++++++++++++++ .../prometheusremotewriteexporter/README.md | 36 +++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/exporter/prometheusexporter/README.md b/exporter/prometheusexporter/README.md index 1951c23e07f9..298074f5a197 100644 --- a/exporter/prometheusexporter/README.md +++ b/exporter/prometheusexporter/README.md @@ -62,3 +62,39 @@ Given the example, metrics will be available at `https://1.2.3.4:1234/metrics`. ## Metric names and labels normalization OpenTelemetry metric names and attributes are normalized to be compliant with Prometheus naming rules. [Details on this normalization process are described in the Prometheus translator module](../../pkg/translator/prometheus/). + +## Setting resource attributes as metric labels + +By default, resource attributes are added to a special metric called `target_info`. To select and group by metrics by resource attributes, you [need to do join on `target_info`](https://prometheus.io/docs/prometheus/latest/querying/operators/#many-to-one-and-one-to-many-vector-matches). For example, to select metrics with `k8s_namespace_name` attribute equal to `my-namespace`: + +```promql +app_ads_ad_requests_total * on (job, instance) group_left target_info{k8s_namespace_name="my-namespace"} +``` + +Or to group by a particular attribute (for ex. `k8s_namespace_name`): + +```promql +sum by (k8s_namespace_name) (app_ads_ad_requests_total * on (job, instance) group_left(k8s_namespace_name) target_info) +``` + +This is not a common pattern, and we recommend copying the most common resource attributes into metric labels. You can do this through the transform processor: + +```yaml +processor: + transform: + metric_statements: + - context: metric + statements: + - set(attributes["namespace"], resource.attributes["k8s_namespace_name"]) + - set(attributes["container"], resource.attributes["k8s.container.name"]) + - set(attributes["pod"], resource.attributes["k8s.pod.name"]) + - set(attributes["cluster"], resource.attributes["k8s.cluster.name"]) +``` + +After this, grouping or selecting becomes as simple as: + +```promql +app_ads_ad_requests_total{namespace="my-namespace"} + +sum by (namespace) (app_ads_ad_requests_total) +``` \ No newline at end of file diff --git a/exporter/prometheusremotewriteexporter/README.md b/exporter/prometheusremotewriteexporter/README.md index f74697a90486..075ed6cfece1 100644 --- a/exporter/prometheusremotewriteexporter/README.md +++ b/exporter/prometheusremotewriteexporter/README.md @@ -101,6 +101,42 @@ Several helper files are leveraged to provide additional capabilities automatica OpenTelemetry metric names and attributes are normalized to be compliant with Prometheus naming rules. [Details on this normalization process are described in the Prometheus translator module](../../pkg/translator/prometheus/). +## Setting resource attributes as metric labels + +By default, resource attributes are added to a special metric called `target_info`. To select and group by metrics by resource attributes, you [need to do join on `target_info`](https://prometheus.io/docs/prometheus/latest/querying/operators/#many-to-one-and-one-to-many-vector-matches). For example, to select metrics with `k8s_namespace_name` attribute equal to `my-namespace`: + +```promql +app_ads_ad_requests_total * on (job, instance) group_left target_info{k8s_namespace_name="my-namespace"} +``` + +Or to group by a particular attribute (for ex. `k8s_namespace_name`): + +```promql +sum by (k8s_namespace_name) (app_ads_ad_requests_total * on (job, instance) group_left(k8s_namespace_name) target_info) +``` + +This is not a common pattern, and we recommend copying the most common resource attributes into metric labels. You can do this through the transform processor: + +```yaml +processor: + transform: + metric_statements: + - context: metric + statements: + - set(attributes["namespace"], resource.attributes["k8s_namespace_name"]) + - set(attributes["container"], resource.attributes["k8s.container.name"]) + - set(attributes["pod"], resource.attributes["k8s.pod.name"]) + - set(attributes["cluster"], resource.attributes["k8s.cluster.name"]) +``` + +After this, grouping or selecting becomes as simple as: + +```promql +app_ads_ad_requests_total{namespace="my-namespace"} + +sum by (namespace) (app_ads_ad_requests_total) +``` + [beta]:https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]:https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib [core]:https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol From 19e05e5556537ce4cc70845f6bf003e88d689b99 Mon Sep 17 00:00:00 2001 From: David Ashpole Date: Fri, 21 Jul 2023 14:21:04 -0400 Subject: [PATCH 12/42] Update documentation for GCP exporters (#23879) Document features added in recent releases. That includes gzip compression, and the grpc connection pool size. This also fixes the comment for use_insecure. --- exporter/googlecloudexporter/README.md | 14 ++++++++++---- exporter/googlemanagedprometheusexporter/README.md | 4 +++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/exporter/googlecloudexporter/README.md b/exporter/googlecloudexporter/README.md index 5fe584de1a43..3ee18a314423 100644 --- a/exporter/googlecloudexporter/README.md +++ b/exporter/googlecloudexporter/README.md @@ -177,7 +177,9 @@ The following configuration options are supported: - `metric` (optional): Configuration for sending metrics to Cloud Monitoring. - `prefix` (default = `workload.googleapis.com`): The prefix to add to metrics. - `endpoint` (default = monitoring.googleapis.com): Endpoint where metric data is going to be sent to. - - `use_insecure` (default = false): If true, use gRPC as their communication transport. Only has effect if Endpoint is not "". + - `compression` (optional): Compression format for Metrics gRPC requests. Supported values: [`gzip`]. Defaults to no compression. + - `grpc_pool_size` (optional): Sets the size of the connection pool in the GCP client. Defaults to a single connection. + - `use_insecure` (default = false): If true, disables gRPC client transport security. Only has effect if Endpoint is not "". - `known_domains` (default = [googleapis.com, kubernetes.io, istio.io, knative.dev]): If a metric belongs to one of these domains it does not get a prefix. - `skip_create_descriptor` (default = false): If set to true, do not send metric descriptors to GCM. - `instrumentation_library_labels` (default = true): If true, set the instrumentation_source and instrumentation_version labels. @@ -197,13 +199,17 @@ The following configuration options are supported: errors (`UNAVAILABLE` or `DEADLINE_EXCEEDED`). - `trace` (optional): Configuration for sending traces to Cloud Trace. - `endpoint` (default = cloudtrace.googleapis.com): Endpoint where trace data is going to be sent to. - - `use_insecure` (default = false): If true. use gRPC as their communication transport. Only has effect if Endpoint is not "". Replaces `use_insecure`. + - `compression` (optional): Compression format for Metrics gRPC requests. Supported values: [`gzip`]. Defaults to no compression. + - `grpc_pool_size` (optional): Sets the size of the connection pool in the GCP client. Defaults to a single connection. + - `use_insecure` (default = false): If true, disables gRPC client transport security. Only has effect if Endpoint is not "". - `attribute_mappings` (optional): AttributeMappings determines how to map from OpenTelemetry attribute keys to Google Cloud Trace keys. By default, it changes http and service keys so that they appear more prominently in the UI. - `key`: Key is the OpenTelemetry attribute key - `replacement`: Replacement is the attribute sent to Google Cloud Trace - `log` (optional): Configuration for sending metrics to Cloud Logging. - - `endpoint` (default = logging.googleapis.com): Endpoint where log data is going to be sent to. D - - `use_insecure` (default = false): If true, use gRPC as their communication transport. Only has effect if Endpoint is not "". + - `endpoint` (default = logging.googleapis.com): Endpoint where log data is going to be sent to. + - `compression` (optional): Compression format for Metrics gRPC requests. Supported values: [`gzip`]. Defaults to no compression. + - `grpc_pool_size` (optional): Sets the size of the connection pool in the GCP client. Defaults to a single connection. + - `use_insecure` (default = false): If true, disables gRPC client transport security. Only has effect if Endpoint is not "". - `default_log_name` (optional): Defines a default name for log entries. If left unset, and a log entry does not have the `gcp.log_name` attribute set, the exporter will return an error processing that entry. - `resource_filters` (default = []): If provided, resource attributes matching any filter will be included in log labels. Can be defined by `prefix`, `regex`, or `prefix` AND `regex`. - `prefix`: Match resource keys by prefix. diff --git a/exporter/googlemanagedprometheusexporter/README.md b/exporter/googlemanagedprometheusexporter/README.md index d02c7d0d0ae8..473fb0f3a8fb 100644 --- a/exporter/googlemanagedprometheusexporter/README.md +++ b/exporter/googlemanagedprometheusexporter/README.md @@ -24,13 +24,15 @@ The following configuration options are supported: - `user_agent` (optional): Override the user agent string sent on requests to Cloud Monitoring (currently only applies to metrics). Specify `{{version}}` to include the application version number. Defaults to `opentelemetry-collector-contrib {{version}}`. - `metric`(optional): Configuration for sending metrics to Cloud Monitoring. - `endpoint` (optional): Endpoint where metric data is going to be sent to. Replaces `endpoint`. + - `compression` (optional): Compression format for Metrics gRPC requests. Supported values: [`gzip`]. Defaults to no compression. + - `grpc_pool_size` (optional): Sets the size of the connection pool in the GCP client. Defaults to a single connection. + - `use_insecure` (optional): If true, disables gRPC client transport security. Only has applies if Endpoint is not "". - `extra_metrics_config` (optional): Enable or disable additional metrics. - `enable_target_info` (default=`true`): Add `target_info` metric based on resource. - `enable_scope_info` (default=`true`): Add `otel_scope_info` metric and `scope_name`/`scope_version` attributes to all other metrics. - `resource_filters` (optional): Provides a list of filters to match resource attributes which will be included in metric labels. - `prefix` (optional): Match resource attribute keys by prefix. - `regex` (optional): Match resource attribute keys by regex. -- `use_insecure` (optional): If true, use gRPC as their communication transport. Only has effect if Endpoint is not "". - `retry_on_failure` (optional): Configuration for how to handle retries when sending data to Google Cloud fails. - `enabled` (default = false) - `initial_interval` (default = 5s): Time to wait after the first failure before retrying; ignored if `enabled` is `false` From d30a938877fd0261d69df6057f056039994b7f0a Mon Sep 17 00:00:00 2001 From: Jay DeLuca Date: Fri, 21 Jul 2023 14:21:57 -0400 Subject: [PATCH 13/42] [chore] fix exhaustive lint for processor spanprocessor (#23266) (#23952) Related #23266 --- .golangci.yml | 3 --- processor/spanprocessor/span.go | 8 ++++++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index f5fefb7e8a34..8a1e0a6f5d96 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -182,9 +182,6 @@ issues: - path: servicegraphprocessor linters: - exhaustive - - path: spanprocessor - linters: - - exhaustive - path: resourcedetectionprocessor linters: - exhaustive diff --git a/processor/spanprocessor/span.go b/processor/spanprocessor/span.go index 4f3f66a14e1d..20f8f2a043fa 100644 --- a/processor/spanprocessor/span.go +++ b/processor/spanprocessor/span.go @@ -142,6 +142,14 @@ func (sp *spanProcessor) processFromAttributes(span ptrace.Span) { sb.WriteString(strconv.FormatFloat(attr.Double(), 'f', -1, 64)) case pcommon.ValueTypeInt: sb.WriteString(strconv.FormatInt(attr.Int(), 10)) + case pcommon.ValueTypeEmpty: + fallthrough + case pcommon.ValueTypeSlice: + fallthrough + case pcommon.ValueTypeBytes: + fallthrough + case pcommon.ValueTypeMap: + fallthrough default: sb.WriteString("") } From 2312eb2752143762a8cb160167c5c2f626bce5e3 Mon Sep 17 00:00:00 2001 From: Antoine Toulme Date: Fri, 21 Jul 2023 15:40:04 -0700 Subject: [PATCH 14/42] [chore] expose codeowners in README (#24227) **Description:** Add fields to status metadata and changes to README template to expose codeowners in component READMEs. **Link to tracking Issue:** https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/23367 --------- Co-authored-by: Alex Boten --- cmd/mdatagen/main.go | 9 ++++- cmd/mdatagen/main_test.go | 40 ++++++++++++++++++- cmd/mdatagen/metadata-schema.yaml | 4 ++ cmd/mdatagen/statusdata.go | 8 ++++ cmd/mdatagen/templates/readme.md.tmpl | 8 ++++ .../testdata/readme_with_status_codeowners.md | 15 +++++++ ...dme_with_status_codeowners_and_emeritus.md | 16 ++++++++ receiver/signalfxreceiver/README.md | 1 + receiver/signalfxreceiver/metadata.yaml | 3 ++ receiver/splunkhecreceiver/README.md | 1 + receiver/splunkhecreceiver/metadata.yaml | 3 ++ receiver/webhookeventreceiver/README.md | 1 + receiver/webhookeventreceiver/metadata.yaml | 4 +- 13 files changed, 110 insertions(+), 3 deletions(-) create mode 100644 cmd/mdatagen/testdata/readme_with_status_codeowners.md create mode 100644 cmd/mdatagen/testdata/readme_with_status_codeowners_and_emeritus.md diff --git a/cmd/mdatagen/main.go b/cmd/mdatagen/main.go index 4821f2162206..4921d747676a 100644 --- a/cmd/mdatagen/main.go +++ b/cmd/mdatagen/main.go @@ -140,7 +140,14 @@ func templatize(tmplFile string, md metadata) *template.Template { }, "stringsJoin": strings.Join, "stringsSplit": strings.Split, - "casesTitle": cases.Title(language.English).String, + "userLinks": func(elems []string) []string { + result := make([]string, len(elems)) + for i, elem := range elems { + result[i] = fmt.Sprintf("[@%s](https://www.github.com/%s)", elem, elem) + } + return result + }, + "casesTitle": cases.Title(language.English).String, "toCamelCase": func(s string) string { caser := cases.Title(language.English).String parts := strings.Split(s, "_") diff --git a/cmd/mdatagen/main_test.go b/cmd/mdatagen/main_test.go index e53f9d4fb916..e23dcb6d129c 100644 --- a/cmd/mdatagen/main_test.go +++ b/cmd/mdatagen/main_test.go @@ -5,6 +5,7 @@ package main import ( "bytes" + "fmt" "os" "path/filepath" "testing" @@ -133,6 +134,7 @@ func Test_inlineReplace(t *testing.T) { warnings []string stability map[string][]string distros []string + codeowners *Codeowners }{ { name: "readme with empty status", @@ -160,6 +162,39 @@ Some info about a component componentClass: "extension", distros: []string{"contrib"}, }, + { + name: "readme with status with codeowners and emeritus", + markdown: `# Some component + + + + +Some info about a component +`, + outputFile: "readme_with_status_codeowners_and_emeritus.md", + componentClass: "receiver", + distros: []string{"contrib"}, + codeowners: &Codeowners{ + Active: []string{"foo"}, + Emeritus: []string{"bar"}, + }, + }, + { + name: "readme with status with codeowners", + markdown: `# Some component + + + + +Some info about a component +`, + outputFile: "readme_with_status_codeowners.md", + componentClass: "receiver", + distros: []string{"contrib"}, + codeowners: &Codeowners{ + Active: []string{"foo"}, + }, + }, { name: "readme with status table", markdown: `# Some component @@ -241,6 +276,7 @@ Some info about a component Distributions: tt.distros, Class: tt.componentClass, Warnings: tt.warnings, + Codeowners: tt.codeowners, }, } tmpdir := t.TempDir() @@ -258,7 +294,9 @@ Some info about a component expected, err := os.ReadFile(filepath.Join("testdata", tt.outputFile)) require.NoError(t, err) expected = bytes.ReplaceAll(expected, []byte("\r\n"), []byte("\n")) - require.Equal(t, expected, got, "got: %s\nexpected: %s", got, expected) + fmt.Println(string(got)) + fmt.Println(string(expected)) + require.Equal(t, string(expected), string(got)) }) } } diff --git a/cmd/mdatagen/metadata-schema.yaml b/cmd/mdatagen/metadata-schema.yaml index 0513b0b92ae8..7b8bdd2f9e1b 100644 --- a/cmd/mdatagen/metadata-schema.yaml +++ b/cmd/mdatagen/metadata-schema.yaml @@ -20,6 +20,10 @@ status: distributions: [string] # Optional: A list of warnings that should be brought to the attention of users looking to use this component warnings: [string] + # Optional: Metadata related to codeowners of the component + codeowners: + active: [string] + emeritus: [string] # Optional: OTel Semantic Conventions version that will be associated with the scraped metrics. # This attribute should be set for metrics compliant with OTel Semantic Conventions. diff --git a/cmd/mdatagen/statusdata.go b/cmd/mdatagen/statusdata.go index 91f785676dbd..901f39806536 100644 --- a/cmd/mdatagen/statusdata.go +++ b/cmd/mdatagen/statusdata.go @@ -21,11 +21,19 @@ var distros = map[string]string{ "redhat": "https://github.com/os-observability/redhat-opentelemetry-collector", } +type Codeowners struct { + // Active codeowners + Active []string `mapstructure:"active"` + // Emeritus codeowners + Emeritus []string `mapstructure:"emeritus"` +} + type Status struct { Stability map[string][]string `mapstructure:"stability"` Distributions []string `mapstructure:"distributions"` Class string `mapstructure:"class"` Warnings []string `mapstructure:"warnings"` + Codeowners *Codeowners `mapstructure:"codeowners"` } func (s *Status) SortedDistributions() []string { diff --git a/cmd/mdatagen/templates/readme.md.tmpl b/cmd/mdatagen/templates/readme.md.tmpl index e55101507e94..60c20800b884 100644 --- a/cmd/mdatagen/templates/readme.md.tmpl +++ b/cmd/mdatagen/templates/readme.md.tmpl @@ -20,6 +20,14 @@ {{- if ne $class "" }} | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3A{{ $class }}%2F{{ $shortName }}%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3A{{ $class }}%2F{{ $shortName }}%20&label=closed&color=blue&logo=opentelemetry) | {{- end }} +{{- if .Status.Codeowners }} +{{- $codeowners := userLinks .Status.Codeowners.Active }} +{{- $emeritus := userLinks .Status.Codeowners.Emeritus }} +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | {{ stringsJoin $codeowners ", " }} | +{{- if $emeritus }} +| Emeritus | {{ stringsJoin $emeritus ", " }} | +{{- end }} +{{- end }} {{range $stability, $val := .Status.Stability}} [{{ $stability }}]: https://github.com/open-telemetry/opentelemetry-collector#{{ $stability }} {{- end }} diff --git a/cmd/mdatagen/testdata/readme_with_status_codeowners.md b/cmd/mdatagen/testdata/readme_with_status_codeowners.md new file mode 100644 index 000000000000..1d6f0fceabd4 --- /dev/null +++ b/cmd/mdatagen/testdata/readme_with_status_codeowners.md @@ -0,0 +1,15 @@ +# Some component + + +| Status | | +| ------------- |-----------| +| Stability | [beta]: metrics | +| Distributions | [contrib] | +| Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Ffoo%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Ffoo%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@foo](https://www.github.com/foo) | + +[beta]: https://github.com/open-telemetry/opentelemetry-collector#beta +[contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib + + +Some info about a component diff --git a/cmd/mdatagen/testdata/readme_with_status_codeowners_and_emeritus.md b/cmd/mdatagen/testdata/readme_with_status_codeowners_and_emeritus.md new file mode 100644 index 000000000000..8de98ec00891 --- /dev/null +++ b/cmd/mdatagen/testdata/readme_with_status_codeowners_and_emeritus.md @@ -0,0 +1,16 @@ +# Some component + + +| Status | | +| ------------- |-----------| +| Stability | [beta]: metrics | +| Distributions | [contrib] | +| Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Ffoo%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Ffoo%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@foo](https://www.github.com/foo) | +| Emeritus | [@bar](https://www.github.com/bar) | + +[beta]: https://github.com/open-telemetry/opentelemetry-collector#beta +[contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib + + +Some info about a component diff --git a/receiver/signalfxreceiver/README.md b/receiver/signalfxreceiver/README.md index bcb236188fb2..bc6f637321c4 100644 --- a/receiver/signalfxreceiver/README.md +++ b/receiver/signalfxreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics, logs | | Distributions | [contrib], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fsignalfx%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fsignalfx%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@dmitryax](https://www.github.com/dmitryax) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/signalfxreceiver/metadata.yaml b/receiver/signalfxreceiver/metadata.yaml index 7a7b4a0ffd67..1ab2bb674571 100644 --- a/receiver/signalfxreceiver/metadata.yaml +++ b/receiver/signalfxreceiver/metadata.yaml @@ -5,3 +5,6 @@ status: stability: beta: [metrics, logs] distributions: [contrib, splunk, sumo] + codeowners: + active: ["dmitryax"] + emeritus: diff --git a/receiver/splunkhecreceiver/README.md b/receiver/splunkhecreceiver/README.md index 04978eb6efc9..95c0bb33cbc8 100644 --- a/receiver/splunkhecreceiver/README.md +++ b/receiver/splunkhecreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics, logs | | Distributions | [contrib], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fsplunkhec%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fsplunkhec%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@atoulme](https://www.github.com/atoulme) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/splunkhecreceiver/metadata.yaml b/receiver/splunkhecreceiver/metadata.yaml index 7bd17cea20cd..e38c35598960 100644 --- a/receiver/splunkhecreceiver/metadata.yaml +++ b/receiver/splunkhecreceiver/metadata.yaml @@ -5,3 +5,6 @@ status: stability: beta: [metrics, logs] distributions: [contrib, splunk, sumo] + codeowners: + active: ["atoulme"] + emeritus: diff --git a/receiver/webhookeventreceiver/README.md b/receiver/webhookeventreceiver/README.md index d0b2d9bedf0f..1331d282764b 100644 --- a/receiver/webhookeventreceiver/README.md +++ b/receiver/webhookeventreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: logs | | Distributions | [] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fwebhookevent%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fwebhookevent%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@atoulme](https://www.github.com/atoulme), [@shalper2](https://www.github.com/shalper2) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha diff --git a/receiver/webhookeventreceiver/metadata.yaml b/receiver/webhookeventreceiver/metadata.yaml index d3212393673c..a7c2d384a3ba 100644 --- a/receiver/webhookeventreceiver/metadata.yaml +++ b/receiver/webhookeventreceiver/metadata.yaml @@ -5,4 +5,6 @@ status: stability: alpha: [logs] distributions: - + codeowners: + active: ["atoulme", "shalper2"] + emeritus: From 20e9a0257d02e20e75f9bdd9d58cf6246190a351 Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Fri, 21 Jul 2023 18:56:10 -0400 Subject: [PATCH 15/42] [receiver/k8sclusterreceiver] Add timestamp field to entity events (#24431) Resolves https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24428 This is part 4 of the work to move to entity events-as-log-records in K8s cluster receiver: https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/19741 Overall design document: https://docs.google.com/document/d/1Tg18sIck3Nakxtd3TFFcIjrmRO_0GLMdHXylVqBQmJA/ I chose to use Timestamp field of the LogRecord (and not ObservedTimestamp). Please speak if you think ObservedTimestamp is a better place. I am not sure if changelog entry is needed for this PR. It is an addition to an API that is experimental and not yet released. Example log record emitted BEFORE this PR: ``` ObservedTimestamp: 1970-01-01 00:00:00 +0000 UTC Timestamp: 1970-01-01 00:00:00 +0000 UTC SeverityText: SeverityNumber: Unspecified(0) Body: Empty() Attributes: -> otel.entity.id: Map({"k8s.pod.uid":"07cc87d9-8e76-4472-b5ee-c9ecbad94ea9"}) -> otel.entity.event.type: Str(entity_state) -> otel.entity.type: Str(k8s.pod) -> otel.entity.attributes: Map({"k8s-app":"kubernetes-dashboard","k8s.deployment.name":"kubernetes-dashboard","k8s.deployment.uid":"4c1ee765-906b-498b-80b5-bea67a714fce","k8s.replicaset.name":"kubernetes-dashboard-6c7ccbcf87","k8s.replicasetuid":"e8c052b4-c1db-43bd-806d-f85d8a861f5b","k8s.service.kubernetes-dashboard":"","k8s.workload.kind":"Deployment","k8s.workload.name":"kubernetes-dashboard","pod-template-hash":"6c7ccbcf87","podcreation_timestamp":"2023-06-30T11:32:00-04:00"}) Trace ID: Span ID: Flags: 0 ``` Example log record emitted AFTER this PR: ``` ObservedTimestamp: 1970-01-01 00:00:00 +0000 UTC Timestamp: 2023-07-21 17:42:54.851743 +0000 UTC SeverityText: SeverityNumber: Unspecified(0) Body: Empty() Attributes: -> otel.entity.id: Map({"k8s.pod.uid":"07cc87d9-8e76-4472-b5ee-c9ecbad94ea9"}) -> otel.entity.event.type: Str(entity_state) -> otel.entity.type: Str(k8s.pod) -> otel.entity.attributes: Map({"k8s-app":"kubernetes-dashboard","k8s.deployment.name":"kubernetes-dashboard","k8s.deployment.uid":"4c1ee765-906b-498b-80b5-bea67a714fce","k8s.replicaset.name":"kubernetes-dashboard-6c7ccbcf87","k8s.replicasetuid":"e8c052b4-c1db-43bd-806d-f85d8a861f5b","k8s.service.kubernetes-dashboard":"","k8s.workload.kind":"Deployment","k8s.workload.name":"kubernetes-dashboard","pod-template-hash":"6c7ccbcf87","podcreation_timestamp":"2023-06-30T11:32:00-04:00"}) Trace ID: Span ID: Flags: 0 ``` --- pkg/experimentalmetricmetadata/entity_events.go | 10 ++++++++++ .../entity_events_test.go | 11 +++++++++++ .../internal/metadata/entities.go | 6 +++++- .../internal/metadata/entities_test.go | 6 +++++- receiver/k8sclusterreceiver/watcher.go | 6 ++++-- receiver/k8sclusterreceiver/watcher_test.go | 13 +++++++++++++ 6 files changed, 48 insertions(+), 4 deletions(-) diff --git a/pkg/experimentalmetricmetadata/entity_events.go b/pkg/experimentalmetricmetadata/entity_events.go index 5edb703cc8aa..3dd14864b668 100644 --- a/pkg/experimentalmetricmetadata/entity_events.go +++ b/pkg/experimentalmetricmetadata/entity_events.go @@ -75,6 +75,16 @@ type EntityEvent struct { orig plog.LogRecord } +// Timestamp of the event. +func (e EntityEvent) Timestamp() pcommon.Timestamp { + return e.orig.Timestamp() +} + +// SetTimestamp sets the event timestamp. +func (e EntityEvent) SetTimestamp(timestamp pcommon.Timestamp) { + e.orig.SetTimestamp(timestamp) +} + // ID of the entity. func (e EntityEvent) ID() pcommon.Map { m, ok := e.orig.Attributes().Get(semconvOtelEntityID) diff --git a/pkg/experimentalmetricmetadata/entity_events_test.go b/pkg/experimentalmetricmetadata/entity_events_test.go index 7ded1c7bb503..b76c6dcd2060 100644 --- a/pkg/experimentalmetricmetadata/entity_events_test.go +++ b/pkg/experimentalmetricmetadata/entity_events_test.go @@ -5,8 +5,10 @@ package experimentalmetricmetadata import ( "testing" + "time" "github.com/stretchr/testify/assert" + "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/pdata/plog" ) @@ -126,3 +128,12 @@ func Test_EntityTypeEmpty(t *testing.T) { e := EntityStateDetails{lr} assert.Equal(t, "", e.EntityType()) } + +func Test_EntityEventTimestamp(t *testing.T) { + lr := plog.NewLogRecord() + e := EntityEvent{lr} + ts := pcommon.NewTimestampFromTime(time.Now()) + e.SetTimestamp(ts) + assert.EqualValues(t, ts, e.Timestamp()) + assert.EqualValues(t, ts, lr.Timestamp()) +} diff --git a/receiver/k8sclusterreceiver/internal/metadata/entities.go b/receiver/k8sclusterreceiver/internal/metadata/entities.go index fd955584be04..ca3bb1295001 100644 --- a/receiver/k8sclusterreceiver/internal/metadata/entities.go +++ b/receiver/k8sclusterreceiver/internal/metadata/entities.go @@ -4,17 +4,20 @@ package metadata // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/metadata" import ( + "go.opentelemetry.io/collector/pdata/pcommon" + metadataPkg "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/experimentalmetricmetadata" ) // GetEntityEvents processes metadata updates and returns entity events that describe the metadata changes. -func GetEntityEvents(old, new map[metadataPkg.ResourceID]*KubernetesMetadata) metadataPkg.EntityEventsSlice { +func GetEntityEvents(old, new map[metadataPkg.ResourceID]*KubernetesMetadata, timestamp pcommon.Timestamp) metadataPkg.EntityEventsSlice { out := metadataPkg.NewEntityEventsSlice() for id, oldObj := range old { if _, ok := new[id]; !ok { // An object was present, but no longer is. Create a "delete" event. entityEvent := out.AppendEmpty() + entityEvent.SetTimestamp(timestamp) entityEvent.ID().PutStr(oldObj.ResourceIDKey, string(oldObj.ResourceID)) entityEvent.SetEntityDelete() } @@ -23,6 +26,7 @@ func GetEntityEvents(old, new map[metadataPkg.ResourceID]*KubernetesMetadata) me // All "new" are current objects. Create "state" events. "old" state does not matter. for _, newObj := range new { entityEvent := out.AppendEmpty() + entityEvent.SetTimestamp(timestamp) entityEvent.ID().PutStr(newObj.ResourceIDKey, string(newObj.ResourceID)) state := entityEvent.SetEntityState() state.SetEntityType(newObj.EntityType) diff --git a/receiver/k8sclusterreceiver/internal/metadata/entities_test.go b/receiver/k8sclusterreceiver/internal/metadata/entities_test.go index 5061d22c3cb7..e27fb52e39d4 100644 --- a/receiver/k8sclusterreceiver/internal/metadata/entities_test.go +++ b/receiver/k8sclusterreceiver/internal/metadata/entities_test.go @@ -5,9 +5,11 @@ package metadata // import "github.com/open-telemetry/opentelemetry-collector-co import ( "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/pdata/pcommon" metadataPkg "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/experimentalmetricmetadata" ) @@ -187,11 +189,13 @@ func Test_GetEntityEvents(t *testing.T) { } // Convert and test expected events. - events := GetEntityEvents(tt.old, tt.new) + timestamp := pcommon.NewTimestampFromTime(time.Now()) + events := GetEntityEvents(tt.old, tt.new, timestamp) require.Equal(t, tt.events.Len(), events.Len()) for i := 0; i < events.Len(); i++ { actual := events.At(i) expected := tt.events.At(i) + assert.EqualValues(t, timestamp, actual.Timestamp()) assert.EqualValues(t, expected.EventType(), actual.EventType()) assert.EqualValues(t, expected.ID().AsRaw(), actual.ID().AsRaw()) if expected.EventType() == metadataPkg.EventTypeState { diff --git a/receiver/k8sclusterreceiver/watcher.go b/receiver/k8sclusterreceiver/watcher.go index ada240927c60..824803602e88 100644 --- a/receiver/k8sclusterreceiver/watcher.go +++ b/receiver/k8sclusterreceiver/watcher.go @@ -14,6 +14,7 @@ import ( quotainformersv1 "github.com/openshift/client-go/quota/informers/externalversions" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/consumer" + "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/receiver" "go.uber.org/zap" "go.uber.org/zap/zapcore" @@ -343,6 +344,8 @@ func validateMetadataExporters(metadataExporters map[string]bool, exporters map[ } func (rw *resourceWatcher) syncMetadataUpdate(oldMetadata, newMetadata map[experimentalmetricmetadata.ResourceID]*metadata.KubernetesMetadata) { + timestamp := pcommon.NewTimestampFromTime(time.Now()) + metadataUpdate := metadata.GetMetadataUpdate(oldMetadata, newMetadata) if len(metadataUpdate) != 0 { for _, consume := range rw.metadataConsumers { @@ -352,8 +355,7 @@ func (rw *resourceWatcher) syncMetadataUpdate(oldMetadata, newMetadata map[exper if rw.entityLogConsumer != nil { // Represent metadata update as entity events. - // TODO: record the timestamp in the events. - entityEvents := metadata.GetEntityEvents(oldMetadata, newMetadata) + entityEvents := metadata.GetEntityEvents(oldMetadata, newMetadata, timestamp) // Convert entity events to log representation. logs := entityEvents.ConvertAndMoveToLogs() diff --git a/receiver/k8sclusterreceiver/watcher_test.go b/receiver/k8sclusterreceiver/watcher_test.go index 28ec630023e1..19a5f7f81d15 100644 --- a/receiver/k8sclusterreceiver/watcher_test.go +++ b/receiver/k8sclusterreceiver/watcher_test.go @@ -5,6 +5,7 @@ package k8sclusterreceiver import ( "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -236,25 +237,32 @@ func TestSyncMetadataAndEmitEntityEvents(t *testing.T) { rw := newResourceWatcher(receivertest.NewNopCreateSettings(), &Config{}) rw.entityLogConsumer = logsConsumer + step1 := time.Now() + // Make some changes to the pod. Each change should result in an entity event represented // as a log record. // Pod is created. rw.syncMetadataUpdate(nil, rw.dataCollector.SyncMetadata(origPod)) + step2 := time.Now() // Pod is updated. rw.syncMetadataUpdate(rw.dataCollector.SyncMetadata(origPod), rw.dataCollector.SyncMetadata(updatedPod)) + step3 := time.Now() // Pod is updated again, but nothing changed in the pod. // Should still result in entity event because they are emitted even // if the entity is not changed. rw.syncMetadataUpdate(rw.dataCollector.SyncMetadata(updatedPod), rw.dataCollector.SyncMetadata(updatedPod)) + step4 := time.Now() // Change pod's state back to original rw.syncMetadataUpdate(rw.dataCollector.SyncMetadata(updatedPod), rw.dataCollector.SyncMetadata(origPod)) + step5 := time.Now() // Delete the pod rw.syncMetadataUpdate(rw.dataCollector.SyncMetadata(origPod), nil) + step6 := time.Now() // Must have 5 entity events. require.EqualValues(t, 5, logsConsumer.LogRecordCount()) @@ -268,22 +276,26 @@ func TestSyncMetadataAndEmitEntityEvents(t *testing.T) { "otel.entity.attributes": map[string]any{"pod.creation_timestamp": "0001-01-01T00:00:00Z"}, } assert.EqualValues(t, expected, lr.Attributes().AsRaw()) + assert.WithinRange(t, lr.Timestamp().AsTime(), step1, step2) // Event 2 should contain the updated state of the pod. lr = logsConsumer.AllLogs()[1].ResourceLogs().At(0).ScopeLogs().At(0).LogRecords().At(0) attrs := expected["otel.entity.attributes"].(map[string]any) attrs["key"] = "value" assert.EqualValues(t, expected, lr.Attributes().AsRaw()) + assert.WithinRange(t, lr.Timestamp().AsTime(), step2, step3) // Event 3 should be identical to the previous one since pod state didn't change. lr = logsConsumer.AllLogs()[2].ResourceLogs().At(0).ScopeLogs().At(0).LogRecords().At(0) assert.EqualValues(t, expected, lr.Attributes().AsRaw()) + assert.WithinRange(t, lr.Timestamp().AsTime(), step3, step4) // Event 4 should contain the reverted state of the pod. lr = logsConsumer.AllLogs()[3].ResourceLogs().At(0).ScopeLogs().At(0).LogRecords().At(0) attrs = expected["otel.entity.attributes"].(map[string]any) delete(attrs, "key") assert.EqualValues(t, expected, lr.Attributes().AsRaw()) + assert.WithinRange(t, lr.Timestamp().AsTime(), step4, step5) // Event 5 should indicate pod deletion. lr = logsConsumer.AllLogs()[4].ResourceLogs().At(0).ScopeLogs().At(0).LogRecords().At(0) @@ -292,4 +304,5 @@ func TestSyncMetadataAndEmitEntityEvents(t *testing.T) { "otel.entity.id": map[string]any{"k8s.pod.uid": "pod0"}, } assert.EqualValues(t, expected, lr.Attributes().AsRaw()) + assert.WithinRange(t, lr.Timestamp().AsTime(), step5, step6) } From 64e6a5e6603da612a13df281156691c0da4fe7b2 Mon Sep 17 00:00:00 2001 From: bryan-aguilar <46550959+bryan-aguilar@users.noreply.github.com> Date: Fri, 21 Jul 2023 16:12:35 -0700 Subject: [PATCH 16/42] [chore] Reenable tests and linting disabled due to testconainters-go issue (#24247) **Description:** Dependent on https://github.com/testcontainers/testcontainers-go/issues/1359 being resolved. Enable tests that were skipped in #24213 **Link to tracking Issue:** https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24240 --- extension/observer/dockerobserver/go.mod | 3 +++ extension/observer/dockerobserver/go.sum | 4 ++-- extension/observer/dockerobserver/integration_test.go | 4 ---- internal/coreinternal/go.mod | 3 +++ internal/coreinternal/go.sum | 4 ++-- internal/coreinternal/scraperinttest/scraperint.go | 2 -- receiver/aerospikereceiver/go.mod | 3 +++ receiver/aerospikereceiver/go.sum | 4 ++-- receiver/apachereceiver/go.mod | 3 +++ receiver/apachereceiver/go.sum | 4 ++-- receiver/apachesparkreceiver/go.mod | 3 +++ receiver/apachesparkreceiver/go.sum | 4 ++-- receiver/bigipreceiver/go.mod | 3 +++ receiver/bigipreceiver/go.sum | 4 ++-- receiver/dockerstatsreceiver/go.mod | 3 +++ receiver/dockerstatsreceiver/go.sum | 4 ++-- receiver/dockerstatsreceiver/integration_test.go | 5 ----- receiver/elasticsearchreceiver/go.mod | 3 +++ receiver/elasticsearchreceiver/go.sum | 4 ++-- receiver/flinkmetricsreceiver/go.mod | 3 +++ receiver/flinkmetricsreceiver/go.sum | 4 ++-- receiver/iisreceiver/go.mod | 3 +++ receiver/iisreceiver/go.sum | 4 ++-- receiver/jmxreceiver/go.mod | 3 +++ receiver/jmxreceiver/go.sum | 4 ++-- receiver/kafkametricsreceiver/go.mod | 3 +++ receiver/kafkametricsreceiver/go.sum | 4 ++-- receiver/memcachedreceiver/go.mod | 3 +++ receiver/memcachedreceiver/go.sum | 4 ++-- receiver/mongodbreceiver/go.mod | 3 +++ receiver/mongodbreceiver/go.sum | 4 ++-- receiver/mysqlreceiver/go.mod | 3 +++ receiver/mysqlreceiver/go.sum | 4 ++-- receiver/nginxreceiver/go.mod | 3 +++ receiver/nginxreceiver/go.sum | 4 ++-- receiver/postgresqlreceiver/go.mod | 3 +++ receiver/postgresqlreceiver/go.sum | 4 ++-- receiver/redisreceiver/go.mod | 3 +++ receiver/redisreceiver/go.sum | 4 ++-- receiver/snmpreceiver/go.mod | 3 +++ receiver/snmpreceiver/go.sum | 4 ++-- receiver/snmpreceiver/integration_test.go | 1 - receiver/sqlqueryreceiver/go.mod | 3 +++ receiver/sqlqueryreceiver/go.sum | 4 ++-- receiver/sqlqueryreceiver/integration_test.go | 1 - receiver/vcenterreceiver/go.mod | 3 +++ receiver/vcenterreceiver/go.sum | 4 ++-- receiver/zookeeperreceiver/go.mod | 3 +++ receiver/zookeeperreceiver/go.sum | 4 ++-- 49 files changed, 110 insertions(+), 57 deletions(-) diff --git a/extension/observer/dockerobserver/go.mod b/extension/observer/dockerobserver/go.mod index a6cbef624d34..ac3fa4860fe1 100644 --- a/extension/observer/dockerobserver/go.mod +++ b/extension/observer/dockerobserver/go.mod @@ -75,6 +75,9 @@ replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/commo // see https://github.com/distribution/distribution/issues/3590 exclude github.com/docker/distribution v2.8.0+incompatible +// see https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24240 +replace github.com/docker/docker v24.0.4+incompatible => github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible + retract ( v0.76.2 v0.76.1 diff --git a/extension/observer/dockerobserver/go.sum b/extension/observer/dockerobserver/go.sum index c21730a9f1ed..eaba9c019ee7 100644 --- a/extension/observer/dockerobserver/go.sum +++ b/extension/observer/dockerobserver/go.sum @@ -57,8 +57,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.4+incompatible h1:s/LVDftw9hjblvqIeTiGYXBCD95nOEEl7qRsRrIOuQI= -github.com/docker/docker v24.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible h1:VhUBTFg4uUWtZORx5FXU5KxlOxsXKAIELtlczNyHlfM= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.1-0.20210727194412-58542c764a11 h1:IPrmumsT9t5BS7XcPhgsCTlkWbYg80SEXUzDpReaU6Y= github.com/docker/go-connections v0.4.1-0.20210727194412-58542c764a11/go.mod h1:a6bNUGTbQBsY6VRHTr4h/rkOXjl244DyRD0tx3fgq4Q= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/extension/observer/dockerobserver/integration_test.go b/extension/observer/dockerobserver/integration_test.go index 62729c5ebaf1..dd431c8e2d64 100644 --- a/extension/observer/dockerobserver/integration_test.go +++ b/extension/observer/dockerobserver/integration_test.go @@ -36,7 +36,6 @@ func (h *testHost) ReportFatalError(err error) { var _ component.Host = (*testHost)(nil) func TestObserverEmitsEndpointsIntegration(t *testing.T) { - t.Skip("See https://github.com/testcontainers/testcontainers-go/issues/1359") image := "docker.io/library/nginx" tag := "1.17" @@ -83,7 +82,6 @@ func TestObserverEmitsEndpointsIntegration(t *testing.T) { } func TestObserverUpdatesEndpointsIntegration(t *testing.T) { - t.Skip("See https://github.com/testcontainers/testcontainers-go/issues/1359") image := "docker.io/library/nginx" tag := "1.17" @@ -145,7 +143,6 @@ func TestObserverUpdatesEndpointsIntegration(t *testing.T) { } func TestObserverRemovesEndpointsIntegration(t *testing.T) { - t.Skip("See https://github.com/testcontainers/testcontainers-go/issues/1359") image := "docker.io/library/nginx" tag := "1.17" @@ -188,7 +185,6 @@ func TestObserverRemovesEndpointsIntegration(t *testing.T) { } func TestObserverExcludesImagesIntegration(t *testing.T) { - t.Skip("See https://github.com/testcontainers/testcontainers-go/issues/1359") ctx := context.Background() req := testcontainers.ContainerRequest{ Image: "docker.io/library/nginx:1.17", diff --git a/internal/coreinternal/go.mod b/internal/coreinternal/go.mod index 2bb83d8f965e..bba1e8ef8fc0 100644 --- a/internal/coreinternal/go.mod +++ b/internal/coreinternal/go.mod @@ -79,3 +79,6 @@ retract ( replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil => ../../pkg/pdatautil replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest => ../../pkg/pdatatest + +// see https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24240 +replace github.com/docker/docker v24.0.4+incompatible => github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible diff --git a/internal/coreinternal/go.sum b/internal/coreinternal/go.sum index 4d4184219fa8..a62a56f40822 100644 --- a/internal/coreinternal/go.sum +++ b/internal/coreinternal/go.sum @@ -58,8 +58,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.4+incompatible h1:s/LVDftw9hjblvqIeTiGYXBCD95nOEEl7qRsRrIOuQI= -github.com/docker/docker v24.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible h1:VhUBTFg4uUWtZORx5FXU5KxlOxsXKAIELtlczNyHlfM= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/internal/coreinternal/scraperinttest/scraperint.go b/internal/coreinternal/scraperinttest/scraperint.go index 11e991d7aefd..de4def2c89b7 100644 --- a/internal/coreinternal/scraperinttest/scraperint.go +++ b/internal/coreinternal/scraperinttest/scraperint.go @@ -143,7 +143,6 @@ func (it *IntegrationTest) Run(t *testing.T) { } func (it *IntegrationTest) createNetwork(t *testing.T) testcontainers.Network { - t.Skip("See https://github.com/testcontainers/testcontainers-go/issues/1359") var errs error var network testcontainers.Network @@ -164,7 +163,6 @@ func (it *IntegrationTest) createNetwork(t *testing.T) testcontainers.Network { } func (it *IntegrationTest) createContainers(t *testing.T) *ContainerInfo { - t.Skip("See https://github.com/testcontainers/testcontainers-go/issues/1359") var wg sync.WaitGroup ci := &ContainerInfo{ containers: make(map[string]testcontainers.Container, len(it.containerRequests)), diff --git a/receiver/aerospikereceiver/go.mod b/receiver/aerospikereceiver/go.mod index ba0d04d85a7d..0722e83f25e5 100644 --- a/receiver/aerospikereceiver/go.mod +++ b/receiver/aerospikereceiver/go.mod @@ -93,3 +93,6 @@ retract ( v0.76.1 v0.65.0 ) + +// see https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24240 +replace github.com/docker/docker v24.0.4+incompatible => github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible diff --git a/receiver/aerospikereceiver/go.sum b/receiver/aerospikereceiver/go.sum index c51b3ec40b7e..4959d440e0b8 100644 --- a/receiver/aerospikereceiver/go.sum +++ b/receiver/aerospikereceiver/go.sum @@ -65,8 +65,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.4+incompatible h1:s/LVDftw9hjblvqIeTiGYXBCD95nOEEl7qRsRrIOuQI= -github.com/docker/docker v24.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible h1:VhUBTFg4uUWtZORx5FXU5KxlOxsXKAIELtlczNyHlfM= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/receiver/apachereceiver/go.mod b/receiver/apachereceiver/go.mod index 56674316942f..7349109d0610 100644 --- a/receiver/apachereceiver/go.mod +++ b/receiver/apachereceiver/go.mod @@ -101,3 +101,6 @@ retract ( v0.76.1 v0.65.0 ) + +// see https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24240 +replace github.com/docker/docker v24.0.4+incompatible => github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible diff --git a/receiver/apachereceiver/go.sum b/receiver/apachereceiver/go.sum index 99d0d45a90d4..5e87f1519a33 100644 --- a/receiver/apachereceiver/go.sum +++ b/receiver/apachereceiver/go.sum @@ -60,8 +60,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.4+incompatible h1:s/LVDftw9hjblvqIeTiGYXBCD95nOEEl7qRsRrIOuQI= -github.com/docker/docker v24.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible h1:VhUBTFg4uUWtZORx5FXU5KxlOxsXKAIELtlczNyHlfM= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/receiver/apachesparkreceiver/go.mod b/receiver/apachesparkreceiver/go.mod index 413b17ef72dd..84522b8d2c7c 100644 --- a/receiver/apachesparkreceiver/go.mod +++ b/receiver/apachesparkreceiver/go.mod @@ -95,3 +95,6 @@ replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal => ../../internal/coreinternal replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil => ../../pkg/pdatautil + +// see https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24240 +replace github.com/docker/docker v24.0.4+incompatible => github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible diff --git a/receiver/apachesparkreceiver/go.sum b/receiver/apachesparkreceiver/go.sum index d8bd86e3a666..096e946f840f 100644 --- a/receiver/apachesparkreceiver/go.sum +++ b/receiver/apachesparkreceiver/go.sum @@ -60,8 +60,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.4+incompatible h1:s/LVDftw9hjblvqIeTiGYXBCD95nOEEl7qRsRrIOuQI= -github.com/docker/docker v24.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible h1:VhUBTFg4uUWtZORx5FXU5KxlOxsXKAIELtlczNyHlfM= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/receiver/bigipreceiver/go.mod b/receiver/bigipreceiver/go.mod index 35e414647eb6..a6e9762ca9ff 100644 --- a/receiver/bigipreceiver/go.mod +++ b/receiver/bigipreceiver/go.mod @@ -101,3 +101,6 @@ retract ( v0.76.1 v0.65.0 ) + +// see https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24240 +replace github.com/docker/docker v24.0.4+incompatible => github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible diff --git a/receiver/bigipreceiver/go.sum b/receiver/bigipreceiver/go.sum index d8bd86e3a666..096e946f840f 100644 --- a/receiver/bigipreceiver/go.sum +++ b/receiver/bigipreceiver/go.sum @@ -60,8 +60,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.4+incompatible h1:s/LVDftw9hjblvqIeTiGYXBCD95nOEEl7qRsRrIOuQI= -github.com/docker/docker v24.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible h1:VhUBTFg4uUWtZORx5FXU5KxlOxsXKAIELtlczNyHlfM= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/receiver/dockerstatsreceiver/go.mod b/receiver/dockerstatsreceiver/go.mod index e2bcca7e006f..f50f5cc9d44c 100644 --- a/receiver/dockerstatsreceiver/go.mod +++ b/receiver/dockerstatsreceiver/go.mod @@ -95,3 +95,6 @@ retract ( v0.76.1 v0.65.0 ) + +// see https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24240 +replace github.com/docker/docker v24.0.4+incompatible => github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible diff --git a/receiver/dockerstatsreceiver/go.sum b/receiver/dockerstatsreceiver/go.sum index f0ee9677673c..922d19c0e1c5 100644 --- a/receiver/dockerstatsreceiver/go.sum +++ b/receiver/dockerstatsreceiver/go.sum @@ -61,8 +61,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.4+incompatible h1:s/LVDftw9hjblvqIeTiGYXBCD95nOEEl7qRsRrIOuQI= -github.com/docker/docker v24.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible h1:VhUBTFg4uUWtZORx5FXU5KxlOxsXKAIELtlczNyHlfM= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/receiver/dockerstatsreceiver/integration_test.go b/receiver/dockerstatsreceiver/integration_test.go index c81e69c213bf..0feb94bbe155 100644 --- a/receiver/dockerstatsreceiver/integration_test.go +++ b/receiver/dockerstatsreceiver/integration_test.go @@ -53,7 +53,6 @@ func paramsAndContext(t *testing.T) (rcvr.CreateSettings, context.Context, conte } func createNginxContainer(ctx context.Context, t *testing.T) testcontainers.Container { - t.Skip("See https://github.com/testcontainers/testcontainers-go/issues/1359") req := testcontainers.ContainerRequest{ Image: "docker.io/library/nginx:1.17", ExposedPorts: []string{"80/tcp"}, @@ -86,8 +85,6 @@ func hasResourceScopeMetrics(containerID string, metrics []pmetric.Metrics) bool func TestDefaultMetricsIntegration(t *testing.T) { t.Parallel() - // remove nolint when https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24240 is resolved - // nolint:staticcheck params, ctx, cancel := paramsAndContext(t) defer cancel() @@ -142,8 +139,6 @@ func TestMonitoringAddedAndRemovedContainerIntegration(t *testing.T) { func TestExcludedImageProducesNoMetricsIntegration(t *testing.T) { t.Parallel() - // remove nolint when https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24240 is resolved - // nolint:staticcheck params, ctx, cancel := paramsAndContext(t) defer cancel() diff --git a/receiver/elasticsearchreceiver/go.mod b/receiver/elasticsearchreceiver/go.mod index ce823cf6b1a3..706ac912fc42 100644 --- a/receiver/elasticsearchreceiver/go.mod +++ b/receiver/elasticsearchreceiver/go.mod @@ -98,6 +98,9 @@ replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal => ../../internal/coreinternal +// see https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24240 +replace github.com/docker/docker v24.0.4+incompatible => github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible + retract ( v0.76.2 v0.76.1 diff --git a/receiver/elasticsearchreceiver/go.sum b/receiver/elasticsearchreceiver/go.sum index bb1ae17703b6..ad89c684b940 100644 --- a/receiver/elasticsearchreceiver/go.sum +++ b/receiver/elasticsearchreceiver/go.sum @@ -60,8 +60,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.4+incompatible h1:s/LVDftw9hjblvqIeTiGYXBCD95nOEEl7qRsRrIOuQI= -github.com/docker/docker v24.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible h1:VhUBTFg4uUWtZORx5FXU5KxlOxsXKAIELtlczNyHlfM= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/receiver/flinkmetricsreceiver/go.mod b/receiver/flinkmetricsreceiver/go.mod index 80c991be6702..ebee4eaf2e23 100644 --- a/receiver/flinkmetricsreceiver/go.mod +++ b/receiver/flinkmetricsreceiver/go.mod @@ -97,6 +97,9 @@ replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal => ../../internal/coreinternal +// see https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24240 +replace github.com/docker/docker v24.0.4+incompatible => github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible + retract ( v0.76.2 v0.76.1 diff --git a/receiver/flinkmetricsreceiver/go.sum b/receiver/flinkmetricsreceiver/go.sum index e0e7505621c2..888bbf9eb850 100644 --- a/receiver/flinkmetricsreceiver/go.sum +++ b/receiver/flinkmetricsreceiver/go.sum @@ -60,8 +60,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.4+incompatible h1:s/LVDftw9hjblvqIeTiGYXBCD95nOEEl7qRsRrIOuQI= -github.com/docker/docker v24.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible h1:VhUBTFg4uUWtZORx5FXU5KxlOxsXKAIELtlczNyHlfM= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/receiver/iisreceiver/go.mod b/receiver/iisreceiver/go.mod index 58461137944d..2fa2cf637603 100644 --- a/receiver/iisreceiver/go.mod +++ b/receiver/iisreceiver/go.mod @@ -83,6 +83,9 @@ replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal => ../../internal/coreinternal +// see https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24240 +replace github.com/docker/docker v24.0.4+incompatible => github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible + retract ( v0.76.2 v0.76.1 diff --git a/receiver/iisreceiver/go.sum b/receiver/iisreceiver/go.sum index a05e1dfab26e..cde6d61808ac 100644 --- a/receiver/iisreceiver/go.sum +++ b/receiver/iisreceiver/go.sum @@ -60,8 +60,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.4+incompatible h1:s/LVDftw9hjblvqIeTiGYXBCD95nOEEl7qRsRrIOuQI= -github.com/docker/docker v24.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible h1:VhUBTFg4uUWtZORx5FXU5KxlOxsXKAIELtlczNyHlfM= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/receiver/jmxreceiver/go.mod b/receiver/jmxreceiver/go.mod index 00468383951f..daee6877ca24 100644 --- a/receiver/jmxreceiver/go.mod +++ b/receiver/jmxreceiver/go.mod @@ -120,3 +120,6 @@ replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/corei // ambiguous import: found package cloud.google.com/go/compute/metadata in multiple modules replace cloud.google.com/go v0.34.0 => cloud.google.com/go v0.110.2 + +// see https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24240 +replace github.com/docker/docker v24.0.4+incompatible => github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible diff --git a/receiver/jmxreceiver/go.sum b/receiver/jmxreceiver/go.sum index ee8e5608d03a..09de2763db5b 100644 --- a/receiver/jmxreceiver/go.sum +++ b/receiver/jmxreceiver/go.sum @@ -689,8 +689,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.4+incompatible h1:s/LVDftw9hjblvqIeTiGYXBCD95nOEEl7qRsRrIOuQI= -github.com/docker/docker v24.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible h1:VhUBTFg4uUWtZORx5FXU5KxlOxsXKAIELtlczNyHlfM= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/receiver/kafkametricsreceiver/go.mod b/receiver/kafkametricsreceiver/go.mod index 741074190645..d0895062eb27 100644 --- a/receiver/kafkametricsreceiver/go.mod +++ b/receiver/kafkametricsreceiver/go.mod @@ -127,3 +127,6 @@ retract ( replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil => ../../pkg/pdatautil replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest => ../../pkg/pdatatest + +// see https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24240 +replace github.com/docker/docker v24.0.4+incompatible => github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible diff --git a/receiver/kafkametricsreceiver/go.sum b/receiver/kafkametricsreceiver/go.sum index f4fa1dce5fdf..671a65cff45d 100644 --- a/receiver/kafkametricsreceiver/go.sum +++ b/receiver/kafkametricsreceiver/go.sum @@ -68,8 +68,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.4+incompatible h1:s/LVDftw9hjblvqIeTiGYXBCD95nOEEl7qRsRrIOuQI= -github.com/docker/docker v24.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible h1:VhUBTFg4uUWtZORx5FXU5KxlOxsXKAIELtlczNyHlfM= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/receiver/memcachedreceiver/go.mod b/receiver/memcachedreceiver/go.mod index e0df90ca4f7f..8d59ce55a285 100644 --- a/receiver/memcachedreceiver/go.mod +++ b/receiver/memcachedreceiver/go.mod @@ -91,3 +91,6 @@ retract ( v0.76.1 v0.65.0 ) + +// see https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24240 +replace github.com/docker/docker v24.0.4+incompatible => github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible diff --git a/receiver/memcachedreceiver/go.sum b/receiver/memcachedreceiver/go.sum index facc25a13e98..f72e429d1f97 100644 --- a/receiver/memcachedreceiver/go.sum +++ b/receiver/memcachedreceiver/go.sum @@ -61,8 +61,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.4+incompatible h1:s/LVDftw9hjblvqIeTiGYXBCD95nOEEl7qRsRrIOuQI= -github.com/docker/docker v24.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible h1:VhUBTFg4uUWtZORx5FXU5KxlOxsXKAIELtlczNyHlfM= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.1-0.20210727194412-58542c764a11 h1:IPrmumsT9t5BS7XcPhgsCTlkWbYg80SEXUzDpReaU6Y= github.com/docker/go-connections v0.4.1-0.20210727194412-58542c764a11/go.mod h1:a6bNUGTbQBsY6VRHTr4h/rkOXjl244DyRD0tx3fgq4Q= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/receiver/mongodbreceiver/go.mod b/receiver/mongodbreceiver/go.mod index f2853e3deaa2..b781c32812a7 100644 --- a/receiver/mongodbreceiver/go.mod +++ b/receiver/mongodbreceiver/go.mod @@ -101,3 +101,6 @@ retract ( v0.76.1 v0.65.0 ) + +// see https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24240 +replace github.com/docker/docker v24.0.4+incompatible => github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible diff --git a/receiver/mongodbreceiver/go.sum b/receiver/mongodbreceiver/go.sum index fcd0e7393b3b..db24efa514d8 100644 --- a/receiver/mongodbreceiver/go.sum +++ b/receiver/mongodbreceiver/go.sum @@ -60,8 +60,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.4+incompatible h1:s/LVDftw9hjblvqIeTiGYXBCD95nOEEl7qRsRrIOuQI= -github.com/docker/docker v24.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible h1:VhUBTFg4uUWtZORx5FXU5KxlOxsXKAIELtlczNyHlfM= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/receiver/mysqlreceiver/go.mod b/receiver/mysqlreceiver/go.mod index 718df24e4507..ef7d71a60cae 100644 --- a/receiver/mysqlreceiver/go.mod +++ b/receiver/mysqlreceiver/go.mod @@ -89,3 +89,6 @@ retract ( v0.76.1 v0.65.0 ) + +// see https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24240 +replace github.com/docker/docker v24.0.4+incompatible => github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible diff --git a/receiver/mysqlreceiver/go.sum b/receiver/mysqlreceiver/go.sum index 54892ca40ca3..ed7037bafde2 100644 --- a/receiver/mysqlreceiver/go.sum +++ b/receiver/mysqlreceiver/go.sum @@ -60,8 +60,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.4+incompatible h1:s/LVDftw9hjblvqIeTiGYXBCD95nOEEl7qRsRrIOuQI= -github.com/docker/docker v24.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible h1:VhUBTFg4uUWtZORx5FXU5KxlOxsXKAIELtlczNyHlfM= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/receiver/nginxreceiver/go.mod b/receiver/nginxreceiver/go.mod index d28dfa25b304..e7ed52f80685 100644 --- a/receiver/nginxreceiver/go.mod +++ b/receiver/nginxreceiver/go.mod @@ -102,3 +102,6 @@ retract ( v0.76.1 v0.65.0 ) + +// see https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24240 +replace github.com/docker/docker v24.0.4+incompatible => github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible diff --git a/receiver/nginxreceiver/go.sum b/receiver/nginxreceiver/go.sum index 470b7604f3c3..1536b0289aa4 100644 --- a/receiver/nginxreceiver/go.sum +++ b/receiver/nginxreceiver/go.sum @@ -60,8 +60,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.4+incompatible h1:s/LVDftw9hjblvqIeTiGYXBCD95nOEEl7qRsRrIOuQI= -github.com/docker/docker v24.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible h1:VhUBTFg4uUWtZORx5FXU5KxlOxsXKAIELtlczNyHlfM= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/receiver/postgresqlreceiver/go.mod b/receiver/postgresqlreceiver/go.mod index de407aa53e31..3b3937618892 100644 --- a/receiver/postgresqlreceiver/go.mod +++ b/receiver/postgresqlreceiver/go.mod @@ -92,3 +92,6 @@ retract ( v0.76.1 v0.65.0 ) + +// see https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24240 +replace github.com/docker/docker v24.0.4+incompatible => github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible diff --git a/receiver/postgresqlreceiver/go.sum b/receiver/postgresqlreceiver/go.sum index eec5b7a9f435..4a726e432ec3 100644 --- a/receiver/postgresqlreceiver/go.sum +++ b/receiver/postgresqlreceiver/go.sum @@ -60,8 +60,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.4+incompatible h1:s/LVDftw9hjblvqIeTiGYXBCD95nOEEl7qRsRrIOuQI= -github.com/docker/docker v24.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible h1:VhUBTFg4uUWtZORx5FXU5KxlOxsXKAIELtlczNyHlfM= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/receiver/redisreceiver/go.mod b/receiver/redisreceiver/go.mod index da7fc894fbf0..900a8c7faca1 100644 --- a/receiver/redisreceiver/go.mod +++ b/receiver/redisreceiver/go.mod @@ -96,3 +96,6 @@ replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal => ../../internal/coreinternal replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest => ../../pkg/pdatatest + +// see https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24240 +replace github.com/docker/docker v24.0.4+incompatible => github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible diff --git a/receiver/redisreceiver/go.sum b/receiver/redisreceiver/go.sum index 6809a8f91b3a..d12040f70141 100644 --- a/receiver/redisreceiver/go.sum +++ b/receiver/redisreceiver/go.sum @@ -61,8 +61,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.4+incompatible h1:s/LVDftw9hjblvqIeTiGYXBCD95nOEEl7qRsRrIOuQI= -github.com/docker/docker v24.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible h1:VhUBTFg4uUWtZORx5FXU5KxlOxsXKAIELtlczNyHlfM= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.1-0.20210727194412-58542c764a11 h1:IPrmumsT9t5BS7XcPhgsCTlkWbYg80SEXUzDpReaU6Y= github.com/docker/go-connections v0.4.1-0.20210727194412-58542c764a11/go.mod h1:a6bNUGTbQBsY6VRHTr4h/rkOXjl244DyRD0tx3fgq4Q= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/receiver/snmpreceiver/go.mod b/receiver/snmpreceiver/go.mod index f85d10dccdc2..bd72501b0e92 100644 --- a/receiver/snmpreceiver/go.mod +++ b/receiver/snmpreceiver/go.mod @@ -122,3 +122,6 @@ retract ( v0.76.1 v0.65.0 ) + +// see https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24240 +replace github.com/docker/docker v24.0.4+incompatible => github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible diff --git a/receiver/snmpreceiver/go.sum b/receiver/snmpreceiver/go.sum index d21a5bfd9c40..b5df9cf46d1a 100644 --- a/receiver/snmpreceiver/go.sum +++ b/receiver/snmpreceiver/go.sum @@ -99,8 +99,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.4+incompatible h1:s/LVDftw9hjblvqIeTiGYXBCD95nOEEl7qRsRrIOuQI= -github.com/docker/docker v24.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible h1:VhUBTFg4uUWtZORx5FXU5KxlOxsXKAIELtlczNyHlfM= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/receiver/snmpreceiver/integration_test.go b/receiver/snmpreceiver/integration_test.go index 95fb887124b7..3ec919f21b04 100644 --- a/receiver/snmpreceiver/integration_test.go +++ b/receiver/snmpreceiver/integration_test.go @@ -96,7 +96,6 @@ var ( ) func getContainer(t *testing.T, req testcontainers.ContainerRequest) testcontainers.Container { - t.Skip("See https://github.com/testcontainers/testcontainers-go/issues/1359") require.NoError(t, req.Validate()) container, err := testcontainers.GenericContainer( context.Background(), diff --git a/receiver/sqlqueryreceiver/go.mod b/receiver/sqlqueryreceiver/go.mod index 9e44c3c4aef9..dc6137cbdede 100644 --- a/receiver/sqlqueryreceiver/go.mod +++ b/receiver/sqlqueryreceiver/go.mod @@ -138,3 +138,6 @@ replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest => ../../pkg/pdatatest replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza => ../../pkg/stanza + +// see https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24240 +replace github.com/docker/docker v24.0.4+incompatible => github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible diff --git a/receiver/sqlqueryreceiver/go.sum b/receiver/sqlqueryreceiver/go.sum index 4c1508398c65..92fd53566bac 100644 --- a/receiver/sqlqueryreceiver/go.sum +++ b/receiver/sqlqueryreceiver/go.sum @@ -146,8 +146,8 @@ github.com/denisenkom/go-mssqldb v0.12.2/go.mod h1:lnIw1mZukFRZDJYQ0Pb833QS2IaC3 github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.4+incompatible h1:s/LVDftw9hjblvqIeTiGYXBCD95nOEEl7qRsRrIOuQI= -github.com/docker/docker v24.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible h1:VhUBTFg4uUWtZORx5FXU5KxlOxsXKAIELtlczNyHlfM= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/receiver/sqlqueryreceiver/integration_test.go b/receiver/sqlqueryreceiver/integration_test.go index 0ec0d1fcc488..4fd470c2f909 100644 --- a/receiver/sqlqueryreceiver/integration_test.go +++ b/receiver/sqlqueryreceiver/integration_test.go @@ -248,7 +248,6 @@ func TestPostgresIntegrationLogsTrackingWithStorage(t *testing.T) { } func startPostgresDbContainer(t *testing.T, externalPort string) testcontainers.Container { - t.Skip("See https://github.com/testcontainers/testcontainers-go/issues/1359") req := testcontainers.ContainerRequest{ Image: "postgres:9.6.24", Env: map[string]string{ diff --git a/receiver/vcenterreceiver/go.mod b/receiver/vcenterreceiver/go.mod index f39fd63ba60a..217fd856c938 100644 --- a/receiver/vcenterreceiver/go.mod +++ b/receiver/vcenterreceiver/go.mod @@ -91,3 +91,6 @@ retract ( v0.76.1 v0.65.0 ) + +// see https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24240 +replace github.com/docker/docker v24.0.4+incompatible => github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible diff --git a/receiver/vcenterreceiver/go.sum b/receiver/vcenterreceiver/go.sum index e14359cd45e0..67d22589721a 100644 --- a/receiver/vcenterreceiver/go.sum +++ b/receiver/vcenterreceiver/go.sum @@ -64,8 +64,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.4+incompatible h1:s/LVDftw9hjblvqIeTiGYXBCD95nOEEl7qRsRrIOuQI= -github.com/docker/docker v24.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible h1:VhUBTFg4uUWtZORx5FXU5KxlOxsXKAIELtlczNyHlfM= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= diff --git a/receiver/zookeeperreceiver/go.mod b/receiver/zookeeperreceiver/go.mod index 7ee11ab645a0..372b7ce88fdc 100644 --- a/receiver/zookeeperreceiver/go.mod +++ b/receiver/zookeeperreceiver/go.mod @@ -93,3 +93,6 @@ retract ( v0.76.1 v0.65.0 ) + +// see https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24240 +replace github.com/docker/docker v24.0.4+incompatible => github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible diff --git a/receiver/zookeeperreceiver/go.sum b/receiver/zookeeperreceiver/go.sum index 3fc145b6c6f1..9be7c6a0e92f 100644 --- a/receiver/zookeeperreceiver/go.sum +++ b/receiver/zookeeperreceiver/go.sum @@ -61,8 +61,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.4+incompatible h1:s/LVDftw9hjblvqIeTiGYXBCD95nOEEl7qRsRrIOuQI= -github.com/docker/docker v24.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible h1:VhUBTFg4uUWtZORx5FXU5KxlOxsXKAIELtlczNyHlfM= +github.com/docker/docker v24.0.5-0.20230719162248-f022632503d1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.1-0.20210727194412-58542c764a11 h1:IPrmumsT9t5BS7XcPhgsCTlkWbYg80SEXUzDpReaU6Y= github.com/docker/go-connections v0.4.1-0.20210727194412-58542c764a11/go.mod h1:a6bNUGTbQBsY6VRHTr4h/rkOXjl244DyRD0tx3fgq4Q= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= From 55e2365e56a7359ad580f31bc4fcaeea2e23c27e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraci=20Paix=C3=A3o=20Kr=C3=B6hling?= Date: Fri, 21 Jul 2023 22:43:14 -0300 Subject: [PATCH 17/42] Add Grafana Agent to list of distributions (#24418) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds Grafana Agent as a distribution and mark the respective components as being present there. Signed-off-by: Juraci Paixão Kröhling --------- Signed-off-by: Juraci Paixão Kröhling --- cmd/mdatagen/statusdata.go | 3 ++- exporter/jaegerexporter/README.md | 3 ++- exporter/jaegerexporter/metadata.yaml | 6 +++++- exporter/loadbalancingexporter/README.md | 3 ++- exporter/loadbalancingexporter/metadata.yaml | 6 +++++- exporter/lokiexporter/metadata.yaml | 4 +++- exporter/prometheusexporter/README.md | 3 ++- exporter/prometheusexporter/metadata.yaml | 9 ++++++++- extension/basicauthextension/README.md | 3 ++- extension/basicauthextension/metadata.yaml | 7 ++++++- extension/bearertokenauthextension/README.md | 3 ++- extension/bearertokenauthextension/metadata.yaml | 7 ++++++- extension/headerssetterextension/README.md | 3 ++- extension/headerssetterextension/metadata.yaml | 5 ++++- extension/jaegerremotesampling/README.md | 3 ++- extension/jaegerremotesampling/metadata.yaml | 6 +++++- extension/oauth2clientauthextension/README.md | 3 ++- extension/oauth2clientauthextension/metadata.yaml | 6 +++++- extension/sigv4authextension/README.md | 3 ++- extension/sigv4authextension/metadata.yaml | 6 +++++- processor/attributesprocessor/README.md | 3 ++- processor/attributesprocessor/metadata.yaml | 10 +++++++++- processor/tailsamplingprocessor/README.md | 3 ++- processor/tailsamplingprocessor/metadata.yaml | 8 +++++++- receiver/jaegerreceiver/README.md | 3 ++- receiver/jaegerreceiver/metadata.yaml | 10 +++++++++- receiver/kafkareceiver/README.md | 3 ++- receiver/kafkareceiver/metadata.yaml | 9 +++++++-- receiver/lokireceiver/metadata.yaml | 4 +++- receiver/opencensusreceiver/README.md | 3 ++- receiver/opencensusreceiver/metadata.yaml | 8 +++++++- receiver/prometheusreceiver/README.md | 3 ++- receiver/prometheusreceiver/metadata.yaml | 10 ++++++++-- receiver/zipkinreceiver/README.md | 3 ++- receiver/zipkinreceiver/metadata.yaml | 10 +++++++++- 35 files changed, 145 insertions(+), 37 deletions(-) diff --git a/cmd/mdatagen/statusdata.go b/cmd/mdatagen/statusdata.go index 901f39806536..a0a13cc5fb97 100644 --- a/cmd/mdatagen/statusdata.go +++ b/cmd/mdatagen/statusdata.go @@ -15,10 +15,11 @@ var distros = map[string]string{ "core": "https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol", "contrib": "https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib", "aws": "https://github.com/aws-observability/aws-otel-collector", + "grafana": "https://github.com/grafana/agent", "observiq": "https://github.com/observIQ/observiq-otel-collector", + "redhat": "https://github.com/os-observability/redhat-opentelemetry-collector", "splunk": "https://github.com/signalfx/splunk-otel-collector", "sumo": "https://github.com/SumoLogic/sumologic-otel-collector", - "redhat": "https://github.com/os-observability/redhat-opentelemetry-collector", } type Codeowners struct { diff --git a/exporter/jaegerexporter/README.md b/exporter/jaegerexporter/README.md index 9ec8f27c2eaf..acbd9f260924 100644 --- a/exporter/jaegerexporter/README.md +++ b/exporter/jaegerexporter/README.md @@ -4,12 +4,13 @@ | Status | | | ------------- |-----------| | Stability | [deprecated]: traces | -| Distributions | [core], [contrib], [redhat] | +| Distributions | [core], [contrib], [grafana], [redhat] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fjaeger%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fjaeger%20&label=closed&color=blue&logo=opentelemetry) | [deprecated]: https://github.com/open-telemetry/opentelemetry-collector#deprecated [core]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib +[grafana]: https://github.com/grafana/agent [redhat]: https://github.com/os-observability/redhat-opentelemetry-collector diff --git a/exporter/jaegerexporter/metadata.yaml b/exporter/jaegerexporter/metadata.yaml index 535cae3aa632..9b8822ccec74 100644 --- a/exporter/jaegerexporter/metadata.yaml +++ b/exporter/jaegerexporter/metadata.yaml @@ -4,4 +4,8 @@ status: class: exporter stability: deprecated: [traces] - distributions: [core, contrib, redhat] + distributions: + - core + - contrib + - grafana + - redhat diff --git a/exporter/loadbalancingexporter/README.md b/exporter/loadbalancingexporter/README.md index 2d3484606d51..bf4f52b93581 100644 --- a/exporter/loadbalancingexporter/README.md +++ b/exporter/loadbalancingexporter/README.md @@ -4,11 +4,12 @@ | Status | | | ------------- |-----------| | Stability | [beta]: traces, logs | -| Distributions | [contrib], [observiq], [sumo] | +| Distributions | [contrib], [grafana], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Floadbalancing%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Floadbalancing%20&label=closed&color=blue&logo=opentelemetry) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib +[grafana]: https://github.com/grafana/agent [observiq]: https://github.com/observIQ/observiq-otel-collector [sumo]: https://github.com/SumoLogic/sumologic-otel-collector diff --git a/exporter/loadbalancingexporter/metadata.yaml b/exporter/loadbalancingexporter/metadata.yaml index 1bbe21e36af2..48a9f287c36a 100644 --- a/exporter/loadbalancingexporter/metadata.yaml +++ b/exporter/loadbalancingexporter/metadata.yaml @@ -4,4 +4,8 @@ status: class: exporter stability: beta: [traces, logs] - distributions: [contrib, observiq, sumo] + distributions: + - contrib + - grafana + - observiq + - sumo diff --git a/exporter/lokiexporter/metadata.yaml b/exporter/lokiexporter/metadata.yaml index 228611500489..1fa18abb7c35 100644 --- a/exporter/lokiexporter/metadata.yaml +++ b/exporter/lokiexporter/metadata.yaml @@ -4,4 +4,6 @@ status: class: exporter stability: beta: [logs] - distributions: [contrib, observiq] + distributions: + - contrib + - observiq diff --git a/exporter/prometheusexporter/README.md b/exporter/prometheusexporter/README.md index 298074f5a197..666d4a852785 100644 --- a/exporter/prometheusexporter/README.md +++ b/exporter/prometheusexporter/README.md @@ -4,13 +4,14 @@ | Status | | | ------------- |-----------| | Stability | [beta]: metrics | -| Distributions | [core], [contrib], [aws], [observiq], [redhat], [sumo] | +| Distributions | [core], [contrib], [aws], [grafana], [observiq], [redhat], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fprometheus%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fprometheus%20&label=closed&color=blue&logo=opentelemetry) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [core]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib [aws]: https://github.com/aws-observability/aws-otel-collector +[grafana]: https://github.com/grafana/agent [observiq]: https://github.com/observIQ/observiq-otel-collector [redhat]: https://github.com/os-observability/redhat-opentelemetry-collector [sumo]: https://github.com/SumoLogic/sumologic-otel-collector diff --git a/exporter/prometheusexporter/metadata.yaml b/exporter/prometheusexporter/metadata.yaml index 3d2512d62a66..07f6ba3cb53b 100644 --- a/exporter/prometheusexporter/metadata.yaml +++ b/exporter/prometheusexporter/metadata.yaml @@ -4,4 +4,11 @@ status: class: exporter stability: beta: [metrics] - distributions: [core, contrib, observiq, sumo, aws, redhat] + distributions: + - core + - contrib + - aws + - grafana + - observiq + - redhat + - sumo diff --git a/extension/basicauthextension/README.md b/extension/basicauthextension/README.md index f3c7e1105621..5077596ea175 100644 --- a/extension/basicauthextension/README.md +++ b/extension/basicauthextension/README.md @@ -3,11 +3,12 @@ | Status | | | ------------- |-----------| | Stability | [beta] | -| Distributions | [contrib], [observiq], [redhat], [sumo] | +| Distributions | [contrib], [grafana], [observiq], [redhat], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aextension%2Fbasicauth%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aextension%2Fbasicauth%20&label=closed&color=blue&logo=opentelemetry) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib +[grafana]: https://github.com/grafana/agent [observiq]: https://github.com/observIQ/observiq-otel-collector [redhat]: https://github.com/os-observability/redhat-opentelemetry-collector [sumo]: https://github.com/SumoLogic/sumologic-otel-collector diff --git a/extension/basicauthextension/metadata.yaml b/extension/basicauthextension/metadata.yaml index 3d264b165de7..883bf10fbfc6 100644 --- a/extension/basicauthextension/metadata.yaml +++ b/extension/basicauthextension/metadata.yaml @@ -4,4 +4,9 @@ status: class: extension stability: beta: [extension] - distributions: [contrib, observiq, sumo, redhat] + distributions: + - contrib + - grafana + - observiq + - redhat + - sumo diff --git a/extension/bearertokenauthextension/README.md b/extension/bearertokenauthextension/README.md index 6acc333a6357..489550032ddf 100644 --- a/extension/bearertokenauthextension/README.md +++ b/extension/bearertokenauthextension/README.md @@ -3,11 +3,12 @@ | Status | | | ------------- |-----------| | Stability | [beta] | -| Distributions | [contrib], [observiq], [redhat], [sumo] | +| Distributions | [contrib], [grafana], [observiq], [redhat], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aextension%2Fbearertokenauth%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aextension%2Fbearertokenauth%20&label=closed&color=blue&logo=opentelemetry) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib +[grafana]: https://github.com/grafana/agent [observiq]: https://github.com/observIQ/observiq-otel-collector [redhat]: https://github.com/os-observability/redhat-opentelemetry-collector [sumo]: https://github.com/SumoLogic/sumologic-otel-collector diff --git a/extension/bearertokenauthextension/metadata.yaml b/extension/bearertokenauthextension/metadata.yaml index 55798ae48e82..ae14f78fe2d3 100644 --- a/extension/bearertokenauthextension/metadata.yaml +++ b/extension/bearertokenauthextension/metadata.yaml @@ -4,4 +4,9 @@ status: class: extension stability: beta: [extension] - distributions: [contrib, observiq, sumo, redhat] + distributions: + - contrib + - grafana + - observiq + - redhat + - sumo diff --git a/extension/headerssetterextension/README.md b/extension/headerssetterextension/README.md index 1ae1da964497..203344ef25d4 100644 --- a/extension/headerssetterextension/README.md +++ b/extension/headerssetterextension/README.md @@ -3,11 +3,12 @@ | Status | | | ------------- |-----------| | Stability | [alpha] | -| Distributions | [contrib], [sumo] | +| Distributions | [contrib], [grafana], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aextension%2Fheaderssetter%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aextension%2Fheaderssetter%20&label=closed&color=blue&logo=opentelemetry) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib +[grafana]: https://github.com/grafana/agent [sumo]: https://github.com/SumoLogic/sumologic-otel-collector diff --git a/extension/headerssetterextension/metadata.yaml b/extension/headerssetterextension/metadata.yaml index a4b6f75d48f1..64da98956080 100644 --- a/extension/headerssetterextension/metadata.yaml +++ b/extension/headerssetterextension/metadata.yaml @@ -4,4 +4,7 @@ status: class: extension stability: alpha: [extension] - distributions: [contrib, sumo] + distributions: + - contrib + - grafana + - sumo diff --git a/extension/jaegerremotesampling/README.md b/extension/jaegerremotesampling/README.md index 98042036a987..7031732ba706 100644 --- a/extension/jaegerremotesampling/README.md +++ b/extension/jaegerremotesampling/README.md @@ -3,11 +3,12 @@ | Status | | | ------------- |-----------| | Stability | [alpha] | -| Distributions | [contrib], [redhat], [sumo] | +| Distributions | [contrib], [grafana], [redhat], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aextension%2Fjaegerremotesampling%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aextension%2Fjaegerremotesampling%20&label=closed&color=blue&logo=opentelemetry) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib +[grafana]: https://github.com/grafana/agent [redhat]: https://github.com/os-observability/redhat-opentelemetry-collector [sumo]: https://github.com/SumoLogic/sumologic-otel-collector diff --git a/extension/jaegerremotesampling/metadata.yaml b/extension/jaegerremotesampling/metadata.yaml index f18d85196246..cc250dda7888 100644 --- a/extension/jaegerremotesampling/metadata.yaml +++ b/extension/jaegerremotesampling/metadata.yaml @@ -4,4 +4,8 @@ status: class: extension stability: alpha: [extension] - distributions: [contrib, sumo, redhat] + distributions: + - contrib + - grafana + - redhat + - sumo diff --git a/extension/oauth2clientauthextension/README.md b/extension/oauth2clientauthextension/README.md index d63628caf5ae..bec8dfd08b77 100644 --- a/extension/oauth2clientauthextension/README.md +++ b/extension/oauth2clientauthextension/README.md @@ -3,11 +3,12 @@ | Status | | | ------------- |-----------| | Stability | [beta] | -| Distributions | [contrib], [redhat], [sumo] | +| Distributions | [contrib], [grafana], [redhat], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aextension%2Foauth2clientauth%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aextension%2Foauth2clientauth%20&label=closed&color=blue&logo=opentelemetry) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib +[grafana]: https://github.com/grafana/agent [redhat]: https://github.com/os-observability/redhat-opentelemetry-collector [sumo]: https://github.com/SumoLogic/sumologic-otel-collector diff --git a/extension/oauth2clientauthextension/metadata.yaml b/extension/oauth2clientauthextension/metadata.yaml index 584a5034a167..80cba5906607 100644 --- a/extension/oauth2clientauthextension/metadata.yaml +++ b/extension/oauth2clientauthextension/metadata.yaml @@ -4,4 +4,8 @@ status: class: extension stability: beta: [extension] - distributions: [contrib, sumo, redhat] + distributions: + - contrib + - grafana + - redhat + - sumo diff --git a/extension/sigv4authextension/README.md b/extension/sigv4authextension/README.md index 73ccf4960975..c5f8ca9139ae 100644 --- a/extension/sigv4authextension/README.md +++ b/extension/sigv4authextension/README.md @@ -3,12 +3,13 @@ | Status | | | ------------- |-----------| | Stability | [beta] | -| Distributions | [contrib], [aws], [sumo] | +| Distributions | [contrib], [aws], [grafana], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aextension%2Fsigv4auth%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aextension%2Fsigv4auth%20&label=closed&color=blue&logo=opentelemetry) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib [aws]: https://github.com/aws-observability/aws-otel-collector +[grafana]: https://github.com/grafana/agent [sumo]: https://github.com/SumoLogic/sumologic-otel-collector diff --git a/extension/sigv4authextension/metadata.yaml b/extension/sigv4authextension/metadata.yaml index 501b3f504864..302d9e18acc1 100644 --- a/extension/sigv4authextension/metadata.yaml +++ b/extension/sigv4authextension/metadata.yaml @@ -4,4 +4,8 @@ status: class: extension stability: beta: [extension] - distributions: [contrib, aws, sumo] + distributions: + - contrib + - aws + - grafana + - sumo diff --git a/processor/attributesprocessor/README.md b/processor/attributesprocessor/README.md index 7ac9340359d3..45b5a061a52d 100644 --- a/processor/attributesprocessor/README.md +++ b/processor/attributesprocessor/README.md @@ -4,7 +4,7 @@ | Status | | | ------------- |-----------| | Stability | [beta]: traces, metrics, logs | -| Distributions | [core], [contrib], [aws], [observiq], [redhat], [splunk], [sumo] | +| Distributions | [core], [contrib], [aws], [grafana], [observiq], [redhat], [splunk], [sumo] | | Warnings | [Identity Conflict](#warnings) | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aprocessor%2Fattributes%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aprocessor%2Fattributes%20&label=closed&color=blue&logo=opentelemetry) | @@ -12,6 +12,7 @@ [core]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib [aws]: https://github.com/aws-observability/aws-otel-collector +[grafana]: https://github.com/grafana/agent [observiq]: https://github.com/observIQ/observiq-otel-collector [redhat]: https://github.com/os-observability/redhat-opentelemetry-collector [splunk]: https://github.com/signalfx/splunk-otel-collector diff --git a/processor/attributesprocessor/metadata.yaml b/processor/attributesprocessor/metadata.yaml index 808c939048d4..95131fa10946 100644 --- a/processor/attributesprocessor/metadata.yaml +++ b/processor/attributesprocessor/metadata.yaml @@ -4,5 +4,13 @@ status: class: processor stability: beta: [traces, metrics, logs] - distributions: [core, contrib, splunk, observiq, sumo, aws, redhat] + distributions: + - core + - contrib + - aws + - grafana + - observiq + - redhat + - splunk + - sumo warnings: [Identity Conflict] diff --git a/processor/tailsamplingprocessor/README.md b/processor/tailsamplingprocessor/README.md index 575a0ba16c3d..26818c9df474 100644 --- a/processor/tailsamplingprocessor/README.md +++ b/processor/tailsamplingprocessor/README.md @@ -4,12 +4,13 @@ | Status | | | ------------- |-----------| | Stability | [beta]: traces | -| Distributions | [contrib], [aws], [observiq], [splunk], [sumo] | +| Distributions | [contrib], [aws], [grafana], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aprocessor%2Ftailsampling%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aprocessor%2Ftailsampling%20&label=closed&color=blue&logo=opentelemetry) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib [aws]: https://github.com/aws-observability/aws-otel-collector +[grafana]: https://github.com/grafana/agent [observiq]: https://github.com/observIQ/observiq-otel-collector [splunk]: https://github.com/signalfx/splunk-otel-collector [sumo]: https://github.com/SumoLogic/sumologic-otel-collector diff --git a/processor/tailsamplingprocessor/metadata.yaml b/processor/tailsamplingprocessor/metadata.yaml index 3d23ee71108b..0b12c78d00a4 100644 --- a/processor/tailsamplingprocessor/metadata.yaml +++ b/processor/tailsamplingprocessor/metadata.yaml @@ -4,4 +4,10 @@ status: class: processor stability: beta: [traces] - distributions: [contrib, observiq, splunk, sumo, aws] + distributions: + - contrib + - aws + - grafana + - observiq + - splunk + - sumo diff --git a/receiver/jaegerreceiver/README.md b/receiver/jaegerreceiver/README.md index 0ba838bef6dd..0d6d41adaac1 100644 --- a/receiver/jaegerreceiver/README.md +++ b/receiver/jaegerreceiver/README.md @@ -4,13 +4,14 @@ | Status | | | ------------- |-----------| | Stability | [beta]: traces | -| Distributions | [core], [contrib], [aws], [observiq], [redhat], [splunk], [sumo] | +| Distributions | [core], [contrib], [aws], [grafana], [observiq], [redhat], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fjaeger%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fjaeger%20&label=closed&color=blue&logo=opentelemetry) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [core]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib [aws]: https://github.com/aws-observability/aws-otel-collector +[grafana]: https://github.com/grafana/agent [observiq]: https://github.com/observIQ/observiq-otel-collector [redhat]: https://github.com/os-observability/redhat-opentelemetry-collector [splunk]: https://github.com/signalfx/splunk-otel-collector diff --git a/receiver/jaegerreceiver/metadata.yaml b/receiver/jaegerreceiver/metadata.yaml index d626c8d4ed68..6f586c5a2f0f 100644 --- a/receiver/jaegerreceiver/metadata.yaml +++ b/receiver/jaegerreceiver/metadata.yaml @@ -4,4 +4,12 @@ status: class: receiver stability: beta: [traces] - distributions: [core, contrib, splunk, observiq, sumo, aws, redhat] + distributions: + - core + - contrib + - aws + - grafana + - observiq + - redhat + - splunk + - sumo diff --git a/receiver/kafkareceiver/README.md b/receiver/kafkareceiver/README.md index 37d808c4b826..905913646515 100644 --- a/receiver/kafkareceiver/README.md +++ b/receiver/kafkareceiver/README.md @@ -4,12 +4,13 @@ | Status | | | ------------- |-----------| | Stability | [beta]: metrics, logs, traces | -| Distributions | [contrib], [aws], [observiq], [splunk], [sumo] | +| Distributions | [contrib], [aws], [grafana], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fkafka%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fkafka%20&label=closed&color=blue&logo=opentelemetry) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib [aws]: https://github.com/aws-observability/aws-otel-collector +[grafana]: https://github.com/grafana/agent [observiq]: https://github.com/observIQ/observiq-otel-collector [splunk]: https://github.com/signalfx/splunk-otel-collector [sumo]: https://github.com/SumoLogic/sumologic-otel-collector diff --git a/receiver/kafkareceiver/metadata.yaml b/receiver/kafkareceiver/metadata.yaml index 4b13f0010e8a..eefed6d2c5b5 100644 --- a/receiver/kafkareceiver/metadata.yaml +++ b/receiver/kafkareceiver/metadata.yaml @@ -4,5 +4,10 @@ status: class: receiver stability: beta: [metrics, logs, traces] - distributions: [contrib, splunk, observiq, sumo, aws] - + distributions: + - contrib + - aws + - grafana + - observiq + - splunk + - sumo diff --git a/receiver/lokireceiver/metadata.yaml b/receiver/lokireceiver/metadata.yaml index 22678209dda4..18f21bde7747 100644 --- a/receiver/lokireceiver/metadata.yaml +++ b/receiver/lokireceiver/metadata.yaml @@ -4,4 +4,6 @@ status: class: receiver stability: alpha: [logs] - distributions: [contrib, sumo] + distributions: + - contrib + - sumo diff --git a/receiver/opencensusreceiver/README.md b/receiver/opencensusreceiver/README.md index 80b9dbf7a28f..706b3fe495cc 100644 --- a/receiver/opencensusreceiver/README.md +++ b/receiver/opencensusreceiver/README.md @@ -4,12 +4,13 @@ | Status | | | ------------- |-----------| | Stability | [beta]: metrics, traces | -| Distributions | [core], [contrib], [observiq], [redhat], [sumo] | +| Distributions | [core], [contrib], [grafana], [observiq], [redhat], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fopencensus%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fopencensus%20&label=closed&color=blue&logo=opentelemetry) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [core]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib +[grafana]: https://github.com/grafana/agent [observiq]: https://github.com/observIQ/observiq-otel-collector [redhat]: https://github.com/os-observability/redhat-opentelemetry-collector [sumo]: https://github.com/SumoLogic/sumologic-otel-collector diff --git a/receiver/opencensusreceiver/metadata.yaml b/receiver/opencensusreceiver/metadata.yaml index 6a6a57a45a82..210665c1ec69 100644 --- a/receiver/opencensusreceiver/metadata.yaml +++ b/receiver/opencensusreceiver/metadata.yaml @@ -4,4 +4,10 @@ status: class: receiver stability: beta: [metrics, traces] - distributions: [core, contrib, observiq, sumo, redhat] + distributions: + - core + - contrib + - grafana + - observiq + - redhat + - sumo diff --git a/receiver/prometheusreceiver/README.md b/receiver/prometheusreceiver/README.md index e4eae02f025d..e0b3268a6945 100644 --- a/receiver/prometheusreceiver/README.md +++ b/receiver/prometheusreceiver/README.md @@ -4,13 +4,14 @@ | Status | | | ------------- |-----------| | Stability | [beta]: metrics | -| Distributions | [core], [contrib], [aws], [observiq], [splunk], [sumo] | +| Distributions | [core], [contrib], [aws], [grafana], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fprometheus%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fprometheus%20&label=closed&color=blue&logo=opentelemetry) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [core]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib [aws]: https://github.com/aws-observability/aws-otel-collector +[grafana]: https://github.com/grafana/agent [observiq]: https://github.com/observIQ/observiq-otel-collector [splunk]: https://github.com/signalfx/splunk-otel-collector [sumo]: https://github.com/SumoLogic/sumologic-otel-collector diff --git a/receiver/prometheusreceiver/metadata.yaml b/receiver/prometheusreceiver/metadata.yaml index ddedfea5f561..1225cb976b11 100644 --- a/receiver/prometheusreceiver/metadata.yaml +++ b/receiver/prometheusreceiver/metadata.yaml @@ -4,5 +4,11 @@ status: class: receiver stability: beta: [metrics] - distributions: [core, contrib, splunk, observiq, sumo, aws] - + distributions: + - core + - contrib + - aws + - grafana + - observiq + - splunk + - sumo diff --git a/receiver/zipkinreceiver/README.md b/receiver/zipkinreceiver/README.md index c4e335e60c1d..462071278449 100644 --- a/receiver/zipkinreceiver/README.md +++ b/receiver/zipkinreceiver/README.md @@ -4,13 +4,14 @@ | Status | | | ------------- |-----------| | Stability | [beta]: traces | -| Distributions | [core], [contrib], [aws], [observiq], [redhat], [splunk], [sumo] | +| Distributions | [core], [contrib], [aws], [grafana], [observiq], [redhat], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fzipkin%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fzipkin%20&label=closed&color=blue&logo=opentelemetry) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [core]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib [aws]: https://github.com/aws-observability/aws-otel-collector +[grafana]: https://github.com/grafana/agent [observiq]: https://github.com/observIQ/observiq-otel-collector [redhat]: https://github.com/os-observability/redhat-opentelemetry-collector [splunk]: https://github.com/signalfx/splunk-otel-collector diff --git a/receiver/zipkinreceiver/metadata.yaml b/receiver/zipkinreceiver/metadata.yaml index 13b1ed9cef1f..707bda723758 100644 --- a/receiver/zipkinreceiver/metadata.yaml +++ b/receiver/zipkinreceiver/metadata.yaml @@ -4,4 +4,12 @@ status: class: receiver stability: beta: [traces] - distributions: [core, contrib, splunk, observiq, sumo, aws, redhat] + distributions: + - core + - contrib + - aws + - grafana + - observiq + - redhat + - splunk + - sumo From fa253b6ec98b9b840eb5f67bc04197b38e149b0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraci=20Paix=C3=A3o=20Kr=C3=B6hling?= Date: Fri, 21 Jul 2023 22:51:43 -0300 Subject: [PATCH 18/42] [processor/tailsampling] Improve debug level logging to include policy name (#24429) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #24421 Signed-off-by: Juraci Paixão Kröhling --------- Signed-off-by: Juraci Paixão Kröhling --- processor/tailsamplingprocessor/processor.go | 2 ++ .../tailsamplingprocessor/processor_test.go | 26 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/processor/tailsamplingprocessor/processor.go b/processor/tailsamplingprocessor/processor.go index 571ce287d16a..abd9783f7fca 100644 --- a/processor/tailsamplingprocessor/processor.go +++ b/processor/tailsamplingprocessor/processor.go @@ -117,6 +117,8 @@ func getPolicyEvaluator(settings component.TelemetrySettings, cfg *PolicyCfg) (s } func getSharedPolicyEvaluator(settings component.TelemetrySettings, cfg *sharedPolicyCfg) (sampling.PolicyEvaluator, error) { + settings.Logger = settings.Logger.With(zap.Any("policy", cfg.Type)) + switch cfg.Type { case AlwaysSample: return sampling.NewAlwaysSample(settings), nil diff --git a/processor/tailsamplingprocessor/processor_test.go b/processor/tailsamplingprocessor/processor_test.go index 500f263673c7..6e0c7b65233c 100644 --- a/processor/tailsamplingprocessor/processor_test.go +++ b/processor/tailsamplingprocessor/processor_test.go @@ -13,12 +13,14 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/consumer/consumertest" "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/pdata/ptrace" "go.uber.org/zap" + "go.uber.org/zap/zaptest/observer" "github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal/timeutils" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/tailsamplingprocessor/internal/idbatcher" @@ -691,6 +693,30 @@ func TestMultipleBatchesAreCombinedIntoOne(t *testing.T) { } } +func TestPolicyLoggerAddsPolicyName(t *testing.T) { + // prepare + zc, logs := observer.New(zap.DebugLevel) + logger := zap.New(zc) + + set := componenttest.NewNopTelemetrySettings() + set.Logger = logger + + cfg := &sharedPolicyCfg{ + Type: AlwaysSample, // we test only one evaluator + } + + evaluator, err := getSharedPolicyEvaluator(set, cfg) + require.NoError(t, err) + + // test + _, err = evaluator.Evaluate(context.Background(), pcommon.TraceID{}, nil) + require.NoError(t, err) + + // verify + assert.Len(t, logs.All(), 1) + assert.Equal(t, AlwaysSample, logs.All()[0].ContextMap()["policy"]) +} + func collectSpanIds(trace ptrace.Traces) []pcommon.SpanID { var spanIDs []pcommon.SpanID From c55822fe72d57a2e61b6611ce1f7e9ee926ace21 Mon Sep 17 00:00:00 2001 From: Ziqi Zhao Date: Sat, 22 Jul 2023 21:54:23 +0800 Subject: [PATCH 19/42] [chore] enable exhaustive option explicit-exhaustive-switch (#24412) --- .golangci.yml | 142 +----------------- .../timeutils/internal/ctimefmt/ctimefmt.go | 5 +- .../internal/ctimefmt/ctimefmt_test.go | 24 +-- 3 files changed, 18 insertions(+), 153 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 8a1e0a6f5d96..d84aebb84d2e 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -123,6 +123,9 @@ linters-settings: files: - "!**/*_test.go" + exhaustive: + explicit-exhaustive-switch: true + linters: enable: - depguard @@ -153,141 +156,4 @@ issues: - gosec - text: "G402:" linters: - - gosec - # Following exclude-rules are used to exclude the existing components which do not pass exhaustive lint, - # in order to enable the exhaustive lint check. - # We should not add more exclude-rules. - # The progress of solving existing exclude-rules will be tracked in https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/23266 - - path: fluentforwardreceiver - linters: - - exhaustive - - path: prometheusreceiver - linters: - - exhaustive - - path: deltatorateprocessor - linters: - - exhaustive - - path: filterprocessor - linters: - - exhaustive - - path: metricsgenerationprocessor - linters: - - exhaustive - - path: metricstransformprocessor - linters: - - exhaustive - - path: probabilisticsamplerprocessor - linters: - - exhaustive - - path: servicegraphprocessor - linters: - - exhaustive - - path: resourcedetectionprocessor - linters: - - exhaustive - - path: tailsamplingprocessor - linters: - - exhaustive - - path: transformprocessor - linters: - - exhaustive - - path: alibabacloudlogserviceexporter - linters: - - exhaustive - - path: awsemfexporter - linters: - - exhaustive - - path: awsxrayexporter - linters: - - exhaustive - - path: azuremonitorexporter - linters: - - exhaustive - - path: azuredataexplorerexporter - linters: - - exhaustive - - path: carbonexporter - linters: - - exhaustive - - path: coralogixexporter - linters: - - exhaustive - - path: datasetexporter - linters: - - exhaustive - - path: elasticsearchexporter - linters: - - exhaustive - - path: googlecloudpubsubexporter - linters: - - exhaustive - - path: instanaexporter - linters: - - exhaustive - - path: jaegerthrifthttpexporter - linters: - - exhaustive - - path: logzioexporter - linters: - - exhaustive - - path: prometheusexporter - linters: - - exhaustive - - path: prometheusremotewriteexporter - linters: - - exhaustive - - path: skywalkingexporter - linters: - - exhaustive - - path: splunkhecexporter - linters: - - exhaustive - - path: tanzuobservabilityexporter - linters: - - exhaustive - - path: k8sobserver - linters: - - exhaustive - - path: containerinsight - linters: - - exhaustive - - path: filter - linters: - - exhaustive - - path: coreinternal - linters: - - exhaustive - - path: k8sconfig - linters: - - exhaustive - - path: ottl - linters: - - exhaustive - - path: resourcetotelemetry - linters: - - exhaustive - - path: jaeger - linters: - - exhaustive - - path: prometheus - linters: - - exhaustive - - path: loki - linters: - - exhaustive - - path: opencensus - linters: - - exhaustive - - path: zipkin - linters: - - exhaustive - - path: configschema - linters: - - exhaustive - - path: testbed - linters: - - exhaustive - # Preserve original source code in attributed package. - - path: ctimefmt - linters: - - revive + - gosec \ No newline at end of file diff --git a/internal/coreinternal/timeutils/internal/ctimefmt/ctimefmt.go b/internal/coreinternal/timeutils/internal/ctimefmt/ctimefmt.go index dbffac25702c..22e8d5d12faf 100644 --- a/internal/coreinternal/timeutils/internal/ctimefmt/ctimefmt.go +++ b/internal/coreinternal/timeutils/internal/ctimefmt/ctimefmt.go @@ -19,7 +19,7 @@ import ( var ctimeRegexp = regexp.MustCompile(`%.`) var decimalsRegexp = regexp.MustCompile(`\d`) -var ctimeSubstitutes map[string]string = map[string]string{ +var ctimeSubstitutes = map[string]string{ "%Y": "2006", "%y": "06", "%m": "01", @@ -129,9 +129,8 @@ func ToNative(format string) (string, error) { replaceFunc := func(directive string) string { if subst, ok := ctimeSubstitutes[directive]; ok { return subst - } else { - errs = append(errs, errors.New("unsupported ctimefmt.ToNative() directive: "+directive)) } + errs = append(errs, errors.New("unsupported ctimefmt.ToNative() directive: "+directive)) return "" } diff --git a/internal/coreinternal/timeutils/internal/ctimefmt/ctimefmt_test.go b/internal/coreinternal/timeutils/internal/ctimefmt/ctimefmt_test.go index a72a9e082516..0d4969afd7ef 100644 --- a/internal/coreinternal/timeutils/internal/ctimefmt/ctimefmt_test.go +++ b/internal/coreinternal/timeutils/internal/ctimefmt/ctimefmt_test.go @@ -14,12 +14,12 @@ import ( "time" ) -var format1 string = "%Y-%m-%d %H:%M:%S.%f" -var format2 string = "%Y-%m-%d %l:%M:%S.%L %P, %a" -var value1 string = "2019-01-02 15:04:05.666666" -var value2 string = "2019-01-02 3:04:05.666 pm, Wed" -var dt1 time.Time = time.Date(2019, 1, 2, 15, 4, 5, 666666000, time.UTC) -var dt2 time.Time = time.Date(2019, 1, 2, 15, 4, 5, 666000000, time.UTC) +var format1 = "%Y-%m-%d %H:%M:%S.%f" +var format2 = "%Y-%m-%d %l:%M:%S.%L %P, %a" +var value1 = "2019-01-02 15:04:05.666666" +var value2 = "2019-01-02 3:04:05.666 pm, Wed" +var dt1 = time.Date(2019, 1, 2, 15, 4, 5, 666666000, time.UTC) +var dt2 = time.Date(2019, 1, 2, 15, 4, 5, 666000000, time.UTC) func TestFormat(t *testing.T) { s, err := Format(format1, dt1) @@ -40,17 +40,17 @@ func TestFormat(t *testing.T) { } func TestParse(t *testing.T) { - dt_, err := Parse(format1, value1) + dt, err := Parse(format1, value1) if err != nil { t.Error(err) - } else if dt_ != dt1 { - t.Errorf("Given: %v, expected: %v", dt_, dt1) + } else if dt != dt1 { + t.Errorf("Given: %v, expected: %v", dt, dt1) } - dt_, err = Parse(format2, value2) + dt, err = Parse(format2, value2) if err != nil { t.Error(err) - } else if dt_ != dt2 { - t.Errorf("Given: %v, expected: %v", dt_, dt2) + } else if dt != dt2 { + t.Errorf("Given: %v, expected: %v", dt, dt2) } } From 7e3d665f091334f738924ce0ddd184e8880d4ddb Mon Sep 17 00:00:00 2001 From: Dmitrii Anoshin Date: Mon, 24 Jul 2023 00:25:14 -0700 Subject: [PATCH 20/42] [chore] [processor/resourcedetection] Create ResourceBuilder on start (#24437) Create ResourceBuilder during the initialization state, not in the Detect call. We want to make sure that ResourceBuilder is initialized only once so we can introduce the same warnings as MetricsBuilder has. Detect is currently called only once as well, but it's better not to depend on such behavior, so it can be changed independently in the future if needed. --- .../internal/aws/ec2/ec2.go | 37 ++++----- .../internal/aws/ec2/ec2_test.go | 8 +- .../internal/aws/ecs/ecs.go | 35 ++++---- .../internal/aws/ecs/ecs_test.go | 6 +- .../internal/aws/eks/detector.go | 28 ++++--- .../internal/aws/eks/detector_test.go | 5 +- .../aws/elasticbeanstalk/elasticbeanstalk.go | 19 ++--- .../elasticbeanstalk/elasticbeanstalk_test.go | 19 ++--- .../internal/aws/lambda/lambda.go | 28 +++---- .../internal/aws/lambda/lambda_test.go | 16 +--- .../internal/azure/azure.go | 36 ++++---- .../internal/azure/azure_test.go | 11 ++- .../internal/consul/consul.go | 17 ++-- .../internal/consul/consul_test.go | 8 +- .../internal/docker/docker.go | 19 ++--- .../internal/gcp/gcp.go | 82 +++++++++---------- .../internal/gcp/gcp_test.go | 8 +- .../internal/heroku/heroku.go | 25 +++--- .../internal/heroku/heroku_test.go | 15 +--- .../internal/openshift/openshift.go | 44 +++++----- .../internal/openshift/openshift_test.go | 4 +- .../internal/system/system.go | 26 +++--- .../internal/system/system_test.go | 26 +++--- 23 files changed, 250 insertions(+), 272 deletions(-) diff --git a/processor/resourcedetectionprocessor/internal/aws/ec2/ec2.go b/processor/resourcedetectionprocessor/internal/aws/ec2/ec2.go index e97d5626ca00..8ac342466d8c 100644 --- a/processor/resourcedetectionprocessor/internal/aws/ec2/ec2.go +++ b/processor/resourcedetectionprocessor/internal/aws/ec2/ec2.go @@ -32,10 +32,10 @@ const ( var _ internal.Detector = (*Detector)(nil) type Detector struct { - metadataProvider ec2provider.Provider - tagKeyRegexes []*regexp.Regexp - logger *zap.Logger - resourceAttributes metadata.ResourceAttributesConfig + metadataProvider ec2provider.Provider + tagKeyRegexes []*regexp.Regexp + logger *zap.Logger + rb *metadata.ResourceBuilder } func NewDetector(set processor.CreateSettings, dcfg internal.DetectorConfig) (internal.Detector, error) { @@ -50,10 +50,10 @@ func NewDetector(set processor.CreateSettings, dcfg internal.DetectorConfig) (in } return &Detector{ - metadataProvider: ec2provider.NewProvider(sess), - tagKeyRegexes: tagKeyRegexes, - logger: set.Logger, - resourceAttributes: cfg.ResourceAttributes, + metadataProvider: ec2provider.NewProvider(sess), + tagKeyRegexes: tagKeyRegexes, + logger: set.Logger, + rb: metadata.NewResourceBuilder(cfg.ResourceAttributes), }, nil } @@ -73,17 +73,16 @@ func (d *Detector) Detect(ctx context.Context) (resource pcommon.Resource, schem return pcommon.NewResource(), "", fmt.Errorf("failed getting hostname: %w", err) } - rb := metadata.NewResourceBuilder(d.resourceAttributes) - rb.SetCloudProvider(conventions.AttributeCloudProviderAWS) - rb.SetCloudPlatform(conventions.AttributeCloudPlatformAWSEC2) - rb.SetCloudRegion(meta.Region) - rb.SetCloudAccountID(meta.AccountID) - rb.SetCloudAvailabilityZone(meta.AvailabilityZone) - rb.SetHostID(meta.InstanceID) - rb.SetHostImageID(meta.ImageID) - rb.SetHostType(meta.InstanceType) - rb.SetHostName(hostname) - res := rb.Emit() + d.rb.SetCloudProvider(conventions.AttributeCloudProviderAWS) + d.rb.SetCloudPlatform(conventions.AttributeCloudPlatformAWSEC2) + d.rb.SetCloudRegion(meta.Region) + d.rb.SetCloudAccountID(meta.AccountID) + d.rb.SetCloudAvailabilityZone(meta.AvailabilityZone) + d.rb.SetHostID(meta.InstanceID) + d.rb.SetHostImageID(meta.ImageID) + d.rb.SetHostType(meta.InstanceType) + d.rb.SetHostName(hostname) + res := d.rb.Emit() if len(d.tagKeyRegexes) != 0 { client := getHTTPClientSettings(ctx, d.logger) diff --git a/processor/resourcedetectionprocessor/internal/aws/ec2/ec2_test.go b/processor/resourcedetectionprocessor/internal/aws/ec2/ec2_test.go index a857b11213c6..b57ca85a2814 100644 --- a/processor/resourcedetectionprocessor/internal/aws/ec2/ec2_test.go +++ b/processor/resourcedetectionprocessor/internal/aws/ec2/ec2_test.go @@ -19,6 +19,7 @@ import ( "go.uber.org/zap" ec2provider "github.com/open-telemetry/opentelemetry-collector-contrib/internal/metadataproviders/aws/ec2" + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/aws/ec2/internal/metadata" ) var errUnavailable = errors.New("ec2metadata unavailable") @@ -172,11 +173,10 @@ func TestDetector_Detect(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - resourceAttributes := CreateDefaultConfig().ResourceAttributes d := &Detector{ - metadataProvider: tt.fields.metadataProvider, - logger: zap.NewNop(), - resourceAttributes: resourceAttributes, + metadataProvider: tt.fields.metadataProvider, + logger: zap.NewNop(), + rb: metadata.NewResourceBuilder(metadata.DefaultResourceAttributesConfig()), } got, _, err := d.Detect(tt.args.ctx) diff --git a/processor/resourcedetectionprocessor/internal/aws/ecs/ecs.go b/processor/resourcedetectionprocessor/internal/aws/ecs/ecs.go index 8be6ee1afcaf..af05693a34eb 100644 --- a/processor/resourcedetectionprocessor/internal/aws/ecs/ecs.go +++ b/processor/resourcedetectionprocessor/internal/aws/ecs/ecs.go @@ -28,8 +28,8 @@ const ( var _ internal.Detector = (*Detector)(nil) type Detector struct { - provider ecsutil.MetadataProvider - resourceAttributes metadata.ResourceAttributesConfig + provider ecsutil.MetadataProvider + rb *metadata.ResourceBuilder } func NewDetector(params processor.CreateSettings, dcfg internal.DetectorConfig) (internal.Detector, error) { @@ -43,7 +43,7 @@ func NewDetector(params processor.CreateSettings, dcfg internal.DetectorConfig) } return nil, fmt.Errorf("unable to create task metadata provider: %w", err) } - return &Detector{provider: provider, resourceAttributes: cfg.ResourceAttributes}, nil + return &Detector{provider: provider, rb: metadata.NewResourceBuilder(cfg.ResourceAttributes)}, nil } // Detect records metadata retrieved from the ECS Task Metadata Endpoint (TMDE) as resource attributes @@ -60,46 +60,45 @@ func (d *Detector) Detect(context.Context) (resource pcommon.Resource, schemaURL return pcommon.NewResource(), "", fmt.Errorf("unable to fetch task metadata: %w", err) } - rb := metadata.NewResourceBuilder(d.resourceAttributes) - rb.SetCloudProvider(conventions.AttributeCloudProviderAWS) - rb.SetCloudPlatform(conventions.AttributeCloudPlatformAWSECS) - rb.SetAwsEcsTaskArn(tmdeResp.TaskARN) - rb.SetAwsEcsTaskFamily(tmdeResp.Family) - rb.SetAwsEcsTaskRevision(tmdeResp.Revision) + d.rb.SetCloudProvider(conventions.AttributeCloudProviderAWS) + d.rb.SetCloudPlatform(conventions.AttributeCloudPlatformAWSECS) + d.rb.SetAwsEcsTaskArn(tmdeResp.TaskARN) + d.rb.SetAwsEcsTaskFamily(tmdeResp.Family) + d.rb.SetAwsEcsTaskRevision(tmdeResp.Revision) region, account := parseRegionAndAccount(tmdeResp.TaskARN) if account != "" { - rb.SetCloudAccountID(account) + d.rb.SetCloudAccountID(account) } if region != "" { - rb.SetCloudRegion(region) + d.rb.SetCloudRegion(region) } // TMDE returns the cluster short name or ARN, so we need to construct the ARN if necessary - rb.SetAwsEcsClusterArn(constructClusterArn(tmdeResp.Cluster, region, account)) + d.rb.SetAwsEcsClusterArn(constructClusterArn(tmdeResp.Cluster, region, account)) if tmdeResp.AvailabilityZone != "" { - rb.SetCloudAvailabilityZone(tmdeResp.AvailabilityZone) + d.rb.SetCloudAvailabilityZone(tmdeResp.AvailabilityZone) } // The launch type and log data attributes are only available in TMDE v4 switch lt := strings.ToLower(tmdeResp.LaunchType); lt { case "ec2": - rb.SetAwsEcsLaunchtype("ec2") + d.rb.SetAwsEcsLaunchtype("ec2") case "fargate": - rb.SetAwsEcsLaunchtype("fargate") + d.rb.SetAwsEcsLaunchtype("fargate") } selfMetaData, err := d.provider.FetchContainerMetadata() if err != nil || selfMetaData == nil { - return rb.Emit(), "", err + return d.rb.Emit(), "", err } - addValidLogData(tmdeResp.Containers, selfMetaData, account, rb) + addValidLogData(tmdeResp.Containers, selfMetaData, account, d.rb) - return rb.Emit(), conventions.SchemaURL, nil + return d.rb.Emit(), conventions.SchemaURL, nil } func constructClusterArn(cluster, region, account string) string { diff --git a/processor/resourcedetectionprocessor/internal/aws/ecs/ecs_test.go b/processor/resourcedetectionprocessor/internal/aws/ecs/ecs_test.go index 9418bb92b400..3c07d981e451 100644 --- a/processor/resourcedetectionprocessor/internal/aws/ecs/ecs_test.go +++ b/processor/resourcedetectionprocessor/internal/aws/ecs/ecs_test.go @@ -120,8 +120,7 @@ func Test_ecsDetectV4(t *testing.T) { attr.PutEmptySlice("aws.log.stream.names").AppendEmpty().SetStr("stream") attr.PutEmptySlice("aws.log.stream.arns").AppendEmpty().SetStr("arn:aws:logs:us-east-1:123456789123:log-group:group:log-stream:stream") - resourceAttributes := CreateDefaultConfig().ResourceAttributes - d := Detector{provider: &mockMetaDataProvider{isV4: true}, resourceAttributes: resourceAttributes} + d := Detector{provider: &mockMetaDataProvider{isV4: true}, rb: metadata.NewResourceBuilder(metadata.DefaultResourceAttributesConfig())} got, _, err := d.Detect(context.TODO()) assert.Nil(t, err) @@ -144,8 +143,7 @@ func Test_ecsDetectV3(t *testing.T) { attr.PutStr("cloud.availability_zone", "us-west-2a") attr.PutStr("cloud.account.id", "123456789123") - resourceAttributes := CreateDefaultConfig().ResourceAttributes - d := Detector{provider: &mockMetaDataProvider{isV4: false}, resourceAttributes: resourceAttributes} + d := Detector{provider: &mockMetaDataProvider{isV4: false}, rb: metadata.NewResourceBuilder(metadata.DefaultResourceAttributesConfig())} got, _, err := d.Detect(context.TODO()) assert.Nil(t, err) diff --git a/processor/resourcedetectionprocessor/internal/aws/eks/detector.go b/processor/resourcedetectionprocessor/internal/aws/eks/detector.go index 438713bc2cea..5727669c7f6f 100644 --- a/processor/resourcedetectionprocessor/internal/aws/eks/detector.go +++ b/processor/resourcedetectionprocessor/internal/aws/eks/detector.go @@ -40,10 +40,10 @@ type eksDetectorUtils struct { // detector for EKS type detector struct { - utils detectorUtils - logger *zap.Logger - err error - resourceAttributes metadata.ResourceAttributesConfig + utils detectorUtils + logger *zap.Logger + err error + rb *metadata.ResourceBuilder } var _ internal.Detector = (*detector)(nil) @@ -54,23 +54,27 @@ var _ detectorUtils = (*eksDetectorUtils)(nil) func NewDetector(set processor.CreateSettings, dcfg internal.DetectorConfig) (internal.Detector, error) { cfg := dcfg.(Config) utils, err := newK8sDetectorUtils() - return &detector{utils: utils, logger: set.Logger, err: err, resourceAttributes: cfg.ResourceAttributes}, nil + return &detector{ + utils: utils, + logger: set.Logger, + err: err, + rb: metadata.NewResourceBuilder(cfg.ResourceAttributes), + }, nil } // Detect returns a Resource describing the Amazon EKS environment being run in. -func (detector *detector) Detect(ctx context.Context) (resource pcommon.Resource, schemaURL string, err error) { +func (d *detector) Detect(ctx context.Context) (resource pcommon.Resource, schemaURL string, err error) { // Check if running on EKS. - isEKS, err := isEKS(ctx, detector.utils) + isEKS, err := isEKS(ctx, d.utils) if !isEKS { - detector.logger.Debug("Unable to identify EKS environment", zap.Error(err)) + d.logger.Debug("Unable to identify EKS environment", zap.Error(err)) return pcommon.NewResource(), "", err } - rb := metadata.NewResourceBuilder(detector.resourceAttributes) - rb.SetCloudProvider(conventions.AttributeCloudProviderAWS) - rb.SetCloudPlatform(conventions.AttributeCloudPlatformAWSEKS) + d.rb.SetCloudProvider(conventions.AttributeCloudProviderAWS) + d.rb.SetCloudPlatform(conventions.AttributeCloudPlatformAWSEKS) - return rb.Emit(), conventions.SchemaURL, nil + return d.rb.Emit(), conventions.SchemaURL, nil } func isEKS(ctx context.Context, utils detectorUtils) (bool, error) { diff --git a/processor/resourcedetectionprocessor/internal/aws/eks/detector_test.go b/processor/resourcedetectionprocessor/internal/aws/eks/detector_test.go index a4ea414ad2d5..4d4b5b111970 100644 --- a/processor/resourcedetectionprocessor/internal/aws/eks/detector_test.go +++ b/processor/resourcedetectionprocessor/internal/aws/eks/detector_test.go @@ -12,6 +12,8 @@ import ( "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/processor/processortest" "go.uber.org/zap" + + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/aws/eks/internal/metadata" ) type MockDetectorUtils struct { @@ -38,8 +40,7 @@ func TestEKS(t *testing.T) { t.Setenv("KUBERNETES_SERVICE_HOST", "localhost") detectorUtils.On("getConfigMap", authConfigmapNS, authConfigmapName).Return(map[string]string{"cluster.name": "my-cluster"}, nil) // Call EKS Resource detector to detect resources - resourceAttributes := CreateDefaultConfig().ResourceAttributes - eksResourceDetector := &detector{utils: detectorUtils, err: nil, resourceAttributes: resourceAttributes} + eksResourceDetector := &detector{utils: detectorUtils, err: nil, rb: metadata.NewResourceBuilder(metadata.DefaultResourceAttributesConfig())} res, _, err := eksResourceDetector.Detect(ctx) require.NoError(t, err) diff --git a/processor/resourcedetectionprocessor/internal/aws/elasticbeanstalk/elasticbeanstalk.go b/processor/resourcedetectionprocessor/internal/aws/elasticbeanstalk/elasticbeanstalk.go index d50245ceff2e..3d40ee81134a 100644 --- a/processor/resourcedetectionprocessor/internal/aws/elasticbeanstalk/elasticbeanstalk.go +++ b/processor/resourcedetectionprocessor/internal/aws/elasticbeanstalk/elasticbeanstalk.go @@ -28,8 +28,8 @@ const ( var _ internal.Detector = (*Detector)(nil) type Detector struct { - fs fileSystem - resourceAttributes metadata.ResourceAttributesConfig + fs fileSystem + rb *metadata.ResourceBuilder } type EbMetaData struct { @@ -40,7 +40,7 @@ type EbMetaData struct { func NewDetector(_ processor.CreateSettings, dcfg internal.DetectorConfig) (internal.Detector, error) { cfg := dcfg.(Config) - return &Detector{fs: &ebFileSystem{}, resourceAttributes: cfg.ResourceAttributes}, nil + return &Detector{fs: &ebFileSystem{}, rb: metadata.NewResourceBuilder(cfg.ResourceAttributes)}, nil } func (d Detector) Detect(context.Context) (resource pcommon.Resource, schemaURL string, err error) { @@ -67,12 +67,11 @@ func (d Detector) Detect(context.Context) (resource pcommon.Resource, schemaURL return pcommon.NewResource(), "", err } - rb := metadata.NewResourceBuilder(d.resourceAttributes) - rb.SetCloudProvider(conventions.AttributeCloudProviderAWS) - rb.SetCloudPlatform(conventions.AttributeCloudPlatformAWSElasticBeanstalk) - rb.SetServiceInstanceID(strconv.Itoa(ebmd.DeploymentID)) - rb.SetDeploymentEnvironment(ebmd.EnvironmentName) - rb.SetServiceVersion(ebmd.VersionLabel) + d.rb.SetCloudProvider(conventions.AttributeCloudProviderAWS) + d.rb.SetCloudPlatform(conventions.AttributeCloudPlatformAWSElasticBeanstalk) + d.rb.SetServiceInstanceID(strconv.Itoa(ebmd.DeploymentID)) + d.rb.SetDeploymentEnvironment(ebmd.EnvironmentName) + d.rb.SetServiceVersion(ebmd.VersionLabel) - return rb.Emit(), conventions.SchemaURL, nil + return d.rb.Emit(), conventions.SchemaURL, nil } diff --git a/processor/resourcedetectionprocessor/internal/aws/elasticbeanstalk/elasticbeanstalk_test.go b/processor/resourcedetectionprocessor/internal/aws/elasticbeanstalk/elasticbeanstalk_test.go index 06588f15c339..b1d2044efcfe 100644 --- a/processor/resourcedetectionprocessor/internal/aws/elasticbeanstalk/elasticbeanstalk_test.go +++ b/processor/resourcedetectionprocessor/internal/aws/elasticbeanstalk/elasticbeanstalk_test.go @@ -11,6 +11,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/processor/processortest" ) @@ -37,17 +38,11 @@ func (mfs *mockFileSystem) IsWindows() bool { return mfs.windows } -func Test_newDetector(t *testing.T) { - dcfg := CreateDefaultConfig() - d, err := NewDetector(processortest.NewNopCreateSettings(), dcfg) - - assert.Nil(t, err) - assert.NotNil(t, d) -} - func Test_windowsPath(t *testing.T) { mfs := &mockFileSystem{windows: true, exists: true, contents: xrayConf} - d := Detector{fs: mfs} + d, err := NewDetector(processortest.NewNopCreateSettings(), CreateDefaultConfig()) + require.NoError(t, err) + d.(*Detector).fs = mfs r, _, err := d.Detect(context.TODO()) @@ -79,9 +74,9 @@ func Test_fileMalformed(t *testing.T) { } func Test_AttributesDetectedSuccessfully(t *testing.T) { - mfs := &mockFileSystem{exists: true, contents: xrayConf} - resourceAttributes := CreateDefaultConfig().ResourceAttributes - d := Detector{fs: mfs, resourceAttributes: resourceAttributes} + d, err := NewDetector(processortest.NewNopCreateSettings(), CreateDefaultConfig()) + require.NoError(t, err) + d.(*Detector).fs = &mockFileSystem{exists: true, contents: xrayConf} want := pcommon.NewResource() attr := want.Attributes() diff --git a/processor/resourcedetectionprocessor/internal/aws/lambda/lambda.go b/processor/resourcedetectionprocessor/internal/aws/lambda/lambda.go index 03058dd49ffe..edf0a91c66b5 100644 --- a/processor/resourcedetectionprocessor/internal/aws/lambda/lambda.go +++ b/processor/resourcedetectionprocessor/internal/aws/lambda/lambda.go @@ -33,13 +33,13 @@ const ( var _ internal.Detector = (*detector)(nil) type detector struct { - logger *zap.Logger - resourceAttributes metadata.ResourceAttributesConfig + logger *zap.Logger + rb *metadata.ResourceBuilder } func NewDetector(set processor.CreateSettings, dcfg internal.DetectorConfig) (internal.Detector, error) { cfg := dcfg.(Config) - return &detector{logger: set.Logger, resourceAttributes: cfg.ResourceAttributes}, nil + return &detector{logger: set.Logger, rb: metadata.NewResourceBuilder(cfg.ResourceAttributes)}, nil } func (d *detector) Detect(_ context.Context) (resource pcommon.Resource, schemaURL string, err error) { @@ -49,38 +49,36 @@ func (d *detector) Detect(_ context.Context) (resource pcommon.Resource, schemaU return pcommon.NewResource(), "", err } - rb := metadata.NewResourceBuilder(d.resourceAttributes) - // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/semantic_conventions/cloud.md - rb.SetCloudProvider(conventions.AttributeCloudProviderAWS) - rb.SetCloudPlatform(conventions.AttributeCloudPlatformAWSLambda) + d.rb.SetCloudProvider(conventions.AttributeCloudProviderAWS) + d.rb.SetCloudPlatform(conventions.AttributeCloudPlatformAWSLambda) if value, ok := os.LookupEnv(awsRegionEnvVar); ok { - rb.SetCloudRegion(value) + d.rb.SetCloudRegion(value) } // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/semantic_conventions/faas.md // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/instrumentation/aws-lambda.md#resource-detector - rb.SetFaasName(functionName) + d.rb.SetFaasName(functionName) if value, ok := os.LookupEnv(awsLambdaFunctionVersionEnvVar); ok { - rb.SetFaasVersion(value) + d.rb.SetFaasVersion(value) } // Note: The FaaS spec (https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/semantic_conventions/faas.md) // recommends setting faas.instance to the full log stream name for AWS Lambda. if value, ok := os.LookupEnv(awsLambdaLogStreamNameEnvVar); ok { - rb.SetFaasInstance(value) + d.rb.SetFaasInstance(value) } if value, ok := os.LookupEnv(awsLambdaFunctionMemorySizeEnvVar); ok { - rb.SetFaasMaxMemory(value) + d.rb.SetFaasMaxMemory(value) } // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/semantic_conventions/cloud_provider/aws/logs.md if value, ok := os.LookupEnv(awsLambdaLogGroupNameEnvVar); ok { - rb.SetAwsLogGroupNames([]any{value}) + d.rb.SetAwsLogGroupNames([]any{value}) } if value, ok := os.LookupEnv(awsLambdaLogStreamNameEnvVar); ok { - rb.SetAwsLogStreamNames([]any{value}) + d.rb.SetAwsLogStreamNames([]any{value}) } - return rb.Emit(), conventions.SchemaURL, nil + return d.rb.Emit(), conventions.SchemaURL, nil } diff --git a/processor/resourcedetectionprocessor/internal/aws/lambda/lambda_test.go b/processor/resourcedetectionprocessor/internal/aws/lambda/lambda_test.go index 165cf6006ada..babc11eb9229 100644 --- a/processor/resourcedetectionprocessor/internal/aws/lambda/lambda_test.go +++ b/processor/resourcedetectionprocessor/internal/aws/lambda/lambda_test.go @@ -11,16 +11,8 @@ import ( "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/processor/processortest" conventions "go.opentelemetry.io/collector/semconv/v1.6.1" - "go.uber.org/zap" ) -func TestNewDetector(t *testing.T) { - dcfg := CreateDefaultConfig() - detector, err := NewDetector(processortest.NewNopCreateSettings(), dcfg) - assert.NoError(t, err) - assert.NotNil(t, detector) -} - // Tests Lambda resource detector running in Lambda environment func TestLambda(t *testing.T) { ctx := context.Background() @@ -29,8 +21,8 @@ func TestLambda(t *testing.T) { t.Setenv(awsLambdaFunctionNameEnvVar, functionName) // Call Lambda Resource detector to detect resources - resourceAttributes := CreateDefaultConfig().ResourceAttributes - lambdaDetector := &detector{logger: zap.NewNop(), resourceAttributes: resourceAttributes} + lambdaDetector, err := NewDetector(processortest.NewNopCreateSettings(), CreateDefaultConfig()) + require.NoError(t, err) res, _, err := lambdaDetector.Detect(ctx) require.NoError(t, err) require.NotNil(t, res) @@ -45,8 +37,8 @@ func TestLambda(t *testing.T) { // Tests Lambda resource detector not running in Lambda environment func TestNotLambda(t *testing.T) { ctx := context.Background() - resourceAttributes := CreateDefaultConfig().ResourceAttributes - lambdaDetector := &detector{logger: zap.NewNop(), resourceAttributes: resourceAttributes} + lambdaDetector, err := NewDetector(processortest.NewNopCreateSettings(), CreateDefaultConfig()) + require.NoError(t, err) res, _, err := lambdaDetector.Detect(ctx) require.NoError(t, err) require.NotNil(t, res) diff --git a/processor/resourcedetectionprocessor/internal/azure/azure.go b/processor/resourcedetectionprocessor/internal/azure/azure.go index 830724830ba6..8b309e3163ce 100644 --- a/processor/resourcedetectionprocessor/internal/azure/azure.go +++ b/processor/resourcedetectionprocessor/internal/azure/azure.go @@ -25,18 +25,18 @@ var _ internal.Detector = (*Detector)(nil) // Detector is an Azure metadata detector type Detector struct { - provider azure.Provider - logger *zap.Logger - resourceAttributes metadata.ResourceAttributesConfig + provider azure.Provider + logger *zap.Logger + rb *metadata.ResourceBuilder } // NewDetector creates a new Azure metadata detector func NewDetector(p processor.CreateSettings, dcfg internal.DetectorConfig) (internal.Detector, error) { cfg := dcfg.(Config) return &Detector{ - provider: azure.NewProvider(), - logger: p.Logger, - resourceAttributes: cfg.ResourceAttributes, + provider: azure.NewProvider(), + logger: p.Logger, + rb: metadata.NewResourceBuilder(cfg.ResourceAttributes), }, nil } @@ -49,21 +49,19 @@ func (d *Detector) Detect(ctx context.Context) (resource pcommon.Resource, schem return pcommon.NewResource(), "", nil } - rb := metadata.NewResourceBuilder(d.resourceAttributes) - - rb.SetCloudProvider(conventions.AttributeCloudProviderAzure) - rb.SetCloudPlatform(conventions.AttributeCloudPlatformAzureVM) - rb.SetHostName(compute.Name) - rb.SetCloudRegion(compute.Location) - rb.SetHostID(compute.VMID) - rb.SetCloudAccountID(compute.SubscriptionID) + d.rb.SetCloudProvider(conventions.AttributeCloudProviderAzure) + d.rb.SetCloudPlatform(conventions.AttributeCloudPlatformAzureVM) + d.rb.SetHostName(compute.Name) + d.rb.SetCloudRegion(compute.Location) + d.rb.SetHostID(compute.VMID) + d.rb.SetCloudAccountID(compute.SubscriptionID) // Also save compute.Name in "azure.vm.name" as host.id (AttributeHostName) is // used by system detector. - rb.SetAzureVMName(compute.Name) - rb.SetAzureVMSize(compute.VMSize) - rb.SetAzureVMScalesetName(compute.VMScaleSetName) - rb.SetAzureResourcegroupName(compute.ResourceGroupName) + d.rb.SetAzureVMName(compute.Name) + d.rb.SetAzureVMSize(compute.VMSize) + d.rb.SetAzureVMScalesetName(compute.VMScaleSetName) + d.rb.SetAzureResourcegroupName(compute.ResourceGroupName) - return rb.Emit(), conventions.SchemaURL, nil + return d.rb.Emit(), conventions.SchemaURL, nil } diff --git a/processor/resourcedetectionprocessor/internal/azure/azure_test.go b/processor/resourcedetectionprocessor/internal/azure/azure_test.go index c94f72b7876c..949132d93c88 100644 --- a/processor/resourcedetectionprocessor/internal/azure/azure_test.go +++ b/processor/resourcedetectionprocessor/internal/azure/azure_test.go @@ -16,6 +16,7 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/internal/metadataproviders/azure" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal" + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/azure/internal/metadata" ) func TestNewDetector(t *testing.T) { @@ -37,8 +38,7 @@ func TestDetectAzureAvailable(t *testing.T) { VMScaleSetName: "myScaleset", }, nil) - resourceAttributes := CreateDefaultConfig().ResourceAttributes - detector := &Detector{provider: mp, resourceAttributes: resourceAttributes} + detector := &Detector{provider: mp, rb: metadata.NewResourceBuilder(metadata.DefaultResourceAttributesConfig())} res, schemaURL, err := detector.Detect(context.Background()) require.NoError(t, err) assert.Equal(t, conventions.SchemaURL, schemaURL) @@ -63,8 +63,11 @@ func TestDetectAzureAvailable(t *testing.T) { func TestDetectError(t *testing.T) { mp := &azure.MockProvider{} mp.On("Metadata").Return(&azure.ComputeMetadata{}, fmt.Errorf("mock error")) - resourceAttributes := CreateDefaultConfig().ResourceAttributes - detector := &Detector{provider: mp, logger: zap.NewNop(), resourceAttributes: resourceAttributes} + detector := &Detector{ + provider: mp, + logger: zap.NewNop(), + rb: metadata.NewResourceBuilder(metadata.DefaultResourceAttributesConfig()), + } res, _, err := detector.Detect(context.Background()) assert.NoError(t, err) assert.True(t, internal.IsEmptyResource(res)) diff --git a/processor/resourcedetectionprocessor/internal/consul/consul.go b/processor/resourcedetectionprocessor/internal/consul/consul.go index 0d873efac3b3..de387f08500b 100644 --- a/processor/resourcedetectionprocessor/internal/consul/consul.go +++ b/processor/resourcedetectionprocessor/internal/consul/consul.go @@ -27,9 +27,9 @@ var _ internal.Detector = (*Detector)(nil) // Detector is a system metadata detector type Detector struct { - provider consul.Provider - logger *zap.Logger - resourceAttributes metadata.ResourceAttributesConfig + provider consul.Provider + logger *zap.Logger + rb *metadata.ResourceBuilder } // NewDetector creates a new system metadata detector @@ -59,7 +59,7 @@ func NewDetector(p processor.CreateSettings, dcfg internal.DetectorConfig) (inte } provider := consul.NewProvider(client, userCfg.MetaLabels) - return &Detector{provider: provider, logger: p.Logger, resourceAttributes: userCfg.ResourceAttributes}, nil + return &Detector{provider: provider, logger: p.Logger, rb: metadata.NewResourceBuilder(userCfg.ResourceAttributes)}, nil } // Detect detects system metadata and returns a resource with the available ones @@ -69,12 +69,11 @@ func (d *Detector) Detect(ctx context.Context) (resource pcommon.Resource, schem return pcommon.NewResource(), "", fmt.Errorf("failed to get consul metadata: %w", err) } - rb := metadata.NewResourceBuilder(d.resourceAttributes) - rb.SetHostName(md.Hostname) - rb.SetCloudRegion(md.Datacenter) - rb.SetHostID(md.NodeID) + d.rb.SetHostName(md.Hostname) + d.rb.SetCloudRegion(md.Datacenter) + d.rb.SetHostID(md.NodeID) - res := rb.Emit() + res := d.rb.Emit() for key, element := range md.HostMetadata { res.Attributes().PutStr(key, element) diff --git a/processor/resourcedetectionprocessor/internal/consul/consul_test.go b/processor/resourcedetectionprocessor/internal/consul/consul_test.go index 29f44cbec0b8..713645845121 100644 --- a/processor/resourcedetectionprocessor/internal/consul/consul_test.go +++ b/processor/resourcedetectionprocessor/internal/consul/consul_test.go @@ -14,6 +14,7 @@ import ( "go.uber.org/zap" "github.com/open-telemetry/opentelemetry-collector-contrib/internal/metadataproviders/consul" + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/consul/internal/metadata" ) var _ consul.Provider = (*mockMetadata)(nil) @@ -39,11 +40,10 @@ func TestDetect(t *testing.T) { }, nil, ) - dcfg := CreateDefaultConfig() detector := &Detector{ - provider: md, - logger: zap.NewNop(), - resourceAttributes: dcfg.ResourceAttributes, + provider: md, + logger: zap.NewNop(), + rb: metadata.NewResourceBuilder(metadata.DefaultResourceAttributesConfig()), } res, schemaURL, err := detector.Detect(context.Background()) require.NoError(t, err) diff --git a/processor/resourcedetectionprocessor/internal/docker/docker.go b/processor/resourcedetectionprocessor/internal/docker/docker.go index 386116871f31..5d70f6a89137 100644 --- a/processor/resourcedetectionprocessor/internal/docker/docker.go +++ b/processor/resourcedetectionprocessor/internal/docker/docker.go @@ -26,9 +26,9 @@ var _ internal.Detector = (*Detector)(nil) // Detector is a system metadata detector type Detector struct { - provider docker.Provider - logger *zap.Logger - resourceAttributes metadata.ResourceAttributesConfig + provider docker.Provider + logger *zap.Logger + rb *metadata.ResourceBuilder } // NewDetector creates a new system metadata detector @@ -39,9 +39,9 @@ func NewDetector(p processor.CreateSettings, cfg internal.DetectorConfig) (inter } return &Detector{ - provider: dockerProvider, - logger: p.Logger, - resourceAttributes: cfg.(Config).ResourceAttributes, + provider: dockerProvider, + logger: p.Logger, + rb: metadata.NewResourceBuilder(cfg.(Config).ResourceAttributes), }, nil } @@ -57,9 +57,8 @@ func (d *Detector) Detect(ctx context.Context) (resource pcommon.Resource, schem return pcommon.NewResource(), "", fmt.Errorf("failed getting OS hostname: %w", err) } - rb := metadata.NewResourceBuilder(d.resourceAttributes) - rb.SetHostName(hostname) - rb.SetOsType(osType) + d.rb.SetHostName(hostname) + d.rb.SetOsType(osType) - return rb.Emit(), conventions.SchemaURL, nil + return d.rb.Emit(), conventions.SchemaURL, nil } diff --git a/processor/resourcedetectionprocessor/internal/gcp/gcp.go b/processor/resourcedetectionprocessor/internal/gcp/gcp.go index 6c1821c835dd..0e9a5dc23072 100644 --- a/processor/resourcedetectionprocessor/internal/gcp/gcp.go +++ b/processor/resourcedetectionprocessor/internal/gcp/gcp.go @@ -32,16 +32,16 @@ const ( func NewDetector(set processor.CreateSettings, dcfg internal.DetectorConfig) (internal.Detector, error) { cfg := dcfg.(Config) return &detector{ - logger: set.Logger, - detector: gcp.NewDetector(), - resourceAttributes: cfg.ResourceAttributes, + logger: set.Logger, + detector: gcp.NewDetector(), + rb: localMetadata.NewResourceBuilder(cfg.ResourceAttributes), }, nil } type detector struct { - logger *zap.Logger - detector gcpDetector - resourceAttributes localMetadata.ResourceAttributesConfig + logger *zap.Logger + detector gcpDetector + rb *localMetadata.ResourceBuilder } func (d *detector) Detect(context.Context) (resource pcommon.Resource, schemaURL string, err error) { @@ -49,69 +49,67 @@ func (d *detector) Detect(context.Context) (resource pcommon.Resource, schemaURL return pcommon.NewResource(), "", nil } - rb := localMetadata.NewResourceBuilder(d.resourceAttributes) - - rb.SetCloudProvider(conventions.AttributeCloudProviderGCP) - errs := rb.SetFromCallable(rb.SetCloudAccountID, d.detector.ProjectID) + d.rb.SetCloudProvider(conventions.AttributeCloudProviderGCP) + errs := d.rb.SetFromCallable(d.rb.SetCloudAccountID, d.detector.ProjectID) switch d.detector.CloudPlatform() { case gcp.GKE: - rb.SetCloudPlatform(conventions.AttributeCloudPlatformGCPKubernetesEngine) + d.rb.SetCloudPlatform(conventions.AttributeCloudPlatformGCPKubernetesEngine) errs = multierr.Combine(errs, - rb.SetZoneOrRegion(d.detector.GKEAvailabilityZoneOrRegion), - rb.SetFromCallable(rb.SetK8sClusterName, d.detector.GKEClusterName), - rb.SetFromCallable(rb.SetHostID, d.detector.GKEHostID), + d.rb.SetZoneOrRegion(d.detector.GKEAvailabilityZoneOrRegion), + d.rb.SetFromCallable(d.rb.SetK8sClusterName, d.detector.GKEClusterName), + d.rb.SetFromCallable(d.rb.SetHostID, d.detector.GKEHostID), ) // GCEHostname is fallible on GKE, since it's not available when using workload identity. if v, err := d.detector.GCEHostName(); err == nil { - rb.SetHostName(v) + d.rb.SetHostName(v) } else { d.logger.Info("Fallible detector failed. This attribute will not be available.", zap.String("key", conventions.AttributeHostName), zap.Error(err)) } case gcp.CloudRun: - rb.SetCloudPlatform(conventions.AttributeCloudPlatformGCPCloudRun) + d.rb.SetCloudPlatform(conventions.AttributeCloudPlatformGCPCloudRun) errs = multierr.Combine(errs, - rb.SetFromCallable(rb.SetFaasName, d.detector.FaaSName), - rb.SetFromCallable(rb.SetFaasVersion, d.detector.FaaSVersion), - rb.SetFromCallable(rb.SetFaasID, d.detector.FaaSID), - rb.SetFromCallable(rb.SetCloudRegion, d.detector.FaaSCloudRegion), + d.rb.SetFromCallable(d.rb.SetFaasName, d.detector.FaaSName), + d.rb.SetFromCallable(d.rb.SetFaasVersion, d.detector.FaaSVersion), + d.rb.SetFromCallable(d.rb.SetFaasID, d.detector.FaaSID), + d.rb.SetFromCallable(d.rb.SetCloudRegion, d.detector.FaaSCloudRegion), ) case gcp.CloudFunctions: - rb.SetCloudPlatform(conventions.AttributeCloudPlatformGCPCloudFunctions) + d.rb.SetCloudPlatform(conventions.AttributeCloudPlatformGCPCloudFunctions) errs = multierr.Combine(errs, - rb.SetFromCallable(rb.SetFaasName, d.detector.FaaSName), - rb.SetFromCallable(rb.SetFaasVersion, d.detector.FaaSVersion), - rb.SetFromCallable(rb.SetFaasID, d.detector.FaaSID), - rb.SetFromCallable(rb.SetCloudRegion, d.detector.FaaSCloudRegion), + d.rb.SetFromCallable(d.rb.SetFaasName, d.detector.FaaSName), + d.rb.SetFromCallable(d.rb.SetFaasVersion, d.detector.FaaSVersion), + d.rb.SetFromCallable(d.rb.SetFaasID, d.detector.FaaSID), + d.rb.SetFromCallable(d.rb.SetCloudRegion, d.detector.FaaSCloudRegion), ) case gcp.AppEngineFlex: - rb.SetCloudPlatform(conventions.AttributeCloudPlatformGCPAppEngine) + d.rb.SetCloudPlatform(conventions.AttributeCloudPlatformGCPAppEngine) errs = multierr.Combine(errs, - rb.SetZoneAndRegion(d.detector.AppEngineFlexAvailabilityZoneAndRegion), - rb.SetFromCallable(rb.SetFaasName, d.detector.AppEngineServiceName), - rb.SetFromCallable(rb.SetFaasVersion, d.detector.AppEngineServiceVersion), - rb.SetFromCallable(rb.SetFaasID, d.detector.AppEngineServiceInstance), + d.rb.SetZoneAndRegion(d.detector.AppEngineFlexAvailabilityZoneAndRegion), + d.rb.SetFromCallable(d.rb.SetFaasName, d.detector.AppEngineServiceName), + d.rb.SetFromCallable(d.rb.SetFaasVersion, d.detector.AppEngineServiceVersion), + d.rb.SetFromCallable(d.rb.SetFaasID, d.detector.AppEngineServiceInstance), ) case gcp.AppEngineStandard: - rb.SetCloudPlatform(conventions.AttributeCloudPlatformGCPAppEngine) + d.rb.SetCloudPlatform(conventions.AttributeCloudPlatformGCPAppEngine) errs = multierr.Combine(errs, - rb.SetFromCallable(rb.SetFaasName, d.detector.AppEngineServiceName), - rb.SetFromCallable(rb.SetFaasVersion, d.detector.AppEngineServiceVersion), - rb.SetFromCallable(rb.SetFaasID, d.detector.AppEngineServiceInstance), - rb.SetFromCallable(rb.SetCloudAvailabilityZone, d.detector.AppEngineStandardAvailabilityZone), - rb.SetFromCallable(rb.SetCloudRegion, d.detector.AppEngineStandardCloudRegion), + d.rb.SetFromCallable(d.rb.SetFaasName, d.detector.AppEngineServiceName), + d.rb.SetFromCallable(d.rb.SetFaasVersion, d.detector.AppEngineServiceVersion), + d.rb.SetFromCallable(d.rb.SetFaasID, d.detector.AppEngineServiceInstance), + d.rb.SetFromCallable(d.rb.SetCloudAvailabilityZone, d.detector.AppEngineStandardAvailabilityZone), + d.rb.SetFromCallable(d.rb.SetCloudRegion, d.detector.AppEngineStandardCloudRegion), ) case gcp.GCE: - rb.SetCloudPlatform(conventions.AttributeCloudPlatformGCPComputeEngine) + d.rb.SetCloudPlatform(conventions.AttributeCloudPlatformGCPComputeEngine) errs = multierr.Combine(errs, - rb.SetZoneAndRegion(d.detector.GCEAvailabilityZoneAndRegion), - rb.SetFromCallable(rb.SetHostType, d.detector.GCEHostType), - rb.SetFromCallable(rb.SetHostID, d.detector.GCEHostID), - rb.SetFromCallable(rb.SetHostName, d.detector.GCEHostName), + d.rb.SetZoneAndRegion(d.detector.GCEAvailabilityZoneAndRegion), + d.rb.SetFromCallable(d.rb.SetHostType, d.detector.GCEHostType), + d.rb.SetFromCallable(d.rb.SetHostID, d.detector.GCEHostID), + d.rb.SetFromCallable(d.rb.SetHostName, d.detector.GCEHostName), ) default: // We don't support this platform yet, so just return with what we have } - return rb.Emit(), conventions.SchemaURL, errs + return d.rb.Emit(), conventions.SchemaURL, errs } diff --git a/processor/resourcedetectionprocessor/internal/gcp/gcp_test.go b/processor/resourcedetectionprocessor/internal/gcp/gcp_test.go index 8a279264036c..ea52c8c49820 100644 --- a/processor/resourcedetectionprocessor/internal/gcp/gcp_test.go +++ b/processor/resourcedetectionprocessor/internal/gcp/gcp_test.go @@ -14,6 +14,7 @@ import ( "go.uber.org/zap" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal" + localMetadata "github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/gcp/internal/metadata" ) func TestDetect(t *testing.T) { @@ -227,11 +228,10 @@ func TestDetect(t *testing.T) { } func newTestDetector(gcpDetector *fakeGCPDetector) *detector { - resourceAttributes := CreateDefaultConfig().ResourceAttributes return &detector{ - logger: zap.NewNop(), - detector: gcpDetector, - resourceAttributes: resourceAttributes, + logger: zap.NewNop(), + detector: gcpDetector, + rb: localMetadata.NewResourceBuilder(localMetadata.DefaultResourceAttributesConfig()), } } diff --git a/processor/resourcedetectionprocessor/internal/heroku/heroku.go b/processor/resourcedetectionprocessor/internal/heroku/heroku.go index dd2301ff7afd..a2ba9f4decdd 100644 --- a/processor/resourcedetectionprocessor/internal/heroku/heroku.go +++ b/processor/resourcedetectionprocessor/internal/heroku/heroku.go @@ -25,14 +25,14 @@ const ( func NewDetector(set processor.CreateSettings, dcfg internal.DetectorConfig) (internal.Detector, error) { cfg := dcfg.(Config) return &detector{ - logger: set.Logger, - resourceAttributes: cfg.ResourceAttributes, + logger: set.Logger, + rb: metadata.NewResourceBuilder(cfg.ResourceAttributes), }, nil } type detector struct { - logger *zap.Logger - resourceAttributes metadata.ResourceAttributesConfig + logger *zap.Logger + rb *metadata.ResourceBuilder } // Detect detects heroku metadata and returns a resource with the available ones @@ -43,24 +43,23 @@ func (d *detector) Detect(_ context.Context) (resource pcommon.Resource, schemaU return pcommon.NewResource(), "", nil } - rb := metadata.NewResourceBuilder(d.resourceAttributes) - rb.SetCloudProvider("heroku") - rb.SetServiceInstanceID(dynoID) + d.rb.SetCloudProvider("heroku") + d.rb.SetServiceInstanceID(dynoID) if v, ok := os.LookupEnv("HEROKU_APP_ID"); ok { - rb.SetHerokuAppID(v) + d.rb.SetHerokuAppID(v) } if v, ok := os.LookupEnv("HEROKU_APP_NAME"); ok { - rb.SetServiceName(v) + d.rb.SetServiceName(v) } if v, ok := os.LookupEnv("HEROKU_RELEASE_CREATED_AT"); ok { - rb.SetHerokuReleaseCreationTimestamp(v) + d.rb.SetHerokuReleaseCreationTimestamp(v) } if v, ok := os.LookupEnv("HEROKU_RELEASE_VERSION"); ok { - rb.SetServiceVersion(v) + d.rb.SetServiceVersion(v) } if v, ok := os.LookupEnv("HEROKU_SLUG_COMMIT"); ok { - rb.SetHerokuReleaseCommit(v) + d.rb.SetHerokuReleaseCommit(v) } - return rb.Emit(), conventions.SchemaURL, nil + return d.rb.Emit(), conventions.SchemaURL, nil } diff --git a/processor/resourcedetectionprocessor/internal/heroku/heroku_test.go b/processor/resourcedetectionprocessor/internal/heroku/heroku_test.go index 0c2b5e460b3a..33ee61ecb5bb 100644 --- a/processor/resourcedetectionprocessor/internal/heroku/heroku_test.go +++ b/processor/resourcedetectionprocessor/internal/heroku/heroku_test.go @@ -16,13 +16,6 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal" ) -func TestNewDetector(t *testing.T) { - dcfg := CreateDefaultConfig() - d, err := NewDetector(processortest.NewNopCreateSettings(), dcfg) - assert.NotNil(t, d) - assert.NoError(t, err) -} - func TestDetectTrue(t *testing.T) { t.Setenv("HEROKU_DYNO_ID", "foo") t.Setenv("HEROKU_APP_ID", "appid") @@ -31,8 +24,8 @@ func TestDetectTrue(t *testing.T) { t.Setenv("HEROKU_RELEASE_VERSION", "v1") t.Setenv("HEROKU_SLUG_COMMIT", "23456") - resourceAttributes := CreateDefaultConfig().ResourceAttributes - detector := &detector{resourceAttributes: resourceAttributes} + detector, err := NewDetector(processortest.NewNopCreateSettings(), CreateDefaultConfig()) + require.NoError(t, err) res, schemaURL, err := detector.Detect(context.Background()) assert.Equal(t, conventions.SchemaURL, schemaURL) require.NoError(t, err) @@ -54,8 +47,8 @@ func TestDetectTruePartial(t *testing.T) { t.Setenv("HEROKU_APP_NAME", "appname") t.Setenv("HEROKU_RELEASE_VERSION", "v1") - resourceAttributes := CreateDefaultConfig().ResourceAttributes - detector := &detector{resourceAttributes: resourceAttributes} + detector, err := NewDetector(processortest.NewNopCreateSettings(), CreateDefaultConfig()) + require.NoError(t, err) res, schemaURL, err := detector.Detect(context.Background()) assert.Equal(t, conventions.SchemaURL, schemaURL) require.NoError(t, err) diff --git a/processor/resourcedetectionprocessor/internal/openshift/openshift.go b/processor/resourcedetectionprocessor/internal/openshift/openshift.go index d4b5e6a1b2f5..76da89e9ba61 100644 --- a/processor/resourcedetectionprocessor/internal/openshift/openshift.go +++ b/processor/resourcedetectionprocessor/internal/openshift/openshift.go @@ -36,16 +36,16 @@ func NewDetector(set processor.CreateSettings, dcfg internal.DetectorConfig) (in } return &detector{ - logger: set.Logger, - provider: ocp.NewProvider(userCfg.Address, userCfg.Token, tlsCfg), - resourceAttributes: userCfg.ResourceAttributes, + logger: set.Logger, + provider: ocp.NewProvider(userCfg.Address, userCfg.Token, tlsCfg), + rb: metadata.NewResourceBuilder(userCfg.ResourceAttributes), }, nil } type detector struct { - logger *zap.Logger - provider ocp.Provider - resourceAttributes metadata.ResourceAttributesConfig + logger *zap.Logger + provider ocp.Provider + rb *metadata.ResourceBuilder } func (d *detector) Detect(ctx context.Context) (resource pcommon.Resource, schemaURL string, err error) { @@ -56,35 +56,33 @@ func (d *detector) Detect(ctx context.Context) (resource pcommon.Resource, schem return pcommon.NewResource(), "", nil } - rb := metadata.NewResourceBuilder(d.resourceAttributes) - if infra.Status.InfrastructureName != "" { - rb.SetK8sClusterName(infra.Status.InfrastructureName) + d.rb.SetK8sClusterName(infra.Status.InfrastructureName) } switch strings.ToLower(infra.Status.PlatformStatus.Type) { case "aws": - rb.SetCloudProvider(conventions.AttributeCloudProviderAWS) - rb.SetCloudPlatform(conventions.AttributeCloudPlatformAWSOpenshift) - rb.SetCloudRegion(strings.ToLower(infra.Status.PlatformStatus.Aws.Region)) + d.rb.SetCloudProvider(conventions.AttributeCloudProviderAWS) + d.rb.SetCloudPlatform(conventions.AttributeCloudPlatformAWSOpenshift) + d.rb.SetCloudRegion(strings.ToLower(infra.Status.PlatformStatus.Aws.Region)) case "azure": - rb.SetCloudProvider(conventions.AttributeCloudProviderAzure) - rb.SetCloudPlatform(conventions.AttributeCloudPlatformAzureOpenshift) - rb.SetCloudRegion(strings.ToLower(infra.Status.PlatformStatus.Azure.CloudName)) + d.rb.SetCloudProvider(conventions.AttributeCloudProviderAzure) + d.rb.SetCloudPlatform(conventions.AttributeCloudPlatformAzureOpenshift) + d.rb.SetCloudRegion(strings.ToLower(infra.Status.PlatformStatus.Azure.CloudName)) case "gcp": - rb.SetCloudProvider(conventions.AttributeCloudProviderGCP) - rb.SetCloudPlatform(conventions.AttributeCloudPlatformGCPOpenshift) - rb.SetCloudRegion(strings.ToLower(infra.Status.PlatformStatus.GCP.Region)) + d.rb.SetCloudProvider(conventions.AttributeCloudProviderGCP) + d.rb.SetCloudPlatform(conventions.AttributeCloudPlatformGCPOpenshift) + d.rb.SetCloudRegion(strings.ToLower(infra.Status.PlatformStatus.GCP.Region)) case "ibmcloud": - rb.SetCloudProvider(conventions.AttributeCloudProviderIbmCloud) - rb.SetCloudPlatform(conventions.AttributeCloudPlatformIbmCloudOpenshift) - rb.SetCloudRegion(strings.ToLower(infra.Status.PlatformStatus.IBMCloud.Location)) + d.rb.SetCloudProvider(conventions.AttributeCloudProviderIbmCloud) + d.rb.SetCloudPlatform(conventions.AttributeCloudPlatformIbmCloudOpenshift) + d.rb.SetCloudRegion(strings.ToLower(infra.Status.PlatformStatus.IBMCloud.Location)) case "openstack": - rb.SetCloudRegion(strings.ToLower(infra.Status.PlatformStatus.OpenStack.CloudName)) + d.rb.SetCloudRegion(strings.ToLower(infra.Status.PlatformStatus.OpenStack.CloudName)) } // TODO(frzifus): support conventions openshift and kubernetes cluster version. // SEE: https://github.com/open-telemetry/opentelemetry-specification/issues/2913 - return rb.Emit(), conventions.SchemaURL, nil + return d.rb.Emit(), conventions.SchemaURL, nil } diff --git a/processor/resourcedetectionprocessor/internal/openshift/openshift_test.go b/processor/resourcedetectionprocessor/internal/openshift/openshift_test.go index 5b7193350cf2..34eabca8ae3b 100644 --- a/processor/resourcedetectionprocessor/internal/openshift/openshift_test.go +++ b/processor/resourcedetectionprocessor/internal/openshift/openshift_test.go @@ -15,6 +15,7 @@ import ( ocp "github.com/open-telemetry/opentelemetry-collector-contrib/internal/metadataproviders/openshift" "github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal" + "github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/openshift/internal/metadata" ) type providerResponse struct { @@ -53,7 +54,6 @@ func (m *mockProvider) Infrastructure(context.Context) (*ocp.InfrastructureAPIRe } func newTestDetector(t *testing.T, res *providerResponse, ocpCVErr, k8sCVErr, infraErr error) internal.Detector { - resourceAttributes := CreateDefaultConfig().ResourceAttributes return &detector{ logger: zaptest.NewLogger(t), provider: &mockProvider{ @@ -62,7 +62,7 @@ func newTestDetector(t *testing.T, res *providerResponse, ocpCVErr, k8sCVErr, in k8sCVErr: k8sCVErr, infraErr: infraErr, }, - resourceAttributes: resourceAttributes, + rb: metadata.NewResourceBuilder(metadata.DefaultResourceAttributesConfig()), } } diff --git a/processor/resourcedetectionprocessor/internal/system/system.go b/processor/resourcedetectionprocessor/internal/system/system.go index 2435bb3ab94a..60f698f55047 100644 --- a/processor/resourcedetectionprocessor/internal/system/system.go +++ b/processor/resourcedetectionprocessor/internal/system/system.go @@ -34,10 +34,10 @@ var _ internal.Detector = (*Detector)(nil) // Detector is a system metadata detector type Detector struct { - provider system.Provider - logger *zap.Logger - hostnameSources []string - resourceAttributes metadata.ResourceAttributesConfig + provider system.Provider + logger *zap.Logger + hostnameSources []string + rb *metadata.ResourceBuilder } // NewDetector creates a new system metadata detector @@ -47,7 +47,12 @@ func NewDetector(p processor.CreateSettings, dcfg internal.DetectorConfig) (inte cfg.HostnameSources = []string{"dns", "os"} } - return &Detector{provider: system.NewProvider(), logger: p.Logger, hostnameSources: cfg.HostnameSources, resourceAttributes: cfg.ResourceAttributes}, nil + return &Detector{ + provider: system.NewProvider(), + logger: p.Logger, + hostnameSources: cfg.HostnameSources, + rb: metadata.NewResourceBuilder(cfg.ResourceAttributes), + }, nil } // Detect detects system metadata and returns a resource with the available ones @@ -73,12 +78,11 @@ func (d *Detector) Detect(ctx context.Context) (resource pcommon.Resource, schem getHostFromSource := hostnameSourcesMap[source] hostname, err = getHostFromSource(d) if err == nil { - rb := metadata.NewResourceBuilder(d.resourceAttributes) - rb.SetHostName(hostname) - rb.SetOsType(osType) - rb.SetHostID(hostID) - rb.SetHostArch(hostArch) - return rb.Emit(), conventions.SchemaURL, nil + d.rb.SetHostName(hostname) + d.rb.SetOsType(osType) + d.rb.SetHostID(hostID) + d.rb.SetHostArch(hostArch) + return d.rb.Emit(), conventions.SchemaURL, nil } d.logger.Debug(err.Error()) } diff --git a/processor/resourcedetectionprocessor/internal/system/system_test.go b/processor/resourcedetectionprocessor/internal/system/system_test.go index 022bb8f0277b..e5b9b3877f2c 100644 --- a/processor/resourcedetectionprocessor/internal/system/system_test.go +++ b/processor/resourcedetectionprocessor/internal/system/system_test.go @@ -102,8 +102,8 @@ func TestDetectFQDNAvailable(t *testing.T) { md.On("HostID").Return("2", nil) md.On("HostArch").Return("amd64", nil) - resourceAttributes := allEnabledConfig() - detector := &Detector{provider: md, logger: zap.NewNop(), hostnameSources: []string{"dns"}, resourceAttributes: resourceAttributes} + detector := &Detector{provider: md, logger: zap.NewNop(), hostnameSources: []string{"dns"}, + rb: metadata.NewResourceBuilder(allEnabledConfig())} res, schemaURL, err := detector.Detect(context.Background()) require.NoError(t, err) assert.Equal(t, conventions.SchemaURL, schemaURL) @@ -128,8 +128,8 @@ func TestFallbackHostname(t *testing.T) { mdHostname.On("HostID").Return("3", nil) mdHostname.On("HostArch").Return("amd64", nil) - resourceAttributes := CreateDefaultConfig().ResourceAttributes - detector := &Detector{provider: mdHostname, logger: zap.NewNop(), hostnameSources: []string{"dns", "os"}, resourceAttributes: resourceAttributes} + detector := &Detector{provider: mdHostname, logger: zap.NewNop(), hostnameSources: []string{"dns", "os"}, + rb: metadata.NewResourceBuilder(metadata.DefaultResourceAttributesConfig())} res, schemaURL, err := detector.Detect(context.Background()) require.NoError(t, err) assert.Equal(t, conventions.SchemaURL, schemaURL) @@ -151,8 +151,8 @@ func TestEnableHostID(t *testing.T) { mdHostname.On("HostID").Return("3", nil) mdHostname.On("HostArch").Return("amd64", nil) - resourceAttributes := allEnabledConfig() - detector := &Detector{provider: mdHostname, logger: zap.NewNop(), hostnameSources: []string{"dns", "os"}, resourceAttributes: resourceAttributes} + detector := &Detector{provider: mdHostname, logger: zap.NewNop(), hostnameSources: []string{"dns", "os"}, + rb: metadata.NewResourceBuilder(allEnabledConfig())} res, schemaURL, err := detector.Detect(context.Background()) require.NoError(t, err) assert.Equal(t, conventions.SchemaURL, schemaURL) @@ -175,8 +175,8 @@ func TestUseHostname(t *testing.T) { mdHostname.On("HostID").Return("1", nil) mdHostname.On("HostArch").Return("amd64", nil) - resourceAttributes := allEnabledConfig() - detector := &Detector{provider: mdHostname, logger: zap.NewNop(), hostnameSources: []string{"os"}, resourceAttributes: resourceAttributes} + detector := &Detector{provider: mdHostname, logger: zap.NewNop(), hostnameSources: []string{"os"}, + rb: metadata.NewResourceBuilder(allEnabledConfig())} res, schemaURL, err := detector.Detect(context.Background()) require.NoError(t, err) assert.Equal(t, conventions.SchemaURL, schemaURL) @@ -201,8 +201,8 @@ func TestDetectError(t *testing.T) { mdFQDN.On("HostID").Return("", errors.New("err")) mdFQDN.On("HostArch").Return("amd64", nil) - resourceAttributes := allEnabledConfig() - detector := &Detector{provider: mdFQDN, logger: zap.NewNop(), hostnameSources: []string{"dns"}, resourceAttributes: resourceAttributes} + detector := &Detector{provider: mdFQDN, logger: zap.NewNop(), hostnameSources: []string{"dns"}, + rb: metadata.NewResourceBuilder(allEnabledConfig())} res, schemaURL, err := detector.Detect(context.Background()) assert.Error(t, err) assert.Equal(t, "", schemaURL) @@ -215,7 +215,8 @@ func TestDetectError(t *testing.T) { mdHostname.On("HostID").Return("", errors.New("err")) mdHostname.On("HostArch").Return("amd64", nil) - detector = &Detector{provider: mdHostname, logger: zap.NewNop(), hostnameSources: []string{"os"}, resourceAttributes: resourceAttributes} + detector = &Detector{provider: mdHostname, logger: zap.NewNop(), hostnameSources: []string{"os"}, + rb: metadata.NewResourceBuilder(allEnabledConfig())} res, schemaURL, err = detector.Detect(context.Background()) assert.Error(t, err) assert.Equal(t, "", schemaURL) @@ -228,7 +229,8 @@ func TestDetectError(t *testing.T) { mdOSType.On("HostID").Return("", errors.New("err")) mdOSType.On("HostArch").Return("amd64", nil) - detector = &Detector{provider: mdOSType, logger: zap.NewNop(), hostnameSources: []string{"dns"}, resourceAttributes: resourceAttributes} + detector = &Detector{provider: mdOSType, logger: zap.NewNop(), hostnameSources: []string{"dns"}, + rb: metadata.NewResourceBuilder(allEnabledConfig())} res, schemaURL, err = detector.Detect(context.Background()) assert.Error(t, err) assert.Equal(t, "", schemaURL) From 831b69cbf9f497079c17b8739236d38ec0c402d7 Mon Sep 17 00:00:00 2001 From: Ziqi Zhao Date: Mon, 24 Jul 2023 15:25:46 +0800 Subject: [PATCH 21/42] [chore] ignore pmetric.MetricTypeEmpty for exhaustive (#24436) **Description:** related #23266 The `pmetric.MetricTypeEmpty` always has no meaning for the components, for example https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/c55822fe72d57a2e61b6611ce1f7e9ee926ace21/processor/metricstransformprocessor/metrics_transform_processor_otlp.go#L503-L517 https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/c55822fe72d57a2e61b6611ce1f7e9ee926ace21/processor/metricstransformprocessor/metrics_transform_processor_otlp.go#L463-L501 so we could optimize the check logic of exhaustive to ignore the type `pmetric.MetricTypeEmpty` to avoid solving many meaningless failed check like ``` metrics_transform_processor_otlp.go:505:2: missing cases in switch of type pmetric.MetricType: pmetric.MetricTypeEmpty (exhaustive) ``` Signed-off-by: Ziqi Zhao --- .golangci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.golangci.yml b/.golangci.yml index d84aebb84d2e..f2f6414f991b 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -125,6 +125,7 @@ linters-settings: exhaustive: explicit-exhaustive-switch: true + ignore-enum-members: "pmetric.MetricTypeEmpty" linters: enable: @@ -156,4 +157,4 @@ issues: - gosec - text: "G402:" linters: - - gosec \ No newline at end of file + - gosec From d95d199b07895d4edd15b3aefab9c2dcc1f3136b Mon Sep 17 00:00:00 2001 From: Tigran Najaryan <4194920+tigrannajaryan@users.noreply.github.com> Date: Mon, 24 Jul 2023 03:26:52 -0400 Subject: [PATCH 22/42] [receiver/k8sclusterreceiver] Report entity state periodically (#24434) Resolves https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24413 This is part of the work to move to entity events-as-log-records in K8s cluster receiver: https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/19741 Overall design document: https://docs.google.com/document/d/1Tg18sIck3Nakxtd3TFFcIjrmRO_0GLMdHXylVqBQmJA/ Note that metadata.GetMetadataUpdate() computes deltas between the old and new state. If the old and new states are equal metadata.GetMetadataUpdate() returns an empty slice. This means periodic polling when no state is changed will NOT result in any additional metadata update calls. So, we expect no changes in the behavior of existing metadata listeners, such as signalfxexporter. As opposed to that entity events are always emitted even if no state is changed. So, this periodic collection will result in periodic emitting of entity events. This is the desirable effect of this PR. ### Testing I was unable to think of a good automated test for this capability that does not require a major refactoring of other code and executes reasonably quickly. For this reason I am not including any tests in this PR. I have tested the functionality manually and can see the entities periodically collected according to the config setting. If anyone has ideas about how to write good unit tests for this PR I am open to suggestions. --- ...receiver-metadata-collection-interval.yaml | 20 +++++++++++++++++++ receiver/k8sclusterreceiver/README.md | 7 +++++++ receiver/k8sclusterreceiver/config.go | 7 +++++++ receiver/k8sclusterreceiver/config_test.go | 2 ++ receiver/k8sclusterreceiver/factory.go | 6 ++++-- receiver/k8sclusterreceiver/factory_test.go | 1 + .../k8sclusterreceiver/testdata/config.yaml | 1 + receiver/k8sclusterreceiver/watcher.go | 2 +- receiver/k8sclusterreceiver/watcher_test.go | 1 + 9 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 .chloggen/k8sclusterreceiver-metadata-collection-interval.yaml diff --git a/.chloggen/k8sclusterreceiver-metadata-collection-interval.yaml b/.chloggen/k8sclusterreceiver-metadata-collection-interval.yaml new file mode 100644 index 000000000000..6b49439be3d2 --- /dev/null +++ b/.chloggen/k8sclusterreceiver-metadata-collection-interval.yaml @@ -0,0 +1,20 @@ +# Use this changelog template to create an entry for release notes. +# If your change doesn't affect end users, such as a test fix or a tooling change, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. + +# 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. filelogreceiver) +component: k8sclustereceiver + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Report entity state periodically + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [24413] + +# (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: diff --git a/receiver/k8sclusterreceiver/README.md b/receiver/k8sclusterreceiver/README.md index e82292bd8b71..f625fd388750 100644 --- a/receiver/k8sclusterreceiver/README.md +++ b/receiver/k8sclusterreceiver/README.md @@ -38,6 +38,13 @@ The following settings are optional: for events using K8s API. However, the metrics collected are emitted only once every collection interval. `collection_interval` will determine the frequency at which metrics are emitted by this receiver. +- `metadata_collection_interval` (default = `5m`): Collection interval for metadata +for K8s entities such as pods, nodes, etc. +Metadata of the particular entity in the cluster is collected when the entity changes. +In addition metadata of all entities is collected periodically even if no changes happen. +This setting controls the interval between periodic collections. +Setting the duration to 0 will disable periodic collection (however will not impact +metadata collection on changes). - `node_conditions_to_report` (default = `[Ready]`): An array of node conditions this receiver should report. See [here](https://kubernetes.io/docs/concepts/architecture/nodes/#condition) for diff --git a/receiver/k8sclusterreceiver/config.go b/receiver/k8sclusterreceiver/config.go index d85d9721903a..7f86e68ccf6f 100644 --- a/receiver/k8sclusterreceiver/config.go +++ b/receiver/k8sclusterreceiver/config.go @@ -28,6 +28,13 @@ type Config struct { // Whether OpenShift supprot should be enabled or not. Distribution string `mapstructure:"distribution"` + + // Collection interval for metadata. + // Metadata of the particular entity in the cluster is collected when the entity changes. + // In addition metadata of all entities is collected periodically even if no changes happen. + // Setting the duration to 0 will disable periodic collection (however will not impact + // metadata collection on changes). + MetadataCollectionInterval time.Duration `mapstructure:"metadata_collection_interval"` } func (cfg *Config) Validate() error { diff --git a/receiver/k8sclusterreceiver/config_test.go b/receiver/k8sclusterreceiver/config_test.go index 1fed2f4d076e..46addb88c3b0 100644 --- a/receiver/k8sclusterreceiver/config_test.go +++ b/receiver/k8sclusterreceiver/config_test.go @@ -43,6 +43,7 @@ func TestLoadConfig(t *testing.T) { APIConfig: k8sconfig.APIConfig{ AuthType: k8sconfig.AuthTypeServiceAccount, }, + MetadataCollectionInterval: 30 * time.Minute, }, }, { @@ -54,6 +55,7 @@ func TestLoadConfig(t *testing.T) { APIConfig: k8sconfig.APIConfig{ AuthType: k8sconfig.AuthTypeServiceAccount, }, + MetadataCollectionInterval: 5 * time.Minute, }, }, } diff --git a/receiver/k8sclusterreceiver/factory.go b/receiver/k8sclusterreceiver/factory.go index bc516001c6d0..5b4e98c0fce1 100644 --- a/receiver/k8sclusterreceiver/factory.go +++ b/receiver/k8sclusterreceiver/factory.go @@ -20,8 +20,9 @@ const ( distributionOpenShift = "openshift" // Default config values. - defaultCollectionInterval = 10 * time.Second - defaultDistribution = distributionKubernetes + defaultCollectionInterval = 10 * time.Second + defaultDistribution = distributionKubernetes + defaultMetadataCollectionInterval = 5 * time.Minute ) var defaultNodeConditionsToReport = []string{"Ready"} @@ -34,6 +35,7 @@ func createDefaultConfig() component.Config { APIConfig: k8sconfig.APIConfig{ AuthType: k8sconfig.AuthTypeServiceAccount, }, + MetadataCollectionInterval: defaultMetadataCollectionInterval, } } diff --git a/receiver/k8sclusterreceiver/factory_test.go b/receiver/k8sclusterreceiver/factory_test.go index 13677bbfd1d9..f1a1d228120b 100644 --- a/receiver/k8sclusterreceiver/factory_test.go +++ b/receiver/k8sclusterreceiver/factory_test.go @@ -38,6 +38,7 @@ func TestFactory(t *testing.T) { APIConfig: k8sconfig.APIConfig{ AuthType: k8sconfig.AuthTypeServiceAccount, }, + MetadataCollectionInterval: 5 * time.Minute, }, rCfg) r, err := f.CreateTracesReceiver( diff --git a/receiver/k8sclusterreceiver/testdata/config.yaml b/receiver/k8sclusterreceiver/testdata/config.yaml index cf3b366e755c..b7d2737c4e79 100644 --- a/receiver/k8sclusterreceiver/testdata/config.yaml +++ b/receiver/k8sclusterreceiver/testdata/config.yaml @@ -4,6 +4,7 @@ k8s_cluster/all_settings: node_conditions_to_report: [ "Ready", "MemoryPressure" ] allocatable_types_to_report: [ "cpu","memory" ] metadata_exporters: [ nop ] + metadata_collection_interval: 30m k8s_cluster/partial_settings: collection_interval: 30s distribution: openshift diff --git a/receiver/k8sclusterreceiver/watcher.go b/receiver/k8sclusterreceiver/watcher.go index 824803602e88..524d633135dd 100644 --- a/receiver/k8sclusterreceiver/watcher.go +++ b/receiver/k8sclusterreceiver/watcher.go @@ -105,7 +105,7 @@ func (rw *resourceWatcher) initialize() error { } func (rw *resourceWatcher) prepareSharedInformerFactory() error { - factory := informers.NewSharedInformerFactoryWithOptions(rw.client, 0) + factory := informers.NewSharedInformerFactoryWithOptions(rw.client, rw.config.MetadataCollectionInterval) // Map of supported group version kinds by name of a kind. // If none of the group versions are supported by k8s server for a specific kind, diff --git a/receiver/k8sclusterreceiver/watcher_test.go b/receiver/k8sclusterreceiver/watcher_test.go index 19a5f7f81d15..96a388d3fd0e 100644 --- a/receiver/k8sclusterreceiver/watcher_test.go +++ b/receiver/k8sclusterreceiver/watcher_test.go @@ -198,6 +198,7 @@ func TestPrepareSharedInformerFactory(t *testing.T) { client: newFakeClientWithAllResources(), logger: obsLogger, dataCollector: collection.NewDataCollector(receivertest.NewNopCreateSettings(), []string{}, []string{}), + config: &Config{}, } assert.NoError(t, rw.prepareSharedInformerFactory()) From 8a4348cb009d1448dc647f2bdad27304b8ce53d3 Mon Sep 17 00:00:00 2001 From: Antoine Toulme Date: Mon, 24 Jul 2023 00:31:05 -0700 Subject: [PATCH 23/42] [chore] add codeowners to metadata (#24404) **Description:** This is a minute set of changes, adding codeowners to every component and additional folders as designed by the CODEOWNERS file. Notable changes are renames: extension/encodingextension/metadata.yml -> extension/encodingextension/metadata.yaml cmd/mdatagen/metadata.yaml -> cmd/mdatagen/metadata-sample.yaml **Link to tracking Issue:** This is step 2 of #23367 **Testing:** I have used a tool I created to regenerate CODEOWNERS from this file. --- cmd/configschema/metadata.yaml | 6 + cmd/mdatagen/doc.go | 2 +- cmd/mdatagen/loader_test.go | 2 +- cmd/mdatagen/main.go | 18 ++- cmd/mdatagen/metadata-sample.yaml | 105 +++++++++++++++++ cmd/mdatagen/metadata.yaml | 107 +----------------- cmd/mdatagen/templates/status.go.tmpl | 2 + cmd/mdatagen/validate.go | 6 +- cmd/opampsupervisor/metadata.yaml | 6 + cmd/otelcontribcol/metadata.yaml | 6 + cmd/oteltestbedcol/metadata.yaml | 6 + cmd/telemetrygen/README.md | 1 + cmd/telemetrygen/metadata.yaml | 2 + confmap/provider/s3provider/metadata.yaml | 3 + connector/countconnector/README.md | 1 + connector/countconnector/metadata.yaml | 2 + connector/routingconnector/README.md | 1 + connector/routingconnector/metadata.yaml | 2 + connector/servicegraphconnector/README.md | 1 + connector/servicegraphconnector/metadata.yaml | 2 + connector/spanmetricsconnector/README.md | 1 + connector/spanmetricsconnector/metadata.yaml | 2 + .../alibabacloudlogserviceexporter/README.md | 1 + .../metadata.yaml | 2 + exporter/awscloudwatchlogsexporter/README.md | 1 + .../awscloudwatchlogsexporter/metadata.yaml | 2 + exporter/awsemfexporter/README.md | 1 + exporter/awsemfexporter/metadata.yaml | 2 + exporter/awskinesisexporter/README.md | 1 + exporter/awskinesisexporter/metadata.yaml | 2 + exporter/awss3exporter/README.md | 1 + exporter/awss3exporter/metadata.yaml | 2 + exporter/awsxrayexporter/README.md | 1 + exporter/awsxrayexporter/metadata.yaml | 2 + exporter/azuredataexplorerexporter/README.md | 1 + .../azuredataexplorerexporter/metadata.yaml | 4 +- exporter/azuremonitorexporter/README.md | 1 + exporter/azuremonitorexporter/metadata.yaml | 4 +- exporter/carbonexporter/README.md | 1 + exporter/carbonexporter/metadata.yaml | 2 + exporter/cassandraexporter/README.md | 1 + exporter/cassandraexporter/metadata.yaml | 2 + exporter/clickhouseexporter/README.md | 1 + exporter/clickhouseexporter/metadata.yaml | 2 + exporter/coralogixexporter/README.md | 1 + exporter/coralogixexporter/metadata.yaml | 2 + exporter/datadogexporter/README.md | 1 + exporter/datadogexporter/metadata.yaml | 2 + exporter/datasetexporter/README.md | 1 + exporter/datasetexporter/metadata.yaml | 2 + exporter/dynatraceexporter/README.md | 1 + exporter/dynatraceexporter/metadata.yaml | 2 + exporter/elasticsearchexporter/README.md | 1 + exporter/elasticsearchexporter/metadata.yaml | 2 + exporter/f5cloudexporter/README.md | 1 + exporter/f5cloudexporter/metadata.yaml | 2 + exporter/fileexporter/README.md | 1 + exporter/fileexporter/metadata.yaml | 2 + exporter/googlecloudexporter/README.md | 1 + exporter/googlecloudexporter/metadata.yaml | 2 + exporter/googlecloudpubsubexporter/README.md | 1 + .../googlecloudpubsubexporter/metadata.yaml | 2 + .../googlemanagedprometheusexporter/README.md | 1 + .../metadata.yaml | 2 + exporter/influxdbexporter/README.md | 1 + exporter/influxdbexporter/metadata.yaml | 2 + exporter/instanaexporter/README.md | 1 + exporter/instanaexporter/metadata.yaml | 2 + exporter/jaegerexporter/README.md | 1 + exporter/jaegerexporter/metadata.yaml | 2 + exporter/jaegerthrifthttpexporter/README.md | 1 + .../jaegerthrifthttpexporter/metadata.yaml | 2 + exporter/kafkaexporter/README.md | 1 + exporter/kafkaexporter/metadata.yaml | 2 + exporter/loadbalancingexporter/README.md | 1 + exporter/loadbalancingexporter/metadata.yaml | 2 + exporter/logicmonitorexporter/README.md | 1 + exporter/logicmonitorexporter/metadata.yaml | 2 + exporter/logzioexporter/README.md | 1 + exporter/logzioexporter/metadata.yaml | 2 + exporter/lokiexporter/README.md | 1 + exporter/lokiexporter/metadata.yaml | 2 + exporter/mezmoexporter/README.md | 1 + exporter/mezmoexporter/metadata.yaml | 2 + exporter/opencensusexporter/README.md | 1 + exporter/opencensusexporter/metadata.yaml | 2 + exporter/parquetexporter/README.md | 1 + exporter/parquetexporter/metadata.yaml | 2 + exporter/prometheusexporter/README.md | 1 + exporter/prometheusexporter/metadata.yaml | 2 + .../prometheusremotewriteexporter/README.md | 1 + .../metadata.yaml | 2 + exporter/pulsarexporter/README.md | 1 + exporter/pulsarexporter/metadata.yaml | 2 + exporter/sapmexporter/README.md | 1 + exporter/sapmexporter/metadata.yaml | 2 + exporter/sentryexporter/README.md | 1 + exporter/sentryexporter/metadata.yaml | 2 + exporter/signalfxexporter/README.md | 1 + exporter/signalfxexporter/metadata.yaml | 2 + exporter/skywalkingexporter/README.md | 1 + exporter/skywalkingexporter/metadata.yaml | 2 + exporter/splunkhecexporter/README.md | 1 + exporter/splunkhecexporter/metadata.yaml | 4 +- exporter/sumologicexporter/README.md | 1 + exporter/sumologicexporter/metadata.yaml | 2 + exporter/syslogexporter/README.md | 1 + exporter/syslogexporter/metadata.yaml | 2 + exporter/tanzuobservabilityexporter/README.md | 1 + .../tanzuobservabilityexporter/metadata.yaml | 2 + .../tencentcloudlogserviceexporter/README.md | 1 + .../metadata.yaml | 2 + exporter/zipkinexporter/README.md | 1 + exporter/zipkinexporter/metadata.yaml | 2 + extension/asapauthextension/README.md | 1 + extension/asapauthextension/metadata.yaml | 2 + extension/awsproxy/README.md | 1 + extension/awsproxy/metadata.yaml | 2 + extension/basicauthextension/README.md | 1 + extension/basicauthextension/metadata.yaml | 2 + extension/bearertokenauthextension/README.md | 1 + .../bearertokenauthextension/metadata.yaml | 2 + extension/encodingextension/README.md | 1 + extension/encodingextension/doc.go | 2 +- .../{metadata.yml => metadata.yaml} | 5 +- extension/headerssetterextension/README.md | 1 + .../headerssetterextension/metadata.yaml | 2 + extension/healthcheckextension/README.md | 1 + extension/healthcheckextension/metadata.yaml | 2 + extension/httpforwarder/README.md | 1 + extension/httpforwarder/metadata.yaml | 2 + extension/jaegerremotesampling/README.md | 1 + extension/jaegerremotesampling/metadata.yaml | 2 + extension/oauth2clientauthextension/README.md | 1 + .../oauth2clientauthextension/metadata.yaml | 2 + extension/observer/dockerobserver/README.md | 1 + .../observer/dockerobserver/metadata.yaml | 2 + extension/observer/ecsobserver/README.md | 1 + extension/observer/ecsobserver/metadata.yaml | 2 + extension/observer/ecstaskobserver/README.md | 1 + .../observer/ecstaskobserver/metadata.yaml | 2 + extension/observer/hostobserver/README.md | 1 + extension/observer/hostobserver/metadata.yaml | 2 + extension/observer/k8sobserver/README.md | 1 + extension/observer/k8sobserver/metadata.yaml | 2 + extension/observer/metadata.yaml | 3 + extension/oidcauthextension/README.md | 1 + extension/oidcauthextension/metadata.yaml | 2 + extension/pprofextension/README.md | 1 + extension/pprofextension/metadata.yaml | 2 + extension/sigv4authextension/README.md | 1 + extension/sigv4authextension/metadata.yaml | 2 + extension/storage/dbstorage/README.md | 1 + extension/storage/dbstorage/metadata.yaml | 2 + extension/storage/filestorage/README.md | 1 + extension/storage/filestorage/metadata.yaml | 2 + extension/storage/metadata.yaml | 3 + internal/aws/metadata.yaml | 3 + internal/coreinternal/metadata.yaml | 3 + internal/docker/metadata.yaml | 3 + internal/filter/metadata.yaml | 3 + internal/k8sconfig/metadata.yaml | 3 + internal/k8stest/metadata.yaml | 3 + internal/kubelet/metadata.yaml | 3 + internal/metadataproviders/metadata.yaml | 3 + internal/sharedcomponent/metadata.yaml | 5 + internal/splunk/metadata.yaml | 3 + internal/tools/metadata.yaml | 3 + pkg/batchperresourceattr/metadata.yaml | 3 + pkg/batchpersignal/metadata.yaml | 3 + pkg/experimentalmetricmetadata/metadata.yaml | 3 + pkg/ottl/metadata.yaml | 3 + pkg/pdatatest/metadata.yaml | 3 + pkg/pdatautil/metadata.yaml | 3 + pkg/resourcetotelemetry/metadata.yaml | 3 + pkg/stanza/metadata.yaml | 3 + pkg/translator/jaeger/metadata.yaml | 3 + pkg/translator/loki/metadata.yaml | 3 + pkg/translator/opencensus/metadata.yaml | 3 + pkg/translator/prometheus/metadata.yaml | 3 + .../prometheusremotewrite/metadata.yaml | 3 + pkg/translator/signalfx/metadata.yaml | 3 + pkg/translator/zipkin/metadata.yaml | 3 + pkg/winperfcounters/metadata.yaml | 3 + processor/attributesprocessor/README.md | 1 + processor/attributesprocessor/metadata.yaml | 2 + .../cumulativetodeltaprocessor/README.md | 1 + .../cumulativetodeltaprocessor/metadata.yaml | 2 + processor/datadogprocessor/README.md | 1 + processor/datadogprocessor/metadata.yaml | 2 + processor/deltatorateprocessor/README.md | 1 + processor/deltatorateprocessor/metadata.yaml | 2 + processor/filterprocessor/README.md | 1 + processor/filterprocessor/metadata.yaml | 2 + processor/groupbyattrsprocessor/README.md | 1 + processor/groupbyattrsprocessor/metadata.yaml | 2 + processor/groupbytraceprocessor/README.md | 1 + processor/groupbytraceprocessor/metadata.yaml | 2 + processor/k8sattributesprocessor/README.md | 1 + .../k8sattributesprocessor/metadata.yaml | 3 +- processor/logstransformprocessor/README.md | 1 + .../logstransformprocessor/metadata.yaml | 2 + .../metricsgenerationprocessor/README.md | 1 + .../metricsgenerationprocessor/metadata.yaml | 2 + processor/metricstransformprocessor/README.md | 1 + .../metricstransformprocessor/metadata.yaml | 2 + .../probabilisticsamplerprocessor/README.md | 1 + .../metadata.yaml | 2 + processor/redactionprocessor/README.md | 1 + processor/redactionprocessor/metadata.yaml | 2 + processor/remoteobserverprocessor/README.md | 1 + .../remoteobserverprocessor/metadata.yaml | 2 + .../resourcedetectionprocessor/README.md | 1 + .../internal/metadata/generated_status.go | 7 ++ .../internal/azure/metadata.yaml | 5 + .../internal/metadata/generated_status.go | 7 ++ .../internal/heroku/metadata.yaml | 5 + .../internal/metadata/generated_status.go | 7 ++ .../internal/openshift/metadata.yaml | 5 + .../resourcedetectionprocessor/metadata.yaml | 2 + processor/resourceprocessor/README.md | 1 + processor/resourceprocessor/metadata.yaml | 2 + processor/routingprocessor/README.md | 1 + processor/routingprocessor/metadata.yaml | 2 + processor/schemaprocessor/README.md | 1 + processor/schemaprocessor/metadata.yaml | 2 + processor/servicegraphprocessor/README.md | 1 + processor/servicegraphprocessor/metadata.yaml | 2 + processor/spanmetricsprocessor/README.md | 1 + processor/spanmetricsprocessor/metadata.yaml | 2 + processor/spanprocessor/README.md | 1 + processor/spanprocessor/metadata.yaml | 2 + processor/tailsamplingprocessor/README.md | 1 + processor/tailsamplingprocessor/metadata.yaml | 2 + processor/transformprocessor/README.md | 1 + processor/transformprocessor/metadata.yaml | 2 + receiver/activedirectorydsreceiver/README.md | 1 + .../activedirectorydsreceiver/metadata.yaml | 2 + receiver/aerospikereceiver/README.md | 1 + receiver/aerospikereceiver/metadata.yaml | 2 + receiver/apachereceiver/README.md | 1 + receiver/apachereceiver/metadata.yaml | 2 + receiver/apachesparkreceiver/README.md | 1 + receiver/apachesparkreceiver/metadata.yaml | 2 + .../awscloudwatchmetricsreceiver/README.md | 1 + .../metadata.yaml | 2 + receiver/awscloudwatchreceiver/README.md | 1 + receiver/awscloudwatchreceiver/metadata.yaml | 3 +- .../awscontainerinsightreceiver/README.md | 1 + .../awscontainerinsightreceiver/metadata.yaml | 2 + .../awsecscontainermetricsreceiver/README.md | 1 + .../metadata.yaml | 3 +- receiver/awsfirehosereceiver/README.md | 1 + receiver/awsfirehosereceiver/metadata.yaml | 3 +- receiver/awsxrayreceiver/README.md | 1 + receiver/awsxrayreceiver/metadata.yaml | 2 + receiver/azureblobreceiver/README.md | 1 + receiver/azureblobreceiver/metadata.yaml | 3 +- receiver/azureeventhubreceiver/README.md | 1 + receiver/azureeventhubreceiver/metadata.yaml | 2 + receiver/azuremonitorreceiver/README.md | 1 + receiver/azuremonitorreceiver/metadata.yaml | 2 + receiver/bigipreceiver/README.md | 1 + receiver/bigipreceiver/metadata.yaml | 2 + receiver/carbonreceiver/README.md | 1 + receiver/carbonreceiver/metadata.yaml | 2 + receiver/chronyreceiver/README.md | 1 + receiver/chronyreceiver/metadata.yaml | 2 + receiver/cloudflarereceiver/README.md | 1 + receiver/cloudflarereceiver/metadata.yaml | 3 +- receiver/cloudfoundryreceiver/README.md | 1 + receiver/cloudfoundryreceiver/metadata.yaml | 3 +- receiver/collectdreceiver/README.md | 1 + receiver/collectdreceiver/metadata.yaml | 3 +- receiver/couchdbreceiver/README.md | 1 + receiver/couchdbreceiver/metadata.yaml | 2 + receiver/datadogreceiver/README.md | 1 + receiver/datadogreceiver/metadata.yaml | 3 +- receiver/dockerstatsreceiver/README.md | 1 + receiver/dockerstatsreceiver/metadata.yaml | 2 + receiver/elasticsearchreceiver/README.md | 1 + receiver/elasticsearchreceiver/metadata.yaml | 2 + receiver/expvarreceiver/README.md | 1 + receiver/expvarreceiver/metadata.yaml | 2 + receiver/filelogreceiver/README.md | 1 + receiver/filelogreceiver/metadata.yaml | 3 +- receiver/filereceiver/README.md | 1 + receiver/filereceiver/metadata.yaml | 3 +- receiver/filestatsreceiver/README.md | 1 + receiver/filestatsreceiver/metadata.yaml | 2 + receiver/flinkmetricsreceiver/README.md | 1 + receiver/flinkmetricsreceiver/metadata.yaml | 2 + receiver/fluentforwardreceiver/README.md | 1 + receiver/fluentforwardreceiver/metadata.yaml | 3 +- receiver/googlecloudpubsubreceiver/README.md | 1 + .../googlecloudpubsubreceiver/metadata.yaml | 3 +- receiver/googlecloudspannerreceiver/README.md | 1 + .../googlecloudspannerreceiver/metadata.yaml | 3 +- receiver/haproxyreceiver/README.md | 1 + receiver/haproxyreceiver/metadata.yaml | 2 + receiver/hostmetricsreceiver/README.md | 1 + receiver/hostmetricsreceiver/metadata.yaml | 3 +- receiver/httpcheckreceiver/README.md | 1 + receiver/httpcheckreceiver/metadata.yaml | 2 + receiver/iisreceiver/README.md | 1 + receiver/iisreceiver/metadata.yaml | 2 + receiver/influxdbreceiver/README.md | 1 + receiver/influxdbreceiver/metadata.yaml | 3 +- receiver/jaegerreceiver/README.md | 1 + receiver/jaegerreceiver/metadata.yaml | 2 + receiver/jmxreceiver/README.md | 1 + receiver/jmxreceiver/metadata.yaml | 3 +- receiver/journaldreceiver/README.md | 1 + receiver/journaldreceiver/metadata.yaml | 3 +- receiver/k8sclusterreceiver/README.md | 1 + receiver/k8sclusterreceiver/metadata.yaml | 3 +- receiver/k8seventsreceiver/README.md | 1 + receiver/k8seventsreceiver/metadata.yaml | 3 +- receiver/k8sobjectsreceiver/README.md | 1 + receiver/k8sobjectsreceiver/metadata.yaml | 3 +- receiver/kafkametricsreceiver/README.md | 1 + receiver/kafkametricsreceiver/metadata.yaml | 2 + receiver/kafkareceiver/README.md | 1 + receiver/kafkareceiver/metadata.yaml | 2 + receiver/kubeletstatsreceiver/README.md | 1 + receiver/kubeletstatsreceiver/metadata.yaml | 2 + receiver/lokireceiver/README.md | 1 + receiver/lokireceiver/metadata.yaml | 2 + receiver/memcachedreceiver/README.md | 1 + receiver/memcachedreceiver/metadata.yaml | 2 + receiver/mongodbatlasreceiver/README.md | 1 + receiver/mongodbatlasreceiver/metadata.yaml | 2 + receiver/mongodbreceiver/README.md | 1 + receiver/mongodbreceiver/metadata.yaml | 2 + receiver/mysqlreceiver/README.md | 1 + receiver/mysqlreceiver/metadata.yaml | 2 + receiver/nginxreceiver/README.md | 1 + receiver/nginxreceiver/metadata.yaml | 2 + receiver/nsxtreceiver/README.md | 1 + receiver/nsxtreceiver/metadata.yaml | 4 +- receiver/opencensusreceiver/README.md | 1 + receiver/opencensusreceiver/metadata.yaml | 2 + receiver/oracledbreceiver/README.md | 1 + receiver/oracledbreceiver/metadata.yaml | 2 + receiver/otlpjsonfilereceiver/README.md | 1 + receiver/otlpjsonfilereceiver/metadata.yaml | 2 + receiver/podmanreceiver/README.md | 1 + receiver/podmanreceiver/metadata.yaml | 2 + receiver/postgresqlreceiver/README.md | 1 + receiver/postgresqlreceiver/metadata.yaml | 2 + receiver/prometheusexecreceiver/README.md | 1 + receiver/prometheusexecreceiver/metadata.yaml | 3 +- receiver/prometheusreceiver/README.md | 1 + receiver/prometheusreceiver/metadata.yaml | 2 + receiver/pulsarreceiver/README.md | 1 + receiver/pulsarreceiver/metadata.yaml | 3 +- receiver/purefareceiver/README.md | 1 + receiver/purefareceiver/metadata.yaml | 3 +- receiver/purefbreceiver/README.md | 1 + receiver/purefbreceiver/metadata.yaml | 3 +- receiver/rabbitmqreceiver/README.md | 1 + receiver/rabbitmqreceiver/metadata.yaml | 2 + receiver/receivercreator/README.md | 1 + receiver/receivercreator/metadata.yaml | 2 + receiver/redisreceiver/README.md | 1 + receiver/redisreceiver/metadata.yaml | 2 + receiver/riakreceiver/README.md | 1 + receiver/riakreceiver/metadata.yaml | 2 + receiver/saphanareceiver/README.md | 1 + receiver/saphanareceiver/metadata.yaml | 2 + receiver/sapmreceiver/README.md | 1 + receiver/sapmreceiver/metadata.yaml | 2 + receiver/simpleprometheusreceiver/README.md | 1 + .../simpleprometheusreceiver/metadata.yaml | 3 +- receiver/skywalkingreceiver/README.md | 1 + receiver/skywalkingreceiver/metadata.yaml | 3 +- receiver/snmpreceiver/README.md | 1 + receiver/snmpreceiver/metadata.yaml | 2 + receiver/snowflakereceiver/README.md | 1 + receiver/snowflakereceiver/metadata.yaml | 3 +- receiver/solacereceiver/README.md | 1 + receiver/solacereceiver/metadata.yaml | 3 +- .../splunkenterprisereceiver/metadata.yaml | 2 + receiver/sqlqueryreceiver/README.md | 1 + receiver/sqlqueryreceiver/metadata.yaml | 2 + receiver/sqlserverreceiver/README.md | 1 + receiver/sqlserverreceiver/metadata.yaml | 2 + receiver/sshcheckreceiver/README.md | 1 + receiver/sshcheckreceiver/metadata.yaml | 4 +- receiver/statsdreceiver/README.md | 1 + receiver/statsdreceiver/metadata.yaml | 2 + receiver/syslogreceiver/README.md | 1 + receiver/syslogreceiver/metadata.yaml | 3 +- receiver/tcplogreceiver/README.md | 1 + receiver/tcplogreceiver/metadata.yaml | 3 +- receiver/udplogreceiver/README.md | 1 + receiver/udplogreceiver/metadata.yaml | 3 +- receiver/vcenterreceiver/README.md | 1 + receiver/vcenterreceiver/metadata.yaml | 2 + receiver/wavefrontreceiver/README.md | 1 + receiver/wavefrontreceiver/metadata.yaml | 3 +- receiver/windowseventlogreceiver/README.md | 1 + .../windowseventlogreceiver/metadata.yaml | 3 +- .../windowsperfcountersreceiver/README.md | 1 + .../windowsperfcountersreceiver/metadata.yaml | 3 +- receiver/zipkinreceiver/README.md | 1 + receiver/zipkinreceiver/metadata.yaml | 2 + receiver/zookeeperreceiver/README.md | 1 + receiver/zookeeperreceiver/metadata.yaml | 2 + testbed/metadata.yaml | 3 + .../mockawsxrayreceiver/metadata.yaml | 3 + .../mockdatadogagentexporter/metadata.yaml | 3 + 412 files changed, 839 insertions(+), 156 deletions(-) create mode 100644 cmd/configschema/metadata.yaml create mode 100644 cmd/mdatagen/metadata-sample.yaml create mode 100644 cmd/opampsupervisor/metadata.yaml create mode 100644 cmd/otelcontribcol/metadata.yaml create mode 100644 cmd/oteltestbedcol/metadata.yaml create mode 100644 confmap/provider/s3provider/metadata.yaml rename extension/encodingextension/{metadata.yml => metadata.yaml} (58%) create mode 100644 extension/observer/metadata.yaml create mode 100644 extension/storage/metadata.yaml create mode 100644 internal/aws/metadata.yaml create mode 100644 internal/coreinternal/metadata.yaml create mode 100644 internal/docker/metadata.yaml create mode 100644 internal/filter/metadata.yaml create mode 100644 internal/k8sconfig/metadata.yaml create mode 100644 internal/k8stest/metadata.yaml create mode 100644 internal/kubelet/metadata.yaml create mode 100644 internal/metadataproviders/metadata.yaml create mode 100644 internal/sharedcomponent/metadata.yaml create mode 100644 internal/splunk/metadata.yaml create mode 100644 internal/tools/metadata.yaml create mode 100644 pkg/batchperresourceattr/metadata.yaml create mode 100644 pkg/batchpersignal/metadata.yaml create mode 100644 pkg/experimentalmetricmetadata/metadata.yaml create mode 100644 pkg/ottl/metadata.yaml create mode 100644 pkg/pdatatest/metadata.yaml create mode 100644 pkg/pdatautil/metadata.yaml create mode 100644 pkg/resourcetotelemetry/metadata.yaml create mode 100644 pkg/stanza/metadata.yaml create mode 100644 pkg/translator/jaeger/metadata.yaml create mode 100644 pkg/translator/loki/metadata.yaml create mode 100644 pkg/translator/opencensus/metadata.yaml create mode 100644 pkg/translator/prometheus/metadata.yaml create mode 100644 pkg/translator/prometheusremotewrite/metadata.yaml create mode 100644 pkg/translator/signalfx/metadata.yaml create mode 100644 pkg/translator/zipkin/metadata.yaml create mode 100644 pkg/winperfcounters/metadata.yaml create mode 100644 processor/resourcedetectionprocessor/internal/azure/internal/metadata/generated_status.go create mode 100644 processor/resourcedetectionprocessor/internal/heroku/internal/metadata/generated_status.go create mode 100644 processor/resourcedetectionprocessor/internal/openshift/internal/metadata/generated_status.go create mode 100644 testbed/metadata.yaml create mode 100644 testbed/mockdatareceivers/mockawsxrayreceiver/metadata.yaml create mode 100644 testbed/mockdatasenders/mockdatadogagentexporter/metadata.yaml diff --git a/cmd/configschema/metadata.yaml b/cmd/configschema/metadata.yaml new file mode 100644 index 000000000000..6f3149878357 --- /dev/null +++ b/cmd/configschema/metadata.yaml @@ -0,0 +1,6 @@ +type: configschema + +status: + class: cmd + codeowners: + active: [mx-psi, dmitryax, pmcollins] \ No newline at end of file diff --git a/cmd/mdatagen/doc.go b/cmd/mdatagen/doc.go index 20dc6df918f6..8f1fc6a71768 100644 --- a/cmd/mdatagen/doc.go +++ b/cmd/mdatagen/doc.go @@ -2,6 +2,6 @@ // 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 +//go:generate mdatagen metadata-sample.yaml package main diff --git a/cmd/mdatagen/loader_test.go b/cmd/mdatagen/loader_test.go index c0514259e822..a2c6be28def9 100644 --- a/cmd/mdatagen/loader_test.go +++ b/cmd/mdatagen/loader_test.go @@ -18,7 +18,7 @@ func Test_loadMetadata(t *testing.T) { wantErr string }{ { - name: "metadata.yaml", + name: "metadata-sample.yaml", want: metadata{ Type: "file", SemConvVersion: "1.9.0", diff --git a/cmd/mdatagen/main.go b/cmd/mdatagen/main.go index 4921d747676a..9a56b1ade1eb 100644 --- a/cmd/mdatagen/main.go +++ b/cmd/mdatagen/main.go @@ -61,11 +61,13 @@ func run(ymlPath string) error { return err } - if err = inlineReplace( - filepath.Join(tmplDir, "readme.md.tmpl"), - filepath.Join(ymlDir, "README.md"), - md, statusStart, statusEnd); err != nil { - return err + if _, err = os.Stat(filepath.Join(ymlDir, "README.md")); err == nil { + if err = inlineReplace( + filepath.Join(tmplDir, "readme.md.tmpl"), + filepath.Join(ymlDir, "README.md"), + md, statusStart, statusEnd); err != nil { + return err + } } } if len(md.Metrics) == 0 && len(md.ResourceAttributes) == 0 { @@ -143,7 +145,11 @@ func templatize(tmplFile string, md metadata) *template.Template { "userLinks": func(elems []string) []string { result := make([]string, len(elems)) for i, elem := range elems { - result[i] = fmt.Sprintf("[@%s](https://www.github.com/%s)", elem, elem) + if elem == "open-telemetry/collector-approvers" { + result[i] = "[@open-telemetry/collector-approvers](https://github.com/orgs/open-telemetry/teams/collector-approvers)" + } else { + result[i] = fmt.Sprintf("[@%s](https://www.github.com/%s)", elem, elem) + } } return result }, diff --git a/cmd/mdatagen/metadata-sample.yaml b/cmd/mdatagen/metadata-sample.yaml new file mode 100644 index 000000000000..054ca3824143 --- /dev/null +++ b/cmd/mdatagen/metadata-sample.yaml @@ -0,0 +1,105 @@ +# Sample metric metadata file with all available configurations. + +type: file + +sem_conv_version: 1.9.0 + +status: + class: receiver + stability: + development: [logs] + beta: [traces] + stable: [metrics] + distributions: [contrib] + 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 + +attributes: + string_attr: + description: Attribute with any string value. + type: string + + overridden_int_attr: + name_override: state + description: Integer attribute with overridden name. + type: int + + enum_attr: + description: Attribute with a known set of string values. + type: string + enum: [red, green, blue] + + boolean_attr: + description: Attribute with a boolean value. + type: bool + + slice_attr: + description: Attribute with a slice value. + type: slice + + map_attr: + description: Attribute with a map value. + type: map + +metrics: + default.metric: + enabled: true + description: Monotonic cumulative sum int metric enabled by default. + extended_documentation: The metric will be become optional soon. + unit: s + sum: + value_type: int + monotonic: true + aggregation: cumulative + attributes: [string_attr, overridden_int_attr, enum_attr, slice_attr, map_attr] + warnings: + if_enabled_not_set: This metric will be disabled by default soon. + + optional.metric: + enabled: false + description: "[DEPRECATED] Gauge double metric disabled by default." + unit: 1 + gauge: + value_type: double + attributes: [string_attr, boolean_attr] + warnings: + if_configured: This metric is deprecated and will be removed soon. + + default.metric.to_be_removed: + enabled: true + description: "[DEPRECATED] Non-monotonic delta sum double metric enabled by default." + extended_documentation: The metric will be will be removed soon. + unit: s + sum: + value_type: double + monotonic: false + aggregation: delta + warnings: + if_enabled: This metric is deprecated and will be removed soon. diff --git a/cmd/mdatagen/metadata.yaml b/cmd/mdatagen/metadata.yaml index 054ca3824143..65bb097a9624 100644 --- a/cmd/mdatagen/metadata.yaml +++ b/cmd/mdatagen/metadata.yaml @@ -1,105 +1,6 @@ -# Sample metric metadata file with all available configurations. - -type: file - -sem_conv_version: 1.9.0 +type: mdatagen status: - class: receiver - stability: - development: [logs] - beta: [traces] - stable: [metrics] - distributions: [contrib] - 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 - -attributes: - string_attr: - description: Attribute with any string value. - type: string - - overridden_int_attr: - name_override: state - description: Integer attribute with overridden name. - type: int - - enum_attr: - description: Attribute with a known set of string values. - type: string - enum: [red, green, blue] - - boolean_attr: - description: Attribute with a boolean value. - type: bool - - slice_attr: - description: Attribute with a slice value. - type: slice - - map_attr: - description: Attribute with a map value. - type: map - -metrics: - default.metric: - enabled: true - description: Monotonic cumulative sum int metric enabled by default. - extended_documentation: The metric will be become optional soon. - unit: s - sum: - value_type: int - monotonic: true - aggregation: cumulative - attributes: [string_attr, overridden_int_attr, enum_attr, slice_attr, map_attr] - warnings: - if_enabled_not_set: This metric will be disabled by default soon. - - optional.metric: - enabled: false - description: "[DEPRECATED] Gauge double metric disabled by default." - unit: 1 - gauge: - value_type: double - attributes: [string_attr, boolean_attr] - warnings: - if_configured: This metric is deprecated and will be removed soon. - - default.metric.to_be_removed: - enabled: true - description: "[DEPRECATED] Non-monotonic delta sum double metric enabled by default." - extended_documentation: The metric will be will be removed soon. - unit: s - sum: - value_type: double - monotonic: false - aggregation: delta - warnings: - if_enabled: This metric is deprecated and will be removed soon. + class: cmd + codeowners: + active: [dmitryax] \ No newline at end of file diff --git a/cmd/mdatagen/templates/status.go.tmpl b/cmd/mdatagen/templates/status.go.tmpl index d91529049404..b9384570b8e6 100644 --- a/cmd/mdatagen/templates/status.go.tmpl +++ b/cmd/mdatagen/templates/status.go.tmpl @@ -2,9 +2,11 @@ package {{ .Package }} +{{- if .Status.Stability }} import ( "go.opentelemetry.io/collector/component" ) +{{- end }} const ( Type = "{{ .Type }}" diff --git a/cmd/mdatagen/validate.go b/cmd/mdatagen/validate.go index d8da40178e79..75bb09271e92 100644 --- a/cmd/mdatagen/validate.go +++ b/cmd/mdatagen/validate.go @@ -48,8 +48,10 @@ func (md *metadata) validateStatus() error { if err := md.Status.validateClass(); err != nil { errs = multierr.Append(errs, err) } - if err := md.Status.validateStability(); err != nil { - errs = multierr.Append(errs, err) + if md.Parent == "" { + if err := md.Status.validateStability(); err != nil { + errs = multierr.Append(errs, err) + } } return errs } diff --git a/cmd/opampsupervisor/metadata.yaml b/cmd/opampsupervisor/metadata.yaml new file mode 100644 index 000000000000..097313f86fb0 --- /dev/null +++ b/cmd/opampsupervisor/metadata.yaml @@ -0,0 +1,6 @@ +type: opampsupervisor + +status: + class: cmd + codeowners: + active: [evan-bradley, atoulme, tigrannajaryan] \ No newline at end of file diff --git a/cmd/otelcontribcol/metadata.yaml b/cmd/otelcontribcol/metadata.yaml new file mode 100644 index 000000000000..0b1f42508bf8 --- /dev/null +++ b/cmd/otelcontribcol/metadata.yaml @@ -0,0 +1,6 @@ +type: otelcontribcol + +status: + class: cmd + codeowners: + active: [] \ No newline at end of file diff --git a/cmd/oteltestbedcol/metadata.yaml b/cmd/oteltestbedcol/metadata.yaml new file mode 100644 index 000000000000..ac90b5c56685 --- /dev/null +++ b/cmd/oteltestbedcol/metadata.yaml @@ -0,0 +1,6 @@ +type: oteltestbedcol + +status: + class: cmd + codeowners: + active: [] \ No newline at end of file diff --git a/cmd/telemetrygen/README.md b/cmd/telemetrygen/README.md index b8757fd07184..d4c7c93f2d07 100644 --- a/cmd/telemetrygen/README.md +++ b/cmd/telemetrygen/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: traces | | | [development]: metrics, logs | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Acmd%2Ftelemetrygen%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Acmd%2Ftelemetrygen%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@mx-psi](https://www.github.com/mx-psi), [@codeboten](https://www.github.com/codeboten) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [development]: https://github.com/open-telemetry/opentelemetry-collector#development diff --git a/cmd/telemetrygen/metadata.yaml b/cmd/telemetrygen/metadata.yaml index 80089ed12591..505e1fab6978 100644 --- a/cmd/telemetrygen/metadata.yaml +++ b/cmd/telemetrygen/metadata.yaml @@ -5,3 +5,5 @@ status: stability: alpha: [traces] development: [metrics, logs] + codeowners: + active: [mx-psi, codeboten] diff --git a/confmap/provider/s3provider/metadata.yaml b/confmap/provider/s3provider/metadata.yaml new file mode 100644 index 000000000000..79f2d095d572 --- /dev/null +++ b/confmap/provider/s3provider/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [Aneurysm9] \ No newline at end of file diff --git a/connector/countconnector/README.md b/connector/countconnector/README.md index 018f1c54d027..74259cf058d5 100644 --- a/connector/countconnector/README.md +++ b/connector/countconnector/README.md @@ -4,6 +4,7 @@ | ------------- |-----------| | Distributions | [contrib], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aconnector%2Fcount%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aconnector%2Fcount%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@djaglowski](https://www.github.com/djaglowski), [@jpkrohling](https://www.github.com/jpkrohling) | [development]: https://github.com/open-telemetry/opentelemetry-collector#development [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/connector/countconnector/metadata.yaml b/connector/countconnector/metadata.yaml index 48358f5bef00..42ab007b9cad 100644 --- a/connector/countconnector/metadata.yaml +++ b/connector/countconnector/metadata.yaml @@ -5,3 +5,5 @@ status: stability: development: [traces_to_metrics, metrics_to_metrics, logs_to_metrics] distributions: [contrib, sumo] + codeowners: + active: [djaglowski, jpkrohling] diff --git a/connector/routingconnector/README.md b/connector/routingconnector/README.md index ecd7a6e5c0cb..79c55a3549f3 100644 --- a/connector/routingconnector/README.md +++ b/connector/routingconnector/README.md @@ -5,6 +5,7 @@ | ------------- |-----------| | Distributions | [contrib] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aconnector%2Frouting%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aconnector%2Frouting%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jpkrohling](https://www.github.com/jpkrohling), [@kovrus](https://www.github.com/kovrus), [@mwear](https://www.github.com/mwear) | [development]: https://github.com/open-telemetry/opentelemetry-collector#development [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/connector/routingconnector/metadata.yaml b/connector/routingconnector/metadata.yaml index c438ad21b0c3..cae3b0280c05 100644 --- a/connector/routingconnector/metadata.yaml +++ b/connector/routingconnector/metadata.yaml @@ -5,3 +5,5 @@ status: stability: development: [traces_to_traces, metrics_to_metrics, logs_to_logs] distributions: [contrib] + codeowners: + active: [jpkrohling, kovrus, mwear] diff --git a/connector/servicegraphconnector/README.md b/connector/servicegraphconnector/README.md index 89576e5f43d2..de3ce4c461e4 100644 --- a/connector/servicegraphconnector/README.md +++ b/connector/servicegraphconnector/README.md @@ -5,6 +5,7 @@ | ------------- |-----------| | Distributions | [contrib], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aconnector%2Fservicegraph%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aconnector%2Fservicegraph%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jpkrohling](https://www.github.com/jpkrohling), [@mapno](https://www.github.com/mapno) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/connector/servicegraphconnector/metadata.yaml b/connector/servicegraphconnector/metadata.yaml index ef39f2df7f72..cb3ab56164cc 100644 --- a/connector/servicegraphconnector/metadata.yaml +++ b/connector/servicegraphconnector/metadata.yaml @@ -5,3 +5,5 @@ status: stability: alpha: [traces_to_metrics] distributions: [contrib, sumo] + codeowners: + active: [jpkrohling, mapno] diff --git a/connector/spanmetricsconnector/README.md b/connector/spanmetricsconnector/README.md index a4d319e13a64..d81e7354c9b5 100644 --- a/connector/spanmetricsconnector/README.md +++ b/connector/spanmetricsconnector/README.md @@ -5,6 +5,7 @@ | ------------- |-----------| | Distributions | [contrib], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aconnector%2Fspanmetrics%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aconnector%2Fspanmetrics%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@albertteoh](https://www.github.com/albertteoh), [@kovrus](https://www.github.com/kovrus) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/connector/spanmetricsconnector/metadata.yaml b/connector/spanmetricsconnector/metadata.yaml index 67c8a76b3bf6..e01dba7cbd30 100644 --- a/connector/spanmetricsconnector/metadata.yaml +++ b/connector/spanmetricsconnector/metadata.yaml @@ -5,3 +5,5 @@ status: stability: alpha: [traces_to_metrics] distributions: [contrib, sumo] + codeowners: + active: [albertteoh, kovrus] diff --git a/exporter/alibabacloudlogserviceexporter/README.md b/exporter/alibabacloudlogserviceexporter/README.md index 10db7d6ff493..1aacbbf1d5a1 100644 --- a/exporter/alibabacloudlogserviceexporter/README.md +++ b/exporter/alibabacloudlogserviceexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces, metrics, logs | | Distributions | [contrib], [observiq] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Falibabacloudlogservice%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Falibabacloudlogservice%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@shabicheng](https://www.github.com/shabicheng), [@kongluoxing](https://www.github.com/kongluoxing), [@qiansheng91](https://www.github.com/qiansheng91) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/alibabacloudlogserviceexporter/metadata.yaml b/exporter/alibabacloudlogserviceexporter/metadata.yaml index 68fa1f60d7d6..4f2b6cb14f64 100644 --- a/exporter/alibabacloudlogserviceexporter/metadata.yaml +++ b/exporter/alibabacloudlogserviceexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [traces, metrics, logs] distributions: [contrib, observiq] + codeowners: + active: [shabicheng, kongluoxing, qiansheng91] diff --git a/exporter/awscloudwatchlogsexporter/README.md b/exporter/awscloudwatchlogsexporter/README.md index 9dd4af054e58..b5f75ca54a64 100644 --- a/exporter/awscloudwatchlogsexporter/README.md +++ b/exporter/awscloudwatchlogsexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: logs | | Distributions | [contrib], [observiq] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fawscloudwatchlogs%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fawscloudwatchlogs%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@boostchicken](https://www.github.com/boostchicken) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/awscloudwatchlogsexporter/metadata.yaml b/exporter/awscloudwatchlogsexporter/metadata.yaml index c5d58fd21633..ff2ec39fd996 100644 --- a/exporter/awscloudwatchlogsexporter/metadata.yaml +++ b/exporter/awscloudwatchlogsexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [logs] distributions: [contrib, observiq] + codeowners: + active: [boostchicken] diff --git a/exporter/awsemfexporter/README.md b/exporter/awsemfexporter/README.md index daecc40096ce..33e5b701a23b 100644 --- a/exporter/awsemfexporter/README.md +++ b/exporter/awsemfexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [contrib], [aws], [observiq] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fawsemf%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fawsemf%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@Aneurysm9](https://www.github.com/Aneurysm9), [@shaochengwang](https://www.github.com/shaochengwang), [@mxiamxia](https://www.github.com/mxiamxia) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/awsemfexporter/metadata.yaml b/exporter/awsemfexporter/metadata.yaml index 625461c5f47d..1c9837072dc0 100644 --- a/exporter/awsemfexporter/metadata.yaml +++ b/exporter/awsemfexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [metrics] distributions: [contrib, aws, observiq] + codeowners: + active: [Aneurysm9, shaochengwang, mxiamxia] diff --git a/exporter/awskinesisexporter/README.md b/exporter/awskinesisexporter/README.md index 9b587ac479ed..d420071e54cd 100644 --- a/exporter/awskinesisexporter/README.md +++ b/exporter/awskinesisexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces, metrics, logs | | Distributions | [contrib], [observiq] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fawskinesis%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fawskinesis%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@Aneurysm9](https://www.github.com/Aneurysm9), [@MovieStoreGuy](https://www.github.com/MovieStoreGuy) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/awskinesisexporter/metadata.yaml b/exporter/awskinesisexporter/metadata.yaml index 3d974ef170c4..c35b07494fc0 100644 --- a/exporter/awskinesisexporter/metadata.yaml +++ b/exporter/awskinesisexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [traces, metrics, logs] distributions: [contrib, observiq] + codeowners: + active: [Aneurysm9, MovieStoreGuy] diff --git a/exporter/awss3exporter/README.md b/exporter/awss3exporter/README.md index 3b8dc3d25056..ceaa6d3186bb 100644 --- a/exporter/awss3exporter/README.md +++ b/exporter/awss3exporter/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: traces, metrics, logs | | Distributions | [contrib], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fawss3%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fawss3%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@atoulme](https://www.github.com/atoulme), [@pdelewski](https://www.github.com/pdelewski) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/awss3exporter/metadata.yaml b/exporter/awss3exporter/metadata.yaml index 8616063b522e..2c3f6559028b 100644 --- a/exporter/awss3exporter/metadata.yaml +++ b/exporter/awss3exporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: alpha: [traces, metrics, logs] distributions: [contrib, observiq, sumo] + codeowners: + active: [atoulme, pdelewski] diff --git a/exporter/awsxrayexporter/README.md b/exporter/awsxrayexporter/README.md index c0944d6398e9..ee34f24555e4 100644 --- a/exporter/awsxrayexporter/README.md +++ b/exporter/awsxrayexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces | | Distributions | [contrib], [aws], [observiq] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fawsxray%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fawsxray%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@wangzlei](https://www.github.com/wangzlei), [@srprash](https://www.github.com/srprash) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/awsxrayexporter/metadata.yaml b/exporter/awsxrayexporter/metadata.yaml index ac771c4194e1..327ff2f2a011 100644 --- a/exporter/awsxrayexporter/metadata.yaml +++ b/exporter/awsxrayexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [traces] distributions: [contrib, aws, observiq] + codeowners: + active: [wangzlei, srprash] diff --git a/exporter/azuredataexplorerexporter/README.md b/exporter/azuredataexplorerexporter/README.md index a56e0baeec83..0b9fed5cdfe3 100644 --- a/exporter/azuredataexplorerexporter/README.md +++ b/exporter/azuredataexplorerexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces, metrics, logs | | Distributions | [contrib] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fazuredataexplorer%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fazuredataexplorer%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@asaharan](https://www.github.com/asaharan), [@ag-ramachandran](https://www.github.com/ag-ramachandran) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/azuredataexplorerexporter/metadata.yaml b/exporter/azuredataexplorerexporter/metadata.yaml index 27ec9ece90b9..a39f4db68bc1 100644 --- a/exporter/azuredataexplorerexporter/metadata.yaml +++ b/exporter/azuredataexplorerexporter/metadata.yaml @@ -4,4 +4,6 @@ status: class: exporter stability: beta: [traces, metrics, logs] - distributions: [contrib] \ No newline at end of file + distributions: [contrib] + codeowners: + active: [asaharan, ag-ramachandran] \ No newline at end of file diff --git a/exporter/azuremonitorexporter/README.md b/exporter/azuremonitorexporter/README.md index 4b2d2005456b..ca916d9bd7af 100644 --- a/exporter/azuremonitorexporter/README.md +++ b/exporter/azuremonitorexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces, metrics, logs | | Distributions | [contrib], [observiq] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fazuremonitor%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fazuremonitor%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@pcwiese](https://www.github.com/pcwiese) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/azuremonitorexporter/metadata.yaml b/exporter/azuremonitorexporter/metadata.yaml index 937398817d9b..f6b86a88aac0 100644 --- a/exporter/azuremonitorexporter/metadata.yaml +++ b/exporter/azuremonitorexporter/metadata.yaml @@ -4,4 +4,6 @@ status: class: exporter stability: beta: [traces, metrics, logs] - distributions: [contrib, observiq] \ No newline at end of file + distributions: [contrib, observiq] + codeowners: + active: [pcwiese] \ No newline at end of file diff --git a/exporter/carbonexporter/README.md b/exporter/carbonexporter/README.md index 643e7fa0c4c4..06f52057dc05 100644 --- a/exporter/carbonexporter/README.md +++ b/exporter/carbonexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [contrib], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fcarbon%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fcarbon%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@aboguszewski-sumo](https://www.github.com/aboguszewski-sumo) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/carbonexporter/metadata.yaml b/exporter/carbonexporter/metadata.yaml index a430e70a01f4..2985110e616b 100644 --- a/exporter/carbonexporter/metadata.yaml +++ b/exporter/carbonexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [metrics] distributions: [contrib, observiq, sumo] + codeowners: + active: [aboguszewski-sumo] diff --git a/exporter/cassandraexporter/README.md b/exporter/cassandraexporter/README.md index 78726d7ba4f7..71f2b53b7b43 100644 --- a/exporter/cassandraexporter/README.md +++ b/exporter/cassandraexporter/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: traces, logs | | Distributions | [contrib] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fcassandra%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fcassandra%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@atoulme](https://www.github.com/atoulme), [@emreyalvac](https://www.github.com/emreyalvac) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/cassandraexporter/metadata.yaml b/exporter/cassandraexporter/metadata.yaml index 437118fc127c..739ceaa6a0af 100644 --- a/exporter/cassandraexporter/metadata.yaml +++ b/exporter/cassandraexporter/metadata.yaml @@ -5,4 +5,6 @@ status: stability: alpha: [traces, logs] distributions: [contrib] + codeowners: + active: [atoulme, emreyalvac] diff --git a/exporter/clickhouseexporter/README.md b/exporter/clickhouseexporter/README.md index 9d67752e1581..91d64aa48dde 100644 --- a/exporter/clickhouseexporter/README.md +++ b/exporter/clickhouseexporter/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: traces, metrics, logs | | Distributions | [contrib] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fclickhouse%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fclickhouse%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@hanjm](https://www.github.com/hanjm), [@dmitryax](https://www.github.com/dmitryax), [@Frapschen](https://www.github.com/Frapschen) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/clickhouseexporter/metadata.yaml b/exporter/clickhouseexporter/metadata.yaml index 82f23fa524c3..06a13bf01b99 100644 --- a/exporter/clickhouseexporter/metadata.yaml +++ b/exporter/clickhouseexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: alpha: [traces, metrics, logs] distributions: [contrib] + codeowners: + active: [hanjm, dmitryax, Frapschen] diff --git a/exporter/coralogixexporter/README.md b/exporter/coralogixexporter/README.md index 6f0c5ea465ca..05a689ff992d 100644 --- a/exporter/coralogixexporter/README.md +++ b/exporter/coralogixexporter/README.md @@ -7,6 +7,7 @@ | | [beta]: traces, metrics | | Distributions | [contrib], [observiq] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fcoralogix%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fcoralogix%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@oded-dd](https://www.github.com/oded-dd), [@povilasv](https://www.github.com/povilasv), [@matej-g](https://www.github.com/matej-g) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta diff --git a/exporter/coralogixexporter/metadata.yaml b/exporter/coralogixexporter/metadata.yaml index de5451eb313a..72220f8b37ec 100644 --- a/exporter/coralogixexporter/metadata.yaml +++ b/exporter/coralogixexporter/metadata.yaml @@ -6,3 +6,5 @@ status: beta: [traces, metrics] alpha: [logs] distributions: [contrib, observiq] + codeowners: + active: [oded-dd, povilasv, matej-g] diff --git a/exporter/datadogexporter/README.md b/exporter/datadogexporter/README.md index 085f470eae9e..6fe753c70c9e 100644 --- a/exporter/datadogexporter/README.md +++ b/exporter/datadogexporter/README.md @@ -7,6 +7,7 @@ | | [beta]: traces, metrics | | Distributions | [contrib], [aws], [observiq] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fdatadog%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fdatadog%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@mx-psi](https://www.github.com/mx-psi), [@gbbr](https://www.github.com/gbbr), [@dineshg13](https://www.github.com/dineshg13), [@liustanley](https://www.github.com/liustanley), [@songy23](https://www.github.com/songy23) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta diff --git a/exporter/datadogexporter/metadata.yaml b/exporter/datadogexporter/metadata.yaml index 62074514a0d3..7d9fad58410c 100644 --- a/exporter/datadogexporter/metadata.yaml +++ b/exporter/datadogexporter/metadata.yaml @@ -6,3 +6,5 @@ status: alpha: [logs] beta: [traces, metrics] distributions: [contrib, aws, observiq] + codeowners: + active: [mx-psi, gbbr, dineshg13, liustanley, songy23] diff --git a/exporter/datasetexporter/README.md b/exporter/datasetexporter/README.md index 90389ac29f5d..56d016afc6b1 100644 --- a/exporter/datasetexporter/README.md +++ b/exporter/datasetexporter/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: logs, traces | | Distributions | [contrib] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fdataset%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fdataset%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@atoulme](https://www.github.com/atoulme), [@martin-majlis-s1](https://www.github.com/martin-majlis-s1), [@zdaratom](https://www.github.com/zdaratom) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/datasetexporter/metadata.yaml b/exporter/datasetexporter/metadata.yaml index b7abd4cf08a6..c31c873cc5cf 100644 --- a/exporter/datasetexporter/metadata.yaml +++ b/exporter/datasetexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: alpha: [logs, traces] distributions: [contrib] + codeowners: + active: [atoulme, martin-majlis-s1, zdaratom] diff --git a/exporter/dynatraceexporter/README.md b/exporter/dynatraceexporter/README.md index 43b543a410ba..2a548d35dea1 100644 --- a/exporter/dynatraceexporter/README.md +++ b/exporter/dynatraceexporter/README.md @@ -23,6 +23,7 @@ More information on using the collector with Dynatrace can be found in the | Stability | [deprecated]: metrics | | Distributions | [contrib], [aws], [observiq] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fdynatrace%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fdynatrace%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@dyladan](https://www.github.com/dyladan), [@arminru](https://www.github.com/arminru), [@evan-bradley](https://www.github.com/evan-bradley) | [deprecated]: https://github.com/open-telemetry/opentelemetry-collector#deprecated [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/dynatraceexporter/metadata.yaml b/exporter/dynatraceexporter/metadata.yaml index d73c47770950..f7d20149eca5 100644 --- a/exporter/dynatraceexporter/metadata.yaml +++ b/exporter/dynatraceexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: deprecated: [metrics] distributions: [contrib, aws, observiq] + codeowners: + active: [dyladan, arminru, evan-bradley] diff --git a/exporter/elasticsearchexporter/README.md b/exporter/elasticsearchexporter/README.md index 879abbdad6ba..344b3a136c3b 100644 --- a/exporter/elasticsearchexporter/README.md +++ b/exporter/elasticsearchexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces, logs | | Distributions | [contrib], [observiq] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Felasticsearch%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Felasticsearch%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@JaredTan95](https://www.github.com/JaredTan95) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/elasticsearchexporter/metadata.yaml b/exporter/elasticsearchexporter/metadata.yaml index a20525105ab5..345ac0dbd94b 100644 --- a/exporter/elasticsearchexporter/metadata.yaml +++ b/exporter/elasticsearchexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [traces, logs] distributions: [contrib, observiq] + codeowners: + active: [JaredTan95] diff --git a/exporter/f5cloudexporter/README.md b/exporter/f5cloudexporter/README.md index 10e9106c4c68..2aaa1a1ef4c3 100644 --- a/exporter/f5cloudexporter/README.md +++ b/exporter/f5cloudexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces, metrics, logs | | Distributions | [contrib], [observiq] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Ff5cloud%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Ff5cloud%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@gramidt](https://www.github.com/gramidt) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/f5cloudexporter/metadata.yaml b/exporter/f5cloudexporter/metadata.yaml index 36e92b4b7be3..1c59a86d4f37 100644 --- a/exporter/f5cloudexporter/metadata.yaml +++ b/exporter/f5cloudexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [traces, metrics, logs] distributions: [contrib, observiq] + codeowners: + active: [gramidt] diff --git a/exporter/fileexporter/README.md b/exporter/fileexporter/README.md index 21165ac751c7..138b203e0876 100644 --- a/exporter/fileexporter/README.md +++ b/exporter/fileexporter/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: traces, metrics, logs | | Distributions | [core], [contrib], [aws], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Ffile%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Ffile%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@atingchen](https://www.github.com/atingchen) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [core]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol diff --git a/exporter/fileexporter/metadata.yaml b/exporter/fileexporter/metadata.yaml index 4cf98e426a1a..7610d9a67c61 100644 --- a/exporter/fileexporter/metadata.yaml +++ b/exporter/fileexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: alpha: [traces, metrics, logs] distributions: [core, contrib, observiq, splunk, sumo, aws] + codeowners: + active: [atingchen] diff --git a/exporter/googlecloudexporter/README.md b/exporter/googlecloudexporter/README.md index 3ee18a314423..ffac59d29ff6 100644 --- a/exporter/googlecloudexporter/README.md +++ b/exporter/googlecloudexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces, metrics, logs | | Distributions | [contrib], [observiq] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fgooglecloud%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fgooglecloud%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@aabmass](https://www.github.com/aabmass), [@dashpole](https://www.github.com/dashpole), [@jsuereth](https://www.github.com/jsuereth), [@punya](https://www.github.com/punya), [@damemi](https://www.github.com/damemi), [@psx95](https://www.github.com/psx95) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/googlecloudexporter/metadata.yaml b/exporter/googlecloudexporter/metadata.yaml index 57ca7d77234b..5b551dc0f188 100644 --- a/exporter/googlecloudexporter/metadata.yaml +++ b/exporter/googlecloudexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [traces, metrics, logs] distributions: [contrib, observiq] + codeowners: + active: [aabmass, dashpole, jsuereth, punya, damemi, psx95] diff --git a/exporter/googlecloudpubsubexporter/README.md b/exporter/googlecloudpubsubexporter/README.md index 3e2b0c13c30b..5eec33928b1b 100644 --- a/exporter/googlecloudpubsubexporter/README.md +++ b/exporter/googlecloudpubsubexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces, metrics, logs | | Distributions | [contrib], [observiq] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fgooglecloudpubsub%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fgooglecloudpubsub%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@alexvanboxel](https://www.github.com/alexvanboxel) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/googlecloudpubsubexporter/metadata.yaml b/exporter/googlecloudpubsubexporter/metadata.yaml index a5f916ee5910..f38f9ae8a2ad 100644 --- a/exporter/googlecloudpubsubexporter/metadata.yaml +++ b/exporter/googlecloudpubsubexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [traces, metrics, logs] distributions: [contrib, observiq] + codeowners: + active: [alexvanboxel] diff --git a/exporter/googlemanagedprometheusexporter/README.md b/exporter/googlemanagedprometheusexporter/README.md index 473fb0f3a8fb..6864285e2625 100644 --- a/exporter/googlemanagedprometheusexporter/README.md +++ b/exporter/googlemanagedprometheusexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [contrib], [observiq] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fgooglemanagedprometheus%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fgooglemanagedprometheus%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@aabmass](https://www.github.com/aabmass), [@dashpole](https://www.github.com/dashpole), [@jsuereth](https://www.github.com/jsuereth), [@punya](https://www.github.com/punya), [@damemi](https://www.github.com/damemi), [@psx95](https://www.github.com/psx95) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/googlemanagedprometheusexporter/metadata.yaml b/exporter/googlemanagedprometheusexporter/metadata.yaml index 6d818544f4cc..6b3d0c326f7e 100644 --- a/exporter/googlemanagedprometheusexporter/metadata.yaml +++ b/exporter/googlemanagedprometheusexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [metrics] distributions: [contrib, observiq] + codeowners: + active: [aabmass, dashpole, jsuereth, punya, damemi, psx95] diff --git a/exporter/influxdbexporter/README.md b/exporter/influxdbexporter/README.md index 06866d2e0d3f..0ea77d562310 100644 --- a/exporter/influxdbexporter/README.md +++ b/exporter/influxdbexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces, metrics, logs | | Distributions | [contrib], [observiq] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Finfluxdb%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Finfluxdb%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jacobmarble](https://www.github.com/jacobmarble) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/influxdbexporter/metadata.yaml b/exporter/influxdbexporter/metadata.yaml index e82ec755c4f0..4d4363dff036 100644 --- a/exporter/influxdbexporter/metadata.yaml +++ b/exporter/influxdbexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [traces, metrics, logs] distributions: [contrib, observiq] + codeowners: + active: [jacobmarble] diff --git a/exporter/instanaexporter/README.md b/exporter/instanaexporter/README.md index d7d71845d67a..b67888e532ac 100644 --- a/exporter/instanaexporter/README.md +++ b/exporter/instanaexporter/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: traces | | Distributions | [contrib] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Finstana%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Finstana%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jpkrohling](https://www.github.com/jpkrohling), [@hickeyma](https://www.github.com/hickeyma) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/instanaexporter/metadata.yaml b/exporter/instanaexporter/metadata.yaml index 29d635ab18f3..572e8b9d9d62 100644 --- a/exporter/instanaexporter/metadata.yaml +++ b/exporter/instanaexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: alpha: [traces] distributions: [contrib] + codeowners: + active: [jpkrohling, hickeyma] diff --git a/exporter/jaegerexporter/README.md b/exporter/jaegerexporter/README.md index acbd9f260924..430c163e41fc 100644 --- a/exporter/jaegerexporter/README.md +++ b/exporter/jaegerexporter/README.md @@ -6,6 +6,7 @@ | Stability | [deprecated]: traces | | Distributions | [core], [contrib], [grafana], [redhat] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fjaeger%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fjaeger%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jpkrohling](https://www.github.com/jpkrohling), [@frzifus](https://www.github.com/frzifus) | [deprecated]: https://github.com/open-telemetry/opentelemetry-collector#deprecated [core]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol diff --git a/exporter/jaegerexporter/metadata.yaml b/exporter/jaegerexporter/metadata.yaml index 9b8822ccec74..ccf9441aedb3 100644 --- a/exporter/jaegerexporter/metadata.yaml +++ b/exporter/jaegerexporter/metadata.yaml @@ -9,3 +9,5 @@ status: - contrib - grafana - redhat + codeowners: + active: [jpkrohling, frzifus] diff --git a/exporter/jaegerthrifthttpexporter/README.md b/exporter/jaegerthrifthttpexporter/README.md index c4754ec91dad..347fcc041c25 100644 --- a/exporter/jaegerthrifthttpexporter/README.md +++ b/exporter/jaegerthrifthttpexporter/README.md @@ -6,6 +6,7 @@ | Stability | [deprecated]: traces | | Distributions | [contrib] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fjaegerthrifthttp%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fjaegerthrifthttp%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jpkrohling](https://www.github.com/jpkrohling), [@pavolloffay](https://www.github.com/pavolloffay), [@frzifus](https://www.github.com/frzifus) | [deprecated]: https://github.com/open-telemetry/opentelemetry-collector#deprecated [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/jaegerthrifthttpexporter/metadata.yaml b/exporter/jaegerthrifthttpexporter/metadata.yaml index 3a1a464a1b79..541c1f41c27d 100644 --- a/exporter/jaegerthrifthttpexporter/metadata.yaml +++ b/exporter/jaegerthrifthttpexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: deprecated: [traces] distributions: [contrib] + codeowners: + active: [jpkrohling, pavolloffay, frzifus] diff --git a/exporter/kafkaexporter/README.md b/exporter/kafkaexporter/README.md index d9641688076c..33aa6235220a 100644 --- a/exporter/kafkaexporter/README.md +++ b/exporter/kafkaexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces, metrics, logs | | Distributions | [contrib], [aws], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fkafka%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fkafka%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@pavolloffay](https://www.github.com/pavolloffay), [@MovieStoreGuy](https://www.github.com/MovieStoreGuy) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/kafkaexporter/metadata.yaml b/exporter/kafkaexporter/metadata.yaml index 18b56e84b77a..34b6d3869cfd 100644 --- a/exporter/kafkaexporter/metadata.yaml +++ b/exporter/kafkaexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [traces, metrics, logs] distributions: [contrib, observiq, splunk, sumo, aws] + codeowners: + active: [pavolloffay, MovieStoreGuy] diff --git a/exporter/loadbalancingexporter/README.md b/exporter/loadbalancingexporter/README.md index bf4f52b93581..679a05bc4a46 100644 --- a/exporter/loadbalancingexporter/README.md +++ b/exporter/loadbalancingexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces, logs | | Distributions | [contrib], [grafana], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Floadbalancing%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Floadbalancing%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jpkrohling](https://www.github.com/jpkrohling) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/loadbalancingexporter/metadata.yaml b/exporter/loadbalancingexporter/metadata.yaml index 48a9f287c36a..deae6432cd2f 100644 --- a/exporter/loadbalancingexporter/metadata.yaml +++ b/exporter/loadbalancingexporter/metadata.yaml @@ -9,3 +9,5 @@ status: - grafana - observiq - sumo + codeowners: + active: [jpkrohling] diff --git a/exporter/logicmonitorexporter/README.md b/exporter/logicmonitorexporter/README.md index d8159e80a8ce..28285f18a9ad 100644 --- a/exporter/logicmonitorexporter/README.md +++ b/exporter/logicmonitorexporter/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: traces, logs | | Distributions | [contrib] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Flogicmonitor%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Flogicmonitor%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@bogdandrutu](https://www.github.com/bogdandrutu), [@khyatigandhi6](https://www.github.com/khyatigandhi6), [@avadhut123pisal](https://www.github.com/avadhut123pisal) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/logicmonitorexporter/metadata.yaml b/exporter/logicmonitorexporter/metadata.yaml index 4915e474a473..b1c3f73a59ba 100644 --- a/exporter/logicmonitorexporter/metadata.yaml +++ b/exporter/logicmonitorexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: alpha: [traces, logs] distributions: [contrib] + codeowners: + active: [bogdandrutu, khyatigandhi6, avadhut123pisal] diff --git a/exporter/logzioexporter/README.md b/exporter/logzioexporter/README.md index 0449852d1044..b0aa78137b7d 100644 --- a/exporter/logzioexporter/README.md +++ b/exporter/logzioexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces, logs | | Distributions | [contrib], [aws], [observiq] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Flogzio%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Flogzio%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@Doron-Bargo](https://www.github.com/Doron-Bargo), [@yotamloe](https://www.github.com/yotamloe) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/logzioexporter/metadata.yaml b/exporter/logzioexporter/metadata.yaml index 26962f4cec28..28d24cc9d2ad 100644 --- a/exporter/logzioexporter/metadata.yaml +++ b/exporter/logzioexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [traces, logs] distributions: [contrib, observiq, aws] + codeowners: + active: [Doron-Bargo, yotamloe] diff --git a/exporter/lokiexporter/README.md b/exporter/lokiexporter/README.md index dd8c1bc1ea33..cb43d1c0c5a9 100644 --- a/exporter/lokiexporter/README.md +++ b/exporter/lokiexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: logs | | Distributions | [contrib], [observiq] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Floki%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Floki%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@gramidt](https://www.github.com/gramidt), [@gouthamve](https://www.github.com/gouthamve), [@jpkrohling](https://www.github.com/jpkrohling), [@kovrus](https://www.github.com/kovrus), [@mar4uk](https://www.github.com/mar4uk) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/lokiexporter/metadata.yaml b/exporter/lokiexporter/metadata.yaml index 1fa18abb7c35..ba9cbdf72813 100644 --- a/exporter/lokiexporter/metadata.yaml +++ b/exporter/lokiexporter/metadata.yaml @@ -7,3 +7,5 @@ status: distributions: - contrib - observiq + codeowners: + active: [gramidt, gouthamve, jpkrohling, kovrus, mar4uk] diff --git a/exporter/mezmoexporter/README.md b/exporter/mezmoexporter/README.md index 439d292565f7..19aac23ff05f 100644 --- a/exporter/mezmoexporter/README.md +++ b/exporter/mezmoexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: logs | | Distributions | [contrib] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fmezmo%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fmezmo%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@dashpole](https://www.github.com/dashpole), [@billmeyer](https://www.github.com/billmeyer), [@gjanco](https://www.github.com/gjanco) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/mezmoexporter/metadata.yaml b/exporter/mezmoexporter/metadata.yaml index 5955db639a0b..5255f57e8e53 100644 --- a/exporter/mezmoexporter/metadata.yaml +++ b/exporter/mezmoexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [logs] distributions: [contrib] + codeowners: + active: [dashpole, billmeyer, gjanco] diff --git a/exporter/opencensusexporter/README.md b/exporter/opencensusexporter/README.md index 0e2a96fee0f4..7ddf79e8d28d 100644 --- a/exporter/opencensusexporter/README.md +++ b/exporter/opencensusexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces, metrics | | Distributions | [contrib], [observiq] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fopencensus%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fopencensus%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@open-telemetry/collector-approvers](https://github.com/orgs/open-telemetry/teams/collector-approvers) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/opencensusexporter/metadata.yaml b/exporter/opencensusexporter/metadata.yaml index addd0aa26cf7..03f1bdbded1a 100644 --- a/exporter/opencensusexporter/metadata.yaml +++ b/exporter/opencensusexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [traces, metrics] distributions: [contrib, observiq] + codeowners: + active: [open-telemetry/collector-approvers] diff --git a/exporter/parquetexporter/README.md b/exporter/parquetexporter/README.md index 92cd0aaee4c5..6cce42f7cf92 100644 --- a/exporter/parquetexporter/README.md +++ b/exporter/parquetexporter/README.md @@ -6,6 +6,7 @@ | Stability | [development]: traces, metrics, logs | | Distributions | [contrib] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fparquet%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fparquet%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@atoulme](https://www.github.com/atoulme) | [development]: https://github.com/open-telemetry/opentelemetry-collector#development [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/parquetexporter/metadata.yaml b/exporter/parquetexporter/metadata.yaml index bbf29de6f4b5..c94d38add903 100644 --- a/exporter/parquetexporter/metadata.yaml +++ b/exporter/parquetexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: development: [traces, metrics, logs] distributions: [contrib] + codeowners: + active: [atoulme] diff --git a/exporter/prometheusexporter/README.md b/exporter/prometheusexporter/README.md index 666d4a852785..5cfb817e5b9a 100644 --- a/exporter/prometheusexporter/README.md +++ b/exporter/prometheusexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [core], [contrib], [aws], [grafana], [observiq], [redhat], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fprometheus%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fprometheus%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@Aneurysm9](https://www.github.com/Aneurysm9) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [core]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol diff --git a/exporter/prometheusexporter/metadata.yaml b/exporter/prometheusexporter/metadata.yaml index 07f6ba3cb53b..9df66711907d 100644 --- a/exporter/prometheusexporter/metadata.yaml +++ b/exporter/prometheusexporter/metadata.yaml @@ -12,3 +12,5 @@ status: - observiq - redhat - sumo + codeowners: + active: [Aneurysm9] diff --git a/exporter/prometheusremotewriteexporter/README.md b/exporter/prometheusremotewriteexporter/README.md index 075ed6cfece1..65045d618c1f 100644 --- a/exporter/prometheusremotewriteexporter/README.md +++ b/exporter/prometheusremotewriteexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [core], [contrib], [aws], [observiq] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fprometheusremotewrite%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fprometheusremotewrite%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@Aneurysm9](https://www.github.com/Aneurysm9), [@rapphil](https://www.github.com/rapphil) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [core]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol diff --git a/exporter/prometheusremotewriteexporter/metadata.yaml b/exporter/prometheusremotewriteexporter/metadata.yaml index 96903a12e166..762142015495 100644 --- a/exporter/prometheusremotewriteexporter/metadata.yaml +++ b/exporter/prometheusremotewriteexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [metrics] distributions: [core, contrib, aws, observiq] + codeowners: + active: [Aneurysm9, rapphil] diff --git a/exporter/pulsarexporter/README.md b/exporter/pulsarexporter/README.md index 1e593a0ec9dc..ada3640eae8f 100644 --- a/exporter/pulsarexporter/README.md +++ b/exporter/pulsarexporter/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: traces, metrics, logs | | Distributions | [contrib] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fpulsar%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fpulsar%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@dmitryax](https://www.github.com/dmitryax), [@dao-jun](https://www.github.com/dao-jun) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/pulsarexporter/metadata.yaml b/exporter/pulsarexporter/metadata.yaml index 993b2ae3a3fd..a353a37e119a 100644 --- a/exporter/pulsarexporter/metadata.yaml +++ b/exporter/pulsarexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: alpha: [traces, metrics, logs] distributions: [contrib] + codeowners: + active: [dmitryax, dao-jun] diff --git a/exporter/sapmexporter/README.md b/exporter/sapmexporter/README.md index efc93df26466..69e56fc19297 100644 --- a/exporter/sapmexporter/README.md +++ b/exporter/sapmexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces | | Distributions | [contrib], [aws], [observiq], [splunk] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fsapm%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fsapm%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@dmitryax](https://www.github.com/dmitryax), [@atoulme](https://www.github.com/atoulme) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/sapmexporter/metadata.yaml b/exporter/sapmexporter/metadata.yaml index ead2f45edf77..3df77e18104b 100644 --- a/exporter/sapmexporter/metadata.yaml +++ b/exporter/sapmexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [traces] distributions: [contrib, splunk, observiq, aws] + codeowners: + active: [dmitryax, atoulme] diff --git a/exporter/sentryexporter/README.md b/exporter/sentryexporter/README.md index 6be6335dc4e6..642355324c10 100644 --- a/exporter/sentryexporter/README.md +++ b/exporter/sentryexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces | | Distributions | [contrib] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fsentry%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fsentry%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@AbhiPrasad](https://www.github.com/AbhiPrasad) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/sentryexporter/metadata.yaml b/exporter/sentryexporter/metadata.yaml index 8820b3515416..74cf89d6984b 100644 --- a/exporter/sentryexporter/metadata.yaml +++ b/exporter/sentryexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [traces] distributions: [contrib] + codeowners: + active: [AbhiPrasad] diff --git a/exporter/signalfxexporter/README.md b/exporter/signalfxexporter/README.md index dc77e0d949fe..05d486df4903 100644 --- a/exporter/signalfxexporter/README.md +++ b/exporter/signalfxexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces, metrics, logs | | Distributions | [contrib], [aws], [observiq], [splunk] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fsignalfx%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fsignalfx%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@dmitryax](https://www.github.com/dmitryax), [@crobert-1](https://www.github.com/crobert-1) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/signalfxexporter/metadata.yaml b/exporter/signalfxexporter/metadata.yaml index d65db121c989..777f6c51b5ce 100644 --- a/exporter/signalfxexporter/metadata.yaml +++ b/exporter/signalfxexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [traces, metrics, logs] distributions: [contrib, splunk, observiq, aws] + codeowners: + active: [dmitryax, crobert-1] diff --git a/exporter/skywalkingexporter/README.md b/exporter/skywalkingexporter/README.md index bfa8c03ee992..6608d30bb903 100644 --- a/exporter/skywalkingexporter/README.md +++ b/exporter/skywalkingexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics, logs | | Distributions | [contrib] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fskywalking%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fskywalking%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@liqiangz](https://www.github.com/liqiangz) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/skywalkingexporter/metadata.yaml b/exporter/skywalkingexporter/metadata.yaml index 30ed076bd76b..42c59039b459 100644 --- a/exporter/skywalkingexporter/metadata.yaml +++ b/exporter/skywalkingexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [metrics, logs] distributions: [contrib] + codeowners: + active: [liqiangz] diff --git a/exporter/splunkhecexporter/README.md b/exporter/splunkhecexporter/README.md index 579a4abf5378..0858c87b1722 100644 --- a/exporter/splunkhecexporter/README.md +++ b/exporter/splunkhecexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces, metrics, logs | | Distributions | [contrib], [observiq], [splunk] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fsplunkhec%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fsplunkhec%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@atoulme](https://www.github.com/atoulme), [@dmitryax](https://www.github.com/dmitryax) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/splunkhecexporter/metadata.yaml b/exporter/splunkhecexporter/metadata.yaml index f3ebc9d3c98b..fb77ac506dfc 100644 --- a/exporter/splunkhecexporter/metadata.yaml +++ b/exporter/splunkhecexporter/metadata.yaml @@ -4,4 +4,6 @@ status: class: exporter stability: beta: [traces, metrics, logs] - distributions: [contrib, splunk, observiq] \ No newline at end of file + distributions: [contrib, splunk, observiq] + codeowners: + active: [atoulme, dmitryax] \ No newline at end of file diff --git a/exporter/sumologicexporter/README.md b/exporter/sumologicexporter/README.md index 00dbdfd4e5d8..82fe04d121d7 100644 --- a/exporter/sumologicexporter/README.md +++ b/exporter/sumologicexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics, logs | | Distributions | [contrib] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fsumologic%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fsumologic%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@sumo-drosiek](https://www.github.com/sumo-drosiek) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/sumologicexporter/metadata.yaml b/exporter/sumologicexporter/metadata.yaml index be04cc06d377..7b7e746efafa 100644 --- a/exporter/sumologicexporter/metadata.yaml +++ b/exporter/sumologicexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [metrics, logs] distributions: [contrib] + codeowners: + active: [sumo-drosiek] diff --git a/exporter/syslogexporter/README.md b/exporter/syslogexporter/README.md index a7740992d30f..3a365e5d55c8 100644 --- a/exporter/syslogexporter/README.md +++ b/exporter/syslogexporter/README.md @@ -6,6 +6,7 @@ | Stability | [development]: logs | | Distributions | [] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fsyslog%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fsyslog%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@kkujawa-sumo](https://www.github.com/kkujawa-sumo), [@rnishtala-sumo](https://www.github.com/rnishtala-sumo), [@astencel-sumo](https://www.github.com/astencel-sumo) | [development]: https://github.com/open-telemetry/opentelemetry-collector#development diff --git a/exporter/syslogexporter/metadata.yaml b/exporter/syslogexporter/metadata.yaml index d4f1293e2546..32a6ec860902 100644 --- a/exporter/syslogexporter/metadata.yaml +++ b/exporter/syslogexporter/metadata.yaml @@ -4,3 +4,5 @@ status: class: exporter stability: development: [logs] + codeowners: + active: [kkujawa-sumo, rnishtala-sumo, astencel-sumo] diff --git a/exporter/tanzuobservabilityexporter/README.md b/exporter/tanzuobservabilityexporter/README.md index 0c69d8bcbad4..6734882b022b 100644 --- a/exporter/tanzuobservabilityexporter/README.md +++ b/exporter/tanzuobservabilityexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces, metrics | | Distributions | [contrib] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Ftanzuobservability%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Ftanzuobservability%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@oppegard](https://www.github.com/oppegard), [@thepeterstone](https://www.github.com/thepeterstone), [@keep94](https://www.github.com/keep94) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/tanzuobservabilityexporter/metadata.yaml b/exporter/tanzuobservabilityexporter/metadata.yaml index de07f7fa4d94..0f5dcb25db32 100644 --- a/exporter/tanzuobservabilityexporter/metadata.yaml +++ b/exporter/tanzuobservabilityexporter/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [traces, metrics] distributions: [contrib] + codeowners: + active: [oppegard, thepeterstone, keep94] diff --git a/exporter/tencentcloudlogserviceexporter/README.md b/exporter/tencentcloudlogserviceexporter/README.md index 7fbe6f83c190..2a7b5139b04d 100644 --- a/exporter/tencentcloudlogserviceexporter/README.md +++ b/exporter/tencentcloudlogserviceexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: logs | | Distributions | [contrib] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Ftencentcloudlogservice%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Ftencentcloudlogservice%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@wgliang](https://www.github.com/wgliang), [@yiyang5055](https://www.github.com/yiyang5055) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/tencentcloudlogserviceexporter/metadata.yaml b/exporter/tencentcloudlogserviceexporter/metadata.yaml index add0af49a0a9..028015509293 100644 --- a/exporter/tencentcloudlogserviceexporter/metadata.yaml +++ b/exporter/tencentcloudlogserviceexporter/metadata.yaml @@ -5,4 +5,6 @@ status: stability: beta: [logs] distributions: [contrib] + codeowners: + active: [wgliang, yiyang5055] diff --git a/exporter/zipkinexporter/README.md b/exporter/zipkinexporter/README.md index c64723fa60a1..d6df08ab1dc8 100644 --- a/exporter/zipkinexporter/README.md +++ b/exporter/zipkinexporter/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces | | Distributions | [core], [contrib], [observiq] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fzipkin%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fzipkin%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@MovieStoreGuy](https://www.github.com/MovieStoreGuy), [@astencel-sumo](https://www.github.com/astencel-sumo), [@crobert-1](https://www.github.com/crobert-1) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [core]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol diff --git a/exporter/zipkinexporter/metadata.yaml b/exporter/zipkinexporter/metadata.yaml index e97b2852d87f..cbc06d45c8ca 100644 --- a/exporter/zipkinexporter/metadata.yaml +++ b/exporter/zipkinexporter/metadata.yaml @@ -5,4 +5,6 @@ status: stability: beta: [traces] distributions: [core, contrib, observiq] + codeowners: + active: [MovieStoreGuy, astencel-sumo, crobert-1] diff --git a/extension/asapauthextension/README.md b/extension/asapauthextension/README.md index aa671019d9c2..f943a1b07ef2 100644 --- a/extension/asapauthextension/README.md +++ b/extension/asapauthextension/README.md @@ -5,6 +5,7 @@ | Stability | [beta] | | Distributions | [contrib], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aextension%2Fasapauth%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aextension%2Fasapauth%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jamesmoessis](https://www.github.com/jamesmoessis), [@MovieStoreGuy](https://www.github.com/MovieStoreGuy) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/extension/asapauthextension/metadata.yaml b/extension/asapauthextension/metadata.yaml index 70f37b504431..e513253ee2af 100644 --- a/extension/asapauthextension/metadata.yaml +++ b/extension/asapauthextension/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [extension] distributions: [contrib, sumo] + codeowners: + active: [jamesmoessis, MovieStoreGuy] diff --git a/extension/awsproxy/README.md b/extension/awsproxy/README.md index 6def3533b2ea..40f576cd6c22 100644 --- a/extension/awsproxy/README.md +++ b/extension/awsproxy/README.md @@ -5,6 +5,7 @@ | Stability | [beta] | | Distributions | [contrib], [aws], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aextension%2Fawsproxy%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aextension%2Fawsproxy%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@Aneurysm9](https://www.github.com/Aneurysm9), [@mxiamxia](https://www.github.com/mxiamxia) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/extension/awsproxy/metadata.yaml b/extension/awsproxy/metadata.yaml index a2a0ddba21e8..a2987a86d0fa 100644 --- a/extension/awsproxy/metadata.yaml +++ b/extension/awsproxy/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [extension] distributions: [contrib, aws, sumo] + codeowners: + active: [Aneurysm9, mxiamxia] diff --git a/extension/basicauthextension/README.md b/extension/basicauthextension/README.md index 5077596ea175..b0e286f16a04 100644 --- a/extension/basicauthextension/README.md +++ b/extension/basicauthextension/README.md @@ -5,6 +5,7 @@ | Stability | [beta] | | Distributions | [contrib], [grafana], [observiq], [redhat], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aextension%2Fbasicauth%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aextension%2Fbasicauth%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jpkrohling](https://www.github.com/jpkrohling), [@svrakitin](https://www.github.com/svrakitin) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/extension/basicauthextension/metadata.yaml b/extension/basicauthextension/metadata.yaml index 883bf10fbfc6..6372d2d0271c 100644 --- a/extension/basicauthextension/metadata.yaml +++ b/extension/basicauthextension/metadata.yaml @@ -10,3 +10,5 @@ status: - observiq - redhat - sumo + codeowners: + active: [jpkrohling, svrakitin] diff --git a/extension/bearertokenauthextension/README.md b/extension/bearertokenauthextension/README.md index 489550032ddf..b1c858eb20b9 100644 --- a/extension/bearertokenauthextension/README.md +++ b/extension/bearertokenauthextension/README.md @@ -5,6 +5,7 @@ | Stability | [beta] | | Distributions | [contrib], [grafana], [observiq], [redhat], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aextension%2Fbearertokenauth%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aextension%2Fbearertokenauth%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jpkrohling](https://www.github.com/jpkrohling), [@pavankrish123](https://www.github.com/pavankrish123), [@frzifus](https://www.github.com/frzifus) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/extension/bearertokenauthextension/metadata.yaml b/extension/bearertokenauthextension/metadata.yaml index ae14f78fe2d3..039782fc787f 100644 --- a/extension/bearertokenauthextension/metadata.yaml +++ b/extension/bearertokenauthextension/metadata.yaml @@ -10,3 +10,5 @@ status: - observiq - redhat - sumo + codeowners: + active: [jpkrohling, pavankrish123, frzifus] diff --git a/extension/encodingextension/README.md b/extension/encodingextension/README.md index df39c4dedd53..f1b5ef014e10 100644 --- a/extension/encodingextension/README.md +++ b/extension/encodingextension/README.md @@ -6,6 +6,7 @@ | Stability | [development] | | Distributions | [] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aextension%2Fencoding%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aextension%2Fencoding%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@MovieStoreGuy](https://www.github.com/MovieStoreGuy) | [development]: https://github.com/open-telemetry/opentelemetry-collector#development diff --git a/extension/encodingextension/doc.go b/extension/encodingextension/doc.go index 2ea892c8ee70..5797e0e6ee9a 100644 --- a/extension/encodingextension/doc.go +++ b/extension/encodingextension/doc.go @@ -1,5 +1,5 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -//go:generate mdatagen metadata.yml +//go:generate mdatagen metadata.yaml package encodingextension // import "github.com/open-telemetry/opentelemetry-collector-contrib/extension/encodingextension" diff --git a/extension/encodingextension/metadata.yml b/extension/encodingextension/metadata.yaml similarity index 58% rename from extension/encodingextension/metadata.yml rename to extension/encodingextension/metadata.yaml index e1202b760b83..653cae90f304 100644 --- a/extension/encodingextension/metadata.yml +++ b/extension/encodingextension/metadata.yaml @@ -1,8 +1,9 @@ ---- type: encoding status: class: extension stability: development: [extension] - distributions: [] \ No newline at end of file + distributions: [] + codeowners: + active: [MovieStoreGuy] \ No newline at end of file diff --git a/extension/headerssetterextension/README.md b/extension/headerssetterextension/README.md index 203344ef25d4..73c42bd73b94 100644 --- a/extension/headerssetterextension/README.md +++ b/extension/headerssetterextension/README.md @@ -5,6 +5,7 @@ | Stability | [alpha] | | Distributions | [contrib], [grafana], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aextension%2Fheaderssetter%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aextension%2Fheaderssetter%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jpkrohling](https://www.github.com/jpkrohling), [@kovrus](https://www.github.com/kovrus) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/extension/headerssetterextension/metadata.yaml b/extension/headerssetterextension/metadata.yaml index 64da98956080..b21ca5e2af7f 100644 --- a/extension/headerssetterextension/metadata.yaml +++ b/extension/headerssetterextension/metadata.yaml @@ -8,3 +8,5 @@ status: - contrib - grafana - sumo + codeowners: + active: [jpkrohling, kovrus] diff --git a/extension/healthcheckextension/README.md b/extension/healthcheckextension/README.md index 12b6103e1e2c..335be461153c 100644 --- a/extension/healthcheckextension/README.md +++ b/extension/healthcheckextension/README.md @@ -6,6 +6,7 @@ | Stability | [beta] | | Distributions | [core], [contrib], [aws], [observiq], [redhat], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aextension%2Fhealthcheck%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aextension%2Fhealthcheck%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jpkrohling](https://www.github.com/jpkrohling) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [core]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol diff --git a/extension/healthcheckextension/metadata.yaml b/extension/healthcheckextension/metadata.yaml index 01c5206df821..b92081833048 100644 --- a/extension/healthcheckextension/metadata.yaml +++ b/extension/healthcheckextension/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [extension] distributions: [core, contrib, splunk, observiq, sumo, aws, redhat] + codeowners: + active: [jpkrohling] diff --git a/extension/httpforwarder/README.md b/extension/httpforwarder/README.md index 7e55e30dcfb0..70d02f8f9d88 100644 --- a/extension/httpforwarder/README.md +++ b/extension/httpforwarder/README.md @@ -5,6 +5,7 @@ | Stability | [beta] | | Distributions | [contrib], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aextension%2Fhttpforwarder%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aextension%2Fhttpforwarder%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@atoulme](https://www.github.com/atoulme), [@rmfitzpatrick](https://www.github.com/rmfitzpatrick) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/extension/httpforwarder/metadata.yaml b/extension/httpforwarder/metadata.yaml index e27797bba603..0b8eebc2cbbe 100644 --- a/extension/httpforwarder/metadata.yaml +++ b/extension/httpforwarder/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [extension] distributions: [contrib, splunk, sumo] + codeowners: + active: [atoulme, rmfitzpatrick] diff --git a/extension/jaegerremotesampling/README.md b/extension/jaegerremotesampling/README.md index 7031732ba706..1365ad074aac 100644 --- a/extension/jaegerremotesampling/README.md +++ b/extension/jaegerremotesampling/README.md @@ -5,6 +5,7 @@ | Stability | [alpha] | | Distributions | [contrib], [grafana], [redhat], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aextension%2Fjaegerremotesampling%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aextension%2Fjaegerremotesampling%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jpkrohling](https://www.github.com/jpkrohling), [@frzifus](https://www.github.com/frzifus) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/extension/jaegerremotesampling/metadata.yaml b/extension/jaegerremotesampling/metadata.yaml index cc250dda7888..73a23a66c216 100644 --- a/extension/jaegerremotesampling/metadata.yaml +++ b/extension/jaegerremotesampling/metadata.yaml @@ -9,3 +9,5 @@ status: - grafana - redhat - sumo + codeowners: + active: [jpkrohling, frzifus] diff --git a/extension/oauth2clientauthextension/README.md b/extension/oauth2clientauthextension/README.md index bec8dfd08b77..a94d44bae643 100644 --- a/extension/oauth2clientauthextension/README.md +++ b/extension/oauth2clientauthextension/README.md @@ -5,6 +5,7 @@ | Stability | [beta] | | Distributions | [contrib], [grafana], [redhat], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aextension%2Foauth2clientauth%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aextension%2Foauth2clientauth%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@pavankrish123](https://www.github.com/pavankrish123), [@jpkrohling](https://www.github.com/jpkrohling) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/extension/oauth2clientauthextension/metadata.yaml b/extension/oauth2clientauthextension/metadata.yaml index 80cba5906607..34b06d6b498b 100644 --- a/extension/oauth2clientauthextension/metadata.yaml +++ b/extension/oauth2clientauthextension/metadata.yaml @@ -9,3 +9,5 @@ status: - grafana - redhat - sumo + codeowners: + active: [pavankrish123, jpkrohling] diff --git a/extension/observer/dockerobserver/README.md b/extension/observer/dockerobserver/README.md index 145893728640..205141b60348 100644 --- a/extension/observer/dockerobserver/README.md +++ b/extension/observer/dockerobserver/README.md @@ -6,6 +6,7 @@ | Stability | [beta] | | Distributions | [contrib], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aextension%2Fdockerobserver%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aextension%2Fdockerobserver%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@MovieStoreGuy](https://www.github.com/MovieStoreGuy) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/extension/observer/dockerobserver/metadata.yaml b/extension/observer/dockerobserver/metadata.yaml index 01a7af55087b..c2bf7666a112 100644 --- a/extension/observer/dockerobserver/metadata.yaml +++ b/extension/observer/dockerobserver/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [extension] distributions: [contrib, splunk, sumo] + codeowners: + active: [MovieStoreGuy] diff --git a/extension/observer/ecsobserver/README.md b/extension/observer/ecsobserver/README.md index 906f7fb14f95..cc7b7fa8fb1a 100644 --- a/extension/observer/ecsobserver/README.md +++ b/extension/observer/ecsobserver/README.md @@ -6,6 +6,7 @@ | Stability | [beta] | | Distributions | [contrib], [aws], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aextension%2Fecsobserver%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aextension%2Fecsobserver%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@dmitryax @rmfitzpatrick](https://www.github.com/dmitryax @rmfitzpatrick) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/extension/observer/ecsobserver/metadata.yaml b/extension/observer/ecsobserver/metadata.yaml index 112b98b62d68..3781b4420f32 100644 --- a/extension/observer/ecsobserver/metadata.yaml +++ b/extension/observer/ecsobserver/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [extension] distributions: [contrib, aws, splunk, sumo] + codeowners: + active: [dmitryax @rmfitzpatrick] diff --git a/extension/observer/ecstaskobserver/README.md b/extension/observer/ecstaskobserver/README.md index 0edf67e635fb..f2a935184e19 100644 --- a/extension/observer/ecstaskobserver/README.md +++ b/extension/observer/ecstaskobserver/README.md @@ -6,6 +6,7 @@ | Stability | [beta] | | Distributions | [contrib], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aextension%2Fecstaskobserver%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aextension%2Fecstaskobserver%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@rmfitzpatrick](https://www.github.com/rmfitzpatrick) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/extension/observer/ecstaskobserver/metadata.yaml b/extension/observer/ecstaskobserver/metadata.yaml index 7a7fd5d21c70..21882823f67f 100644 --- a/extension/observer/ecstaskobserver/metadata.yaml +++ b/extension/observer/ecstaskobserver/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [extension] distributions: [contrib, splunk, sumo] + codeowners: + active: [rmfitzpatrick] diff --git a/extension/observer/hostobserver/README.md b/extension/observer/hostobserver/README.md index c2947f6a030e..c1a441a120c0 100644 --- a/extension/observer/hostobserver/README.md +++ b/extension/observer/hostobserver/README.md @@ -6,6 +6,7 @@ | Stability | [beta] | | Distributions | [contrib], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aextension%2Fhostobserver%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aextension%2Fhostobserver%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@MovieStoreGuy](https://www.github.com/MovieStoreGuy) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/extension/observer/hostobserver/metadata.yaml b/extension/observer/hostobserver/metadata.yaml index f870c12a43cc..ec27148d5cd2 100644 --- a/extension/observer/hostobserver/metadata.yaml +++ b/extension/observer/hostobserver/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [extension] distributions: [contrib, splunk, sumo] + codeowners: + active: [MovieStoreGuy] diff --git a/extension/observer/k8sobserver/README.md b/extension/observer/k8sobserver/README.md index b4895caa80e2..69894d9f2cb3 100644 --- a/extension/observer/k8sobserver/README.md +++ b/extension/observer/k8sobserver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha] | | Distributions | [contrib], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aextension%2Fk8sobserver%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aextension%2Fk8sobserver%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@rmfitzpatrick](https://www.github.com/rmfitzpatrick), [@dmitryax](https://www.github.com/dmitryax) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/extension/observer/k8sobserver/metadata.yaml b/extension/observer/k8sobserver/metadata.yaml index 1ac77239d954..db0065725397 100644 --- a/extension/observer/k8sobserver/metadata.yaml +++ b/extension/observer/k8sobserver/metadata.yaml @@ -5,3 +5,5 @@ status: stability: alpha: [extension] distributions: [contrib, splunk, sumo] + codeowners: + active: [rmfitzpatrick, dmitryax] diff --git a/extension/observer/metadata.yaml b/extension/observer/metadata.yaml new file mode 100644 index 000000000000..66a66302e5f1 --- /dev/null +++ b/extension/observer/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [dmitryax, rmfitzpatrick] \ No newline at end of file diff --git a/extension/oidcauthextension/README.md b/extension/oidcauthextension/README.md index 7e0e1a859e91..7f6ea595e443 100644 --- a/extension/oidcauthextension/README.md +++ b/extension/oidcauthextension/README.md @@ -6,6 +6,7 @@ | Stability | [beta] | | Distributions | [contrib], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aextension%2Foidcauth%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aextension%2Foidcauth%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jpkrohling](https://www.github.com/jpkrohling) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/extension/oidcauthextension/metadata.yaml b/extension/oidcauthextension/metadata.yaml index fe8cd214a76d..e498713fa6c7 100644 --- a/extension/oidcauthextension/metadata.yaml +++ b/extension/oidcauthextension/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [extension] distributions: [contrib, observiq, sumo] + codeowners: + active: [jpkrohling] diff --git a/extension/pprofextension/README.md b/extension/pprofextension/README.md index 2d242c9e4cad..8fb3a1458b20 100644 --- a/extension/pprofextension/README.md +++ b/extension/pprofextension/README.md @@ -6,6 +6,7 @@ | Stability | [beta] | | Distributions | [core], [contrib], [aws], [observiq], [redhat], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aextension%2Fpprof%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aextension%2Fpprof%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@MovieStoreGuy](https://www.github.com/MovieStoreGuy) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [core]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol diff --git a/extension/pprofextension/metadata.yaml b/extension/pprofextension/metadata.yaml index 6a2d57cefeb7..e96abd2d0738 100644 --- a/extension/pprofextension/metadata.yaml +++ b/extension/pprofextension/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [extension] distributions: [core, contrib, splunk, observiq, sumo, aws, redhat] + codeowners: + active: [MovieStoreGuy] diff --git a/extension/sigv4authextension/README.md b/extension/sigv4authextension/README.md index c5f8ca9139ae..0e5a92c59bd2 100644 --- a/extension/sigv4authextension/README.md +++ b/extension/sigv4authextension/README.md @@ -5,6 +5,7 @@ | Stability | [beta] | | Distributions | [contrib], [aws], [grafana], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aextension%2Fsigv4auth%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aextension%2Fsigv4auth%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@Aneurysm9](https://www.github.com/Aneurysm9), [@erichsueh3](https://www.github.com/erichsueh3) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/extension/sigv4authextension/metadata.yaml b/extension/sigv4authextension/metadata.yaml index 302d9e18acc1..e96cc55e7afc 100644 --- a/extension/sigv4authextension/metadata.yaml +++ b/extension/sigv4authextension/metadata.yaml @@ -9,3 +9,5 @@ status: - aws - grafana - sumo + codeowners: + active: [Aneurysm9, erichsueh3] diff --git a/extension/storage/dbstorage/README.md b/extension/storage/dbstorage/README.md index 69dbfefb4702..4360dda42502 100644 --- a/extension/storage/dbstorage/README.md +++ b/extension/storage/dbstorage/README.md @@ -6,6 +6,7 @@ | Stability | [alpha] | | Distributions | [contrib], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aextension%2Fdbstorage%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aextension%2Fdbstorage%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@dmitryax](https://www.github.com/dmitryax), [@atoulme](https://www.github.com/atoulme) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/extension/storage/dbstorage/metadata.yaml b/extension/storage/dbstorage/metadata.yaml index 41d299ec9c8f..3142ebba4c29 100644 --- a/extension/storage/dbstorage/metadata.yaml +++ b/extension/storage/dbstorage/metadata.yaml @@ -5,3 +5,5 @@ status: stability: alpha: [extension] distributions: [contrib, sumo] + codeowners: + active: [dmitryax, atoulme] diff --git a/extension/storage/filestorage/README.md b/extension/storage/filestorage/README.md index 124acb600e45..d496c00e631c 100644 --- a/extension/storage/filestorage/README.md +++ b/extension/storage/filestorage/README.md @@ -6,6 +6,7 @@ | Stability | [beta] | | Distributions | [contrib], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aextension%2Ffilestorage%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aextension%2Ffilestorage%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@djaglowski](https://www.github.com/djaglowski) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/extension/storage/filestorage/metadata.yaml b/extension/storage/filestorage/metadata.yaml index 65b01d0051ca..4a89b792335d 100644 --- a/extension/storage/filestorage/metadata.yaml +++ b/extension/storage/filestorage/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [extension] distributions: [contrib, observiq, splunk, sumo] + codeowners: + active: [djaglowski] diff --git a/extension/storage/metadata.yaml b/extension/storage/metadata.yaml new file mode 100644 index 000000000000..742c324467a8 --- /dev/null +++ b/extension/storage/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [dmitryax, atoulme, djaglowski] \ No newline at end of file diff --git a/internal/aws/metadata.yaml b/internal/aws/metadata.yaml new file mode 100644 index 000000000000..6997dc17500d --- /dev/null +++ b/internal/aws/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [Aneurysm9, mxiamxia] \ No newline at end of file diff --git a/internal/coreinternal/metadata.yaml b/internal/coreinternal/metadata.yaml new file mode 100644 index 000000000000..d33786a6475a --- /dev/null +++ b/internal/coreinternal/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [open-telemetry/collector-approvers] \ No newline at end of file diff --git a/internal/docker/metadata.yaml b/internal/docker/metadata.yaml new file mode 100644 index 000000000000..5407e2033345 --- /dev/null +++ b/internal/docker/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [rmfitzpatrick, jamesmoessis] \ No newline at end of file diff --git a/internal/filter/metadata.yaml b/internal/filter/metadata.yaml new file mode 100644 index 000000000000..d33786a6475a --- /dev/null +++ b/internal/filter/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [open-telemetry/collector-approvers] \ No newline at end of file diff --git a/internal/k8sconfig/metadata.yaml b/internal/k8sconfig/metadata.yaml new file mode 100644 index 000000000000..f726a58cdfc3 --- /dev/null +++ b/internal/k8sconfig/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [dmitryax] \ No newline at end of file diff --git a/internal/k8stest/metadata.yaml b/internal/k8stest/metadata.yaml new file mode 100644 index 000000000000..55e148ace799 --- /dev/null +++ b/internal/k8stest/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [crobert-1] \ No newline at end of file diff --git a/internal/kubelet/metadata.yaml b/internal/kubelet/metadata.yaml new file mode 100644 index 000000000000..f726a58cdfc3 --- /dev/null +++ b/internal/kubelet/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [dmitryax] \ No newline at end of file diff --git a/internal/metadataproviders/metadata.yaml b/internal/metadataproviders/metadata.yaml new file mode 100644 index 000000000000..c71c6694ecc4 --- /dev/null +++ b/internal/metadataproviders/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [Aneurysm9, dashpole] \ No newline at end of file diff --git a/internal/sharedcomponent/metadata.yaml b/internal/sharedcomponent/metadata.yaml new file mode 100644 index 000000000000..57ff0e2295c5 --- /dev/null +++ b/internal/sharedcomponent/metadata.yaml @@ -0,0 +1,5 @@ +metadata: + yaml: +status: + codeowners: + active: [open-telemetry/collector-approvers] \ No newline at end of file diff --git a/internal/splunk/metadata.yaml b/internal/splunk/metadata.yaml new file mode 100644 index 000000000000..f726a58cdfc3 --- /dev/null +++ b/internal/splunk/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [dmitryax] \ No newline at end of file diff --git a/internal/tools/metadata.yaml b/internal/tools/metadata.yaml new file mode 100644 index 000000000000..6997dc17500d --- /dev/null +++ b/internal/tools/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [Aneurysm9, mxiamxia] \ No newline at end of file diff --git a/pkg/batchperresourceattr/metadata.yaml b/pkg/batchperresourceattr/metadata.yaml new file mode 100644 index 000000000000..d12358413bc0 --- /dev/null +++ b/pkg/batchperresourceattr/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [atoulme, dmitryax] diff --git a/pkg/batchpersignal/metadata.yaml b/pkg/batchpersignal/metadata.yaml new file mode 100644 index 000000000000..01842a240be8 --- /dev/null +++ b/pkg/batchpersignal/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [jpkrohling] \ No newline at end of file diff --git a/pkg/experimentalmetricmetadata/metadata.yaml b/pkg/experimentalmetricmetadata/metadata.yaml new file mode 100644 index 000000000000..e2972c99bb93 --- /dev/null +++ b/pkg/experimentalmetricmetadata/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [rmfitzpatrick] \ No newline at end of file diff --git a/pkg/ottl/metadata.yaml b/pkg/ottl/metadata.yaml new file mode 100644 index 000000000000..a5288ab53293 --- /dev/null +++ b/pkg/ottl/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [TylerHelmuth, kentquirk, bogdandrutu, evan-bradley] \ No newline at end of file diff --git a/pkg/pdatatest/metadata.yaml b/pkg/pdatatest/metadata.yaml new file mode 100644 index 000000000000..b0d475f9fe83 --- /dev/null +++ b/pkg/pdatatest/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [djaglowski, fatsheep9146] \ No newline at end of file diff --git a/pkg/pdatautil/metadata.yaml b/pkg/pdatautil/metadata.yaml new file mode 100644 index 000000000000..f726a58cdfc3 --- /dev/null +++ b/pkg/pdatautil/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [dmitryax] \ No newline at end of file diff --git a/pkg/resourcetotelemetry/metadata.yaml b/pkg/resourcetotelemetry/metadata.yaml new file mode 100644 index 000000000000..eeaff821b509 --- /dev/null +++ b/pkg/resourcetotelemetry/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [mx-psi] \ No newline at end of file diff --git a/pkg/stanza/metadata.yaml b/pkg/stanza/metadata.yaml new file mode 100644 index 000000000000..49243f906e11 --- /dev/null +++ b/pkg/stanza/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [djaglowski] \ No newline at end of file diff --git a/pkg/translator/jaeger/metadata.yaml b/pkg/translator/jaeger/metadata.yaml new file mode 100644 index 000000000000..d33786a6475a --- /dev/null +++ b/pkg/translator/jaeger/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [open-telemetry/collector-approvers] \ No newline at end of file diff --git a/pkg/translator/loki/metadata.yaml b/pkg/translator/loki/metadata.yaml new file mode 100644 index 000000000000..2b9d4919864e --- /dev/null +++ b/pkg/translator/loki/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [gouthamve, jpkrohling, kovrus, mar4uk] \ No newline at end of file diff --git a/pkg/translator/opencensus/metadata.yaml b/pkg/translator/opencensus/metadata.yaml new file mode 100644 index 000000000000..d33786a6475a --- /dev/null +++ b/pkg/translator/opencensus/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [open-telemetry/collector-approvers] \ No newline at end of file diff --git a/pkg/translator/prometheus/metadata.yaml b/pkg/translator/prometheus/metadata.yaml new file mode 100644 index 000000000000..ad3618bcdf56 --- /dev/null +++ b/pkg/translator/prometheus/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [dashpole, bertysentry] \ No newline at end of file diff --git a/pkg/translator/prometheusremotewrite/metadata.yaml b/pkg/translator/prometheusremotewrite/metadata.yaml new file mode 100644 index 000000000000..1f5c7161da0e --- /dev/null +++ b/pkg/translator/prometheusremotewrite/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [Aneurysm9, kovrus] \ No newline at end of file diff --git a/pkg/translator/signalfx/metadata.yaml b/pkg/translator/signalfx/metadata.yaml new file mode 100644 index 000000000000..f726a58cdfc3 --- /dev/null +++ b/pkg/translator/signalfx/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [dmitryax] \ No newline at end of file diff --git a/pkg/translator/zipkin/metadata.yaml b/pkg/translator/zipkin/metadata.yaml new file mode 100644 index 000000000000..0517083c3a29 --- /dev/null +++ b/pkg/translator/zipkin/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [MovieStoreGuy, astencel-sumo, crobert-1] \ No newline at end of file diff --git a/pkg/winperfcounters/metadata.yaml b/pkg/winperfcounters/metadata.yaml new file mode 100644 index 000000000000..49f2050b2c4a --- /dev/null +++ b/pkg/winperfcounters/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [dashpole, mrod1598, binaryfissiongames] \ No newline at end of file diff --git a/processor/attributesprocessor/README.md b/processor/attributesprocessor/README.md index 45b5a061a52d..619faff019ea 100644 --- a/processor/attributesprocessor/README.md +++ b/processor/attributesprocessor/README.md @@ -7,6 +7,7 @@ | Distributions | [core], [contrib], [aws], [grafana], [observiq], [redhat], [splunk], [sumo] | | Warnings | [Identity Conflict](#warnings) | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aprocessor%2Fattributes%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aprocessor%2Fattributes%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@boostchicken](https://www.github.com/boostchicken) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [core]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol diff --git a/processor/attributesprocessor/metadata.yaml b/processor/attributesprocessor/metadata.yaml index 95131fa10946..b01c93d57a5d 100644 --- a/processor/attributesprocessor/metadata.yaml +++ b/processor/attributesprocessor/metadata.yaml @@ -14,3 +14,5 @@ status: - splunk - sumo warnings: [Identity Conflict] + codeowners: + active: [boostchicken] diff --git a/processor/cumulativetodeltaprocessor/README.md b/processor/cumulativetodeltaprocessor/README.md index c87063760c45..007e5b90629b 100644 --- a/processor/cumulativetodeltaprocessor/README.md +++ b/processor/cumulativetodeltaprocessor/README.md @@ -6,6 +6,7 @@ | Distributions | [contrib], [aws], [observiq], [sumo] | | Warnings | [Statefulness](#warnings) | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aprocessor%2Fcumulativetodelta%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aprocessor%2Fcumulativetodelta%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@TylerHelmuth](https://www.github.com/TylerHelmuth) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/processor/cumulativetodeltaprocessor/metadata.yaml b/processor/cumulativetodeltaprocessor/metadata.yaml index 634d7c52252c..271bf37805c7 100644 --- a/processor/cumulativetodeltaprocessor/metadata.yaml +++ b/processor/cumulativetodeltaprocessor/metadata.yaml @@ -6,3 +6,5 @@ status: beta: [metrics] distributions: [contrib, observiq, sumo, aws] warnings: [Statefulness] + codeowners: + active: [TylerHelmuth] \ No newline at end of file diff --git a/processor/datadogprocessor/README.md b/processor/datadogprocessor/README.md index 5b6be134ab15..4c02853b23d0 100644 --- a/processor/datadogprocessor/README.md +++ b/processor/datadogprocessor/README.md @@ -5,6 +5,7 @@ | Stability | [beta]: traces | | Distributions | [contrib] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aprocessor%2Fdatadog%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aprocessor%2Fdatadog%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@mx-psi](https://www.github.com/mx-psi), [@gbbr](https://www.github.com/gbbr), [@dineshg13](https://www.github.com/dineshg13) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/processor/datadogprocessor/metadata.yaml b/processor/datadogprocessor/metadata.yaml index 01618afdcc01..f48f725eeac6 100644 --- a/processor/datadogprocessor/metadata.yaml +++ b/processor/datadogprocessor/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [traces] distributions: [contrib] + codeowners: + active: [mx-psi, gbbr, dineshg13] \ No newline at end of file diff --git a/processor/deltatorateprocessor/README.md b/processor/deltatorateprocessor/README.md index b3d8c48efcd5..74a3d814c24d 100644 --- a/processor/deltatorateprocessor/README.md +++ b/processor/deltatorateprocessor/README.md @@ -5,6 +5,7 @@ | Stability | [development]: metrics | | Distributions | [contrib], [aws], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aprocessor%2Fdeltatorate%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aprocessor%2Fdeltatorate%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@Aneurysm9](https://www.github.com/Aneurysm9) | [development]: https://github.com/open-telemetry/opentelemetry-collector#development [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/processor/deltatorateprocessor/metadata.yaml b/processor/deltatorateprocessor/metadata.yaml index f14b7555cad4..1198892cbc5f 100644 --- a/processor/deltatorateprocessor/metadata.yaml +++ b/processor/deltatorateprocessor/metadata.yaml @@ -5,3 +5,5 @@ status: stability: development: [metrics] distributions: [contrib, observiq, sumo, aws] + codeowners: + active: [Aneurysm9] \ No newline at end of file diff --git a/processor/filterprocessor/README.md b/processor/filterprocessor/README.md index f8098946259d..e780bb84d03c 100644 --- a/processor/filterprocessor/README.md +++ b/processor/filterprocessor/README.md @@ -6,6 +6,7 @@ | Distributions | [core], [contrib], [aws], [observiq], [redhat], [splunk], [sumo] | | Warnings | [Orphaned Telemetry, Other](#warnings) | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aprocessor%2Ffilter%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aprocessor%2Ffilter%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@TylerHelmuth](https://www.github.com/TylerHelmuth), [@boostchicken](https://www.github.com/boostchicken) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [core]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol diff --git a/processor/filterprocessor/metadata.yaml b/processor/filterprocessor/metadata.yaml index 47f1a3920287..eb3d801a6383 100644 --- a/processor/filterprocessor/metadata.yaml +++ b/processor/filterprocessor/metadata.yaml @@ -6,3 +6,5 @@ status: alpha: [traces, metrics, logs] distributions: [core, contrib, splunk, observiq, sumo, aws, redhat] warnings: [Orphaned Telemetry, Other] + codeowners: + active: [TylerHelmuth, boostchicken] \ No newline at end of file diff --git a/processor/groupbyattrsprocessor/README.md b/processor/groupbyattrsprocessor/README.md index 4ff0da190895..0461d2ad3960 100644 --- a/processor/groupbyattrsprocessor/README.md +++ b/processor/groupbyattrsprocessor/README.md @@ -5,6 +5,7 @@ | Stability | [beta]: traces, metrics, logs | | Distributions | [contrib], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aprocessor%2Fgroupbyattrs%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aprocessor%2Fgroupbyattrs%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@rnishtala-sumo](https://www.github.com/rnishtala-sumo) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/processor/groupbyattrsprocessor/metadata.yaml b/processor/groupbyattrsprocessor/metadata.yaml index fe9bbfe7fc58..665d2170653e 100644 --- a/processor/groupbyattrsprocessor/metadata.yaml +++ b/processor/groupbyattrsprocessor/metadata.yaml @@ -6,3 +6,5 @@ status: beta: [traces, metrics, logs] distributions: [contrib, splunk, observiq, sumo] warnings: [] + codeowners: + active: [rnishtala-sumo] \ No newline at end of file diff --git a/processor/groupbytraceprocessor/README.md b/processor/groupbytraceprocessor/README.md index e063edbd85a2..ba1e0939d36f 100644 --- a/processor/groupbytraceprocessor/README.md +++ b/processor/groupbytraceprocessor/README.md @@ -6,6 +6,7 @@ | Distributions | [contrib], [aws], [observiq], [sumo] | | Warnings | [Statefulness](#warnings) | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aprocessor%2Fgroupbytrace%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aprocessor%2Fgroupbytrace%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jpkrohling](https://www.github.com/jpkrohling) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/processor/groupbytraceprocessor/metadata.yaml b/processor/groupbytraceprocessor/metadata.yaml index cc2219d01c51..e24caa652793 100644 --- a/processor/groupbytraceprocessor/metadata.yaml +++ b/processor/groupbytraceprocessor/metadata.yaml @@ -6,3 +6,5 @@ status: beta: [traces] distributions: [contrib, observiq, sumo, aws] warnings: [Statefulness] + codeowners: + active: [jpkrohling] \ No newline at end of file diff --git a/processor/k8sattributesprocessor/README.md b/processor/k8sattributesprocessor/README.md index 6f381dad83c1..a33157c4292d 100644 --- a/processor/k8sattributesprocessor/README.md +++ b/processor/k8sattributesprocessor/README.md @@ -5,6 +5,7 @@ | Stability | [beta]: logs, metrics, traces | | Distributions | [contrib], [observiq], [redhat], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aprocessor%2Fk8sattributes%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aprocessor%2Fk8sattributes%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@dmitryax](https://www.github.com/dmitryax), [@rmfitzpatrick](https://www.github.com/rmfitzpatrick), [@fatsheep9146](https://www.github.com/fatsheep9146) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/processor/k8sattributesprocessor/metadata.yaml b/processor/k8sattributesprocessor/metadata.yaml index a1412be6ddfa..58c9b5d526cf 100644 --- a/processor/k8sattributesprocessor/metadata.yaml +++ b/processor/k8sattributesprocessor/metadata.yaml @@ -5,7 +5,8 @@ status: stability: beta: [logs, metrics, traces] distributions: [contrib, splunk, observiq, sumo, redhat] - + codeowners: + active: [dmitryax, rmfitzpatrick, fatsheep9146] # resource attributes are exposed through a different configuration interface (extract::metadata). resource_attributes: k8s.namespace.name: diff --git a/processor/logstransformprocessor/README.md b/processor/logstransformprocessor/README.md index 47fac2e2c8d0..025e744ef4d8 100644 --- a/processor/logstransformprocessor/README.md +++ b/processor/logstransformprocessor/README.md @@ -6,6 +6,7 @@ | Stability | [development]: logs | | Distributions | [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aprocessor%2Flogstransform%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aprocessor%2Flogstransform%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@djaglowski](https://www.github.com/djaglowski), [@dehaansa](https://www.github.com/dehaansa) | [development]: https://github.com/open-telemetry/opentelemetry-collector#development [observiq]: https://github.com/observIQ/observiq-otel-collector diff --git a/processor/logstransformprocessor/metadata.yaml b/processor/logstransformprocessor/metadata.yaml index e18438a622f8..5edf8909d332 100644 --- a/processor/logstransformprocessor/metadata.yaml +++ b/processor/logstransformprocessor/metadata.yaml @@ -5,3 +5,5 @@ status: stability: development: [logs] distributions: [observiq, splunk, sumo] + codeowners: + active: [djaglowski, dehaansa] \ No newline at end of file diff --git a/processor/metricsgenerationprocessor/README.md b/processor/metricsgenerationprocessor/README.md index 78d55802315e..ba406e618df0 100644 --- a/processor/metricsgenerationprocessor/README.md +++ b/processor/metricsgenerationprocessor/README.md @@ -6,6 +6,7 @@ | Stability | [development]: metrics | | Distributions | [contrib], [aws], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aprocessor%2Fmetricsgeneration%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aprocessor%2Fmetricsgeneration%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@Aneurysm9](https://www.github.com/Aneurysm9) | [development]: https://github.com/open-telemetry/opentelemetry-collector#development [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/processor/metricsgenerationprocessor/metadata.yaml b/processor/metricsgenerationprocessor/metadata.yaml index b1863e991c1b..707bf2afe775 100644 --- a/processor/metricsgenerationprocessor/metadata.yaml +++ b/processor/metricsgenerationprocessor/metadata.yaml @@ -5,3 +5,5 @@ status: stability: development: [metrics] distributions: [contrib, sumo, aws] + codeowners: + active: [Aneurysm9] \ No newline at end of file diff --git a/processor/metricstransformprocessor/README.md b/processor/metricstransformprocessor/README.md index 5c29e6e7b4a2..03e18808f73a 100644 --- a/processor/metricstransformprocessor/README.md +++ b/processor/metricstransformprocessor/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [contrib], [aws], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aprocessor%2Fmetricstransform%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aprocessor%2Fmetricstransform%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@dmitryax](https://www.github.com/dmitryax) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/processor/metricstransformprocessor/metadata.yaml b/processor/metricstransformprocessor/metadata.yaml index 4031fa3d8ea4..8859d5492293 100644 --- a/processor/metricstransformprocessor/metadata.yaml +++ b/processor/metricstransformprocessor/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [metrics] distributions: [contrib, observiq, splunk, sumo, aws] + codeowners: + active: [dmitryax] \ No newline at end of file diff --git a/processor/probabilisticsamplerprocessor/README.md b/processor/probabilisticsamplerprocessor/README.md index 56b45f851f49..3d96a792fa9a 100644 --- a/processor/probabilisticsamplerprocessor/README.md +++ b/processor/probabilisticsamplerprocessor/README.md @@ -7,6 +7,7 @@ | | [beta]: traces | | Distributions | [core], [contrib], [aws], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aprocessor%2Fprobabilisticsampler%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aprocessor%2Fprobabilisticsampler%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jpkrohling](https://www.github.com/jpkrohling) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta diff --git a/processor/probabilisticsamplerprocessor/metadata.yaml b/processor/probabilisticsamplerprocessor/metadata.yaml index ae3bae8d58b1..40692f53c81d 100644 --- a/processor/probabilisticsamplerprocessor/metadata.yaml +++ b/processor/probabilisticsamplerprocessor/metadata.yaml @@ -6,3 +6,5 @@ status: beta: [traces] alpha: [logs] distributions: [core, contrib, observiq, splunk, sumo, aws] + codeowners: + active: [jpkrohling] \ No newline at end of file diff --git a/processor/redactionprocessor/README.md b/processor/redactionprocessor/README.md index db696f941080..82a260dc578f 100644 --- a/processor/redactionprocessor/README.md +++ b/processor/redactionprocessor/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces | | Distributions | [contrib], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aprocessor%2Fredaction%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aprocessor%2Fredaction%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@leonsp-ai](https://www.github.com/leonsp-ai), [@dmitryax](https://www.github.com/dmitryax), [@mx-psi](https://www.github.com/mx-psi) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/processor/redactionprocessor/metadata.yaml b/processor/redactionprocessor/metadata.yaml index 5a54c83c83c9..80eeb6a7b4ff 100644 --- a/processor/redactionprocessor/metadata.yaml +++ b/processor/redactionprocessor/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [traces] distributions: [contrib, sumo] + codeowners: + active: [leonsp-ai, dmitryax, mx-psi] \ No newline at end of file diff --git a/processor/remoteobserverprocessor/README.md b/processor/remoteobserverprocessor/README.md index 34bfca8573f4..e204ca7b4b3f 100644 --- a/processor/remoteobserverprocessor/README.md +++ b/processor/remoteobserverprocessor/README.md @@ -5,6 +5,7 @@ | Stability | [alpha]: logs, metrics, traces | | Distributions | [contrib] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aprocessor%2Fremoteobserver%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aprocessor%2Fremoteobserver%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@pmcollins](https://www.github.com/pmcollins) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/processor/remoteobserverprocessor/metadata.yaml b/processor/remoteobserverprocessor/metadata.yaml index a1c99165bf9b..a0d756231e4f 100644 --- a/processor/remoteobserverprocessor/metadata.yaml +++ b/processor/remoteobserverprocessor/metadata.yaml @@ -5,3 +5,5 @@ status: stability: alpha: [logs, metrics, traces] distributions: [contrib] + codeowners: + active: [pmcollins] \ No newline at end of file diff --git a/processor/resourcedetectionprocessor/README.md b/processor/resourcedetectionprocessor/README.md index 5a4367c6dd31..4d893f485f2c 100644 --- a/processor/resourcedetectionprocessor/README.md +++ b/processor/resourcedetectionprocessor/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces, metrics, logs | | Distributions | [contrib], [aws], [observiq], [redhat], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aprocessor%2Fresourcedetection%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aprocessor%2Fresourcedetection%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@Aneurysm9](https://www.github.com/Aneurysm9), [@dashpole](https://www.github.com/dashpole) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/processor/resourcedetectionprocessor/internal/azure/internal/metadata/generated_status.go b/processor/resourcedetectionprocessor/internal/azure/internal/metadata/generated_status.go new file mode 100644 index 000000000000..ce3d0625ab32 --- /dev/null +++ b/processor/resourcedetectionprocessor/internal/azure/internal/metadata/generated_status.go @@ -0,0 +1,7 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +const ( + Type = "resourcedetectionprocessor/azure" +) diff --git a/processor/resourcedetectionprocessor/internal/azure/metadata.yaml b/processor/resourcedetectionprocessor/internal/azure/metadata.yaml index f49e03d59d5e..3e896d9c3e44 100644 --- a/processor/resourcedetectionprocessor/internal/azure/metadata.yaml +++ b/processor/resourcedetectionprocessor/internal/azure/metadata.yaml @@ -2,6 +2,11 @@ type: resourcedetectionprocessor/azure parent: resourcedetection +status: + class: processor + codeowners: + active: [mx-psi] + resource_attributes: cloud.provider: description: The cloud.provider diff --git a/processor/resourcedetectionprocessor/internal/heroku/internal/metadata/generated_status.go b/processor/resourcedetectionprocessor/internal/heroku/internal/metadata/generated_status.go new file mode 100644 index 000000000000..b8fe4cf34870 --- /dev/null +++ b/processor/resourcedetectionprocessor/internal/heroku/internal/metadata/generated_status.go @@ -0,0 +1,7 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +const ( + Type = "resourcedetectionprocessor/heroku" +) diff --git a/processor/resourcedetectionprocessor/internal/heroku/metadata.yaml b/processor/resourcedetectionprocessor/internal/heroku/metadata.yaml index 275932d67fb7..85f166703e9c 100644 --- a/processor/resourcedetectionprocessor/internal/heroku/metadata.yaml +++ b/processor/resourcedetectionprocessor/internal/heroku/metadata.yaml @@ -2,6 +2,11 @@ type: resourcedetectionprocessor/heroku parent: resourcedetection +status: + class: processor + codeowners: + active: [atoulme] + resource_attributes: cloud.provider: description: The cloud.provider diff --git a/processor/resourcedetectionprocessor/internal/openshift/internal/metadata/generated_status.go b/processor/resourcedetectionprocessor/internal/openshift/internal/metadata/generated_status.go new file mode 100644 index 000000000000..5b551af20c6b --- /dev/null +++ b/processor/resourcedetectionprocessor/internal/openshift/internal/metadata/generated_status.go @@ -0,0 +1,7 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +const ( + Type = "resourcedetectionprocessor/openshift" +) diff --git a/processor/resourcedetectionprocessor/internal/openshift/metadata.yaml b/processor/resourcedetectionprocessor/internal/openshift/metadata.yaml index edfcb522e4d0..499c2e571a76 100644 --- a/processor/resourcedetectionprocessor/internal/openshift/metadata.yaml +++ b/processor/resourcedetectionprocessor/internal/openshift/metadata.yaml @@ -2,6 +2,11 @@ type: resourcedetectionprocessor/openshift parent: resourcedetection +status: + class: processor + codeowners: + active: [frzifus] + resource_attributes: cloud.provider: description: The cloud.provider diff --git a/processor/resourcedetectionprocessor/metadata.yaml b/processor/resourcedetectionprocessor/metadata.yaml index 80bbdb1146c4..a95149e62354 100644 --- a/processor/resourcedetectionprocessor/metadata.yaml +++ b/processor/resourcedetectionprocessor/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [traces, metrics, logs] distributions: [contrib, splunk, observiq, sumo, aws, redhat] + codeowners: + active: [Aneurysm9, dashpole] diff --git a/processor/resourceprocessor/README.md b/processor/resourceprocessor/README.md index c9a54805bad4..20141d73af5b 100644 --- a/processor/resourceprocessor/README.md +++ b/processor/resourceprocessor/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces, metrics, logs | | Distributions | [core], [contrib], [aws], [observiq], [redhat], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aprocessor%2Fresource%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aprocessor%2Fresource%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@dmitryax](https://www.github.com/dmitryax) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [core]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol diff --git a/processor/resourceprocessor/metadata.yaml b/processor/resourceprocessor/metadata.yaml index ba6653379fc8..1ed200501ccc 100644 --- a/processor/resourceprocessor/metadata.yaml +++ b/processor/resourceprocessor/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [traces, metrics, logs] distributions: [core, contrib, splunk, observiq, sumo, aws, redhat] + codeowners: + active: [dmitryax] \ No newline at end of file diff --git a/processor/routingprocessor/README.md b/processor/routingprocessor/README.md index 625621ca1057..590757be314a 100644 --- a/processor/routingprocessor/README.md +++ b/processor/routingprocessor/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces, metrics, logs | | Distributions | [contrib], [observiq], [redhat], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aprocessor%2Frouting%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aprocessor%2Frouting%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jpkrohling](https://www.github.com/jpkrohling), [@kovrus](https://www.github.com/kovrus) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/processor/routingprocessor/metadata.yaml b/processor/routingprocessor/metadata.yaml index 630f1fe84d96..d9b9c0b18d9f 100644 --- a/processor/routingprocessor/metadata.yaml +++ b/processor/routingprocessor/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [traces, metrics, logs] distributions: [contrib, observiq, splunk, sumo, redhat] + codeowners: + active: [jpkrohling, kovrus] \ No newline at end of file diff --git a/processor/schemaprocessor/README.md b/processor/schemaprocessor/README.md index 5c5a966ab2d7..2dd078bf3df2 100644 --- a/processor/schemaprocessor/README.md +++ b/processor/schemaprocessor/README.md @@ -6,6 +6,7 @@ | Stability | [development]: traces, metrics, logs | | Distributions | [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aprocessor%2Fschema%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aprocessor%2Fschema%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@MovieStoreGuy](https://www.github.com/MovieStoreGuy) | [development]: https://github.com/open-telemetry/opentelemetry-collector#development [sumo]: https://github.com/SumoLogic/sumologic-otel-collector diff --git a/processor/schemaprocessor/metadata.yaml b/processor/schemaprocessor/metadata.yaml index 31f837481e68..4f1269f0c916 100644 --- a/processor/schemaprocessor/metadata.yaml +++ b/processor/schemaprocessor/metadata.yaml @@ -5,3 +5,5 @@ status: stability: development: [traces, metrics, logs] distributions: [sumo] + codeowners: + active: [MovieStoreGuy] \ No newline at end of file diff --git a/processor/servicegraphprocessor/README.md b/processor/servicegraphprocessor/README.md index 4f1c8a508413..f0c57c237e85 100644 --- a/processor/servicegraphprocessor/README.md +++ b/processor/servicegraphprocessor/README.md @@ -6,6 +6,7 @@ | Stability | [deprecated]: traces | | Distributions | [contrib], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aprocessor%2Fservicegraph%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aprocessor%2Fservicegraph%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jpkrohling](https://www.github.com/jpkrohling), [@mapno](https://www.github.com/mapno) | [deprecated]: https://github.com/open-telemetry/opentelemetry-collector#deprecated [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/processor/servicegraphprocessor/metadata.yaml b/processor/servicegraphprocessor/metadata.yaml index bf86a0d65086..92d5e0065c7f 100644 --- a/processor/servicegraphprocessor/metadata.yaml +++ b/processor/servicegraphprocessor/metadata.yaml @@ -6,3 +6,5 @@ status: deprecated: [traces] distributions: [contrib, sumo] warnings: [] + codeowners: + active: [jpkrohling, mapno] \ No newline at end of file diff --git a/processor/spanmetricsprocessor/README.md b/processor/spanmetricsprocessor/README.md index 62eb2f5553d3..68a153a207cc 100644 --- a/processor/spanmetricsprocessor/README.md +++ b/processor/spanmetricsprocessor/README.md @@ -6,6 +6,7 @@ | Stability | [deprecated]: traces | | Distributions | [contrib], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aprocessor%2Fspanmetrics%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aprocessor%2Fspanmetrics%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@albertteoh](https://www.github.com/albertteoh) | [deprecated]: https://github.com/open-telemetry/opentelemetry-collector#deprecated [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/processor/spanmetricsprocessor/metadata.yaml b/processor/spanmetricsprocessor/metadata.yaml index 48fd8e7e0546..0317a0696c3f 100644 --- a/processor/spanmetricsprocessor/metadata.yaml +++ b/processor/spanmetricsprocessor/metadata.yaml @@ -5,3 +5,5 @@ status: stability: deprecated: [traces] distributions: [contrib, observiq, splunk, sumo] + codeowners: + active: [albertteoh] \ No newline at end of file diff --git a/processor/spanprocessor/README.md b/processor/spanprocessor/README.md index 7a8306c44738..820035bebc39 100644 --- a/processor/spanprocessor/README.md +++ b/processor/spanprocessor/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: traces | | Distributions | [core], [contrib], [aws], [observiq], [redhat], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aprocessor%2Fspan%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aprocessor%2Fspan%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@boostchicken](https://www.github.com/boostchicken) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [core]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol diff --git a/processor/spanprocessor/metadata.yaml b/processor/spanprocessor/metadata.yaml index 6fac613e754f..3fc30af02b79 100644 --- a/processor/spanprocessor/metadata.yaml +++ b/processor/spanprocessor/metadata.yaml @@ -5,3 +5,5 @@ status: stability: alpha: [traces] distributions: [core, contrib, observiq, splunk, sumo, aws, redhat] + codeowners: + active: [boostchicken] \ No newline at end of file diff --git a/processor/tailsamplingprocessor/README.md b/processor/tailsamplingprocessor/README.md index 26818c9df474..29d5d1bfddee 100644 --- a/processor/tailsamplingprocessor/README.md +++ b/processor/tailsamplingprocessor/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces | | Distributions | [contrib], [aws], [grafana], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aprocessor%2Ftailsampling%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aprocessor%2Ftailsampling%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jpkrohling](https://www.github.com/jpkrohling) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/processor/tailsamplingprocessor/metadata.yaml b/processor/tailsamplingprocessor/metadata.yaml index 0b12c78d00a4..c68c47e447ad 100644 --- a/processor/tailsamplingprocessor/metadata.yaml +++ b/processor/tailsamplingprocessor/metadata.yaml @@ -11,3 +11,5 @@ status: - observiq - splunk - sumo + codeowners: + active: [jpkrohling] diff --git a/processor/transformprocessor/README.md b/processor/transformprocessor/README.md index 40b165d7418c..818c2cbfaa25 100644 --- a/processor/transformprocessor/README.md +++ b/processor/transformprocessor/README.md @@ -6,6 +6,7 @@ | Distributions | [contrib], [observiq], [splunk], [sumo] | | Warnings | [Unsound Transformations, Identity Conflict, Orphaned Telemetry, Other](#warnings) | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aprocessor%2Ftransform%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aprocessor%2Ftransform%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@TylerHelmuth](https://www.github.com/TylerHelmuth), [@kentquirk](https://www.github.com/kentquirk), [@bogdandrutu](https://www.github.com/bogdandrutu), [@evan-bradley](https://www.github.com/evan-bradley) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/processor/transformprocessor/metadata.yaml b/processor/transformprocessor/metadata.yaml index 14f1b1a33985..fb4e77c34687 100644 --- a/processor/transformprocessor/metadata.yaml +++ b/processor/transformprocessor/metadata.yaml @@ -6,3 +6,5 @@ status: alpha: [traces, metrics, logs] distributions: [contrib, splunk, observiq, sumo] warnings: [Unsound Transformations, Identity Conflict, Orphaned Telemetry, Other] + codeowners: + active: [TylerHelmuth, kentquirk, bogdandrutu, evan-bradley] \ No newline at end of file diff --git a/receiver/activedirectorydsreceiver/README.md b/receiver/activedirectorydsreceiver/README.md index ed78e3ed10f7..70e80429048c 100644 --- a/receiver/activedirectorydsreceiver/README.md +++ b/receiver/activedirectorydsreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [contrib], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Factivedirectoryds%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Factivedirectoryds%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@djaglowski](https://www.github.com/djaglowski), [@binaryfissiongames](https://www.github.com/binaryfissiongames) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/activedirectorydsreceiver/metadata.yaml b/receiver/activedirectorydsreceiver/metadata.yaml index 92b9d3e56af3..c98e0a42f169 100644 --- a/receiver/activedirectorydsreceiver/metadata.yaml +++ b/receiver/activedirectorydsreceiver/metadata.yaml @@ -5,6 +5,8 @@ status: stability: beta: [metrics] distributions: [contrib, observiq, sumo] + codeowners: + active: [djaglowski, binaryfissiongames] attributes: direction: diff --git a/receiver/aerospikereceiver/README.md b/receiver/aerospikereceiver/README.md index ed68cbab6b6d..117d12c0480a 100644 --- a/receiver/aerospikereceiver/README.md +++ b/receiver/aerospikereceiver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: metrics | | Distributions | [contrib], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Faerospike%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Faerospike%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@djaglowski](https://www.github.com/djaglowski), [@antonblock](https://www.github.com/antonblock) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/aerospikereceiver/metadata.yaml b/receiver/aerospikereceiver/metadata.yaml index 66244612f603..9795e1e1bc61 100644 --- a/receiver/aerospikereceiver/metadata.yaml +++ b/receiver/aerospikereceiver/metadata.yaml @@ -5,6 +5,8 @@ status: stability: alpha: [metrics] distributions: [contrib, observiq, sumo] + codeowners: + active: [djaglowski, antonblock] resource_attributes: aerospike.node.name: diff --git a/receiver/apachereceiver/README.md b/receiver/apachereceiver/README.md index a3b994f62ea1..321b89dc4091 100644 --- a/receiver/apachereceiver/README.md +++ b/receiver/apachereceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [contrib], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fapache%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fapache%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@djaglowski](https://www.github.com/djaglowski) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/apachereceiver/metadata.yaml b/receiver/apachereceiver/metadata.yaml index 41ac9c18a3e3..abc1130f8342 100644 --- a/receiver/apachereceiver/metadata.yaml +++ b/receiver/apachereceiver/metadata.yaml @@ -5,6 +5,8 @@ status: stability: beta: [metrics] distributions: [contrib, observiq, sumo] + codeowners: + active: [djaglowski] resource_attributes: apache.server.name: diff --git a/receiver/apachesparkreceiver/README.md b/receiver/apachesparkreceiver/README.md index edfb3a9b6cca..0b16b285bdb4 100644 --- a/receiver/apachesparkreceiver/README.md +++ b/receiver/apachesparkreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [development]: metrics | | Distributions | [contrib] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fapachespark%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fapachespark%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@djaglowski](https://www.github.com/djaglowski), [@Caleb-Hurshman](https://www.github.com/Caleb-Hurshman), [@mrsillydog](https://www.github.com/mrsillydog) | [development]: https://github.com/open-telemetry/opentelemetry-collector#development [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/apachesparkreceiver/metadata.yaml b/receiver/apachesparkreceiver/metadata.yaml index 24099173f33c..57e64d73ee54 100644 --- a/receiver/apachesparkreceiver/metadata.yaml +++ b/receiver/apachesparkreceiver/metadata.yaml @@ -5,6 +5,8 @@ status: stability: development: [metrics] distributions: [contrib] + codeowners: + active: [djaglowski, Caleb-Hurshman, mrsillydog] resource_attributes: spark.application.id: diff --git a/receiver/awscloudwatchmetricsreceiver/README.md b/receiver/awscloudwatchmetricsreceiver/README.md index 6655f31f35e9..518ec0ba9adc 100644 --- a/receiver/awscloudwatchmetricsreceiver/README.md +++ b/receiver/awscloudwatchmetricsreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [development]: metrics | | Distributions | [contrib] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fawscloudwatchmetrics%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fawscloudwatchmetrics%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jpkrohling](https://www.github.com/jpkrohling), [@kovrus](https://www.github.com/kovrus) | [development]: https://github.com/open-telemetry/opentelemetry-collector#development [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/awscloudwatchmetricsreceiver/metadata.yaml b/receiver/awscloudwatchmetricsreceiver/metadata.yaml index f2c2b83a8dc0..a10c59f43335 100644 --- a/receiver/awscloudwatchmetricsreceiver/metadata.yaml +++ b/receiver/awscloudwatchmetricsreceiver/metadata.yaml @@ -5,3 +5,5 @@ status: stability: development: [metrics] distributions: [contrib] + codeowners: + active: [jpkrohling, kovrus] \ No newline at end of file diff --git a/receiver/awscloudwatchreceiver/README.md b/receiver/awscloudwatchreceiver/README.md index ecea78b480f6..05153a073cea 100644 --- a/receiver/awscloudwatchreceiver/README.md +++ b/receiver/awscloudwatchreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: logs | | Distributions | [contrib], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fawscloudwatch%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fawscloudwatch%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@djaglowski](https://www.github.com/djaglowski), [@schmikei](https://www.github.com/schmikei) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/awscloudwatchreceiver/metadata.yaml b/receiver/awscloudwatchreceiver/metadata.yaml index 86f281a4599f..5d45699e2f81 100644 --- a/receiver/awscloudwatchreceiver/metadata.yaml +++ b/receiver/awscloudwatchreceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: alpha: [logs] distributions: [contrib, observiq, sumo] - + codeowners: + active: [djaglowski, schmikei] diff --git a/receiver/awscontainerinsightreceiver/README.md b/receiver/awscontainerinsightreceiver/README.md index 01d60025b0ba..b6b626eef397 100644 --- a/receiver/awscontainerinsightreceiver/README.md +++ b/receiver/awscontainerinsightreceiver/README.md @@ -7,6 +7,7 @@ | Distributions | [contrib], [aws], [observiq], [sumo] | | Warnings | [Other](#warnings) | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fawscontainerinsight%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fawscontainerinsight%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@Aneurysm9](https://www.github.com/Aneurysm9), [@pxaws](https://www.github.com/pxaws) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/awscontainerinsightreceiver/metadata.yaml b/receiver/awscontainerinsightreceiver/metadata.yaml index 7298a706cbc8..6e86fe37b3d6 100644 --- a/receiver/awscontainerinsightreceiver/metadata.yaml +++ b/receiver/awscontainerinsightreceiver/metadata.yaml @@ -6,3 +6,5 @@ status: beta: [metrics] distributions: [contrib, aws, observiq, sumo] warnings: [Other] + codeowners: + active: [Aneurysm9, pxaws] \ No newline at end of file diff --git a/receiver/awsecscontainermetricsreceiver/README.md b/receiver/awsecscontainermetricsreceiver/README.md index 684aeeefc191..936550162bdb 100644 --- a/receiver/awsecscontainermetricsreceiver/README.md +++ b/receiver/awsecscontainermetricsreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [contrib], [aws], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fawsecscontainermetrics%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fawsecscontainermetrics%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@Aneurysm9](https://www.github.com/Aneurysm9) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/awsecscontainermetricsreceiver/metadata.yaml b/receiver/awsecscontainermetricsreceiver/metadata.yaml index a503a72926b2..d51d95cc9de9 100644 --- a/receiver/awsecscontainermetricsreceiver/metadata.yaml +++ b/receiver/awsecscontainermetricsreceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: beta: [metrics] distributions: [contrib, aws, observiq, sumo] - + codeowners: + active: [Aneurysm9] diff --git a/receiver/awsfirehosereceiver/README.md b/receiver/awsfirehosereceiver/README.md index 3cce444f7849..e40f5cd72746 100644 --- a/receiver/awsfirehosereceiver/README.md +++ b/receiver/awsfirehosereceiver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: metrics | | Distributions | [contrib], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fawsfirehose%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fawsfirehose%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@Aneurysm9](https://www.github.com/Aneurysm9) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/awsfirehosereceiver/metadata.yaml b/receiver/awsfirehosereceiver/metadata.yaml index 7539733b416b..9cb632b03e6b 100644 --- a/receiver/awsfirehosereceiver/metadata.yaml +++ b/receiver/awsfirehosereceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: alpha: [metrics] distributions: [contrib, observiq, sumo] - + codeowners: + active: [Aneurysm9] diff --git a/receiver/awsxrayreceiver/README.md b/receiver/awsxrayreceiver/README.md index 6ab63e024bf9..86bb94a48969 100644 --- a/receiver/awsxrayreceiver/README.md +++ b/receiver/awsxrayreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces | | Distributions | [contrib], [aws], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fawsxray%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fawsxray%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@wangzlei](https://www.github.com/wangzlei), [@srprash](https://www.github.com/srprash) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/awsxrayreceiver/metadata.yaml b/receiver/awsxrayreceiver/metadata.yaml index bb56594cbf0f..a7b197099a08 100644 --- a/receiver/awsxrayreceiver/metadata.yaml +++ b/receiver/awsxrayreceiver/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [traces] distributions: [contrib, aws, observiq, sumo] + codeowners: + active: [wangzlei, srprash] \ No newline at end of file diff --git a/receiver/azureblobreceiver/README.md b/receiver/azureblobreceiver/README.md index 3c6f9063b244..fff4910c5151 100644 --- a/receiver/azureblobreceiver/README.md +++ b/receiver/azureblobreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [development]: logs, traces | | Distributions | [contrib] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fazureblob%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fazureblob%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@eedorenko](https://www.github.com/eedorenko), [@mx-psi](https://www.github.com/mx-psi) | [development]: https://github.com/open-telemetry/opentelemetry-collector#development [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/azureblobreceiver/metadata.yaml b/receiver/azureblobreceiver/metadata.yaml index 9302c4f97d90..3cf4f6c83017 100644 --- a/receiver/azureblobreceiver/metadata.yaml +++ b/receiver/azureblobreceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: development: [logs, traces] distributions: [contrib] - + codeowners: + active: [eedorenko, mx-psi] diff --git a/receiver/azureeventhubreceiver/README.md b/receiver/azureeventhubreceiver/README.md index 9e8d5f02b228..87bd1a55f0f9 100644 --- a/receiver/azureeventhubreceiver/README.md +++ b/receiver/azureeventhubreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: metrics, logs | | Distributions | [contrib], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fazureeventhub%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fazureeventhub%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@atoulme](https://www.github.com/atoulme), [@djaglowski](https://www.github.com/djaglowski) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/azureeventhubreceiver/metadata.yaml b/receiver/azureeventhubreceiver/metadata.yaml index 0c725e521d4d..ace512760f42 100644 --- a/receiver/azureeventhubreceiver/metadata.yaml +++ b/receiver/azureeventhubreceiver/metadata.yaml @@ -5,3 +5,5 @@ status: stability: alpha: [metrics, logs] distributions: [contrib, splunk, observiq, sumo] + codeowners: + active: [atoulme, djaglowski] diff --git a/receiver/azuremonitorreceiver/README.md b/receiver/azuremonitorreceiver/README.md index edfa2fdfba3e..ae01cdea7c6b 100644 --- a/receiver/azuremonitorreceiver/README.md +++ b/receiver/azuremonitorreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [development]: metrics | | Distributions | [contrib] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fazuremonitor%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fazuremonitor%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@altuner](https://www.github.com/altuner), [@codeboten](https://www.github.com/codeboten) | [development]: https://github.com/open-telemetry/opentelemetry-collector#development [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/azuremonitorreceiver/metadata.yaml b/receiver/azuremonitorreceiver/metadata.yaml index 8f6d2f5d0f9c..f0f5c34bdde1 100644 --- a/receiver/azuremonitorreceiver/metadata.yaml +++ b/receiver/azuremonitorreceiver/metadata.yaml @@ -5,6 +5,8 @@ status: stability: development: [metrics] distributions: [contrib] + codeowners: + active: [altuner, codeboten] resource_attributes: azuremonitor.tenant_id: diff --git a/receiver/bigipreceiver/README.md b/receiver/bigipreceiver/README.md index ee5826ddcc39..13e6daa0bd3e 100644 --- a/receiver/bigipreceiver/README.md +++ b/receiver/bigipreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [contrib], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fbigip%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fbigip%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@djaglowski](https://www.github.com/djaglowski), [@StefanKurek](https://www.github.com/StefanKurek) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/bigipreceiver/metadata.yaml b/receiver/bigipreceiver/metadata.yaml index b6973e260890..4a137bfc2f64 100644 --- a/receiver/bigipreceiver/metadata.yaml +++ b/receiver/bigipreceiver/metadata.yaml @@ -5,6 +5,8 @@ status: stability: beta: [metrics] distributions: [contrib, observiq, sumo] + codeowners: + active: [djaglowski, StefanKurek] resource_attributes: bigip.virtual_server.name: diff --git a/receiver/carbonreceiver/README.md b/receiver/carbonreceiver/README.md index 159342934b51..a2d84123c379 100644 --- a/receiver/carbonreceiver/README.md +++ b/receiver/carbonreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [contrib], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fcarbon%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fcarbon%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@aboguszewski-sumo](https://www.github.com/aboguszewski-sumo) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/carbonreceiver/metadata.yaml b/receiver/carbonreceiver/metadata.yaml index f199e92e5be9..bbf85c50df99 100644 --- a/receiver/carbonreceiver/metadata.yaml +++ b/receiver/carbonreceiver/metadata.yaml @@ -5,4 +5,6 @@ status: stability: beta: [metrics] distributions: [contrib, splunk, observiq, sumo] + codeowners: + active: [aboguszewski-sumo] diff --git a/receiver/chronyreceiver/README.md b/receiver/chronyreceiver/README.md index f170b2e21205..d68dfc5ad73d 100644 --- a/receiver/chronyreceiver/README.md +++ b/receiver/chronyreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: metrics | | Distributions | [contrib] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fchrony%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fchrony%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@MovieStoreGuy](https://www.github.com/MovieStoreGuy), [@jamesmoessis](https://www.github.com/jamesmoessis) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/chronyreceiver/metadata.yaml b/receiver/chronyreceiver/metadata.yaml index 4763ba1dbe99..50fc1adb4d50 100644 --- a/receiver/chronyreceiver/metadata.yaml +++ b/receiver/chronyreceiver/metadata.yaml @@ -6,6 +6,8 @@ status: stability: alpha: [metrics] distributions: [contrib] + codeowners: + active: [MovieStoreGuy, jamesmoessis] attributes: leap.status: diff --git a/receiver/cloudflarereceiver/README.md b/receiver/cloudflarereceiver/README.md index 8bf5deb2add3..bc76edfc36df 100644 --- a/receiver/cloudflarereceiver/README.md +++ b/receiver/cloudflarereceiver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: logs | | Distributions | [contrib], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fcloudflare%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fcloudflare%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@dehaansa](https://www.github.com/dehaansa), [@djaglowski](https://www.github.com/djaglowski) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/cloudflarereceiver/metadata.yaml b/receiver/cloudflarereceiver/metadata.yaml index 4aab0f426558..031aae49d673 100644 --- a/receiver/cloudflarereceiver/metadata.yaml +++ b/receiver/cloudflarereceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: alpha: [logs] distributions: [contrib, observiq, sumo] - + codeowners: + active: [dehaansa, djaglowski] diff --git a/receiver/cloudfoundryreceiver/README.md b/receiver/cloudfoundryreceiver/README.md index cb6ee3ad758b..87bf1b175ca1 100644 --- a/receiver/cloudfoundryreceiver/README.md +++ b/receiver/cloudfoundryreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [contrib], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fcloudfoundry%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fcloudfoundry%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@agoallikmaa](https://www.github.com/agoallikmaa), [@pellared](https://www.github.com/pellared), [@crobert-1](https://www.github.com/crobert-1) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/cloudfoundryreceiver/metadata.yaml b/receiver/cloudfoundryreceiver/metadata.yaml index 89d83451d898..f1397246fc35 100644 --- a/receiver/cloudfoundryreceiver/metadata.yaml +++ b/receiver/cloudfoundryreceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: beta: [metrics] distributions: [contrib, splunk, observiq, sumo] - + codeowners: + active: [agoallikmaa, pellared, crobert-1] diff --git a/receiver/collectdreceiver/README.md b/receiver/collectdreceiver/README.md index c144c497e11a..010353ace270 100644 --- a/receiver/collectdreceiver/README.md +++ b/receiver/collectdreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: metrics | | Distributions | [contrib], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fcollectd%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fcollectd%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@atoulme](https://www.github.com/atoulme) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/collectdreceiver/metadata.yaml b/receiver/collectdreceiver/metadata.yaml index 09249d9e4d4c..79ee2362c968 100644 --- a/receiver/collectdreceiver/metadata.yaml +++ b/receiver/collectdreceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: alpha: [metrics] distributions: [contrib, splunk, observiq, sumo] - + codeowners: + active: [atoulme] diff --git a/receiver/couchdbreceiver/README.md b/receiver/couchdbreceiver/README.md index b873bf0dba86..c6266a845b23 100644 --- a/receiver/couchdbreceiver/README.md +++ b/receiver/couchdbreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [contrib], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fcouchdb%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fcouchdb%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@djaglowski](https://www.github.com/djaglowski) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/couchdbreceiver/metadata.yaml b/receiver/couchdbreceiver/metadata.yaml index fba4ecb5df23..b58cf89fc126 100644 --- a/receiver/couchdbreceiver/metadata.yaml +++ b/receiver/couchdbreceiver/metadata.yaml @@ -5,6 +5,8 @@ status: stability: beta: [metrics] distributions: [contrib,observiq, sumo] + codeowners: + active: [djaglowski] resource_attributes: couchdb.node.name: diff --git a/receiver/datadogreceiver/README.md b/receiver/datadogreceiver/README.md index 0c4b7695fa7a..192e41780796 100644 --- a/receiver/datadogreceiver/README.md +++ b/receiver/datadogreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: traces | | Distributions | [contrib], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fdatadog%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fdatadog%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@boostchicken](https://www.github.com/boostchicken), [@gouthamve](https://www.github.com/gouthamve), [@jpkrohling](https://www.github.com/jpkrohling), [@MovieStoreGuy](https://www.github.com/MovieStoreGuy) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/datadogreceiver/metadata.yaml b/receiver/datadogreceiver/metadata.yaml index 16788dc48415..f20a1db74158 100644 --- a/receiver/datadogreceiver/metadata.yaml +++ b/receiver/datadogreceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: alpha: [traces] distributions: [contrib, sumo] - + codeowners: + active: [boostchicken, gouthamve, jpkrohling, MovieStoreGuy] diff --git a/receiver/dockerstatsreceiver/README.md b/receiver/dockerstatsreceiver/README.md index c6b62e292a56..d7d8c00c9254 100644 --- a/receiver/dockerstatsreceiver/README.md +++ b/receiver/dockerstatsreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: metrics | | Distributions | [contrib], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fdockerstats%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fdockerstats%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@rmfitzpatrick](https://www.github.com/rmfitzpatrick), [@jamesmoessis](https://www.github.com/jamesmoessis) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/dockerstatsreceiver/metadata.yaml b/receiver/dockerstatsreceiver/metadata.yaml index a586aee13f26..c3cbc9c25538 100644 --- a/receiver/dockerstatsreceiver/metadata.yaml +++ b/receiver/dockerstatsreceiver/metadata.yaml @@ -5,6 +5,8 @@ status: stability: alpha: [metrics] distributions: [contrib, observiq, sumo] + codeowners: + active: [rmfitzpatrick, jamesmoessis] sem_conv_version: 1.6.1 diff --git a/receiver/elasticsearchreceiver/README.md b/receiver/elasticsearchreceiver/README.md index c12788469221..0becbe53545e 100644 --- a/receiver/elasticsearchreceiver/README.md +++ b/receiver/elasticsearchreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [contrib], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Felasticsearch%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Felasticsearch%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@djaglowski](https://www.github.com/djaglowski), [@binaryfissiongames](https://www.github.com/binaryfissiongames) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/elasticsearchreceiver/metadata.yaml b/receiver/elasticsearchreceiver/metadata.yaml index 14ad7b1bee4c..d535a0ffe5f3 100644 --- a/receiver/elasticsearchreceiver/metadata.yaml +++ b/receiver/elasticsearchreceiver/metadata.yaml @@ -5,6 +5,8 @@ status: stability: beta: [metrics] distributions: [contrib, observiq, sumo] + codeowners: + active: [djaglowski, binaryfissiongames] resource_attributes: elasticsearch.cluster.name: diff --git a/receiver/expvarreceiver/README.md b/receiver/expvarreceiver/README.md index 37ad4c1b49fa..0d879df503b8 100644 --- a/receiver/expvarreceiver/README.md +++ b/receiver/expvarreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: metrics | | Distributions | [contrib], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fexpvar%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fexpvar%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jamesmoessis](https://www.github.com/jamesmoessis), [@MovieStoreGuy](https://www.github.com/MovieStoreGuy) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/expvarreceiver/metadata.yaml b/receiver/expvarreceiver/metadata.yaml index 1ae5a1c8caf1..4eab43395711 100644 --- a/receiver/expvarreceiver/metadata.yaml +++ b/receiver/expvarreceiver/metadata.yaml @@ -5,6 +5,8 @@ status: stability: alpha: [metrics] distributions: [contrib, sumo] + codeowners: + active: [jamesmoessis, MovieStoreGuy] metrics: process.runtime.memstats.total_alloc: diff --git a/receiver/filelogreceiver/README.md b/receiver/filelogreceiver/README.md index 95397d1a3cd3..2703d8d46684 100644 --- a/receiver/filelogreceiver/README.md +++ b/receiver/filelogreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: logs | | Distributions | [contrib], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Ffilelog%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Ffilelog%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@djaglowski](https://www.github.com/djaglowski) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/filelogreceiver/metadata.yaml b/receiver/filelogreceiver/metadata.yaml index 8973756cbcb4..9ad32ef8ffdf 100644 --- a/receiver/filelogreceiver/metadata.yaml +++ b/receiver/filelogreceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: beta: [logs] distributions: [contrib, splunk, observiq, sumo] - + codeowners: + active: [djaglowski] diff --git a/receiver/filereceiver/README.md b/receiver/filereceiver/README.md index e5cb11b9a7ac..e2b9caaca311 100644 --- a/receiver/filereceiver/README.md +++ b/receiver/filereceiver/README.md @@ -6,6 +6,7 @@ | Stability | [development]: metrics, traces, logs | | Distributions | [contrib] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Ffile%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Ffile%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@pmcollins](https://www.github.com/pmcollins), [@djaglowski](https://www.github.com/djaglowski) | [development]: https://github.com/open-telemetry/opentelemetry-collector#development [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/filereceiver/metadata.yaml b/receiver/filereceiver/metadata.yaml index 60a582bc466b..bc4cad50cd4c 100644 --- a/receiver/filereceiver/metadata.yaml +++ b/receiver/filereceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: development: [metrics, traces, logs] distributions: [contrib] - + codeowners: + active: [pmcollins, djaglowski] diff --git a/receiver/filestatsreceiver/README.md b/receiver/filestatsreceiver/README.md index d9fe15878023..c5c8b537924e 100644 --- a/receiver/filestatsreceiver/README.md +++ b/receiver/filestatsreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: metrics | | Distributions | [contrib], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Ffilestats%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Ffilestats%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@atoulme](https://www.github.com/atoulme) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/filestatsreceiver/metadata.yaml b/receiver/filestatsreceiver/metadata.yaml index 3aa24b76936d..383d3753b949 100644 --- a/receiver/filestatsreceiver/metadata.yaml +++ b/receiver/filestatsreceiver/metadata.yaml @@ -5,6 +5,8 @@ status: stability: alpha: [metrics] distributions: [contrib, sumo] + codeowners: + active: [atoulme] resource_attributes: diff --git a/receiver/flinkmetricsreceiver/README.md b/receiver/flinkmetricsreceiver/README.md index db3fafd3180e..92e52d0383b3 100644 --- a/receiver/flinkmetricsreceiver/README.md +++ b/receiver/flinkmetricsreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: metrics | | Distributions | [contrib], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fflinkmetrics%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fflinkmetrics%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jonathanwamsley](https://www.github.com/jonathanwamsley), [@djaglowski](https://www.github.com/djaglowski) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/flinkmetricsreceiver/metadata.yaml b/receiver/flinkmetricsreceiver/metadata.yaml index 09282f9b6e39..8405f259e19d 100644 --- a/receiver/flinkmetricsreceiver/metadata.yaml +++ b/receiver/flinkmetricsreceiver/metadata.yaml @@ -5,6 +5,8 @@ status: stability: alpha: [metrics] distributions: [contrib,observiq, sumo] + codeowners: + active: [jonathanwamsley, djaglowski] resource_attributes: # These resource attributes are Flinks system scope variables, which contains context information about metrics. These are required to uniquely identify incoming metrics as the same job can run multiple times concurrently. See https://nightlies.apache.org/flink/flink-docs-release-1.14/docs/ops/metrics/#system-scope for more information. diff --git a/receiver/fluentforwardreceiver/README.md b/receiver/fluentforwardreceiver/README.md index 2803914e0683..d65a375f8bb5 100644 --- a/receiver/fluentforwardreceiver/README.md +++ b/receiver/fluentforwardreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: logs | | Distributions | [contrib], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Ffluentforward%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Ffluentforward%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@dmitryax](https://www.github.com/dmitryax) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/fluentforwardreceiver/metadata.yaml b/receiver/fluentforwardreceiver/metadata.yaml index 596f82ebfbea..6b55ad731e7e 100644 --- a/receiver/fluentforwardreceiver/metadata.yaml +++ b/receiver/fluentforwardreceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: beta: [logs] distributions: [contrib, splunk, observiq, sumo] - + codeowners: + active: [dmitryax] diff --git a/receiver/googlecloudpubsubreceiver/README.md b/receiver/googlecloudpubsubreceiver/README.md index 76bcab730ef4..a9b166c8321a 100644 --- a/receiver/googlecloudpubsubreceiver/README.md +++ b/receiver/googlecloudpubsubreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces, logs, metrics | | Distributions | [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fgooglecloudpubsub%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fgooglecloudpubsub%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@alexvanboxel](https://www.github.com/alexvanboxel) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [observiq]: https://github.com/observIQ/observiq-otel-collector diff --git a/receiver/googlecloudpubsubreceiver/metadata.yaml b/receiver/googlecloudpubsubreceiver/metadata.yaml index d310fc52b1cb..9837e28052d6 100644 --- a/receiver/googlecloudpubsubreceiver/metadata.yaml +++ b/receiver/googlecloudpubsubreceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: beta: [traces, logs, metrics] distributions: [observiq, sumo] - + codeowners: + active: [alexvanboxel] diff --git a/receiver/googlecloudspannerreceiver/README.md b/receiver/googlecloudspannerreceiver/README.md index aca5fc32ab70..35a17b88f178 100644 --- a/receiver/googlecloudspannerreceiver/README.md +++ b/receiver/googlecloudspannerreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [contrib], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fgooglecloudspanner%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fgooglecloudspanner%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@architjugran](https://www.github.com/architjugran), [@varunraiko](https://www.github.com/varunraiko), [@kiranmayib](https://www.github.com/kiranmayib) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/googlecloudspannerreceiver/metadata.yaml b/receiver/googlecloudspannerreceiver/metadata.yaml index fe834cae83c8..5083961d92f4 100644 --- a/receiver/googlecloudspannerreceiver/metadata.yaml +++ b/receiver/googlecloudspannerreceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: beta: [metrics] distributions: [contrib, observiq, sumo] - + codeowners: + active: [architjugran, varunraiko, kiranmayib] diff --git a/receiver/haproxyreceiver/README.md b/receiver/haproxyreceiver/README.md index de9ca9aa20e9..cecf826ada90 100644 --- a/receiver/haproxyreceiver/README.md +++ b/receiver/haproxyreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: metrics | | Distributions | [contrib], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fhaproxy%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fhaproxy%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@atoulme](https://www.github.com/atoulme), [@MovieStoreGuy](https://www.github.com/MovieStoreGuy) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/haproxyreceiver/metadata.yaml b/receiver/haproxyreceiver/metadata.yaml index 96abe32963e0..96e67351343f 100644 --- a/receiver/haproxyreceiver/metadata.yaml +++ b/receiver/haproxyreceiver/metadata.yaml @@ -5,6 +5,8 @@ status: stability: alpha: [metrics] distributions: [contrib, sumo] + codeowners: + active: [atoulme, MovieStoreGuy] resource_attributes: haproxy.url: diff --git a/receiver/hostmetricsreceiver/README.md b/receiver/hostmetricsreceiver/README.md index 252272ec43cb..556e6373d971 100644 --- a/receiver/hostmetricsreceiver/README.md +++ b/receiver/hostmetricsreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [core], [contrib], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fhostmetrics%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fhostmetrics%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@dmitryax](https://www.github.com/dmitryax) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [core]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol diff --git a/receiver/hostmetricsreceiver/metadata.yaml b/receiver/hostmetricsreceiver/metadata.yaml index 5fa75f1ddaad..9a06ef68d734 100644 --- a/receiver/hostmetricsreceiver/metadata.yaml +++ b/receiver/hostmetricsreceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: beta: [metrics] distributions: [core, contrib, observiq, splunk, sumo] - + codeowners: + active: [dmitryax] diff --git a/receiver/httpcheckreceiver/README.md b/receiver/httpcheckreceiver/README.md index eaabbba8ed2b..8873fecd2e8c 100644 --- a/receiver/httpcheckreceiver/README.md +++ b/receiver/httpcheckreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [development]: metrics | | Distributions | [contrib], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fhttpcheck%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fhttpcheck%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@codeboten](https://www.github.com/codeboten) | [development]: https://github.com/open-telemetry/opentelemetry-collector#development [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/httpcheckreceiver/metadata.yaml b/receiver/httpcheckreceiver/metadata.yaml index 8b310d94a07c..0c272d0992b4 100644 --- a/receiver/httpcheckreceiver/metadata.yaml +++ b/receiver/httpcheckreceiver/metadata.yaml @@ -6,6 +6,8 @@ status: development: [metrics] distributions: [contrib, sumo] warnings: [] + codeowners: + active: [codeboten] resource_attributes: diff --git a/receiver/iisreceiver/README.md b/receiver/iisreceiver/README.md index d96ed281809a..e4602171e4fe 100644 --- a/receiver/iisreceiver/README.md +++ b/receiver/iisreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [contrib], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fiis%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fiis%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@mrod1598](https://www.github.com/mrod1598), [@djaglowski](https://www.github.com/djaglowski) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/iisreceiver/metadata.yaml b/receiver/iisreceiver/metadata.yaml index 7d648889be8e..ac26f8a8374f 100644 --- a/receiver/iisreceiver/metadata.yaml +++ b/receiver/iisreceiver/metadata.yaml @@ -5,6 +5,8 @@ status: stability: beta: [metrics] distributions: [contrib, observiq, sumo] + codeowners: + active: [mrod1598, djaglowski] resource_attributes: iis.site: diff --git a/receiver/influxdbreceiver/README.md b/receiver/influxdbreceiver/README.md index 06fbb4722a47..bde18c3da6f7 100644 --- a/receiver/influxdbreceiver/README.md +++ b/receiver/influxdbreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [contrib], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Finfluxdb%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Finfluxdb%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jacobmarble](https://www.github.com/jacobmarble) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/influxdbreceiver/metadata.yaml b/receiver/influxdbreceiver/metadata.yaml index 78d4d92f13c9..1778488433ff 100644 --- a/receiver/influxdbreceiver/metadata.yaml +++ b/receiver/influxdbreceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: beta: [metrics] distributions: [contrib, observiq, sumo] - + codeowners: + active: [jacobmarble] diff --git a/receiver/jaegerreceiver/README.md b/receiver/jaegerreceiver/README.md index 0d6d41adaac1..f3745bfb51fd 100644 --- a/receiver/jaegerreceiver/README.md +++ b/receiver/jaegerreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces | | Distributions | [core], [contrib], [aws], [grafana], [observiq], [redhat], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fjaeger%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fjaeger%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jpkrohling](https://www.github.com/jpkrohling) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [core]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol diff --git a/receiver/jaegerreceiver/metadata.yaml b/receiver/jaegerreceiver/metadata.yaml index 6f586c5a2f0f..7b9b51627872 100644 --- a/receiver/jaegerreceiver/metadata.yaml +++ b/receiver/jaegerreceiver/metadata.yaml @@ -13,3 +13,5 @@ status: - redhat - splunk - sumo + codeowners: + active: [jpkrohling] diff --git a/receiver/jmxreceiver/README.md b/receiver/jmxreceiver/README.md index 3bd57a62b148..37a99d83fd37 100644 --- a/receiver/jmxreceiver/README.md +++ b/receiver/jmxreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: metrics | | Distributions | [contrib], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fjmx%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fjmx%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@rmfitzpatrick](https://www.github.com/rmfitzpatrick) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/jmxreceiver/metadata.yaml b/receiver/jmxreceiver/metadata.yaml index 75eef988a141..871628d5a6d8 100644 --- a/receiver/jmxreceiver/metadata.yaml +++ b/receiver/jmxreceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: alpha: [metrics] distributions: [contrib, splunk, observiq, sumo] - + codeowners: + active: [rmfitzpatrick] diff --git a/receiver/journaldreceiver/README.md b/receiver/journaldreceiver/README.md index 7c66e34b9d09..8d10d5412455 100644 --- a/receiver/journaldreceiver/README.md +++ b/receiver/journaldreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: logs | | Distributions | [contrib], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fjournald%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fjournald%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@sumo-drosiek](https://www.github.com/sumo-drosiek), [@djaglowski](https://www.github.com/djaglowski) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/journaldreceiver/metadata.yaml b/receiver/journaldreceiver/metadata.yaml index d7d6bf80b566..87907040efa7 100644 --- a/receiver/journaldreceiver/metadata.yaml +++ b/receiver/journaldreceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: alpha: [logs] distributions: [contrib, splunk, observiq, sumo] - + codeowners: + active: [sumo-drosiek, djaglowski] diff --git a/receiver/k8sclusterreceiver/README.md b/receiver/k8sclusterreceiver/README.md index f625fd388750..414894a847a5 100644 --- a/receiver/k8sclusterreceiver/README.md +++ b/receiver/k8sclusterreceiver/README.md @@ -7,6 +7,7 @@ | | [development]: logs | | Distributions | [contrib], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fk8scluster%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fk8scluster%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@dmitryax](https://www.github.com/dmitryax) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [development]: https://github.com/open-telemetry/opentelemetry-collector#development diff --git a/receiver/k8sclusterreceiver/metadata.yaml b/receiver/k8sclusterreceiver/metadata.yaml index b27e538518f9..4cb9a55aebd6 100644 --- a/receiver/k8sclusterreceiver/metadata.yaml +++ b/receiver/k8sclusterreceiver/metadata.yaml @@ -6,4 +6,5 @@ status: beta: [metrics] development: [logs] distributions: [contrib, splunk, observiq, sumo] - + codeowners: + active: [dmitryax] diff --git a/receiver/k8seventsreceiver/README.md b/receiver/k8seventsreceiver/README.md index b0c2e80b08bb..caf4bb63a00a 100644 --- a/receiver/k8seventsreceiver/README.md +++ b/receiver/k8seventsreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: logs | | Distributions | [contrib], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fk8sevents%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fk8sevents%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@dmitryax](https://www.github.com/dmitryax) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/k8seventsreceiver/metadata.yaml b/receiver/k8seventsreceiver/metadata.yaml index 411997be560e..e6cb73619725 100644 --- a/receiver/k8seventsreceiver/metadata.yaml +++ b/receiver/k8seventsreceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: alpha: [logs] distributions: [contrib, splunk, observiq, sumo] - + codeowners: + active: [dmitryax] diff --git a/receiver/k8sobjectsreceiver/README.md b/receiver/k8sobjectsreceiver/README.md index 0832708984dc..ff4fd972a491 100644 --- a/receiver/k8sobjectsreceiver/README.md +++ b/receiver/k8sobjectsreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: logs | | Distributions | [contrib], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fk8sobjects%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fk8sobjects%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@dmitryax](https://www.github.com/dmitryax), [@hvaghani221](https://www.github.com/hvaghani221) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/k8sobjectsreceiver/metadata.yaml b/receiver/k8sobjectsreceiver/metadata.yaml index 3fb1ea817e25..dabdec4d7c35 100644 --- a/receiver/k8sobjectsreceiver/metadata.yaml +++ b/receiver/k8sobjectsreceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: alpha: [logs] distributions: [contrib, splunk, sumo] - + codeowners: + active: [dmitryax, hvaghani221] diff --git a/receiver/kafkametricsreceiver/README.md b/receiver/kafkametricsreceiver/README.md index 82544c95d560..03dca2c9c63d 100644 --- a/receiver/kafkametricsreceiver/README.md +++ b/receiver/kafkametricsreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [contrib], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fkafkametrics%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fkafkametrics%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@dmitryax](https://www.github.com/dmitryax) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/kafkametricsreceiver/metadata.yaml b/receiver/kafkametricsreceiver/metadata.yaml index 06c79be6741b..1c5ea51816c0 100644 --- a/receiver/kafkametricsreceiver/metadata.yaml +++ b/receiver/kafkametricsreceiver/metadata.yaml @@ -5,6 +5,8 @@ status: stability: beta: [metrics] distributions: [contrib, splunk, sumo] + codeowners: + active: [dmitryax] attributes: topic: diff --git a/receiver/kafkareceiver/README.md b/receiver/kafkareceiver/README.md index 905913646515..715971eba683 100644 --- a/receiver/kafkareceiver/README.md +++ b/receiver/kafkareceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics, logs, traces | | Distributions | [contrib], [aws], [grafana], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fkafka%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fkafka%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@pavolloffay](https://www.github.com/pavolloffay), [@MovieStoreGuy](https://www.github.com/MovieStoreGuy) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/kafkareceiver/metadata.yaml b/receiver/kafkareceiver/metadata.yaml index eefed6d2c5b5..58c399f2171a 100644 --- a/receiver/kafkareceiver/metadata.yaml +++ b/receiver/kafkareceiver/metadata.yaml @@ -11,3 +11,5 @@ status: - observiq - splunk - sumo + codeowners: + active: [pavolloffay, MovieStoreGuy] diff --git a/receiver/kubeletstatsreceiver/README.md b/receiver/kubeletstatsreceiver/README.md index a1a6454aaf32..88fa13c89052 100644 --- a/receiver/kubeletstatsreceiver/README.md +++ b/receiver/kubeletstatsreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [contrib], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fkubeletstats%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fkubeletstats%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@dmitryax](https://www.github.com/dmitryax) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/kubeletstatsreceiver/metadata.yaml b/receiver/kubeletstatsreceiver/metadata.yaml index 6b5249229caf..51f4dc7d560f 100644 --- a/receiver/kubeletstatsreceiver/metadata.yaml +++ b/receiver/kubeletstatsreceiver/metadata.yaml @@ -5,6 +5,8 @@ status: stability: beta: [metrics] distributions: [contrib, observiq, splunk, sumo] + codeowners: + active: [dmitryax] resource_attributes: k8s.node.name: diff --git a/receiver/lokireceiver/README.md b/receiver/lokireceiver/README.md index d2cac70fab78..a788af4a8f09 100644 --- a/receiver/lokireceiver/README.md +++ b/receiver/lokireceiver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: logs | | Distributions | [contrib], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Floki%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Floki%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@mar4uk](https://www.github.com/mar4uk), [@kovrus](https://www.github.com/kovrus), [@jpkrohling](https://www.github.com/jpkrohling) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/lokireceiver/metadata.yaml b/receiver/lokireceiver/metadata.yaml index 18f21bde7747..08a702fd9194 100644 --- a/receiver/lokireceiver/metadata.yaml +++ b/receiver/lokireceiver/metadata.yaml @@ -7,3 +7,5 @@ status: distributions: - contrib - sumo + codeowners: + active: [mar4uk, kovrus, jpkrohling] diff --git a/receiver/memcachedreceiver/README.md b/receiver/memcachedreceiver/README.md index 061cfa8f3f40..3e4d278847a0 100644 --- a/receiver/memcachedreceiver/README.md +++ b/receiver/memcachedreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [contrib], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fmemcached%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fmemcached%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@djaglowski](https://www.github.com/djaglowski) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/memcachedreceiver/metadata.yaml b/receiver/memcachedreceiver/metadata.yaml index 777d627dc506..808ac682d36e 100644 --- a/receiver/memcachedreceiver/metadata.yaml +++ b/receiver/memcachedreceiver/metadata.yaml @@ -5,6 +5,8 @@ status: stability: beta: [metrics] distributions: [contrib, observiq, sumo] + codeowners: + active: [djaglowski] attributes: command: diff --git a/receiver/mongodbatlasreceiver/README.md b/receiver/mongodbatlasreceiver/README.md index e379d3f06d2f..c0f98bb3c0f5 100644 --- a/receiver/mongodbatlasreceiver/README.md +++ b/receiver/mongodbatlasreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics, logs | | Distributions | [contrib], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fmongodbatlas%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fmongodbatlas%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@djaglowski](https://www.github.com/djaglowski), [@schmikei](https://www.github.com/schmikei) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/mongodbatlasreceiver/metadata.yaml b/receiver/mongodbatlasreceiver/metadata.yaml index e5cb5ea9f6dc..15bc144aba48 100644 --- a/receiver/mongodbatlasreceiver/metadata.yaml +++ b/receiver/mongodbatlasreceiver/metadata.yaml @@ -5,6 +5,8 @@ status: stability: beta: [metrics, logs] distributions: [contrib, splunk, observiq, sumo] + codeowners: + active: [djaglowski, schmikei] resource_attributes: mongodb_atlas.org_name: diff --git a/receiver/mongodbreceiver/README.md b/receiver/mongodbreceiver/README.md index f06255e663d8..f2a42fea6e0b 100644 --- a/receiver/mongodbreceiver/README.md +++ b/receiver/mongodbreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [contrib], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fmongodb%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fmongodb%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@djaglowski](https://www.github.com/djaglowski), [@schmikei](https://www.github.com/schmikei) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/mongodbreceiver/metadata.yaml b/receiver/mongodbreceiver/metadata.yaml index fcd3b1b98d8e..ffda9be59dd3 100644 --- a/receiver/mongodbreceiver/metadata.yaml +++ b/receiver/mongodbreceiver/metadata.yaml @@ -5,6 +5,8 @@ status: stability: beta: [metrics] distributions: [contrib, observiq, sumo] + codeowners: + active: [djaglowski, schmikei] resource_attributes: database: diff --git a/receiver/mysqlreceiver/README.md b/receiver/mysqlreceiver/README.md index 59f48f516399..cce20156e8ac 100644 --- a/receiver/mysqlreceiver/README.md +++ b/receiver/mysqlreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [contrib], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fmysql%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fmysql%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@djaglowski](https://www.github.com/djaglowski) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/mysqlreceiver/metadata.yaml b/receiver/mysqlreceiver/metadata.yaml index c1a80d7d059a..5befb33c91f8 100644 --- a/receiver/mysqlreceiver/metadata.yaml +++ b/receiver/mysqlreceiver/metadata.yaml @@ -5,6 +5,8 @@ status: stability: beta: [metrics] distributions: [contrib, observiq, sumo] + codeowners: + active: [djaglowski] resource_attributes: mysql.instance.endpoint: diff --git a/receiver/nginxreceiver/README.md b/receiver/nginxreceiver/README.md index 2c428309b75e..f79861a8d138 100644 --- a/receiver/nginxreceiver/README.md +++ b/receiver/nginxreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [contrib], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fnginx%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fnginx%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@djaglowski](https://www.github.com/djaglowski) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/nginxreceiver/metadata.yaml b/receiver/nginxreceiver/metadata.yaml index b74cb1a21ba4..eaec897076df 100644 --- a/receiver/nginxreceiver/metadata.yaml +++ b/receiver/nginxreceiver/metadata.yaml @@ -5,6 +5,8 @@ status: stability: beta: [metrics] distributions: [contrib, observiq, sumo] + codeowners: + active: [djaglowski] attributes: state: diff --git a/receiver/nsxtreceiver/README.md b/receiver/nsxtreceiver/README.md index a6bc1b58879b..a5e0e6a1bc90 100644 --- a/receiver/nsxtreceiver/README.md +++ b/receiver/nsxtreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: metrics | | Distributions | [contrib], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fnsxt%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fnsxt%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@dashpole](https://www.github.com/dashpole), [@schmikei](https://www.github.com/schmikei) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/nsxtreceiver/metadata.yaml b/receiver/nsxtreceiver/metadata.yaml index 3ea7ab9be24f..b4a98d2a0b21 100644 --- a/receiver/nsxtreceiver/metadata.yaml +++ b/receiver/nsxtreceiver/metadata.yaml @@ -5,7 +5,9 @@ status: stability: alpha: [metrics] distributions: [contrib, sumo] - + codeowners: + active: [dashpole, schmikei] + resource_attributes: nsxt.node.name: description: The name of the NSX Node. diff --git a/receiver/opencensusreceiver/README.md b/receiver/opencensusreceiver/README.md index 706b3fe495cc..9b2b8dc0d631 100644 --- a/receiver/opencensusreceiver/README.md +++ b/receiver/opencensusreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics, traces | | Distributions | [core], [contrib], [grafana], [observiq], [redhat], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fopencensus%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fopencensus%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@open-telemetry/collector-approvers](https://github.com/orgs/open-telemetry/teams/collector-approvers) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [core]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol diff --git a/receiver/opencensusreceiver/metadata.yaml b/receiver/opencensusreceiver/metadata.yaml index 210665c1ec69..5ad4557b86e6 100644 --- a/receiver/opencensusreceiver/metadata.yaml +++ b/receiver/opencensusreceiver/metadata.yaml @@ -11,3 +11,5 @@ status: - observiq - redhat - sumo + codeowners: + active: [open-telemetry/collector-approvers] diff --git a/receiver/oracledbreceiver/README.md b/receiver/oracledbreceiver/README.md index c1d42fab6ec0..6d617b2556f1 100644 --- a/receiver/oracledbreceiver/README.md +++ b/receiver/oracledbreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: metrics | | Distributions | [contrib], [splunk] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Foracledb%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Foracledb%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@dmitryax](https://www.github.com/dmitryax), [@crobert-1](https://www.github.com/crobert-1), [@atoulme](https://www.github.com/atoulme) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/oracledbreceiver/metadata.yaml b/receiver/oracledbreceiver/metadata.yaml index df698ac74218..84c506dd93d6 100644 --- a/receiver/oracledbreceiver/metadata.yaml +++ b/receiver/oracledbreceiver/metadata.yaml @@ -5,6 +5,8 @@ status: stability: alpha: [metrics] distributions: [contrib, splunk] + codeowners: + active: [dmitryax, crobert-1, atoulme] resource_attributes: oracledb.instance.name: diff --git a/receiver/otlpjsonfilereceiver/README.md b/receiver/otlpjsonfilereceiver/README.md index d23227eebde5..2d0a35485e9f 100644 --- a/receiver/otlpjsonfilereceiver/README.md +++ b/receiver/otlpjsonfilereceiver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: traces, metrics, logs | | Distributions | [contrib], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fotlpjsonfile%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fotlpjsonfile%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@djaglowski](https://www.github.com/djaglowski), [@atoulme](https://www.github.com/atoulme) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/otlpjsonfilereceiver/metadata.yaml b/receiver/otlpjsonfilereceiver/metadata.yaml index 1d7df40186eb..e6ab3530249a 100644 --- a/receiver/otlpjsonfilereceiver/metadata.yaml +++ b/receiver/otlpjsonfilereceiver/metadata.yaml @@ -5,3 +5,5 @@ status: stability: alpha: [traces, metrics, logs] distributions: [contrib, sumo] + codeowners: + active: [djaglowski, atoulme] \ No newline at end of file diff --git a/receiver/podmanreceiver/README.md b/receiver/podmanreceiver/README.md index 5664274f7742..dfdde05fe671 100644 --- a/receiver/podmanreceiver/README.md +++ b/receiver/podmanreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [development]: metrics | | Distributions | [contrib], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fpodman%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fpodman%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@rogercoll](https://www.github.com/rogercoll) | [development]: https://github.com/open-telemetry/opentelemetry-collector#development [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/podmanreceiver/metadata.yaml b/receiver/podmanreceiver/metadata.yaml index c6ac5f3917ce..348cc1c86537 100644 --- a/receiver/podmanreceiver/metadata.yaml +++ b/receiver/podmanreceiver/metadata.yaml @@ -5,4 +5,6 @@ status: stability: development: [metrics] distributions: [contrib, observiq, sumo] + codeowners: + active: [rogercoll] diff --git a/receiver/postgresqlreceiver/README.md b/receiver/postgresqlreceiver/README.md index 5108df17a685..7436fe860a11 100644 --- a/receiver/postgresqlreceiver/README.md +++ b/receiver/postgresqlreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [contrib], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fpostgresql%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fpostgresql%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@djaglowski](https://www.github.com/djaglowski) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/postgresqlreceiver/metadata.yaml b/receiver/postgresqlreceiver/metadata.yaml index e097e390eb9d..641643e4e17b 100644 --- a/receiver/postgresqlreceiver/metadata.yaml +++ b/receiver/postgresqlreceiver/metadata.yaml @@ -5,6 +5,8 @@ status: stability: beta: [metrics] distributions: [contrib, splunk, observiq, sumo] + codeowners: + active: [djaglowski] resource_attributes: postgresql.database.name: diff --git a/receiver/prometheusexecreceiver/README.md b/receiver/prometheusexecreceiver/README.md index 7375b543b068..6c316402e88e 100644 --- a/receiver/prometheusexecreceiver/README.md +++ b/receiver/prometheusexecreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [deprecated]: metrics | | Distributions | [splunk] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fprometheusexec%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fprometheusexec%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@dmitryax](https://www.github.com/dmitryax) | [deprecated]: https://github.com/open-telemetry/opentelemetry-collector#deprecated [splunk]: https://github.com/signalfx/splunk-otel-collector diff --git a/receiver/prometheusexecreceiver/metadata.yaml b/receiver/prometheusexecreceiver/metadata.yaml index 8e038b3835d1..8c10f1e0644f 100644 --- a/receiver/prometheusexecreceiver/metadata.yaml +++ b/receiver/prometheusexecreceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: deprecated: [metrics] distributions: [splunk] - + codeowners: + active: [dmitryax] diff --git a/receiver/prometheusreceiver/README.md b/receiver/prometheusreceiver/README.md index e0b3268a6945..f19fed79a697 100644 --- a/receiver/prometheusreceiver/README.md +++ b/receiver/prometheusreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [core], [contrib], [aws], [grafana], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fprometheus%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fprometheus%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@Aneurysm9](https://www.github.com/Aneurysm9), [@dashpole](https://www.github.com/dashpole) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [core]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol diff --git a/receiver/prometheusreceiver/metadata.yaml b/receiver/prometheusreceiver/metadata.yaml index 1225cb976b11..38a3aa19f3ea 100644 --- a/receiver/prometheusreceiver/metadata.yaml +++ b/receiver/prometheusreceiver/metadata.yaml @@ -12,3 +12,5 @@ status: - observiq - splunk - sumo + codeowners: + active: [Aneurysm9, dashpole] diff --git a/receiver/pulsarreceiver/README.md b/receiver/pulsarreceiver/README.md index 56f88558c83b..d88f4058eeae 100644 --- a/receiver/pulsarreceiver/README.md +++ b/receiver/pulsarreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: metrics, traces, logs | | Distributions | [contrib] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fpulsar%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fpulsar%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@dmitryax](https://www.github.com/dmitryax), [@dao-jun](https://www.github.com/dao-jun) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/pulsarreceiver/metadata.yaml b/receiver/pulsarreceiver/metadata.yaml index 8daf59de1417..680d4608233d 100644 --- a/receiver/pulsarreceiver/metadata.yaml +++ b/receiver/pulsarreceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: alpha: [metrics, traces, logs] distributions: [contrib] - + codeowners: + active: [dmitryax, dao-jun] diff --git a/receiver/purefareceiver/README.md b/receiver/purefareceiver/README.md index 8df7ba51a09e..72ea4bcb1aad 100644 --- a/receiver/purefareceiver/README.md +++ b/receiver/purefareceiver/README.md @@ -6,6 +6,7 @@ | Stability | [development]: metrics | | Distributions | [contrib], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fpurefa%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fpurefa%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jpkrohling](https://www.github.com/jpkrohling), [@dgoscn](https://www.github.com/dgoscn), [@chrroberts-pure](https://www.github.com/chrroberts-pure) | [development]: https://github.com/open-telemetry/opentelemetry-collector#development [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/purefareceiver/metadata.yaml b/receiver/purefareceiver/metadata.yaml index ce8f4c76cf10..6d2f2f3fb08f 100644 --- a/receiver/purefareceiver/metadata.yaml +++ b/receiver/purefareceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: development: [metrics] distributions: [contrib, sumo] - + codeowners: + active: [jpkrohling, dgoscn, chrroberts-pure] diff --git a/receiver/purefbreceiver/README.md b/receiver/purefbreceiver/README.md index 7fa2b68fd7e8..dbdf4fb6626b 100644 --- a/receiver/purefbreceiver/README.md +++ b/receiver/purefbreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [development]: metrics | | Distributions | [contrib], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fpurefb%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fpurefb%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jpkrohling](https://www.github.com/jpkrohling), [@dgoscn](https://www.github.com/dgoscn), [@chrroberts-pure](https://www.github.com/chrroberts-pure) | [development]: https://github.com/open-telemetry/opentelemetry-collector#development [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/purefbreceiver/metadata.yaml b/receiver/purefbreceiver/metadata.yaml index 497b6aa9869f..5c4c52d2612f 100644 --- a/receiver/purefbreceiver/metadata.yaml +++ b/receiver/purefbreceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: development: [metrics] distributions: [contrib, sumo] - + codeowners: + active: [jpkrohling, dgoscn, chrroberts-pure] diff --git a/receiver/rabbitmqreceiver/README.md b/receiver/rabbitmqreceiver/README.md index 1cf1d9307db3..50168bc5fd3c 100644 --- a/receiver/rabbitmqreceiver/README.md +++ b/receiver/rabbitmqreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [contrib], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Frabbitmq%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Frabbitmq%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@djaglowski](https://www.github.com/djaglowski), [@cpheps](https://www.github.com/cpheps) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/rabbitmqreceiver/metadata.yaml b/receiver/rabbitmqreceiver/metadata.yaml index 0d87ba16b529..799ff4b630b9 100644 --- a/receiver/rabbitmqreceiver/metadata.yaml +++ b/receiver/rabbitmqreceiver/metadata.yaml @@ -5,6 +5,8 @@ status: stability: beta: [metrics] distributions: [contrib, observiq, sumo] + codeowners: + active: [djaglowski, cpheps] resource_attributes: rabbitmq.queue.name: diff --git a/receiver/receivercreator/README.md b/receiver/receivercreator/README.md index 6ad572ac1ba9..d6037fcd5f1f 100644 --- a/receiver/receivercreator/README.md +++ b/receiver/receivercreator/README.md @@ -7,6 +7,7 @@ | | [beta]: metrics | | Distributions | [contrib], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Freceivercreator%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Freceivercreator%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@rmfitzpatrick](https://www.github.com/rmfitzpatrick) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta diff --git a/receiver/receivercreator/metadata.yaml b/receiver/receivercreator/metadata.yaml index 9d488db0db55..095baca2fed1 100644 --- a/receiver/receivercreator/metadata.yaml +++ b/receiver/receivercreator/metadata.yaml @@ -6,3 +6,5 @@ status: beta: [metrics] alpha: [logs, traces] distributions: [contrib, splunk, sumo] + codeowners: + active: [rmfitzpatrick] \ No newline at end of file diff --git a/receiver/redisreceiver/README.md b/receiver/redisreceiver/README.md index 989255c0c6c4..1253a29e40b4 100644 --- a/receiver/redisreceiver/README.md +++ b/receiver/redisreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [contrib], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fredis%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fredis%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@dmitryax](https://www.github.com/dmitryax), [@hughesjj](https://www.github.com/hughesjj) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/redisreceiver/metadata.yaml b/receiver/redisreceiver/metadata.yaml index 5dad24352c24..21b91396433f 100644 --- a/receiver/redisreceiver/metadata.yaml +++ b/receiver/redisreceiver/metadata.yaml @@ -5,6 +5,8 @@ status: stability: beta: [metrics] distributions: [contrib, splunk, observiq, sumo] + codeowners: + active: [dmitryax, hughesjj] resource_attributes: redis.version: diff --git a/receiver/riakreceiver/README.md b/receiver/riakreceiver/README.md index 700bff14e80e..8a111bffed04 100644 --- a/receiver/riakreceiver/README.md +++ b/receiver/riakreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [contrib], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Friak%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Friak%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@djaglowski](https://www.github.com/djaglowski), [@armstrmi](https://www.github.com/armstrmi) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/riakreceiver/metadata.yaml b/receiver/riakreceiver/metadata.yaml index b9c29eb247d9..73e911ee5fa8 100644 --- a/receiver/riakreceiver/metadata.yaml +++ b/receiver/riakreceiver/metadata.yaml @@ -5,6 +5,8 @@ status: stability: beta: [metrics] distributions: [contrib, observiq, sumo] + codeowners: + active: [djaglowski, armstrmi] resource_attributes: riak.node.name: diff --git a/receiver/saphanareceiver/README.md b/receiver/saphanareceiver/README.md index baf92806d7b2..e4be1948e4b6 100644 --- a/receiver/saphanareceiver/README.md +++ b/receiver/saphanareceiver/README.md @@ -6,6 +6,7 @@ | Stability | [development]: metrics | | Distributions | [contrib], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fsaphana%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fsaphana%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@dehaansa](https://www.github.com/dehaansa) | [development]: https://github.com/open-telemetry/opentelemetry-collector#development [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/saphanareceiver/metadata.yaml b/receiver/saphanareceiver/metadata.yaml index f57ec1b158f4..8932f20cf4ee 100644 --- a/receiver/saphanareceiver/metadata.yaml +++ b/receiver/saphanareceiver/metadata.yaml @@ -5,6 +5,8 @@ status: stability: development: [metrics] distributions: [contrib, observiq, sumo] + codeowners: + active: [dehaansa] resource_attributes: saphana.host: diff --git a/receiver/sapmreceiver/README.md b/receiver/sapmreceiver/README.md index 3cfdaf6a3cd1..ead811dfde6f 100644 --- a/receiver/sapmreceiver/README.md +++ b/receiver/sapmreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces | | Distributions | [contrib], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fsapm%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fsapm%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@atoulme](https://www.github.com/atoulme) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/sapmreceiver/metadata.yaml b/receiver/sapmreceiver/metadata.yaml index e5112b72596f..e1307fbe30d8 100644 --- a/receiver/sapmreceiver/metadata.yaml +++ b/receiver/sapmreceiver/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [traces] distributions: [contrib, splunk, observiq, sumo] + codeowners: + active: [atoulme] \ No newline at end of file diff --git a/receiver/simpleprometheusreceiver/README.md b/receiver/simpleprometheusreceiver/README.md index ea0547b5cb1b..3594740f1bfd 100644 --- a/receiver/simpleprometheusreceiver/README.md +++ b/receiver/simpleprometheusreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [contrib], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fsimpleprometheus%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fsimpleprometheus%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@fatsheep9146](https://www.github.com/fatsheep9146) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/simpleprometheusreceiver/metadata.yaml b/receiver/simpleprometheusreceiver/metadata.yaml index 3c23ca9ab4b6..ee7e54472a10 100644 --- a/receiver/simpleprometheusreceiver/metadata.yaml +++ b/receiver/simpleprometheusreceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: beta: [metrics] distributions: [contrib, splunk, observiq, sumo] - + codeowners: + active: [fatsheep9146] diff --git a/receiver/skywalkingreceiver/README.md b/receiver/skywalkingreceiver/README.md index 6c794cab26a4..dbfce38ba10e 100644 --- a/receiver/skywalkingreceiver/README.md +++ b/receiver/skywalkingreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces | | Distributions | [contrib], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fskywalking%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fskywalking%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@JaredTan95](https://www.github.com/JaredTan95) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/skywalkingreceiver/metadata.yaml b/receiver/skywalkingreceiver/metadata.yaml index 71de6abb8e99..76b1806a3750 100644 --- a/receiver/skywalkingreceiver/metadata.yaml +++ b/receiver/skywalkingreceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: beta: [traces] distributions: [contrib, sumo] - + codeowners: + active: [JaredTan95] diff --git a/receiver/snmpreceiver/README.md b/receiver/snmpreceiver/README.md index 8c666fad79aa..190157981bbe 100644 --- a/receiver/snmpreceiver/README.md +++ b/receiver/snmpreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: metrics | | Distributions | [contrib], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fsnmp%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fsnmp%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@djaglowski](https://www.github.com/djaglowski), [@StefanKurek](https://www.github.com/StefanKurek), [@tamir-michaeli](https://www.github.com/tamir-michaeli) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/snmpreceiver/metadata.yaml b/receiver/snmpreceiver/metadata.yaml index b4fd01951fd6..204f1e9eadf3 100644 --- a/receiver/snmpreceiver/metadata.yaml +++ b/receiver/snmpreceiver/metadata.yaml @@ -5,3 +5,5 @@ status: stability: alpha: [metrics] distributions: [contrib, sumo] + codeowners: + active: [djaglowski, StefanKurek, tamir-michaeli] \ No newline at end of file diff --git a/receiver/snowflakereceiver/README.md b/receiver/snowflakereceiver/README.md index 6b2dd705a1f9..924ab0dca1f4 100644 --- a/receiver/snowflakereceiver/README.md +++ b/receiver/snowflakereceiver/README.md @@ -5,6 +5,7 @@ | Stability | [alpha]: metrics | | Distributions | [contrib] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fsnowflake%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fsnowflake%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@dmitryax](https://www.github.com/dmitryax), [@shalper2](https://www.github.com/shalper2) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/snowflakereceiver/metadata.yaml b/receiver/snowflakereceiver/metadata.yaml index b44477746f2b..f3d31d3a0430 100644 --- a/receiver/snowflakereceiver/metadata.yaml +++ b/receiver/snowflakereceiver/metadata.yaml @@ -5,7 +5,8 @@ status: stability: alpha: [metrics] distributions: [contrib] - + codeowners: + active: [dmitryax, shalper2] # every meter will have these attributes resource_attributes: diff --git a/receiver/solacereceiver/README.md b/receiver/solacereceiver/README.md index 6ba7486020c6..815043361f6c 100644 --- a/receiver/solacereceiver/README.md +++ b/receiver/solacereceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces | | Distributions | [contrib], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fsolace%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fsolace%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@djaglowski](https://www.github.com/djaglowski), [@mcardy](https://www.github.com/mcardy) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/solacereceiver/metadata.yaml b/receiver/solacereceiver/metadata.yaml index aefd792f1f71..1e318c583689 100644 --- a/receiver/solacereceiver/metadata.yaml +++ b/receiver/solacereceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: beta: [traces] distributions: [contrib, sumo] - + codeowners: + active: [djaglowski, mcardy] diff --git a/receiver/splunkenterprisereceiver/metadata.yaml b/receiver/splunkenterprisereceiver/metadata.yaml index 113d0619bc0d..eb4493825fa8 100644 --- a/receiver/splunkenterprisereceiver/metadata.yaml +++ b/receiver/splunkenterprisereceiver/metadata.yaml @@ -5,3 +5,5 @@ status: stability: development: [metrics] distributions: + codeowners: + active: [shalper2, MovieStoreGuy] \ No newline at end of file diff --git a/receiver/sqlqueryreceiver/README.md b/receiver/sqlqueryreceiver/README.md index 7c4f7cbfe5aa..be7663069643 100644 --- a/receiver/sqlqueryreceiver/README.md +++ b/receiver/sqlqueryreceiver/README.md @@ -7,6 +7,7 @@ | | [development]: logs | | Distributions | [contrib], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fsqlquery%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fsqlquery%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@dmitryax](https://www.github.com/dmitryax), [@pmcollins](https://www.github.com/pmcollins) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [development]: https://github.com/open-telemetry/opentelemetry-collector#development diff --git a/receiver/sqlqueryreceiver/metadata.yaml b/receiver/sqlqueryreceiver/metadata.yaml index 5b0a6e159a6e..5094a3ab8b44 100644 --- a/receiver/sqlqueryreceiver/metadata.yaml +++ b/receiver/sqlqueryreceiver/metadata.yaml @@ -6,3 +6,5 @@ status: alpha: [metrics] development: [logs] distributions: [contrib, splunk, observiq, sumo] + codeowners: + active: [dmitryax, pmcollins] \ No newline at end of file diff --git a/receiver/sqlserverreceiver/README.md b/receiver/sqlserverreceiver/README.md index c00b8fbabbe6..03b766b3ffcb 100644 --- a/receiver/sqlserverreceiver/README.md +++ b/receiver/sqlserverreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [contrib], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fsqlserver%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fsqlserver%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@djaglowski](https://www.github.com/djaglowski), [@StefanKurek](https://www.github.com/StefanKurek) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/sqlserverreceiver/metadata.yaml b/receiver/sqlserverreceiver/metadata.yaml index 5b8d23afbcf2..286c30044798 100644 --- a/receiver/sqlserverreceiver/metadata.yaml +++ b/receiver/sqlserverreceiver/metadata.yaml @@ -5,6 +5,8 @@ status: stability: beta: [metrics] distributions: [contrib, observiq, sumo] + codeowners: + active: [djaglowski, StefanKurek] resource_attributes: sqlserver.database.name: diff --git a/receiver/sshcheckreceiver/README.md b/receiver/sshcheckreceiver/README.md index 8bea52fb31e0..0319846e16dd 100644 --- a/receiver/sshcheckreceiver/README.md +++ b/receiver/sshcheckreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: metrics | | Distributions | [contrib], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fsshcheck%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fsshcheck%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@nslaughter](https://www.github.com/nslaughter), [@codeboten](https://www.github.com/codeboten) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/sshcheckreceiver/metadata.yaml b/receiver/sshcheckreceiver/metadata.yaml index c2db4acc1be9..fef02440abc3 100644 --- a/receiver/sshcheckreceiver/metadata.yaml +++ b/receiver/sshcheckreceiver/metadata.yaml @@ -5,7 +5,9 @@ status: stability: alpha: [metrics] distributions: [contrib, sumo] - + codeowners: + active: [nslaughter, codeboten] + resource_attributes: ssh.endpoint: description: Full SSH endpoint diff --git a/receiver/statsdreceiver/README.md b/receiver/statsdreceiver/README.md index 00e6dd2bb82f..b01c1c01bb73 100644 --- a/receiver/statsdreceiver/README.md +++ b/receiver/statsdreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [contrib], [aws], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fstatsd%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fstatsd%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jmacd](https://www.github.com/jmacd), [@dmitryax](https://www.github.com/dmitryax) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/statsdreceiver/metadata.yaml b/receiver/statsdreceiver/metadata.yaml index 0e2c8bae1ece..cd17f73b5133 100644 --- a/receiver/statsdreceiver/metadata.yaml +++ b/receiver/statsdreceiver/metadata.yaml @@ -5,3 +5,5 @@ status: stability: beta: [metrics] distributions: [contrib, splunk, sumo, aws] + codeowners: + active: [jmacd, dmitryax] \ No newline at end of file diff --git a/receiver/syslogreceiver/README.md b/receiver/syslogreceiver/README.md index 7d31787ea43e..0e9825ad9256 100644 --- a/receiver/syslogreceiver/README.md +++ b/receiver/syslogreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: logs | | Distributions | [contrib], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fsyslog%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fsyslog%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@djaglowski](https://www.github.com/djaglowski) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/syslogreceiver/metadata.yaml b/receiver/syslogreceiver/metadata.yaml index 821ad9847566..2374df77559a 100644 --- a/receiver/syslogreceiver/metadata.yaml +++ b/receiver/syslogreceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: alpha: [logs] distributions: [contrib, splunk, observiq, sumo] - + codeowners: + active: [djaglowski] diff --git a/receiver/tcplogreceiver/README.md b/receiver/tcplogreceiver/README.md index 25210b33f86f..fbffce624a01 100644 --- a/receiver/tcplogreceiver/README.md +++ b/receiver/tcplogreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: logs | | Distributions | [contrib], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Ftcplog%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Ftcplog%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@djaglowski](https://www.github.com/djaglowski) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/tcplogreceiver/metadata.yaml b/receiver/tcplogreceiver/metadata.yaml index b9c1c8ef98f0..8f95bbe11e2f 100644 --- a/receiver/tcplogreceiver/metadata.yaml +++ b/receiver/tcplogreceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: alpha: [logs] distributions: [contrib, splunk, observiq, sumo] - + codeowners: + active: [djaglowski] diff --git a/receiver/udplogreceiver/README.md b/receiver/udplogreceiver/README.md index 26bd4aa41bc9..5689454f6de3 100644 --- a/receiver/udplogreceiver/README.md +++ b/receiver/udplogreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: logs | | Distributions | [contrib], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fudplog%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fudplog%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@djaglowski](https://www.github.com/djaglowski) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/udplogreceiver/metadata.yaml b/receiver/udplogreceiver/metadata.yaml index aed7e39f355b..42d6edef6961 100644 --- a/receiver/udplogreceiver/metadata.yaml +++ b/receiver/udplogreceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: alpha: [logs] distributions: [contrib, observiq, sumo] - + codeowners: + active: [djaglowski] \ No newline at end of file diff --git a/receiver/vcenterreceiver/README.md b/receiver/vcenterreceiver/README.md index 3c9ae04609cb..47610e58f8f0 100644 --- a/receiver/vcenterreceiver/README.md +++ b/receiver/vcenterreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: metrics | | Distributions | [contrib], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fvcenter%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fvcenter%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@djaglowski](https://www.github.com/djaglowski), [@schmikei](https://www.github.com/schmikei) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/vcenterreceiver/metadata.yaml b/receiver/vcenterreceiver/metadata.yaml index 5f83ba50edba..c287f27a4d76 100644 --- a/receiver/vcenterreceiver/metadata.yaml +++ b/receiver/vcenterreceiver/metadata.yaml @@ -5,6 +5,8 @@ status: stability: alpha: [metrics] distributions: [contrib, observiq, sumo] + codeowners: + active: [djaglowski, schmikei] resource_attributes: vcenter.cluster.name: diff --git a/receiver/wavefrontreceiver/README.md b/receiver/wavefrontreceiver/README.md index a607a8351be4..fb969f203b9c 100644 --- a/receiver/wavefrontreceiver/README.md +++ b/receiver/wavefrontreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [unmaintained]: metrics | | Distributions | [contrib], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fwavefront%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fwavefront%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | | [unmaintained]: https://github.com/open-telemetry/opentelemetry-collector#unmaintained [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/wavefrontreceiver/metadata.yaml b/receiver/wavefrontreceiver/metadata.yaml index 094b2aaf7e30..fc0ae4cb1e89 100644 --- a/receiver/wavefrontreceiver/metadata.yaml +++ b/receiver/wavefrontreceiver/metadata.yaml @@ -5,5 +5,6 @@ status: stability: unmaintained: [metrics] distributions: [contrib, sumo] - + codeowners: + active: [ ] diff --git a/receiver/windowseventlogreceiver/README.md b/receiver/windowseventlogreceiver/README.md index 2787cdc0ada0..d8535fd9490a 100644 --- a/receiver/windowseventlogreceiver/README.md +++ b/receiver/windowseventlogreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [alpha]: logs | | Distributions | [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fwindowseventlog%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fwindowseventlog%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@djaglowski](https://www.github.com/djaglowski), [@armstrmi](https://www.github.com/armstrmi) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [observiq]: https://github.com/observIQ/observiq-otel-collector diff --git a/receiver/windowseventlogreceiver/metadata.yaml b/receiver/windowseventlogreceiver/metadata.yaml index 0ffcf7d98c6b..847cbff7ecbd 100644 --- a/receiver/windowseventlogreceiver/metadata.yaml +++ b/receiver/windowseventlogreceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: alpha: [logs] distributions: [splunk, observiq, sumo] - + codeowners: + active: [djaglowski, armstrmi] \ No newline at end of file diff --git a/receiver/windowsperfcountersreceiver/README.md b/receiver/windowsperfcountersreceiver/README.md index fa9522becc5d..13967f247d18 100644 --- a/receiver/windowsperfcountersreceiver/README.md +++ b/receiver/windowsperfcountersreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: metrics | | Distributions | [contrib], [observiq], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fwindowsperfcounters%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fwindowsperfcounters%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@dashpole](https://www.github.com/dashpole) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/windowsperfcountersreceiver/metadata.yaml b/receiver/windowsperfcountersreceiver/metadata.yaml index df77c75daa7a..482a82cefcb1 100644 --- a/receiver/windowsperfcountersreceiver/metadata.yaml +++ b/receiver/windowsperfcountersreceiver/metadata.yaml @@ -5,4 +5,5 @@ status: stability: beta: [metrics] distributions: [contrib, splunk, observiq, sumo] - + codeowners: + active: [dashpole] diff --git a/receiver/zipkinreceiver/README.md b/receiver/zipkinreceiver/README.md index 462071278449..2c222ca7c65f 100644 --- a/receiver/zipkinreceiver/README.md +++ b/receiver/zipkinreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [beta]: traces | | Distributions | [core], [contrib], [aws], [grafana], [observiq], [redhat], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fzipkin%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fzipkin%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@MovieStoreGuy](https://www.github.com/MovieStoreGuy), [@astencel-sumo](https://www.github.com/astencel-sumo), [@crobert-1](https://www.github.com/crobert-1) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [core]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol diff --git a/receiver/zipkinreceiver/metadata.yaml b/receiver/zipkinreceiver/metadata.yaml index 707bda723758..bfbdffacf008 100644 --- a/receiver/zipkinreceiver/metadata.yaml +++ b/receiver/zipkinreceiver/metadata.yaml @@ -13,3 +13,5 @@ status: - redhat - splunk - sumo + codeowners: + active: [MovieStoreGuy, astencel-sumo, crobert-1] diff --git a/receiver/zookeeperreceiver/README.md b/receiver/zookeeperreceiver/README.md index 61dae1b633c8..43742e16ea0e 100644 --- a/receiver/zookeeperreceiver/README.md +++ b/receiver/zookeeperreceiver/README.md @@ -6,6 +6,7 @@ | Stability | [development]: metrics | | Distributions | [contrib], [observiq], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fzookeeper%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fzookeeper%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@djaglowski](https://www.github.com/djaglowski) | [development]: https://github.com/open-telemetry/opentelemetry-collector#development [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/zookeeperreceiver/metadata.yaml b/receiver/zookeeperreceiver/metadata.yaml index 81e89fd86fd6..5e7985dc06f2 100644 --- a/receiver/zookeeperreceiver/metadata.yaml +++ b/receiver/zookeeperreceiver/metadata.yaml @@ -5,6 +5,8 @@ status: stability: development: [metrics] distributions: [contrib, observiq, sumo] + codeowners: + active: [djaglowski] resource_attributes: server.state: diff --git a/testbed/metadata.yaml b/testbed/metadata.yaml new file mode 100644 index 000000000000..d33786a6475a --- /dev/null +++ b/testbed/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [open-telemetry/collector-approvers] \ No newline at end of file diff --git a/testbed/mockdatareceivers/mockawsxrayreceiver/metadata.yaml b/testbed/mockdatareceivers/mockawsxrayreceiver/metadata.yaml new file mode 100644 index 000000000000..d8ad05f45689 --- /dev/null +++ b/testbed/mockdatareceivers/mockawsxrayreceiver/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [wangzlei, srprash] \ No newline at end of file diff --git a/testbed/mockdatasenders/mockdatadogagentexporter/metadata.yaml b/testbed/mockdatasenders/mockdatadogagentexporter/metadata.yaml new file mode 100644 index 000000000000..0212fba91a11 --- /dev/null +++ b/testbed/mockdatasenders/mockdatadogagentexporter/metadata.yaml @@ -0,0 +1,3 @@ +status: + codeowners: + active: [boostchicken] \ No newline at end of file From 13ff0180cb964fbf1f44eb3d6a4371fdbb180f40 Mon Sep 17 00:00:00 2001 From: Fabrizio Ferri-Benedetti Date: Mon, 24 Jul 2023 13:26:31 +0200 Subject: [PATCH 24/42] Fix typo in k8sclusterreceiver config.go file (#24445) Fixing a typo in the description of the distribution mapstructure. --- receiver/k8sclusterreceiver/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/receiver/k8sclusterreceiver/config.go b/receiver/k8sclusterreceiver/config.go index 7f86e68ccf6f..0b98fa9bf522 100644 --- a/receiver/k8sclusterreceiver/config.go +++ b/receiver/k8sclusterreceiver/config.go @@ -26,7 +26,7 @@ type Config struct { // List of exporters to which metadata from this receiver should be forwarded to. MetadataExporters []string `mapstructure:"metadata_exporters"` - // Whether OpenShift supprot should be enabled or not. + // Whether OpenShift support should be enabled or not. Distribution string `mapstructure:"distribution"` // Collection interval for metadata. From 25aa9237a7687de9da5246662bf53d70157d79ea Mon Sep 17 00:00:00 2001 From: Curtis Robert <92119472+crobert-1@users.noreply.github.com> Date: Mon, 24 Jul 2023 12:48:39 -0700 Subject: [PATCH 25/42] [receiver/k8scluster] Convert clusterresourcequota to use pdata (#24416) **Description:** This converts the clusterresourcequota metrics of the k8scluster receiver to use the pdata metric format instead of opencensus. **Link to tracking Issue:** #4367 --- ...cluster-receiver-clusterresourcequota.yaml | 21 + .../clusteresourcequotas.go | 114 ------ .../clusterresourcequotas.go | 55 +++ .../clusterresourcequotas_test.go | 136 +----- .../internal/clusterresourcequota/doc.go | 6 + .../clusterresourcequota/documentation.md | 81 ++++ .../internal/metadata/generated_config.go | 88 ++++ .../metadata/generated_config_test.go | 76 ++++ .../internal/metadata/generated_metrics.go | 387 ++++++++++++++++++ .../metadata/generated_metrics_test.go | 189 +++++++++ .../internal/metadata/testdata/config.yaml | 35 ++ .../clusterresourcequota/metadata.yaml | 67 +++ .../testdata/expected.yaml | 81 ++++ .../internal/collection/collector.go | 2 +- .../internal/testutils/objects.go | 45 ++ 15 files changed, 1149 insertions(+), 234 deletions(-) create mode 100644 .chloggen/k8s-cluster-receiver-clusterresourcequota.yaml delete mode 100644 receiver/k8sclusterreceiver/internal/clusterresourcequota/clusteresourcequotas.go create mode 100644 receiver/k8sclusterreceiver/internal/clusterresourcequota/clusterresourcequotas.go create mode 100644 receiver/k8sclusterreceiver/internal/clusterresourcequota/doc.go create mode 100644 receiver/k8sclusterreceiver/internal/clusterresourcequota/documentation.md create mode 100644 receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_config.go create mode 100644 receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_config_test.go create mode 100644 receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_metrics.go create mode 100644 receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_metrics_test.go create mode 100644 receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/testdata/config.yaml create mode 100644 receiver/k8sclusterreceiver/internal/clusterresourcequota/metadata.yaml create mode 100644 receiver/k8sclusterreceiver/internal/clusterresourcequota/testdata/expected.yaml diff --git a/.chloggen/k8s-cluster-receiver-clusterresourcequota.yaml b/.chloggen/k8s-cluster-receiver-clusterresourcequota.yaml new file mode 100644 index 000000000000..3b7e69e75a8c --- /dev/null +++ b/.chloggen/k8s-cluster-receiver-clusterresourcequota.yaml @@ -0,0 +1,21 @@ + +# Use this changelog template to create an entry for release notes. +# If your change doesn't affect end users, such as a test fix or a tooling change, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. + +# 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. filelogreceiver) +component: "k8sclusterreceiver" + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: "Change k8s.clusterresourcequota metrics to use mdatagen" + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [4367] + +# (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: \ No newline at end of file diff --git a/receiver/k8sclusterreceiver/internal/clusterresourcequota/clusteresourcequotas.go b/receiver/k8sclusterreceiver/internal/clusterresourcequota/clusteresourcequotas.go deleted file mode 100644 index dc77c0d5f5d4..000000000000 --- a/receiver/k8sclusterreceiver/internal/clusterresourcequota/clusteresourcequotas.go +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package clusterresourcequota // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/clusterresourcequota" - -import ( - "strings" - - agentmetricspb "github.com/census-instrumentation/opencensus-proto/gen-go/agent/metrics/v1" - metricspb "github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1" - resourcepb "github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1" - quotav1 "github.com/openshift/api/quota/v1" - conventions "go.opentelemetry.io/collector/semconv/v1.6.1" - corev1 "k8s.io/api/core/v1" - - "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/constants" - "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/utils" -) - -var clusterResourceQuotaLimitMetric = &metricspb.MetricDescriptor{ - Name: "openshift.clusterquota.limit", - Description: "The configured upper limit for a particular resource.", - Type: metricspb.MetricDescriptor_GAUGE_INT64, - LabelKeys: []*metricspb.LabelKey{{ - Key: "resource", - }}, -} - -var clusterResourceQuotaUsedMetric = &metricspb.MetricDescriptor{ - Name: "openshift.clusterquota.used", - Description: "The usage for a particular resource with a configured limit.", - Type: metricspb.MetricDescriptor_GAUGE_INT64, - LabelKeys: []*metricspb.LabelKey{{ - Key: "resource", - }}, -} - -var appliedClusterResourceQuotaLimitMetric = &metricspb.MetricDescriptor{ - Name: "openshift.appliedclusterquota.limit", - Description: "The upper limit for a particular resource in a specific namespace.", - Type: metricspb.MetricDescriptor_GAUGE_INT64, - LabelKeys: []*metricspb.LabelKey{ - { - Key: "resource", - }, - { - Key: conventions.AttributeK8SNamespaceName, - }, - }, -} - -var appliedClusterResourceQuotaUsedMetric = &metricspb.MetricDescriptor{ - Name: "openshift.appliedclusterquota.used", - Description: "The usage for a particular resource in a specific namespace.", - Type: metricspb.MetricDescriptor_GAUGE_INT64, - LabelKeys: []*metricspb.LabelKey{ - { - Key: "resource", - }, - { - Key: conventions.AttributeK8SNamespaceName, - }, - }, -} - -func GetMetrics(rq *quotav1.ClusterResourceQuota) []*agentmetricspb.ExportMetricsServiceRequest { - var metrics []*metricspb.Metric - - metrics = appendClusterQuotaMetrics(metrics, clusterResourceQuotaLimitMetric, rq.Status.Total.Hard, "") - metrics = appendClusterQuotaMetrics(metrics, clusterResourceQuotaUsedMetric, rq.Status.Total.Used, "") - for _, ns := range rq.Status.Namespaces { - metrics = appendClusterQuotaMetrics(metrics, appliedClusterResourceQuotaLimitMetric, ns.Status.Hard, ns.Namespace) - metrics = appendClusterQuotaMetrics(metrics, appliedClusterResourceQuotaUsedMetric, ns.Status.Used, ns.Namespace) - } - return []*agentmetricspb.ExportMetricsServiceRequest{ - { - Resource: getResource(rq), - Metrics: metrics, - }, - } -} - -func appendClusterQuotaMetrics(metrics []*metricspb.Metric, metric *metricspb.MetricDescriptor, rl corev1.ResourceList, namespace string) []*metricspb.Metric { - for k, v := range rl { - val := v.Value() - if strings.HasSuffix(string(k), ".cpu") { - val = v.MilliValue() - } - - labels := []*metricspb.LabelValue{{Value: string(k), HasValue: true}} - if namespace != "" { - labels = append(labels, &metricspb.LabelValue{Value: namespace, HasValue: true}) - } - metrics = append(metrics, - &metricspb.Metric{ - MetricDescriptor: metric, - Timeseries: []*metricspb.TimeSeries{ - utils.GetInt64TimeSeriesWithLabels(val, labels), - }, - }, - ) - } - return metrics -} - -func getResource(rq *quotav1.ClusterResourceQuota) *resourcepb.Resource { - return &resourcepb.Resource{ - Type: constants.K8sType, - Labels: map[string]string{ - constants.K8sKeyClusterResourceQuotaUID: string(rq.UID), - constants.K8sKeyClusterResourceQuotaName: rq.Name, - }, - } -} diff --git a/receiver/k8sclusterreceiver/internal/clusterresourcequota/clusterresourcequotas.go b/receiver/k8sclusterreceiver/internal/clusterresourcequota/clusterresourcequotas.go new file mode 100644 index 000000000000..687dac5c6cb4 --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/clusterresourcequota/clusterresourcequotas.go @@ -0,0 +1,55 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package clusterresourcequota // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/clusterresourcequota" + +import ( + "strings" + "time" + + quotav1 "github.com/openshift/api/quota/v1" + "go.opentelemetry.io/collector/pdata/pcommon" + "go.opentelemetry.io/collector/pdata/pmetric" + "go.opentelemetry.io/collector/receiver" + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + + imetadataphase "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata" +) + +func GetMetrics(set receiver.CreateSettings, crq *quotav1.ClusterResourceQuota) pmetric.Metrics { + mbphase := imetadataphase.NewMetricsBuilder(imetadataphase.DefaultMetricsBuilderConfig(), set) + ts := pcommon.NewTimestampFromTime(time.Now()) + + for k, v := range crq.Status.Total.Hard { + val := extractValue(k, v) + mbphase.RecordOpenshiftClusterquotaLimitDataPoint(ts, val, string(k)) + } + + for k, v := range crq.Status.Total.Used { + val := extractValue(k, v) + mbphase.RecordOpenshiftClusterquotaUsedDataPoint(ts, val, string(k)) + } + + for _, ns := range crq.Status.Namespaces { + for k, v := range ns.Status.Hard { + val := extractValue(k, v) + mbphase.RecordOpenshiftAppliedclusterquotaLimitDataPoint(ts, val, ns.Namespace, string(k)) + } + + for k, v := range ns.Status.Used { + val := extractValue(k, v) + mbphase.RecordOpenshiftAppliedclusterquotaUsedDataPoint(ts, val, ns.Namespace, string(k)) + } + } + + return mbphase.Emit(imetadataphase.WithOpenshiftClusterquotaName(crq.Name), imetadataphase.WithOpenshiftClusterquotaUID(string(crq.UID)), imetadataphase.WithOpencensusResourcetype("k8s")) +} + +func extractValue(k v1.ResourceName, v resource.Quantity) int64 { + val := v.Value() + if strings.HasSuffix(string(k), ".cpu") { + val = v.MilliValue() + } + return val +} diff --git a/receiver/k8sclusterreceiver/internal/clusterresourcequota/clusterresourcequotas_test.go b/receiver/k8sclusterreceiver/internal/clusterresourcequota/clusterresourcequotas_test.go index d3bdb6b56608..e0edf7110919 100644 --- a/receiver/k8sclusterreceiver/internal/clusterresourcequota/clusterresourcequotas_test.go +++ b/receiver/k8sclusterreceiver/internal/clusterresourcequota/clusterresourcequotas_test.go @@ -4,132 +4,30 @@ package clusterresourcequota import ( + "path/filepath" "testing" - metricspb "github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1" - quotav1 "github.com/openshift/api/quota/v1" "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" + "go.opentelemetry.io/collector/receiver/receivertest" - "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/constants" + "github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal/golden" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest/pmetrictest" "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/testutils" ) func TestClusterRequestQuotaMetrics(t *testing.T) { - rq := newMockClusterResourceQuota("1") - - actualResourceMetrics := GetMetrics(rq) - - require.Equal(t, 1, len(actualResourceMetrics)) - - metrics := actualResourceMetrics[0].Metrics - require.Equal(t, 6, len(metrics)) - testutils.AssertResource(t, actualResourceMetrics[0].Resource, constants.K8sType, - map[string]string{ - "openshift.clusterquota.uid": "test-clusterquota-1-uid", - "openshift.clusterquota.name": "test-clusterquota-1", - }, + crq := testutils.NewClusterResourceQuota("1") + + m := GetMetrics(receivertest.NewNopCreateSettings(), crq) + + expected, err := golden.ReadMetrics(filepath.Join("testdata", "expected.yaml")) + require.NoError(t, err) + require.NoError(t, pmetrictest.CompareMetrics(expected, m, + pmetrictest.IgnoreTimestamp(), + pmetrictest.IgnoreStartTimestamp(), + pmetrictest.IgnoreResourceMetricsOrder(), + pmetrictest.IgnoreMetricsOrder(), + pmetrictest.IgnoreScopeMetricsOrder(), + ), ) - - for i, tc := range []struct { - name string - value int64 - labels map[string]string - }{ - { - "openshift.clusterquota.limit", - 10000, - map[string]string{ - "resource": "requests.cpu", - }, - }, - { - "openshift.clusterquota.used", - 6000, - map[string]string{ - "resource": "requests.cpu", - }, - }, - { - "openshift.appliedclusterquota.limit", - 6000, - map[string]string{ - "resource": "requests.cpu", - "k8s.namespace.name": "ns1", - }, - }, - { - "openshift.appliedclusterquota.used", - 1000, - map[string]string{ - "resource": "requests.cpu", - "k8s.namespace.name": "ns1", - }, - }, - { - "openshift.appliedclusterquota.limit", - 4000, - map[string]string{ - "resource": "requests.cpu", - "k8s.namespace.name": "ns2", - }, - }, - { - "openshift.appliedclusterquota.used", - 5000, - map[string]string{ - "resource": "requests.cpu", - "k8s.namespace.name": "ns2", - }, - }, - } { - testutils.AssertMetricsWithLabels(t, metrics[i], tc.name, - metricspb.MetricDescriptor_GAUGE_INT64, tc.labels, tc.value) - } -} - -func newMockClusterResourceQuota(id string) *quotav1.ClusterResourceQuota { - return "av1.ClusterResourceQuota{ - ObjectMeta: v1.ObjectMeta{ - Name: "test-clusterquota-" + id, - UID: types.UID("test-clusterquota-" + id + "-uid"), - }, - Status: quotav1.ClusterResourceQuotaStatus{ - Total: corev1.ResourceQuotaStatus{ - Hard: corev1.ResourceList{ - "requests.cpu": *resource.NewQuantity(10, resource.DecimalSI), - }, - Used: corev1.ResourceList{ - "requests.cpu": *resource.NewQuantity(6, resource.DecimalSI), - }, - }, - Namespaces: quotav1.ResourceQuotasStatusByNamespace{ - { - Namespace: "ns1", - Status: corev1.ResourceQuotaStatus{ - Hard: corev1.ResourceList{ - "requests.cpu": *resource.NewQuantity(6, resource.DecimalSI), - }, - Used: corev1.ResourceList{ - "requests.cpu": *resource.NewQuantity(1, resource.DecimalSI), - }, - }, - }, - { - Namespace: "ns2", - Status: corev1.ResourceQuotaStatus{ - Hard: corev1.ResourceList{ - "requests.cpu": *resource.NewQuantity(4, resource.DecimalSI), - }, - Used: corev1.ResourceList{ - "requests.cpu": *resource.NewQuantity(5, resource.DecimalSI), - }, - }, - }, - }, - }, - } } diff --git a/receiver/k8sclusterreceiver/internal/clusterresourcequota/doc.go b/receiver/k8sclusterreceiver/internal/clusterresourcequota/doc.go new file mode 100644 index 000000000000..a30fe432c28d --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/clusterresourcequota/doc.go @@ -0,0 +1,6 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +//go:generate mdatagen metadata.yaml + +package clusterresourcequota // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/clusterresourcequota" diff --git a/receiver/k8sclusterreceiver/internal/clusterresourcequota/documentation.md b/receiver/k8sclusterreceiver/internal/clusterresourcequota/documentation.md new file mode 100644 index 000000000000..cc54ab308380 --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/clusterresourcequota/documentation.md @@ -0,0 +1,81 @@ +[comment]: <> (Code generated by mdatagen. DO NOT EDIT.) + +# k8s/clusterresourcequota + +**Parent Component:** k8s_cluster + +## Default Metrics + +The following metrics are emitted by default. Each of them can be disabled by applying the following configuration: + +```yaml +metrics: + : + enabled: false +``` + +### openshift.appliedclusterquota.limit + +The upper limit for a particular resource in a specific namespace. + +| Unit | Metric Type | Value Type | +| ---- | ----------- | ---------- | +| 1 | Gauge | Int | + +#### Attributes + +| Name | Description | Values | +| ---- | ----------- | ------ | +| k8s.namespace.name | The k8s namespace name. | Any Str | +| resource | The name of the resource on which the cluster quota is applied | Any Str | + +### openshift.appliedclusterquota.used + +The usage for a particular resource in a specific namespace. + +| Unit | Metric Type | Value Type | +| ---- | ----------- | ---------- | +| 1 | Gauge | Int | + +#### Attributes + +| Name | Description | Values | +| ---- | ----------- | ------ | +| k8s.namespace.name | The k8s namespace name. | Any Str | +| resource | The name of the resource on which the cluster quota is applied | Any Str | + +### openshift.clusterquota.limit + +The configured upper limit for a particular resource. + +| Unit | Metric Type | Value Type | +| ---- | ----------- | ---------- | +| 1 | Gauge | Int | + +#### Attributes + +| Name | Description | Values | +| ---- | ----------- | ------ | +| resource | The name of the resource on which the cluster quota is applied | Any Str | + +### openshift.clusterquota.used + +The usage for a particular resource with a configured limit. + +| Unit | Metric Type | Value Type | +| ---- | ----------- | ---------- | +| 1 | Gauge | Int | + +#### Attributes + +| Name | Description | Values | +| ---- | ----------- | ------ | +| resource | The name of the resource on which the cluster quota is applied | Any Str | + +## Resource Attributes + +| Name | Description | Values | Enabled | +| ---- | ----------- | ------ | ------- | +| opencensus.resourcetype | The OpenCensus resource type. | Any Str | true | +| openshift.clusterquota.name | The k8s ClusterResourceQuota name. | Any Str | true | +| openshift.clusterquota.uid | The k8s ClusterResourceQuota uid. | Any Str | true | diff --git a/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_config.go b/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_config.go new file mode 100644 index 000000000000..cee0b047101b --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_config.go @@ -0,0 +1,88 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import "go.opentelemetry.io/collector/confmap" + +// MetricConfig provides common config for a particular metric. +type MetricConfig struct { + Enabled bool `mapstructure:"enabled"` + + enabledSetByUser bool +} + +func (ms *MetricConfig) Unmarshal(parser *confmap.Conf) error { + if parser == nil { + return nil + } + err := parser.Unmarshal(ms, confmap.WithErrorUnused()) + if err != nil { + return err + } + ms.enabledSetByUser = parser.IsSet("enabled") + return nil +} + +// MetricsConfig provides config for k8s/clusterresourcequota metrics. +type MetricsConfig struct { + OpenshiftAppliedclusterquotaLimit MetricConfig `mapstructure:"openshift.appliedclusterquota.limit"` + OpenshiftAppliedclusterquotaUsed MetricConfig `mapstructure:"openshift.appliedclusterquota.used"` + OpenshiftClusterquotaLimit MetricConfig `mapstructure:"openshift.clusterquota.limit"` + OpenshiftClusterquotaUsed MetricConfig `mapstructure:"openshift.clusterquota.used"` +} + +func DefaultMetricsConfig() MetricsConfig { + return MetricsConfig{ + OpenshiftAppliedclusterquotaLimit: MetricConfig{ + Enabled: true, + }, + OpenshiftAppliedclusterquotaUsed: MetricConfig{ + Enabled: true, + }, + OpenshiftClusterquotaLimit: MetricConfig{ + Enabled: true, + }, + OpenshiftClusterquotaUsed: MetricConfig{ + Enabled: true, + }, + } +} + +// ResourceAttributeConfig provides common config for a particular resource attribute. +type ResourceAttributeConfig struct { + Enabled bool `mapstructure:"enabled"` +} + +// ResourceAttributesConfig provides config for k8s/clusterresourcequota resource attributes. +type ResourceAttributesConfig struct { + OpencensusResourcetype ResourceAttributeConfig `mapstructure:"opencensus.resourcetype"` + OpenshiftClusterquotaName ResourceAttributeConfig `mapstructure:"openshift.clusterquota.name"` + OpenshiftClusterquotaUID ResourceAttributeConfig `mapstructure:"openshift.clusterquota.uid"` +} + +func DefaultResourceAttributesConfig() ResourceAttributesConfig { + return ResourceAttributesConfig{ + OpencensusResourcetype: ResourceAttributeConfig{ + Enabled: true, + }, + OpenshiftClusterquotaName: ResourceAttributeConfig{ + Enabled: true, + }, + OpenshiftClusterquotaUID: ResourceAttributeConfig{ + Enabled: true, + }, + } +} + +// MetricsBuilderConfig is a configuration for k8s/clusterresourcequota metrics builder. +type MetricsBuilderConfig struct { + Metrics MetricsConfig `mapstructure:"metrics"` + ResourceAttributes ResourceAttributesConfig `mapstructure:"resource_attributes"` +} + +func DefaultMetricsBuilderConfig() MetricsBuilderConfig { + return MetricsBuilderConfig{ + Metrics: DefaultMetricsConfig(), + ResourceAttributes: DefaultResourceAttributesConfig(), + } +} diff --git a/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_config_test.go b/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_config_test.go new file mode 100644 index 000000000000..5758ce83ebc8 --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_config_test.go @@ -0,0 +1,76 @@ +// 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/component" + "go.opentelemetry.io/collector/confmap/confmaptest" +) + +func TestMetricsBuilderConfig(t *testing.T) { + tests := []struct { + name string + want MetricsBuilderConfig + }{ + { + name: "default", + want: DefaultMetricsBuilderConfig(), + }, + { + name: "all_set", + want: MetricsBuilderConfig{ + Metrics: MetricsConfig{ + OpenshiftAppliedclusterquotaLimit: MetricConfig{Enabled: true}, + OpenshiftAppliedclusterquotaUsed: MetricConfig{Enabled: true}, + OpenshiftClusterquotaLimit: MetricConfig{Enabled: true}, + OpenshiftClusterquotaUsed: MetricConfig{Enabled: true}, + }, + ResourceAttributes: ResourceAttributesConfig{ + OpencensusResourcetype: ResourceAttributeConfig{Enabled: true}, + OpenshiftClusterquotaName: ResourceAttributeConfig{Enabled: true}, + OpenshiftClusterquotaUID: ResourceAttributeConfig{Enabled: true}, + }, + }, + }, + { + name: "none_set", + want: MetricsBuilderConfig{ + Metrics: MetricsConfig{ + OpenshiftAppliedclusterquotaLimit: MetricConfig{Enabled: false}, + OpenshiftAppliedclusterquotaUsed: MetricConfig{Enabled: false}, + OpenshiftClusterquotaLimit: MetricConfig{Enabled: false}, + OpenshiftClusterquotaUsed: MetricConfig{Enabled: false}, + }, + ResourceAttributes: ResourceAttributesConfig{ + OpencensusResourcetype: ResourceAttributeConfig{Enabled: false}, + OpenshiftClusterquotaName: ResourceAttributeConfig{Enabled: false}, + OpenshiftClusterquotaUID: ResourceAttributeConfig{Enabled: false}, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cfg := loadMetricsBuilderConfig(t, tt.name) + if diff := cmp.Diff(tt.want, cfg, cmpopts.IgnoreUnexported(MetricConfig{}, ResourceAttributeConfig{})); diff != "" { + t.Errorf("Config mismatch (-expected +actual):\n%s", diff) + } + }) + } +} + +func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { + cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config.yaml")) + require.NoError(t, err) + sub, err := cm.Sub(name) + require.NoError(t, err) + cfg := DefaultMetricsBuilderConfig() + require.NoError(t, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_metrics.go b/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_metrics.go new file mode 100644 index 000000000000..08e3431d9572 --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_metrics.go @@ -0,0 +1,387 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "time" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/pdata/pcommon" + "go.opentelemetry.io/collector/pdata/pmetric" + "go.opentelemetry.io/collector/receiver" + conventions "go.opentelemetry.io/collector/semconv/v1.18.0" +) + +type metricOpenshiftAppliedclusterquotaLimit struct { + data pmetric.Metric // data buffer for generated metric. + config MetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills openshift.appliedclusterquota.limit metric with initial data. +func (m *metricOpenshiftAppliedclusterquotaLimit) init() { + m.data.SetName("openshift.appliedclusterquota.limit") + m.data.SetDescription("The upper limit for a particular resource in a specific namespace.") + m.data.SetUnit("1") + m.data.SetEmptyGauge() + m.data.Gauge().DataPoints().EnsureCapacity(m.capacity) +} + +func (m *metricOpenshiftAppliedclusterquotaLimit) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, k8sNamespaceNameAttributeValue string, resourceAttributeValue string) { + if !m.config.Enabled { + return + } + dp := m.data.Gauge().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntValue(val) + dp.Attributes().PutStr("k8s.namespace.name", k8sNamespaceNameAttributeValue) + dp.Attributes().PutStr("resource", resourceAttributeValue) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricOpenshiftAppliedclusterquotaLimit) updateCapacity() { + if m.data.Gauge().DataPoints().Len() > m.capacity { + m.capacity = m.data.Gauge().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricOpenshiftAppliedclusterquotaLimit) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricOpenshiftAppliedclusterquotaLimit(cfg MetricConfig) metricOpenshiftAppliedclusterquotaLimit { + m := metricOpenshiftAppliedclusterquotaLimit{config: cfg} + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricOpenshiftAppliedclusterquotaUsed struct { + data pmetric.Metric // data buffer for generated metric. + config MetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills openshift.appliedclusterquota.used metric with initial data. +func (m *metricOpenshiftAppliedclusterquotaUsed) init() { + m.data.SetName("openshift.appliedclusterquota.used") + m.data.SetDescription("The usage for a particular resource in a specific namespace.") + m.data.SetUnit("1") + m.data.SetEmptyGauge() + m.data.Gauge().DataPoints().EnsureCapacity(m.capacity) +} + +func (m *metricOpenshiftAppliedclusterquotaUsed) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, k8sNamespaceNameAttributeValue string, resourceAttributeValue string) { + if !m.config.Enabled { + return + } + dp := m.data.Gauge().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntValue(val) + dp.Attributes().PutStr("k8s.namespace.name", k8sNamespaceNameAttributeValue) + dp.Attributes().PutStr("resource", resourceAttributeValue) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricOpenshiftAppliedclusterquotaUsed) updateCapacity() { + if m.data.Gauge().DataPoints().Len() > m.capacity { + m.capacity = m.data.Gauge().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricOpenshiftAppliedclusterquotaUsed) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricOpenshiftAppliedclusterquotaUsed(cfg MetricConfig) metricOpenshiftAppliedclusterquotaUsed { + m := metricOpenshiftAppliedclusterquotaUsed{config: cfg} + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricOpenshiftClusterquotaLimit struct { + data pmetric.Metric // data buffer for generated metric. + config MetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills openshift.clusterquota.limit metric with initial data. +func (m *metricOpenshiftClusterquotaLimit) init() { + m.data.SetName("openshift.clusterquota.limit") + m.data.SetDescription("The configured upper limit for a particular resource.") + m.data.SetUnit("1") + m.data.SetEmptyGauge() + m.data.Gauge().DataPoints().EnsureCapacity(m.capacity) +} + +func (m *metricOpenshiftClusterquotaLimit) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, resourceAttributeValue string) { + if !m.config.Enabled { + return + } + dp := m.data.Gauge().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntValue(val) + dp.Attributes().PutStr("resource", resourceAttributeValue) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricOpenshiftClusterquotaLimit) updateCapacity() { + if m.data.Gauge().DataPoints().Len() > m.capacity { + m.capacity = m.data.Gauge().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricOpenshiftClusterquotaLimit) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricOpenshiftClusterquotaLimit(cfg MetricConfig) metricOpenshiftClusterquotaLimit { + m := metricOpenshiftClusterquotaLimit{config: cfg} + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricOpenshiftClusterquotaUsed struct { + data pmetric.Metric // data buffer for generated metric. + config MetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills openshift.clusterquota.used metric with initial data. +func (m *metricOpenshiftClusterquotaUsed) init() { + m.data.SetName("openshift.clusterquota.used") + m.data.SetDescription("The usage for a particular resource with a configured limit.") + m.data.SetUnit("1") + m.data.SetEmptyGauge() + m.data.Gauge().DataPoints().EnsureCapacity(m.capacity) +} + +func (m *metricOpenshiftClusterquotaUsed) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, resourceAttributeValue string) { + if !m.config.Enabled { + return + } + dp := m.data.Gauge().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntValue(val) + dp.Attributes().PutStr("resource", resourceAttributeValue) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricOpenshiftClusterquotaUsed) updateCapacity() { + if m.data.Gauge().DataPoints().Len() > m.capacity { + m.capacity = m.data.Gauge().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricOpenshiftClusterquotaUsed) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricOpenshiftClusterquotaUsed(cfg MetricConfig) metricOpenshiftClusterquotaUsed { + m := metricOpenshiftClusterquotaUsed{config: cfg} + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +// MetricsBuilder provides an interface for scrapers to report metrics while taking care of all the transformations +// required to produce metric representation defined in metadata and user config. +type MetricsBuilder struct { + startTime pcommon.Timestamp // start time that will be applied to all recorded data points. + metricsCapacity int // maximum observed number of metrics per resource. + resourceCapacity int // maximum observed number of resource attributes. + metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. + buildInfo component.BuildInfo // contains version information + resourceAttributesConfig ResourceAttributesConfig + metricOpenshiftAppliedclusterquotaLimit metricOpenshiftAppliedclusterquotaLimit + metricOpenshiftAppliedclusterquotaUsed metricOpenshiftAppliedclusterquotaUsed + metricOpenshiftClusterquotaLimit metricOpenshiftClusterquotaLimit + metricOpenshiftClusterquotaUsed metricOpenshiftClusterquotaUsed +} + +// metricBuilderOption applies changes to default metrics builder. +type metricBuilderOption func(*MetricsBuilder) + +// WithStartTime sets startTime on the metrics builder. +func WithStartTime(startTime pcommon.Timestamp) metricBuilderOption { + return func(mb *MetricsBuilder) { + mb.startTime = startTime + } +} + +func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSettings, options ...metricBuilderOption) *MetricsBuilder { + mb := &MetricsBuilder{ + startTime: pcommon.NewTimestampFromTime(time.Now()), + metricsBuffer: pmetric.NewMetrics(), + buildInfo: settings.BuildInfo, + resourceAttributesConfig: mbc.ResourceAttributes, + metricOpenshiftAppliedclusterquotaLimit: newMetricOpenshiftAppliedclusterquotaLimit(mbc.Metrics.OpenshiftAppliedclusterquotaLimit), + metricOpenshiftAppliedclusterquotaUsed: newMetricOpenshiftAppliedclusterquotaUsed(mbc.Metrics.OpenshiftAppliedclusterquotaUsed), + metricOpenshiftClusterquotaLimit: newMetricOpenshiftClusterquotaLimit(mbc.Metrics.OpenshiftClusterquotaLimit), + metricOpenshiftClusterquotaUsed: newMetricOpenshiftClusterquotaUsed(mbc.Metrics.OpenshiftClusterquotaUsed), + } + for _, op := range options { + op(mb) + } + return mb +} + +// updateCapacity updates max length of metrics and resource attributes that will be used for the slice capacity. +func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { + if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { + mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() + } + if mb.resourceCapacity < rm.Resource().Attributes().Len() { + mb.resourceCapacity = rm.Resource().Attributes().Len() + } +} + +// ResourceMetricsOption applies changes to provided resource metrics. +type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) + +// WithOpencensusResourcetype sets provided value as "opencensus.resourcetype" attribute for current resource. +func WithOpencensusResourcetype(val string) ResourceMetricsOption { + return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + if rac.OpencensusResourcetype.Enabled { + rm.Resource().Attributes().PutStr("opencensus.resourcetype", val) + } + } +} + +// WithOpenshiftClusterquotaName sets provided value as "openshift.clusterquota.name" attribute for current resource. +func WithOpenshiftClusterquotaName(val string) ResourceMetricsOption { + return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + if rac.OpenshiftClusterquotaName.Enabled { + rm.Resource().Attributes().PutStr("openshift.clusterquota.name", val) + } + } +} + +// WithOpenshiftClusterquotaUID sets provided value as "openshift.clusterquota.uid" attribute for current resource. +func WithOpenshiftClusterquotaUID(val string) ResourceMetricsOption { + return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + if rac.OpenshiftClusterquotaUID.Enabled { + rm.Resource().Attributes().PutStr("openshift.clusterquota.uid", val) + } + } +} + +// WithStartTimeOverride overrides start time for all the resource metrics data points. +// This option should be only used if different start time has to be set on metrics coming from different resources. +func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { + return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + var dps pmetric.NumberDataPointSlice + metrics := rm.ScopeMetrics().At(0).Metrics() + for i := 0; i < metrics.Len(); i++ { + switch metrics.At(i).Type() { + case pmetric.MetricTypeGauge: + dps = metrics.At(i).Gauge().DataPoints() + case pmetric.MetricTypeSum: + dps = metrics.At(i).Sum().DataPoints() + } + for j := 0; j < dps.Len(); j++ { + dps.At(j).SetStartTimestamp(start) + } + } + } +} + +// EmitForResource saves all the generated metrics under a new resource and updates the internal state to be ready for +// recording another set of data points as part of another resource. This function can be helpful when one scraper +// needs to emit metrics from several resources. Otherwise calling this function is not required, +// just `Emit` function can be called instead. +// Resource attributes should be provided as ResourceMetricsOption arguments. +func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { + rm := pmetric.NewResourceMetrics() + rm.SetSchemaUrl(conventions.SchemaURL) + rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) + ils := rm.ScopeMetrics().AppendEmpty() + ils.Scope().SetName("otelcol/k8sclusterreceiver") + ils.Scope().SetVersion(mb.buildInfo.Version) + ils.Metrics().EnsureCapacity(mb.metricsCapacity) + mb.metricOpenshiftAppliedclusterquotaLimit.emit(ils.Metrics()) + mb.metricOpenshiftAppliedclusterquotaUsed.emit(ils.Metrics()) + mb.metricOpenshiftClusterquotaLimit.emit(ils.Metrics()) + mb.metricOpenshiftClusterquotaUsed.emit(ils.Metrics()) + + for _, op := range rmo { + op(mb.resourceAttributesConfig, rm) + } + if ils.Metrics().Len() > 0 { + mb.updateCapacity(rm) + rm.MoveTo(mb.metricsBuffer.ResourceMetrics().AppendEmpty()) + } +} + +// Emit returns all the metrics accumulated by the metrics builder and updates the internal state to be ready for +// recording another set of metrics. This function will be responsible for applying all the transformations required to +// produce metric representation defined in metadata and user config, e.g. delta or cumulative. +func (mb *MetricsBuilder) Emit(rmo ...ResourceMetricsOption) pmetric.Metrics { + mb.EmitForResource(rmo...) + metrics := mb.metricsBuffer + mb.metricsBuffer = pmetric.NewMetrics() + return metrics +} + +// RecordOpenshiftAppliedclusterquotaLimitDataPoint adds a data point to openshift.appliedclusterquota.limit metric. +func (mb *MetricsBuilder) RecordOpenshiftAppliedclusterquotaLimitDataPoint(ts pcommon.Timestamp, val int64, k8sNamespaceNameAttributeValue string, resourceAttributeValue string) { + mb.metricOpenshiftAppliedclusterquotaLimit.recordDataPoint(mb.startTime, ts, val, k8sNamespaceNameAttributeValue, resourceAttributeValue) +} + +// RecordOpenshiftAppliedclusterquotaUsedDataPoint adds a data point to openshift.appliedclusterquota.used metric. +func (mb *MetricsBuilder) RecordOpenshiftAppliedclusterquotaUsedDataPoint(ts pcommon.Timestamp, val int64, k8sNamespaceNameAttributeValue string, resourceAttributeValue string) { + mb.metricOpenshiftAppliedclusterquotaUsed.recordDataPoint(mb.startTime, ts, val, k8sNamespaceNameAttributeValue, resourceAttributeValue) +} + +// RecordOpenshiftClusterquotaLimitDataPoint adds a data point to openshift.clusterquota.limit metric. +func (mb *MetricsBuilder) RecordOpenshiftClusterquotaLimitDataPoint(ts pcommon.Timestamp, val int64, resourceAttributeValue string) { + mb.metricOpenshiftClusterquotaLimit.recordDataPoint(mb.startTime, ts, val, resourceAttributeValue) +} + +// RecordOpenshiftClusterquotaUsedDataPoint adds a data point to openshift.clusterquota.used metric. +func (mb *MetricsBuilder) RecordOpenshiftClusterquotaUsedDataPoint(ts pcommon.Timestamp, val int64, resourceAttributeValue string) { + mb.metricOpenshiftClusterquotaUsed.recordDataPoint(mb.startTime, ts, val, resourceAttributeValue) +} + +// Reset resets metrics builder to its initial state. It should be used when external metrics source is restarted, +// and metrics builder should update its startTime and reset it's internal state accordingly. +func (mb *MetricsBuilder) Reset(options ...metricBuilderOption) { + mb.startTime = pcommon.NewTimestampFromTime(time.Now()) + for _, op := range options { + op(mb) + } +} diff --git a/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_metrics_test.go b/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_metrics_test.go new file mode 100644 index 000000000000..88afbd526cc3 --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_metrics_test.go @@ -0,0 +1,189 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "go.opentelemetry.io/collector/pdata/pcommon" + "go.opentelemetry.io/collector/pdata/pmetric" + "go.opentelemetry.io/collector/receiver/receivertest" + "go.uber.org/zap" + "go.uber.org/zap/zaptest/observer" +) + +type testConfigCollection int + +const ( + testSetDefault testConfigCollection = iota + testSetAll + testSetNone +) + +func TestMetricsBuilder(t *testing.T) { + tests := []struct { + name string + configSet testConfigCollection + }{ + { + name: "default", + configSet: testSetDefault, + }, + { + name: "all_set", + configSet: testSetAll, + }, + { + name: "none_set", + configSet: testSetNone, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + start := pcommon.Timestamp(1_000_000_000) + ts := pcommon.Timestamp(1_000_001_000) + observedZapCore, observedLogs := observer.New(zap.WarnLevel) + settings := receivertest.NewNopCreateSettings() + settings.Logger = zap.New(observedZapCore) + mb := NewMetricsBuilder(loadMetricsBuilderConfig(t, test.name), settings, WithStartTime(start)) + + expectedWarnings := 0 + assert.Equal(t, expectedWarnings, observedLogs.Len()) + + defaultMetricsCount := 0 + allMetricsCount := 0 + + defaultMetricsCount++ + allMetricsCount++ + mb.RecordOpenshiftAppliedclusterquotaLimitDataPoint(ts, 1, "k8s.namespace.name-val", "resource-val") + + defaultMetricsCount++ + allMetricsCount++ + mb.RecordOpenshiftAppliedclusterquotaUsedDataPoint(ts, 1, "k8s.namespace.name-val", "resource-val") + + defaultMetricsCount++ + allMetricsCount++ + mb.RecordOpenshiftClusterquotaLimitDataPoint(ts, 1, "resource-val") + + defaultMetricsCount++ + allMetricsCount++ + mb.RecordOpenshiftClusterquotaUsedDataPoint(ts, 1, "resource-val") + + metrics := mb.Emit(WithOpencensusResourcetype("opencensus.resourcetype-val"), WithOpenshiftClusterquotaName("openshift.clusterquota.name-val"), WithOpenshiftClusterquotaUID("openshift.clusterquota.uid-val")) + + if test.configSet == testSetNone { + assert.Equal(t, 0, metrics.ResourceMetrics().Len()) + return + } + + assert.Equal(t, 1, metrics.ResourceMetrics().Len()) + rm := metrics.ResourceMetrics().At(0) + attrCount := 0 + enabledAttrCount := 0 + attrVal, ok := rm.Resource().Attributes().Get("opencensus.resourcetype") + attrCount++ + assert.Equal(t, mb.resourceAttributesConfig.OpencensusResourcetype.Enabled, ok) + if mb.resourceAttributesConfig.OpencensusResourcetype.Enabled { + enabledAttrCount++ + assert.EqualValues(t, "opencensus.resourcetype-val", attrVal.Str()) + } + attrVal, ok = rm.Resource().Attributes().Get("openshift.clusterquota.name") + attrCount++ + assert.Equal(t, mb.resourceAttributesConfig.OpenshiftClusterquotaName.Enabled, ok) + if mb.resourceAttributesConfig.OpenshiftClusterquotaName.Enabled { + enabledAttrCount++ + assert.EqualValues(t, "openshift.clusterquota.name-val", attrVal.Str()) + } + attrVal, ok = rm.Resource().Attributes().Get("openshift.clusterquota.uid") + attrCount++ + assert.Equal(t, mb.resourceAttributesConfig.OpenshiftClusterquotaUID.Enabled, ok) + if mb.resourceAttributesConfig.OpenshiftClusterquotaUID.Enabled { + enabledAttrCount++ + assert.EqualValues(t, "openshift.clusterquota.uid-val", attrVal.Str()) + } + assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) + assert.Equal(t, attrCount, 3) + + assert.Equal(t, 1, rm.ScopeMetrics().Len()) + ms := rm.ScopeMetrics().At(0).Metrics() + if test.configSet == testSetDefault { + assert.Equal(t, defaultMetricsCount, ms.Len()) + } + if test.configSet == testSetAll { + assert.Equal(t, allMetricsCount, ms.Len()) + } + validatedMetrics := make(map[string]bool) + for i := 0; i < ms.Len(); i++ { + switch ms.At(i).Name() { + case "openshift.appliedclusterquota.limit": + assert.False(t, validatedMetrics["openshift.appliedclusterquota.limit"], "Found a duplicate in the metrics slice: openshift.appliedclusterquota.limit") + validatedMetrics["openshift.appliedclusterquota.limit"] = true + assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) + assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) + assert.Equal(t, "The upper limit for a particular resource in a specific namespace.", ms.At(i).Description()) + assert.Equal(t, "1", ms.At(i).Unit()) + dp := ms.At(i).Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + assert.Equal(t, int64(1), dp.IntValue()) + attrVal, ok := dp.Attributes().Get("k8s.namespace.name") + assert.True(t, ok) + assert.EqualValues(t, "k8s.namespace.name-val", attrVal.Str()) + attrVal, ok = dp.Attributes().Get("resource") + assert.True(t, ok) + assert.EqualValues(t, "resource-val", attrVal.Str()) + case "openshift.appliedclusterquota.used": + assert.False(t, validatedMetrics["openshift.appliedclusterquota.used"], "Found a duplicate in the metrics slice: openshift.appliedclusterquota.used") + validatedMetrics["openshift.appliedclusterquota.used"] = true + assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) + assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) + assert.Equal(t, "The usage for a particular resource in a specific namespace.", ms.At(i).Description()) + assert.Equal(t, "1", ms.At(i).Unit()) + dp := ms.At(i).Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + assert.Equal(t, int64(1), dp.IntValue()) + attrVal, ok := dp.Attributes().Get("k8s.namespace.name") + assert.True(t, ok) + assert.EqualValues(t, "k8s.namespace.name-val", attrVal.Str()) + attrVal, ok = dp.Attributes().Get("resource") + assert.True(t, ok) + assert.EqualValues(t, "resource-val", attrVal.Str()) + case "openshift.clusterquota.limit": + assert.False(t, validatedMetrics["openshift.clusterquota.limit"], "Found a duplicate in the metrics slice: openshift.clusterquota.limit") + validatedMetrics["openshift.clusterquota.limit"] = true + assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) + assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) + assert.Equal(t, "The configured upper limit for a particular resource.", ms.At(i).Description()) + assert.Equal(t, "1", ms.At(i).Unit()) + dp := ms.At(i).Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + assert.Equal(t, int64(1), dp.IntValue()) + attrVal, ok := dp.Attributes().Get("resource") + assert.True(t, ok) + assert.EqualValues(t, "resource-val", attrVal.Str()) + case "openshift.clusterquota.used": + assert.False(t, validatedMetrics["openshift.clusterquota.used"], "Found a duplicate in the metrics slice: openshift.clusterquota.used") + validatedMetrics["openshift.clusterquota.used"] = true + assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) + assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) + assert.Equal(t, "The usage for a particular resource with a configured limit.", ms.At(i).Description()) + assert.Equal(t, "1", ms.At(i).Unit()) + dp := ms.At(i).Gauge().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + assert.Equal(t, int64(1), dp.IntValue()) + attrVal, ok := dp.Attributes().Get("resource") + assert.True(t, ok) + assert.EqualValues(t, "resource-val", attrVal.Str()) + } + } + }) + } +} diff --git a/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/testdata/config.yaml b/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/testdata/config.yaml new file mode 100644 index 000000000000..385232b2f6a2 --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/testdata/config.yaml @@ -0,0 +1,35 @@ +default: +all_set: + metrics: + openshift.appliedclusterquota.limit: + enabled: true + openshift.appliedclusterquota.used: + enabled: true + openshift.clusterquota.limit: + enabled: true + openshift.clusterquota.used: + enabled: true + resource_attributes: + opencensus.resourcetype: + enabled: true + openshift.clusterquota.name: + enabled: true + openshift.clusterquota.uid: + enabled: true +none_set: + metrics: + openshift.appliedclusterquota.limit: + enabled: false + openshift.appliedclusterquota.used: + enabled: false + openshift.clusterquota.limit: + enabled: false + openshift.clusterquota.used: + enabled: false + resource_attributes: + opencensus.resourcetype: + enabled: false + openshift.clusterquota.name: + enabled: false + openshift.clusterquota.uid: + enabled: false diff --git a/receiver/k8sclusterreceiver/internal/clusterresourcequota/metadata.yaml b/receiver/k8sclusterreceiver/internal/clusterresourcequota/metadata.yaml new file mode 100644 index 000000000000..10cd59e40044 --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/clusterresourcequota/metadata.yaml @@ -0,0 +1,67 @@ +type: k8s/clusterresourcequota + +sem_conv_version: 1.18.0 + +parent: k8s_cluster + +resource_attributes: + openshift.clusterquota.uid: + description: The k8s ClusterResourceQuota uid. + type: string + enabled: true + + openshift.clusterquota.name: + description: The k8s ClusterResourceQuota name. + type: string + enabled: true + + opencensus.resourcetype: + description: The OpenCensus resource type. + type: string + enabled: true + +attributes: + k8s.namespace.name: + description: The k8s namespace name. + type: string + enabled: true + resource: + description: The name of the resource on which the cluster quota is applied + type: string + enabled: true + +metrics: + openshift.clusterquota.limit: + enabled: true + description: The configured upper limit for a particular resource. + unit: "1" + gauge: + value_type: int + attributes: + - resource + openshift.clusterquota.used: + enabled: true + description: The usage for a particular resource with a configured limit. + unit: "1" + gauge: + value_type: int + attributes: + - resource + openshift.appliedclusterquota.limit: + enabled: true + description: The upper limit for a particular resource in a specific namespace. + unit: "1" + gauge: + value_type: int + attributes: + - k8s.namespace.name + - resource + openshift.appliedclusterquota.used: + enabled: true + description: The usage for a particular resource in a specific namespace. + unit: "1" + gauge: + value_type: int + attributes: + - k8s.namespace.name + - resource diff --git a/receiver/k8sclusterreceiver/internal/clusterresourcequota/testdata/expected.yaml b/receiver/k8sclusterreceiver/internal/clusterresourcequota/testdata/expected.yaml new file mode 100644 index 000000000000..1fdcd0580e33 --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/clusterresourcequota/testdata/expected.yaml @@ -0,0 +1,81 @@ +resourceMetrics: + - resource: + attributes: + - key: openshift.clusterquota.name + value: + stringValue: test-clusterquota-1 + - key: openshift.clusterquota.uid + value: + stringValue: test-clusterquota-1-uid + - key: opencensus.resourcetype + value: + stringValue: k8s + schemaUrl: https://opentelemetry.io/schemas/1.18.0 + scopeMetrics: + - metrics: + - description: The configured upper limit for a particular resource. + gauge: + dataPoints: + - asInt: "10000" + attributes: + - key: resource + value: + stringValue: requests.cpu + name: openshift.clusterquota.limit + unit: "1" + - description: The usage for a particular resource with a configured limit. + gauge: + dataPoints: + - asInt: "6000" + attributes: + - key: resource + value: + stringValue: requests.cpu + name: openshift.clusterquota.used + unit: "1" + - description: The upper limit for a particular resource in a specific namespace. + gauge: + dataPoints: + - asInt: "6000" + attributes: + - key: resource + value: + stringValue: requests.cpu + - key: k8s.namespace.name + value: + stringValue: "ns1" + - asInt: "4000" + attributes: + - key: resource + value: + stringValue: requests.cpu + - key: k8s.namespace.name + value: + stringValue: "ns2" + name: openshift.appliedclusterquota.limit + unit: "1" + - description: The usage for a particular resource in a specific namespace. + gauge: + dataPoints: + - asInt: "1000" + attributes: + - key: resource + value: + stringValue: requests.cpu + - key: k8s.namespace.name + value: + stringValue: "ns1" + - asInt: "5000" + attributes: + - key: resource + value: + stringValue: requests.cpu + - key: + k8s.namespace.name + value: + stringValue: "ns2" + name: openshift.appliedclusterquota.used + unit: "1" + scope: + name: otelcol/k8sclusterreceiver + version: latest \ No newline at end of file diff --git a/receiver/k8sclusterreceiver/internal/collection/collector.go b/receiver/k8sclusterreceiver/internal/collection/collector.go index 430c75a95705..41b50edc24b8 100644 --- a/receiver/k8sclusterreceiver/internal/collection/collector.go +++ b/receiver/k8sclusterreceiver/internal/collection/collector.go @@ -132,7 +132,7 @@ func (dc *DataCollector) SyncMetrics(obj interface{}) { case *autoscalingv2beta2.HorizontalPodAutoscaler: md = hpa.GetMetricsBeta(dc.settings, o) case *quotav1.ClusterResourceQuota: - md = ocsToMetrics(clusterresourcequota.GetMetrics(o)) + md = clusterresourcequota.GetMetrics(dc.settings, o) default: return } diff --git a/receiver/k8sclusterreceiver/internal/testutils/objects.go b/receiver/k8sclusterreceiver/internal/testutils/objects.go index 17c33651a48f..f8f67d8a0eda 100644 --- a/receiver/k8sclusterreceiver/internal/testutils/objects.go +++ b/receiver/k8sclusterreceiver/internal/testutils/objects.go @@ -4,6 +4,7 @@ package testutils // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/testutils" import ( + quotav1 "github.com/openshift/api/quota/v1" appsv1 "k8s.io/api/apps/v1" autoscalingv2 "k8s.io/api/autoscaling/v2" autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2" @@ -77,6 +78,50 @@ func NewJob(id string) *batchv1.Job { } } +func NewClusterResourceQuota(id string) *quotav1.ClusterResourceQuota { + return "av1.ClusterResourceQuota{ + ObjectMeta: v1.ObjectMeta{ + Name: "test-clusterquota-" + id, + Namespace: "test-namespace", + UID: types.UID("test-clusterquota-" + id + "-uid"), + }, + Status: quotav1.ClusterResourceQuotaStatus{ + Total: corev1.ResourceQuotaStatus{ + Hard: corev1.ResourceList{ + "requests.cpu": *resource.NewQuantity(10, resource.DecimalSI), + }, + Used: corev1.ResourceList{ + "requests.cpu": *resource.NewQuantity(6, resource.DecimalSI), + }, + }, + Namespaces: quotav1.ResourceQuotasStatusByNamespace{ + { + Namespace: "ns1", + Status: corev1.ResourceQuotaStatus{ + Hard: corev1.ResourceList{ + "requests.cpu": *resource.NewQuantity(6, resource.DecimalSI), + }, + Used: corev1.ResourceList{ + "requests.cpu": *resource.NewQuantity(1, resource.DecimalSI), + }, + }, + }, + { + Namespace: "ns2", + Status: corev1.ResourceQuotaStatus{ + Hard: corev1.ResourceList{ + "requests.cpu": *resource.NewQuantity(4, resource.DecimalSI), + }, + Used: corev1.ResourceList{ + "requests.cpu": *resource.NewQuantity(5, resource.DecimalSI), + }, + }, + }, + }, + }, + } +} + func NewDaemonset(id string) *appsv1.DaemonSet { return &appsv1.DaemonSet{ ObjectMeta: v1.ObjectMeta{ From 24bcaede225657445ee2ccb567f0cd85ade21acc Mon Sep 17 00:00:00 2001 From: Curtis Robert <92119472+crobert-1@users.noreply.github.com> Date: Mon, 24 Jul 2023 15:15:53 -0700 Subject: [PATCH 26/42] [chore] [receiver/k8scluster] Remove dead code (#24535) As a result of the effort to move metrics in the k8s cluster receiver to use the pdata format instead of OpenCensus, some helper methods are now unused. This change removes unused code. --- .../internal/testutils/metrics.go | 89 ------------------- .../internal/utils/timeseries.go | 28 ------ .../internal/utils/timeseries_test.go | 28 ------ 3 files changed, 145 deletions(-) delete mode 100644 receiver/k8sclusterreceiver/internal/utils/timeseries.go delete mode 100644 receiver/k8sclusterreceiver/internal/utils/timeseries_test.go diff --git a/receiver/k8sclusterreceiver/internal/testutils/metrics.go b/receiver/k8sclusterreceiver/internal/testutils/metrics.go index c2b8fab56ba8..669122ae17fb 100644 --- a/receiver/k8sclusterreceiver/internal/testutils/metrics.go +++ b/receiver/k8sclusterreceiver/internal/testutils/metrics.go @@ -6,27 +6,10 @@ package testutils // import "github.com/open-telemetry/opentelemetry-collector-c import ( "testing" - metricspb "github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1" - resourcepb "github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1" "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/pdata/pmetric" ) -func AssertResource(t *testing.T, actualResource *resourcepb.Resource, - expectedType string, expectedLabels map[string]string) { - require.Equal(t, - expectedType, - actualResource.Type, - "mismatching resource types", - ) - - require.Equal(t, - expectedLabels, - actualResource.Labels, - "mismatching resource labels", - ) -} - func AssertMetricInt(t testing.TB, m pmetric.Metric, expectedMetric string, expectedType pmetric.MetricType, expectedValue any) { dps := assertMetric(t, m, expectedMetric, expectedType) require.EqualValues(t, expectedValue, dps.At(0).IntValue(), "mismatching metric values") @@ -54,75 +37,3 @@ func assertMetric(t testing.TB, m pmetric.Metric, expectedMetric string, expecte require.Equal(t, 1, dps.Len()) return dps } - -func AssertMetricsWithLabels(t *testing.T, actualMetric *metricspb.Metric, - expectedMetric string, expectedType metricspb.MetricDescriptor_Type, - expectedLabels map[string]string, expectedValue int64) { - - require.Equal(t, - len(expectedLabels), - len(actualMetric.MetricDescriptor.LabelKeys), - "mismatching number of labels", - ) - - require.Equal(t, - expectedLabels, - getLabelsMap(actualMetric), - "mismatching labels", - ) - - AssertMetricsInt(t, actualMetric, expectedMetric, expectedType, expectedValue) -} - -func AssertMetricsInt(t *testing.T, actualMetric *metricspb.Metric, expectedMetric string, - expectedType metricspb.MetricDescriptor_Type, expectedValue int64) { - assertMetricsBase(t, actualMetric, expectedMetric, expectedType) - - require.Equal(t, - expectedValue, - actualMetric.Timeseries[0].Points[0].GetInt64Value(), - "mismatching metric values", - ) -} - -func AssertMetricsDouble(t *testing.T, actualMetric *metricspb.Metric, expectedMetric string, - expectedType metricspb.MetricDescriptor_Type, expectedValue float64) { - assertMetricsBase(t, actualMetric, expectedMetric, expectedType) - - require.Equal(t, - expectedValue, - actualMetric.Timeseries[0].Points[0].GetDoubleValue(), - "mismatching metric values", - ) -} - -func assertMetricsBase(t *testing.T, actualMetric *metricspb.Metric, expectedMetric string, - expectedType metricspb.MetricDescriptor_Type) { - - require.Equal(t, - expectedMetric, - actualMetric.MetricDescriptor.Name, - "mismatching metric names", - ) - - require.NotEmpty(t, - actualMetric.MetricDescriptor.Description, - "empty description on metric", - ) - - require.Equal(t, - expectedType, - actualMetric.MetricDescriptor.Type, - "mismatching metric types", - ) -} - -// getLabelsMap returns a map of labels. -func getLabelsMap(m *metricspb.Metric) map[string]string { - out := map[string]string{} - for i, k := range m.MetricDescriptor.LabelKeys { - out[k.Key] = m.Timeseries[0].LabelValues[i].Value - } - - return out -} diff --git a/receiver/k8sclusterreceiver/internal/utils/timeseries.go b/receiver/k8sclusterreceiver/internal/utils/timeseries.go deleted file mode 100644 index dd9bc08b312d..000000000000 --- a/receiver/k8sclusterreceiver/internal/utils/timeseries.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package utils // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/utils" - -import v1 "github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1" - -func GetInt64TimeSeries(val int64) *v1.TimeSeries { - return GetInt64TimeSeriesWithLabels(val, nil) -} - -func GetInt64TimeSeriesWithLabels(val int64, labelVals []*v1.LabelValue) *v1.TimeSeries { - return &v1.TimeSeries{ - LabelValues: labelVals, - Points: []*v1.Point{{Value: &v1.Point_Int64Value{Int64Value: val}}}, - } -} - -func GetDoubleTimeSeries(val float64) *v1.TimeSeries { - return GetDoubleTimeSeriesWithLabels(val, nil) -} - -func GetDoubleTimeSeriesWithLabels(val float64, labelVals []*v1.LabelValue) *v1.TimeSeries { - return &v1.TimeSeries{ - LabelValues: labelVals, - Points: []*v1.Point{{Value: &v1.Point_DoubleValue{DoubleValue: val}}}, - } -} diff --git a/receiver/k8sclusterreceiver/internal/utils/timeseries_test.go b/receiver/k8sclusterreceiver/internal/utils/timeseries_test.go deleted file mode 100644 index b5d9b26a14af..000000000000 --- a/receiver/k8sclusterreceiver/internal/utils/timeseries_test.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package utils - -import ( - "testing" - - v1 "github.com/census-instrumentation/opencensus-proto/gen-go/metrics/v1" - "github.com/stretchr/testify/require" -) - -func TestGetInt64TimeSeries(t *testing.T) { - dpVal := int64(10) - ts := GetInt64TimeSeries(dpVal) - - require.Equal(t, dpVal, ts.Points[0].GetInt64Value()) -} - -func TestGetInt64TimeSeriesWithLabels(t *testing.T) { - dpVal := int64(10) - labelVals := []*v1.LabelValue{{Value: "value1"}, {Value: "value2"}} - - ts := GetInt64TimeSeriesWithLabels(dpVal, labelVals) - - require.Equal(t, dpVal, ts.Points[0].GetInt64Value()) - require.Equal(t, labelVals, ts.LabelValues) -} From 3f3817c6b520e29e8ba889a7c65347ced1f43072 Mon Sep 17 00:00:00 2001 From: Antoine Toulme Date: Mon, 24 Jul 2023 15:47:30 -0700 Subject: [PATCH 27/42] [chore] update codeowners to match the CODEOWNERS file (#24454) **Description:** Follow up of #24404, some changes occurred in the last week or I had misses in translating the CODEOWNERS file over. Those minute changes fix that and prepare for the script to generate `.github/CODEOWNERS`. --- connector/exceptionsconnector/README.md | 1 + connector/exceptionsconnector/metadata.yaml | 2 ++ examples/demo/metadata.yaml | 5 +++++ exporter/datasetexporter/README.md | 2 +- exporter/datasetexporter/metadata.yaml | 2 +- exporter/opensearchexporter/metadata.yaml | 6 ++++++ internal/tools/metadata.yaml | 2 +- 7 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 examples/demo/metadata.yaml create mode 100644 exporter/opensearchexporter/metadata.yaml diff --git a/connector/exceptionsconnector/README.md b/connector/exceptionsconnector/README.md index e2199e46d89f..acb907ed2d43 100644 --- a/connector/exceptionsconnector/README.md +++ b/connector/exceptionsconnector/README.md @@ -5,6 +5,7 @@ | ------------- |-----------| | Distributions | [contrib] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aconnector%2Fexceptions%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aconnector%2Fexceptions%20&label=closed&color=blue&logo=opentelemetry) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jpkrohling](https://www.github.com/jpkrohling) | [development]: https://github.com/open-telemetry/opentelemetry-collector#development [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/connector/exceptionsconnector/metadata.yaml b/connector/exceptionsconnector/metadata.yaml index d9e66a50c76b..5bf4696c041c 100644 --- a/connector/exceptionsconnector/metadata.yaml +++ b/connector/exceptionsconnector/metadata.yaml @@ -5,3 +5,5 @@ status: stability: development: [traces_to_metrics, traces_to_logs] distributions: [contrib] + codeowners: + active: [jpkrohling] diff --git a/examples/demo/metadata.yaml b/examples/demo/metadata.yaml new file mode 100644 index 000000000000..e6ca6dbe7c29 --- /dev/null +++ b/examples/demo/metadata.yaml @@ -0,0 +1,5 @@ +type: demo + +status: + codeowners: + active: [open-telemetry/collector-approvers] \ No newline at end of file diff --git a/exporter/datasetexporter/README.md b/exporter/datasetexporter/README.md index 56d016afc6b1..5e6492fd08db 100644 --- a/exporter/datasetexporter/README.md +++ b/exporter/datasetexporter/README.md @@ -6,7 +6,7 @@ | Stability | [alpha]: logs, traces | | Distributions | [contrib] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Fdataset%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Fdataset%20&label=closed&color=blue&logo=opentelemetry) | -| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@atoulme](https://www.github.com/atoulme), [@martin-majlis-s1](https://www.github.com/martin-majlis-s1), [@zdaratom](https://www.github.com/zdaratom) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@atoulme](https://www.github.com/atoulme), [@martin-majlis-s1](https://www.github.com/martin-majlis-s1), [@zdaratom](https://www.github.com/zdaratom), [@tomaz-s1](https://www.github.com/tomaz-s1) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/datasetexporter/metadata.yaml b/exporter/datasetexporter/metadata.yaml index c31c873cc5cf..98819460e5cc 100644 --- a/exporter/datasetexporter/metadata.yaml +++ b/exporter/datasetexporter/metadata.yaml @@ -6,4 +6,4 @@ status: alpha: [logs, traces] distributions: [contrib] codeowners: - active: [atoulme, martin-majlis-s1, zdaratom] + active: [atoulme, martin-majlis-s1, zdaratom, tomaz-s1] diff --git a/exporter/opensearchexporter/metadata.yaml b/exporter/opensearchexporter/metadata.yaml new file mode 100644 index 000000000000..3adb26673a1d --- /dev/null +++ b/exporter/opensearchexporter/metadata.yaml @@ -0,0 +1,6 @@ +type: opensearch + +status: + class: exporter + codeowners: + active: [Aneurysm9, MitchellGale, MaxKsyunz, YANG-DB] \ No newline at end of file diff --git a/internal/tools/metadata.yaml b/internal/tools/metadata.yaml index 6997dc17500d..d325553bfa7a 100644 --- a/internal/tools/metadata.yaml +++ b/internal/tools/metadata.yaml @@ -1,3 +1,3 @@ status: codeowners: - active: [Aneurysm9, mxiamxia] \ No newline at end of file + active: [] \ No newline at end of file From d71f107d6e8f84b1fad0fd54c36dab41c5afaf1a Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 25 Jul 2023 17:17:42 +0200 Subject: [PATCH 28/42] Update prom/prometheus Docker tag to v2.46.0 (#24546) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Update | Change | |---|---|---| | prom/prometheus | minor | `v2.45.0` -> `v2.46.0` | --- ### Configuration 📅 **Schedule**: Branch creation - "on tuesday" (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/open-telemetry/opentelemetry-collector-contrib). --- examples/couchbase/docker-compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/couchbase/docker-compose.yaml b/examples/couchbase/docker-compose.yaml index 76ba6e7b0abb..bce7bec64486 100644 --- a/examples/couchbase/docker-compose.yaml +++ b/examples/couchbase/docker-compose.yaml @@ -17,7 +17,7 @@ services: depends_on: - couchbase prometheus: - image: prom/prometheus:v2.45.0 + image: prom/prometheus:v2.46.0 volumes: - ./prometheus-config.yaml:/etc/prometheus/prometheus.yml ports: From 911336cad136f583155845591a0b1e8c7dbade13 Mon Sep 17 00:00:00 2001 From: Daniel Jaglowski Date: Tue, 25 Jul 2023 11:23:42 -0400 Subject: [PATCH 29/42] [chore][fileconsumer] Extract internal header package (#24264) This continues from #24036 by moving additional complexity into an internal package. Some files contain headers that are different than the rest of the file. In such cases, we may need to extract file attributes that will be applied to logs from that file. --- pkg/stanza/fileconsumer/config.go | 17 +- pkg/stanza/fileconsumer/config_test.go | 6 +- pkg/stanza/fileconsumer/file_test.go | 1 - pkg/stanza/fileconsumer/header.go | 147 -------------- pkg/stanza/fileconsumer/header_test.go | 179 ------------------ .../fileconsumer/internal/header/config.go | 84 ++++++++ .../internal/header/config_test.go | 144 ++++++++++++++ .../fileconsumer/internal/header/output.go | 56 ++++++ .../fileconsumer/internal/header/reader.go | 75 ++++++++ .../internal/header/reader_test.go | 87 +++++++++ pkg/stanza/fileconsumer/reader.go | 92 +++------ pkg/stanza/fileconsumer/reader_factory.go | 27 +-- pkg/stanza/fileconsumer/reader_test.go | 14 +- 13 files changed, 496 insertions(+), 433 deletions(-) delete mode 100644 pkg/stanza/fileconsumer/header.go delete mode 100644 pkg/stanza/fileconsumer/header_test.go create mode 100644 pkg/stanza/fileconsumer/internal/header/config.go create mode 100644 pkg/stanza/fileconsumer/internal/header/config_test.go create mode 100644 pkg/stanza/fileconsumer/internal/header/output.go create mode 100644 pkg/stanza/fileconsumer/internal/header/reader.go create mode 100644 pkg/stanza/fileconsumer/internal/header/reader_test.go diff --git a/pkg/stanza/fileconsumer/config.go b/pkg/stanza/fileconsumer/config.go index cf9ada6e6373..dc3b13b3851e 100644 --- a/pkg/stanza/fileconsumer/config.go +++ b/pkg/stanza/fileconsumer/config.go @@ -15,6 +15,8 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/fileconsumer/emit" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/fileconsumer/internal/fingerprint" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/fileconsumer/internal/header" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/helper" ) @@ -72,6 +74,11 @@ type Config struct { Header *HeaderConfig `mapstructure:"header,omitempty"` } +type HeaderConfig struct { + Pattern string `mapstructure:"pattern"` + MetadataOperators []operator.Config `mapstructure:"metadata_operators"` +} + // Build will build a file input operator from the supplied configuration func (c Config) Build(logger *zap.SugaredLogger, emit emit.Callback) (*Manager, error) { if err := c.validate(); err != nil { @@ -120,14 +127,14 @@ func (c Config) buildManager(logger *zap.SugaredLogger, emit emit.Callback, fact return nil, fmt.Errorf("invalid start_at location '%s'", c.StartAt) } - var hs *headerSettings + var hCfg *header.Config if c.Header != nil { enc, err := c.Splitter.EncodingConfig.Build() if err != nil { return nil, fmt.Errorf("failed to create encoding: %w", err) } - hs, err = c.Header.buildHeaderSettings(enc.Encoding) + hCfg, err = header.NewConfig(c.Header.Pattern, c.Header.MetadataOperators, enc.Encoding) if err != nil { return nil, fmt.Errorf("failed to build header config: %w", err) } @@ -150,7 +157,7 @@ func (c Config) buildManager(logger *zap.SugaredLogger, emit emit.Callback, fact fromBeginning: startAtBeginning, splitterFactory: factory, encodingConfig: c.Splitter.EncodingConfig, - headerSettings: hs, + headerConfig: hCfg, }, finder: c.MatchingCriteria, roller: newRoller(), @@ -226,13 +233,13 @@ func (c Config) validate() error { return errors.New("`max_batches` must not be negative") } - _, err := c.Splitter.EncodingConfig.Build() + enc, err := c.Splitter.EncodingConfig.Build() if err != nil { return err } if c.Header != nil { - if err := c.Header.validate(); err != nil { + if _, err := header.NewConfig(c.Header.Pattern, c.Header.MetadataOperators, enc.Encoding); err != nil { return fmt.Errorf("invalid config for `header`: %w", err) } } diff --git a/pkg/stanza/fileconsumer/config_test.go b/pkg/stanza/fileconsumer/config_test.go index 9ebef1861aa9..4b6b82edf752 100644 --- a/pkg/stanza/fileconsumer/config_test.go +++ b/pkg/stanza/fileconsumer/config_test.go @@ -790,10 +790,7 @@ func TestBuildWithHeader(t *testing.T) { }, require.NoError, func(t *testing.T, f *Manager) { - require.NotNil(t, f.readerFactory.headerSettings) - require.NotNil(t, f.readerFactory.headerSettings.matchRegex) - require.NotNil(t, f.readerFactory.headerSettings.splitFunc) - require.NotNil(t, f.readerFactory.headerSettings.config) + require.NotNil(t, f.readerFactory.headerConfig.SplitFunc) }, }, } @@ -810,7 +807,6 @@ func TestBuildWithHeader(t *testing.T) { if err != nil { return } - tc.validate(t, input) }) } diff --git a/pkg/stanza/fileconsumer/file_test.go b/pkg/stanza/fileconsumer/file_test.go index 235bcb7e9556..a8b608c9c3e0 100644 --- a/pkg/stanza/fileconsumer/file_test.go +++ b/pkg/stanza/fileconsumer/file_test.go @@ -1630,7 +1630,6 @@ func TestHeaderPersistanceInHeader(t *testing.T) { }) require.NoError(t, op2.Stop()) - } func TestStalePartialFingerprintDiscarded(t *testing.T) { diff --git a/pkg/stanza/fileconsumer/header.go b/pkg/stanza/fileconsumer/header.go deleted file mode 100644 index 12b640e0df8f..000000000000 --- a/pkg/stanza/fileconsumer/header.go +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package fileconsumer // import "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/fileconsumer" - -import ( - "bufio" - "bytes" - "context" - "errors" - "fmt" - "regexp" - - "go.uber.org/zap" - "golang.org/x/text/encoding" - - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/entry" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/helper" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/pipeline" -) - -const headerPipelineOutputType = "header_log_emitter" - -type HeaderConfig struct { - Pattern string `mapstructure:"pattern"` - MetadataOperators []operator.Config `mapstructure:"metadata_operators"` -} - -// validate returns an error describing why the configuration is invalid, or nil if the configuration is valid. -func (hc *HeaderConfig) validate() error { - if len(hc.MetadataOperators) == 0 { - return errors.New("at least one operator must be specified for `metadata_operators`") - } - - nopLogger := zap.NewNop().Sugar() - outOp := newHeaderPipelineOutput(nopLogger) - p, err := pipeline.Config{ - Operators: hc.MetadataOperators, - DefaultOutput: outOp, - }.Build(nopLogger) - - if err != nil { - return fmt.Errorf("failed to build pipelines: %w", err) - } - - for _, op := range p.Operators() { - // This is the default output we created, it's always valid - if op.Type() == headerPipelineOutputType { - continue - } - - if !op.CanProcess() { - return fmt.Errorf("operator '%s' in `metadata_operators` cannot process entries", op.ID()) - } - - if !op.CanOutput() { - return fmt.Errorf("operator '%s' in `metadata_operators` does not propagate entries", op.ID()) - } - - // Filter processor also may fail to propagate some entries - if op.Type() == "filter" { - return fmt.Errorf("operator of type filter is not allowed in `metadata_operators`") - } - } - - return nil -} - -func (hc *HeaderConfig) buildHeaderSettings(enc encoding.Encoding) (*headerSettings, error) { - var err error - matchRegex, err := regexp.Compile(hc.Pattern) - if err != nil { - return nil, fmt.Errorf("failed to compile `pattern`: %w", err) - } - - splitFunc, err := helper.NewNewlineSplitFunc(enc, false, func(b []byte) []byte { - return bytes.Trim(b, "\r\n") - }) - if err != nil { - return nil, fmt.Errorf("failed to create split func: %w", err) - } - - return &headerSettings{ - matchRegex: matchRegex, - splitFunc: splitFunc, - config: hc, - }, nil -} - -// headerSettings contains compiled objects defined by a HeaderConfig -type headerSettings struct { - matchRegex *regexp.Regexp - splitFunc bufio.SplitFunc - config *HeaderConfig -} - -// headerPipelineOutput is a stanza operator that emits log entries to a channel -type headerPipelineOutput struct { - helper.OutputOperator - logChan chan *entry.Entry -} - -// newHeaderPipelineOutput creates a new receiver output -func newHeaderPipelineOutput(logger *zap.SugaredLogger) *headerPipelineOutput { - return &headerPipelineOutput{ - OutputOperator: helper.OutputOperator{ - BasicOperator: helper.BasicOperator{ - OperatorID: headerPipelineOutputType, - OperatorType: headerPipelineOutputType, - SugaredLogger: logger, - }, - }, - logChan: make(chan *entry.Entry, 1), - } -} - -// Start starts the goroutine(s) required for this operator -func (e *headerPipelineOutput) Start(_ operator.Persister) error { - return nil -} - -// Stop will close the log channel and stop running goroutines -func (e *headerPipelineOutput) Stop() error { - return nil -} - -func (e *headerPipelineOutput) Process(_ context.Context, ent *entry.Entry) error { - // Drop the entry if logChan is full, in order to avoid this operator blocking. - // This protects against a case where an operator could return an error, but continue propagating a log entry, - // leaving an unexpected entry in the output channel. - select { - case e.logChan <- ent: - default: - } - - return nil -} - -func (e *headerPipelineOutput) WaitForEntry(ctx context.Context) (*entry.Entry, error) { - select { - case <-ctx.Done(): - return nil, fmt.Errorf("got context cancellation while waiting for entry: %w", ctx.Err()) - case ent := <-e.logChan: - return ent, nil - } -} diff --git a/pkg/stanza/fileconsumer/header_test.go b/pkg/stanza/fileconsumer/header_test.go deleted file mode 100644 index 945e6335059b..000000000000 --- a/pkg/stanza/fileconsumer/header_test.go +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package fileconsumer - -import ( - "testing" - - "github.com/stretchr/testify/require" - "golang.org/x/text/encoding" - - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/input/generate" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/output/stdout" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/parser/regex" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/transformer/filter" -) - -func TestHeaderConfig_validate(t *testing.T) { - regexConf := regex.NewConfig() - regexConf.Regex = "^#(?P.*)" - - invalidRegexConf := regex.NewConfig() - invalidRegexConf.Regex = "(" - - generateConf := generate.NewConfig("") - stdoutConf := stdout.NewConfig("") - filterConfg := filter.NewConfig() - filterConfg.Expression = "true" - - testCases := []struct { - name string - conf HeaderConfig - expectedErr string - }{ - { - name: "Valid config", - conf: HeaderConfig{ - Pattern: "^#", - MetadataOperators: []operator.Config{ - { - Builder: regexConf, - }, - }, - }, - }, - { - name: "Valid without specified header size", - conf: HeaderConfig{ - Pattern: "^#", - MetadataOperators: []operator.Config{ - { - Builder: regexConf, - }, - }, - }, - }, - { - name: "No operators specified", - conf: HeaderConfig{ - Pattern: "^#", - MetadataOperators: []operator.Config{}, - }, - expectedErr: "at least one operator must be specified for `metadata_operators`", - }, - { - name: "Invalid operator specified", - conf: HeaderConfig{ - Pattern: "^#", - MetadataOperators: []operator.Config{ - { - Builder: invalidRegexConf, - }, - }, - }, - expectedErr: "failed to build pipelines:", - }, - { - name: "first operator cannot process", - conf: HeaderConfig{ - Pattern: "^#", - MetadataOperators: []operator.Config{ - { - Builder: generateConf, - }, - }, - }, - expectedErr: "operator 'generate_input' in `metadata_operators` cannot process entries", - }, - { - name: "operator cannot output", - conf: HeaderConfig{ - Pattern: "^#", - MetadataOperators: []operator.Config{ - { - Builder: stdoutConf, - }, - }, - }, - expectedErr: "operator 'stdout' in `metadata_operators` does not propagate entries", - }, - { - name: "filter operator present", - conf: HeaderConfig{ - Pattern: "^#", - MetadataOperators: []operator.Config{ - { - Builder: filterConfg, - }, - }, - }, - expectedErr: "operator of type filter is not allowed in `metadata_operators`", - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - err := tc.conf.validate() - if tc.expectedErr != "" { - require.ErrorContains(t, err, tc.expectedErr) - } else { - require.NoError(t, err) - } - }) - } -} - -func TestHeaderConfig_buildHeaderSettings(t *testing.T) { - regexConf := regex.NewConfig() - regexConf.Regex = "^#(?P.*)" - - invalidRegexConf := regex.NewConfig() - invalidRegexConf.Regex = "(" - - testCases := []struct { - name string - enc encoding.Encoding - conf HeaderConfig - expectedErr string - }{ - { - name: "valid config", - enc: encoding.Nop, - conf: HeaderConfig{ - Pattern: "^#", - MetadataOperators: []operator.Config{ - { - Builder: regexConf, - }, - }, - }, - }, - { - name: "Invalid pattern", - conf: HeaderConfig{ - Pattern: "(", - MetadataOperators: []operator.Config{ - { - Builder: regexConf, - }, - }, - }, - expectedErr: "failed to compile `pattern`:", - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - h, err := tc.conf.buildHeaderSettings(tc.enc) - if tc.expectedErr != "" { - require.ErrorContains(t, err, tc.expectedErr) - } else { - require.NoError(t, err) - require.NotNil(t, h) - } - - }) - } -} diff --git a/pkg/stanza/fileconsumer/internal/header/config.go b/pkg/stanza/fileconsumer/internal/header/config.go new file mode 100644 index 000000000000..9bd329a95ec8 --- /dev/null +++ b/pkg/stanza/fileconsumer/internal/header/config.go @@ -0,0 +1,84 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package header // import "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/fileconsumer/internal/header" + +import ( + "bufio" + "bytes" + "errors" + "fmt" + "regexp" + + "go.uber.org/zap" + "golang.org/x/text/encoding" + + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/helper" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/pipeline" +) + +type Config struct { + regex *regexp.Regexp + SplitFunc bufio.SplitFunc + metadataOperators []operator.Config +} + +func NewConfig(matchRegex string, metadataOperators []operator.Config, enc encoding.Encoding) (*Config, error) { + var err error + if len(metadataOperators) == 0 { + return nil, errors.New("at least one operator must be specified for `metadata_operators`") + } + + if enc == nil { + return nil, errors.New("encoding must be specified") + } + + nopLogger := zap.NewNop().Sugar() + p, err := pipeline.Config{ + Operators: metadataOperators, + DefaultOutput: newPipelineOutput(nopLogger), + }.Build(nopLogger) + + if err != nil { + return nil, fmt.Errorf("failed to build pipelines: %w", err) + } + + for _, op := range p.Operators() { + // This is the default output we created, it's always valid + if op.Type() == pipelineOutputType { + continue + } + + if !op.CanProcess() { + return nil, fmt.Errorf("operator '%s' in `metadata_operators` cannot process entries", op.ID()) + } + + if !op.CanOutput() { + return nil, fmt.Errorf("operator '%s' in `metadata_operators` does not propagate entries", op.ID()) + } + + // Filter processor also may fail to propagate some entries + if op.Type() == "filter" { + return nil, fmt.Errorf("operator of type filter is not allowed in `metadata_operators`") + } + } + + regex, err := regexp.Compile(matchRegex) + if err != nil { + return nil, fmt.Errorf("failed to compile `pattern`: %w", err) + } + + splitFunc, err := helper.NewNewlineSplitFunc(enc, false, func(b []byte) []byte { + return bytes.Trim(b, "\r\n") + }) + if err != nil { + return nil, fmt.Errorf("failed to create split func: %w", err) + } + + return &Config{ + regex: regex, + SplitFunc: splitFunc, + metadataOperators: metadataOperators, + }, nil +} diff --git a/pkg/stanza/fileconsumer/internal/header/config_test.go b/pkg/stanza/fileconsumer/internal/header/config_test.go new file mode 100644 index 000000000000..bab02f437161 --- /dev/null +++ b/pkg/stanza/fileconsumer/internal/header/config_test.go @@ -0,0 +1,144 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package header + +import ( + "testing" + + "github.com/stretchr/testify/require" + "golang.org/x/text/encoding" + "golang.org/x/text/encoding/unicode" + + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/input/generate" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/output/stdout" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/parser/regex" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/transformer/filter" +) + +func TestBuild(t *testing.T) { + regexConf := regex.NewConfig() + regexConf.Regex = "^#(?P.*)" + + invalidRegexConf := regex.NewConfig() + invalidRegexConf.Regex = "(" + + generateConf := generate.NewConfig("") + stdoutConf := stdout.NewConfig("") + filterConfg := filter.NewConfig() + filterConfg.Expression = "true" + + testCases := []struct { + name string + enc encoding.Encoding + pattern string + ops []operator.Config + expectedErr string + }{ + { + name: "valid config", + enc: encoding.Nop, + pattern: "^#", + ops: []operator.Config{ + { + Builder: regexConf, + }, + }, + }, + { + name: "Invalid pattern", + enc: unicode.UTF8, + pattern: "(", + ops: []operator.Config{ + { + Builder: regexConf, + }, + }, + expectedErr: "failed to compile `pattern`:", + }, + { + name: "Valid without specified header size", + enc: unicode.UTF8, + pattern: "^#", + ops: []operator.Config{ + { + Builder: regexConf, + }, + }, + }, + { + name: "No operators specified", + enc: unicode.UTF8, + pattern: "^#", + ops: []operator.Config{}, + expectedErr: "at least one operator must be specified for `metadata_operators`", + }, + { + name: "No encoding specified", + pattern: "^#", + ops: []operator.Config{ + { + Builder: regexConf, + }, + }, + expectedErr: "encoding must be specified", + }, + { + name: "Invalid operator specified", + enc: unicode.UTF8, + pattern: "^#", + ops: []operator.Config{ + { + Builder: invalidRegexConf, + }, + }, + expectedErr: "failed to build pipelines:", + }, + { + name: "first operator cannot process", + enc: unicode.UTF8, + pattern: "^#", + ops: []operator.Config{ + { + Builder: generateConf, + }, + }, + expectedErr: "operator 'generate_input' in `metadata_operators` cannot process entries", + }, + { + name: "operator cannot output", + enc: unicode.UTF8, + pattern: "^#", + ops: []operator.Config{ + { + Builder: stdoutConf, + }, + }, + expectedErr: "operator 'stdout' in `metadata_operators` does not propagate entries", + }, + { + name: "filter operator present", + enc: unicode.UTF8, + pattern: "^#", + ops: []operator.Config{ + { + Builder: filterConfg, + }, + }, + expectedErr: "operator of type filter is not allowed in `metadata_operators`", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + h, err := NewConfig(tc.pattern, tc.ops, tc.enc) + if tc.expectedErr != "" { + require.ErrorContains(t, err, tc.expectedErr) + } else { + require.NoError(t, err) + require.NotNil(t, h) + } + }) + } +} diff --git a/pkg/stanza/fileconsumer/internal/header/output.go b/pkg/stanza/fileconsumer/internal/header/output.go new file mode 100644 index 000000000000..7caf7f9a89e0 --- /dev/null +++ b/pkg/stanza/fileconsumer/internal/header/output.go @@ -0,0 +1,56 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package header // import "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/fileconsumer/internal/header" + +import ( + "context" + "fmt" + + "go.uber.org/zap" + + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/entry" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/helper" +) + +const pipelineOutputType = "header_log_emitter" + +// pipelineOutput is a stanza operator that emits log entries to a channel +type pipelineOutput struct { + helper.OutputOperator + logChan chan *entry.Entry +} + +// newPipelineOutput creates a new receiver output +func newPipelineOutput(logger *zap.SugaredLogger) *pipelineOutput { + return &pipelineOutput{ + OutputOperator: helper.OutputOperator{ + BasicOperator: helper.BasicOperator{ + OperatorID: pipelineOutputType, + OperatorType: pipelineOutputType, + SugaredLogger: logger, + }, + }, + logChan: make(chan *entry.Entry, 1), + } +} + +// Drop the entry if logChan is full, in order to avoid this operator blocking. +// This protects against a case where an operator could return an error, but continue propagating a log entry, +// leaving an unexpected entry in the output channel. +func (e *pipelineOutput) Process(_ context.Context, ent *entry.Entry) error { + select { + case e.logChan <- ent: + default: + } + return nil +} + +func (e *pipelineOutput) WaitForEntry(ctx context.Context) (*entry.Entry, error) { + select { + case <-ctx.Done(): + return nil, fmt.Errorf("wait for entry: %w", ctx.Err()) + case ent := <-e.logChan: + return ent, nil + } +} diff --git a/pkg/stanza/fileconsumer/internal/header/reader.go b/pkg/stanza/fileconsumer/internal/header/reader.go new file mode 100644 index 000000000000..f55b2323cfee --- /dev/null +++ b/pkg/stanza/fileconsumer/internal/header/reader.go @@ -0,0 +1,75 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package header // import "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/fileconsumer/internal/header" + +import ( + "context" + "errors" + "fmt" + + "go.opentelemetry.io/collector/extension/experimental/storage" + "go.uber.org/zap" + + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/entry" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/pipeline" +) + +var ErrEndOfHeader = errors.New("end of header") + +type Reader struct { + logger *zap.SugaredLogger + cfg Config + pipeline pipeline.Pipeline + output *pipelineOutput +} + +func NewReader(logger *zap.SugaredLogger, cfg Config) (*Reader, error) { + r := &Reader{logger: logger, cfg: cfg} + var err error + r.output = newPipelineOutput(logger) + r.pipeline, err = pipeline.Config{ + Operators: cfg.metadataOperators, + DefaultOutput: r.output, + }.Build(logger) + if err != nil { + return nil, fmt.Errorf("failed to build pipeline: %w", err) + } + if err = r.pipeline.Start(storage.NewNopClient()); err != nil { + return nil, fmt.Errorf("failed to start header pipeline: %w", err) + } + return r, nil +} + +// Process checks if the given token is a line of the header, and consumes it if it is. +// An EndOfHeaderError is returned if the given line was not a header line. +func (r *Reader) Process(ctx context.Context, token []byte, fileAttributes map[string]any) error { + if !r.cfg.regex.Match(token) { + return ErrEndOfHeader + } + + firstOperator := r.pipeline.Operators()[0] + + newEntry := entry.New() + newEntry.Body = string(token) + + if err := firstOperator.Process(ctx, newEntry); err != nil { + return fmt.Errorf("process header entry: %w", err) + } + + ent, err := r.output.WaitForEntry(ctx) + if err != nil { + return fmt.Errorf("wait for header entry: %w", err) + } + + // Copy resultant attributes over current set of attributes (upsert) + for k, v := range ent.Attributes { + // fileAttributes is an output parameter + fileAttributes[k] = v + } + return nil +} + +func (r *Reader) Stop() error { + return r.pipeline.Stop() +} diff --git a/pkg/stanza/fileconsumer/internal/header/reader_test.go b/pkg/stanza/fileconsumer/internal/header/reader_test.go new file mode 100644 index 000000000000..721306e7e5eb --- /dev/null +++ b/pkg/stanza/fileconsumer/internal/header/reader_test.go @@ -0,0 +1,87 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package header + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zaptest" + "golang.org/x/text/encoding/unicode" + + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/entry" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/parser/keyvalue" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/parser/regex" +) + +func TestReader(t *testing.T) { + logger := zaptest.NewLogger(t).Sugar() + + regexConf := regex.NewConfig() + regexConf.Regex = "^#(?P.*)" + regexConf.ParseTo = entry.RootableField{Field: entry.NewBodyField()} + + kvConf := keyvalue.NewConfig() + kvConf.ParseFrom = entry.NewBodyField("header_line") + kvConf.Delimiter = ":" + + cfg, err := NewConfig("^#", []operator.Config{ + {Builder: regexConf}, + {Builder: kvConf}, + }, unicode.UTF8) + require.NoError(t, err) + + reader, err := NewReader(logger, *cfg) + assert.NoError(t, err) + + attrs := make(map[string]any) + assert.NoError(t, reader.Process(context.Background(), []byte("# foo:bar\n"), attrs)) + assert.NoError(t, reader.Process(context.Background(), []byte("# hello:world\n"), attrs)) + assert.ErrorIs(t, reader.Process(context.Background(), []byte("First log line"), attrs), ErrEndOfHeader) + assert.Len(t, attrs, 2) + assert.Equal(t, "bar", attrs["foo"]) + assert.Equal(t, "world", attrs["hello"]) + + assert.NoError(t, reader.Stop()) +} + +func TestSkipUnmatchedHeaderLine(t *testing.T) { + logger := zaptest.NewLogger(t).Sugar() + + regexConf := regex.NewConfig() + regexConf.Regex = "^#(?P.*)" + regexConf.ParseTo = entry.RootableField{Field: entry.NewBodyField()} + + kvConf := keyvalue.NewConfig() + kvConf.ParseFrom = entry.NewBodyField("header_line") + kvConf.Delimiter = ":" + + cfg, err := NewConfig("^#", []operator.Config{ + {Builder: regexConf}, + {Builder: kvConf}, + }, unicode.UTF8) + require.NoError(t, err) + + reader, err := NewReader(logger, *cfg) + assert.NoError(t, err) + + attrs := make(map[string]any) + assert.NoError(t, reader.Process(context.Background(), []byte("# foo:bar\n"), attrs)) + assert.NoError(t, reader.Process(context.Background(), []byte("# matches header regex but not metadata operator assumptions\n"), attrs)) + assert.NoError(t, reader.Process(context.Background(), []byte("# hello:world\n"), attrs)) + assert.ErrorIs(t, reader.Process(context.Background(), []byte("First log line"), attrs), ErrEndOfHeader) + assert.Len(t, attrs, 2) + assert.Equal(t, "bar", attrs["foo"]) + assert.Equal(t, "world", attrs["hello"]) + + assert.NoError(t, reader.Stop()) +} + +func TestNewReaderErr(t *testing.T) { + _, err := NewReader(nil, Config{}) + assert.Error(t, err) +} diff --git a/pkg/stanza/fileconsumer/reader.go b/pkg/stanza/fileconsumer/reader.go index ef7b0cb490d4..9f1dc61c3591 100644 --- a/pkg/stanza/fileconsumer/reader.go +++ b/pkg/stanza/fileconsumer/reader.go @@ -6,17 +6,17 @@ package fileconsumer // import "github.com/open-telemetry/opentelemetry-collecto import ( "bufio" "context" + "errors" "fmt" "os" "go.uber.org/zap" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/entry" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/fileconsumer/emit" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/fileconsumer/internal/fingerprint" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/fileconsumer/internal/header" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/fileconsumer/internal/scanner" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/helper" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/pipeline" ) type readerConfig struct { @@ -48,11 +48,7 @@ type Reader struct { eof bool HeaderFinalized bool - recreateScanner bool - - headerSettings *headerSettings - headerPipeline pipeline.Pipeline - headerPipelineOutput *headerPipelineOutput + headerReader *header.Reader } // offsetToEnd sets the starting offset @@ -96,70 +92,36 @@ func (r *Reader) ReadToEnd(ctx context.Context) { token, err := r.encoding.Decode(s.Bytes()) if err != nil { r.Errorw("decode: %w", zap.Error(err)) - } else if err = r.processFunc(ctx, token, r.FileAttributes); err != nil { - r.Errorw("process: %w", zap.Error(err)) - } - - if r.recreateScanner { - r.recreateScanner = false - // recreate the scanner with the log-line's split func. - // We do not use the updated offset from the scanner, - // as the log line we just read could be multiline, and would be - // split differently with the new splitter. - if _, err := r.file.Seek(r.Offset, 0); err != nil { - r.Errorw("Failed to seek post-header", zap.Error(err)) - return + } else if err := r.processFunc(ctx, token, r.FileAttributes); err != nil { + if errors.Is(err, header.ErrEndOfHeader) { + r.finalizeHeader() + + // Now that the header is consumed, use the normal split and process functions. + // Recreate the scanner with the normal split func. + // Do not use the updated offset from the old scanner, as the most recent token + // could be split differently with the new splitter. + r.splitFunc = r.lineSplitFunc + r.processFunc = r.emit + if _, err = r.file.Seek(r.Offset, 0); err != nil { + r.Errorw("Failed to seek post-header", zap.Error(err)) + return + } + s = scanner.New(r, r.maxLogSize, scanner.DefaultBufferSize, r.Offset, r.splitFunc) + } else { + r.Errorw("process: %w", zap.Error(err)) } - - s = scanner.New(r, r.maxLogSize, scanner.DefaultBufferSize, r.Offset, r.splitFunc) } r.Offset = s.Pos() } } -// consumeHeaderLine checks if the given token is a line of the header, and consumes it if it is. -// The return value dictates whether the given line was a header line or not. -// If false is returned, the full header can be assumed to be read. -func (r *Reader) consumeHeaderLine(ctx context.Context, token []byte, _ map[string]any) error { - if !r.headerSettings.matchRegex.Match(token) { - // Finalize and cleanup the pipeline - r.HeaderFinalized = true - - // Stop and drop the header pipeline. - if err := r.headerPipeline.Stop(); err != nil { - return fmt.Errorf("stop header pipeline: %w", err) - } - r.headerPipeline = nil - r.headerPipelineOutput = nil - - // Use the line split func instead of the header split func - r.splitFunc = r.lineSplitFunc - r.processFunc = r.emit - // Mark that we should recreate the scanner, since we changed the split function - r.recreateScanner = true - return nil +func (r *Reader) finalizeHeader() { + if err := r.headerReader.Stop(); err != nil { + r.Errorw("Failed to stop header pipeline during finalization", zap.Error(err)) } - - firstOperator := r.headerPipeline.Operators()[0] - - newEntry := entry.New() - newEntry.Body = string(token) - - if err := firstOperator.Process(ctx, newEntry); err != nil { - return fmt.Errorf("process header entry: %w", err) - } - - ent, err := r.headerPipelineOutput.WaitForEntry(ctx) - if err != nil { - return fmt.Errorf("wait for header entry: %w", err) - } - - // Copy resultant attributes over current set of attributes (upsert) - for k, v := range ent.Attributes { - r.FileAttributes[k] = v - } - return nil + r.headerReader = nil + r.HeaderFinalized = true } // Close will close the file @@ -170,8 +132,8 @@ func (r *Reader) Close() { } } - if r.headerPipeline != nil { - if err := r.headerPipeline.Stop(); err != nil { + if r.headerReader != nil { + if err := r.headerReader.Stop(); err != nil { r.Errorw("Failed to stop header pipeline", zap.Error(err)) } } diff --git a/pkg/stanza/fileconsumer/reader_factory.go b/pkg/stanza/fileconsumer/reader_factory.go index 98c44a1e8d40..416f4876cfa7 100644 --- a/pkg/stanza/fileconsumer/reader_factory.go +++ b/pkg/stanza/fileconsumer/reader_factory.go @@ -5,18 +5,16 @@ package fileconsumer // import "github.com/open-telemetry/opentelemetry-collecto import ( "bufio" - "fmt" "os" "path/filepath" "runtime" - "go.opentelemetry.io/collector/extension/experimental/storage" "go.uber.org/zap" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/fileconsumer/internal/fingerprint" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/fileconsumer/internal/header" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/fileconsumer/internal/util" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/helper" - "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/pipeline" ) type readerFactory struct { @@ -25,7 +23,7 @@ type readerFactory struct { fromBeginning bool splitterFactory splitterFactory encodingConfig helper.EncodingConfig - headerSettings *headerSettings + headerConfig *header.Config } func (f *readerFactory) newReader(file *os.File, fp *fingerprint.Fingerprint) (*Reader, error) { @@ -103,7 +101,6 @@ func (b *readerBuilder) build() (r *Reader, err error) { r = &Reader{ readerConfig: b.readerConfig, Offset: b.offset, - headerSettings: b.headerSettings, HeaderFinalized: b.headerFinalized, FileAttributes: b.fileAttributes, } @@ -122,26 +119,16 @@ func (b *readerBuilder) build() (r *Reader, err error) { return nil, err } - if b.headerSettings == nil || b.headerFinalized { + if b.headerConfig == nil || b.headerFinalized { r.splitFunc = r.lineSplitFunc r.processFunc = b.readerConfig.emit } else { - // We are reading the header. Use the header split func - r.splitFunc = b.headerSettings.splitFunc - r.processFunc = r.consumeHeaderLine - - // Create the header pipeline - r.headerPipelineOutput = newHeaderPipelineOutput(b.SugaredLogger) - r.headerPipeline, err = pipeline.Config{ - Operators: b.headerSettings.config.MetadataOperators, - DefaultOutput: r.headerPipelineOutput, - }.Build(b.SugaredLogger) + r.splitFunc = b.headerConfig.SplitFunc + r.headerReader, err = header.NewReader(b.SugaredLogger, *b.headerConfig) if err != nil { - return nil, fmt.Errorf("failed to build pipeline: %w", err) - } - if err = r.headerPipeline.Start(storage.NewNopClient()); err != nil { - return nil, fmt.Errorf("failed to start header pipeline: %w", err) + return nil, err } + r.processFunc = r.headerReader.Process } if b.file == nil { diff --git a/pkg/stanza/fileconsumer/reader_test.go b/pkg/stanza/fileconsumer/reader_test.go index aedd9d99e026..cba92842a1d7 100644 --- a/pkg/stanza/fileconsumer/reader_test.go +++ b/pkg/stanza/fileconsumer/reader_test.go @@ -14,6 +14,7 @@ import ( "github.com/stretchr/testify/require" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/fileconsumer/internal/fingerprint" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/fileconsumer/internal/header" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/helper" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/parser/regex" @@ -165,23 +166,14 @@ func TestHeaderFingerprintIncluded(t *testing.T) { regexConf := regex.NewConfig() regexConf.Regex = "^#(?P
.*)" - headerConf := &HeaderConfig{ - Pattern: "^#", - MetadataOperators: []operator.Config{ - { - Builder: regexConf, - }, - }, - } - enc, err := helper.EncodingConfig{ Encoding: "utf-8", }.Build() require.NoError(t, err) - h, err := headerConf.buildHeaderSettings(enc.Encoding) + h, err := header.NewConfig("^#", []operator.Config{{Builder: regexConf}}, enc.Encoding) require.NoError(t, err) - f.headerSettings = h + f.headerConfig = h temp := openTemp(t, t.TempDir()) From 50fe850bd34e715107e4239d8653a2fe5d366c12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20=C5=9Awi=C4=85tek?= Date: Tue, 25 Jul 2023 17:29:53 +0000 Subject: [PATCH 30/42] Allow access to the metrics slice in the OTTL metric context (#24447) **Description:** Allow OTTL functions to access the MetricsSlice in the metric context. This makes it possible for functions to create new metrics without having to use the datapoint context. **Link to tracking Issue:** https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/24446 **Testing:** Tested this change with a new function in #24368 --- .../feat_ottl_metrics-context-slice.yaml | 20 +++++++++++++++++++ connector/countconnector/connector.go | 2 +- .../filter/filtermetric/filtermetric_test.go | 4 ++-- internal/filter/filterottl/functions_test.go | 4 ++-- pkg/ottl/contexts/ottlmetric/metrics.go | 8 +++++++- pkg/ottl/contexts/ottlmetric/metrics_test.go | 2 +- .../attributesprocessor/attributes_metric.go | 2 +- processor/filterprocessor/metrics.go | 2 +- .../internal/common/metrics.go | 2 +- 9 files changed, 36 insertions(+), 10 deletions(-) create mode 100755 .chloggen/feat_ottl_metrics-context-slice.yaml diff --git a/.chloggen/feat_ottl_metrics-context-slice.yaml b/.chloggen/feat_ottl_metrics-context-slice.yaml new file mode 100755 index 000000000000..5a476b2449d8 --- /dev/null +++ b/.chloggen/feat_ottl_metrics-context-slice.yaml @@ -0,0 +1,20 @@ +# Use this changelog template to create an entry for release notes. +# If your change doesn't affect end users, such as a test fix or a tooling change, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: breaking + +# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) +component: pkg/ottl + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Allow access to the metrics slice in the metric context + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [24446] + +# (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: This is only a breaking change for users using OTTL in custom components. For all Contrib components this is an enhancement. diff --git a/connector/countconnector/connector.go b/connector/countconnector/connector.go index 694dcb799abf..00e051c1234e 100644 --- a/connector/countconnector/connector.go +++ b/connector/countconnector/connector.go @@ -101,7 +101,7 @@ func (c *count) ConsumeMetrics(ctx context.Context, md pmetric.Metrics) error { for k := 0; k < scopeMetrics.Metrics().Len(); k++ { metric := scopeMetrics.Metrics().At(k) - mCtx := ottlmetric.NewTransformContext(metric, scopeMetrics.Scope(), resourceMetric.Resource()) + mCtx := ottlmetric.NewTransformContext(metric, scopeMetrics.Metrics(), scopeMetrics.Scope(), resourceMetric.Resource()) errors = multierr.Append(errors, metricsCounter.update(ctx, pcommon.NewMap(), mCtx)) switch metric.Type() { diff --git a/internal/filter/filtermetric/filtermetric_test.go b/internal/filter/filtermetric/filtermetric_test.go index 1ba06482d1b7..ea63fa7eb7f7 100644 --- a/internal/filter/filtermetric/filtermetric_test.go +++ b/internal/filter/filtermetric/filtermetric_test.go @@ -83,7 +83,7 @@ func TestMatcherMatches(t *testing.T) { assert.NotNil(t, matcher) assert.NoError(t, err) - matches, err := matcher.Eval(context.Background(), ottlmetric.NewTransformContext(test.metric, pcommon.NewInstrumentationScope(), pcommon.NewResource())) + matches, err := matcher.Eval(context.Background(), ottlmetric.NewTransformContext(test.metric, pmetric.NewMetricSlice(), pcommon.NewInstrumentationScope(), pcommon.NewResource())) assert.NoError(t, err) assert.Equal(t, test.shouldMatch, matches) }) @@ -188,7 +188,7 @@ func Test_NewSkipExpr_With_Bridge(t *testing.T) { scope := pcommon.NewInstrumentationScope() - tCtx := ottlmetric.NewTransformContext(metric, scope, resource) + tCtx := ottlmetric.NewTransformContext(metric, pmetric.NewMetricSlice(), scope, resource) boolExpr, err := NewSkipExpr(tt.include, tt.exclude) require.NoError(t, err) diff --git a/internal/filter/filterottl/functions_test.go b/internal/filter/filterottl/functions_test.go index a219862daef4..2e1755361d27 100644 --- a/internal/filter/filterottl/functions_test.go +++ b/internal/filter/filterottl/functions_test.go @@ -126,7 +126,7 @@ func Test_HasAttrKeyOnDatapoint(t *testing.T) { t.Run(tt.name, func(t *testing.T) { exprFunc, err := hasAttributeKeyOnDatapoint(tt.key) assert.NoError(t, err) - result, err := exprFunc(context.Background(), ottlmetric.NewTransformContext(tt.input(), pcommon.NewInstrumentationScope(), pcommon.NewResource())) + result, err := exprFunc(context.Background(), ottlmetric.NewTransformContext(tt.input(), pmetric.NewMetricSlice(), pcommon.NewInstrumentationScope(), pcommon.NewResource())) assert.NoError(t, err) assert.Equal(t, tt.expected, result) }) @@ -351,7 +351,7 @@ func Test_HasAttrOnDatapoint(t *testing.T) { t.Run(tt.name, func(t *testing.T) { exprFunc, err := hasAttributeOnDatapoint(tt.key, tt.expectedVal) assert.NoError(t, err) - result, err := exprFunc(context.Background(), ottlmetric.NewTransformContext(tt.input(), pcommon.NewInstrumentationScope(), pcommon.NewResource())) + result, err := exprFunc(context.Background(), ottlmetric.NewTransformContext(tt.input(), pmetric.NewMetricSlice(), pcommon.NewInstrumentationScope(), pcommon.NewResource())) assert.NoError(t, err) assert.Equal(t, tt.expected, result) }) diff --git a/pkg/ottl/contexts/ottlmetric/metrics.go b/pkg/ottl/contexts/ottlmetric/metrics.go index 0ecad0021efc..fd2fd4a9069f 100644 --- a/pkg/ottl/contexts/ottlmetric/metrics.go +++ b/pkg/ottl/contexts/ottlmetric/metrics.go @@ -21,6 +21,7 @@ var _ internal.MetricContext = TransformContext{} type TransformContext struct { metric pmetric.Metric + metrics pmetric.MetricSlice instrumentationScope pcommon.InstrumentationScope resource pcommon.Resource cache pcommon.Map @@ -28,9 +29,10 @@ type TransformContext struct { type Option func(*ottl.Parser[TransformContext]) -func NewTransformContext(metric pmetric.Metric, instrumentationScope pcommon.InstrumentationScope, resource pcommon.Resource) TransformContext { +func NewTransformContext(metric pmetric.Metric, metrics pmetric.MetricSlice, instrumentationScope pcommon.InstrumentationScope, resource pcommon.Resource) TransformContext { return TransformContext{ metric: metric, + metrics: metrics, instrumentationScope: instrumentationScope, resource: resource, cache: pcommon.NewMap(), @@ -41,6 +43,10 @@ func (tCtx TransformContext) GetMetric() pmetric.Metric { return tCtx.metric } +func (tCtx TransformContext) GetMetrics() pmetric.MetricSlice { + return tCtx.metrics +} + func (tCtx TransformContext) GetInstrumentationScope() pcommon.InstrumentationScope { return tCtx.instrumentationScope } diff --git a/pkg/ottl/contexts/ottlmetric/metrics_test.go b/pkg/ottl/contexts/ottlmetric/metrics_test.go index 6cd11e3ee361..e41e06f898db 100644 --- a/pkg/ottl/contexts/ottlmetric/metrics_test.go +++ b/pkg/ottl/contexts/ottlmetric/metrics_test.go @@ -165,7 +165,7 @@ func Test_newPathGetSetter(t *testing.T) { metric := createMetricTelemetry() - ctx := NewTransformContext(metric, pcommon.NewInstrumentationScope(), pcommon.NewResource()) + ctx := NewTransformContext(metric, pmetric.NewMetricSlice(), pcommon.NewInstrumentationScope(), pcommon.NewResource()) got, err := accessor.Get(context.Background(), ctx) assert.Nil(t, err) diff --git a/processor/attributesprocessor/attributes_metric.go b/processor/attributesprocessor/attributes_metric.go index a28e21002b2d..c913d1f85d99 100644 --- a/processor/attributesprocessor/attributes_metric.go +++ b/processor/attributesprocessor/attributes_metric.go @@ -44,7 +44,7 @@ func (a *metricAttributesProcessor) processMetrics(ctx context.Context, md pmetr for k := 0; k < metrics.Len(); k++ { m := metrics.At(k) if a.skipExpr != nil { - skip, err := a.skipExpr.Eval(ctx, ottlmetric.NewTransformContext(m, scope, resource)) + skip, err := a.skipExpr.Eval(ctx, ottlmetric.NewTransformContext(m, metrics, scope, resource)) if err != nil { return md, err } diff --git a/processor/filterprocessor/metrics.go b/processor/filterprocessor/metrics.go index 613c95eadda8..51fbb857c62f 100644 --- a/processor/filterprocessor/metrics.go +++ b/processor/filterprocessor/metrics.go @@ -124,7 +124,7 @@ func (fmp *filterMetricProcessor) processMetrics(ctx context.Context, md pmetric scope := smetrics.Scope() smetrics.Metrics().RemoveIf(func(metric pmetric.Metric) bool { if fmp.skipMetricExpr != nil { - skip, err := fmp.skipMetricExpr.Eval(ctx, ottlmetric.NewTransformContext(metric, scope, resource)) + skip, err := fmp.skipMetricExpr.Eval(ctx, ottlmetric.NewTransformContext(metric, smetrics.Metrics(), scope, resource)) if err != nil { errors = multierr.Append(errors, err) } diff --git a/processor/transformprocessor/internal/common/metrics.go b/processor/transformprocessor/internal/common/metrics.go index 9a9ec9c20ea2..1ca67d0b262a 100644 --- a/processor/transformprocessor/internal/common/metrics.go +++ b/processor/transformprocessor/internal/common/metrics.go @@ -37,7 +37,7 @@ func (m metricStatements) ConsumeMetrics(ctx context.Context, md pmetric.Metrics smetrics := rmetrics.ScopeMetrics().At(j) metrics := smetrics.Metrics() for k := 0; k < metrics.Len(); k++ { - tCtx := ottlmetric.NewTransformContext(metrics.At(k), smetrics.Scope(), rmetrics.Resource()) + tCtx := ottlmetric.NewTransformContext(metrics.At(k), smetrics.Metrics(), smetrics.Scope(), rmetrics.Resource()) err := m.Execute(ctx, tCtx) if err != nil { return err From e88686ff1e120c4ec0ba059f9966083db569d6d5 Mon Sep 17 00:00:00 2001 From: Antoine Toulme Date: Tue, 25 Jul 2023 10:51:02 -0700 Subject: [PATCH 31/42] Introduce cmd/githubgen, a tool to generate `.github` files (#24455) **Description:** This tool reads the metadata.yaml files and generates the `.github/CODEOWNERS` and `.github/ALLOWLIST` files based on component status and current codeowners. It adds to the CI a check that the generated files match exactly what is being generated. **Link to tracking Issue:** See #23367 **Testing:** The tool generates exactly what is currently in the files. --------- Co-authored-by: Alex Boten --- .github/ALLOWLIST | 1 + .github/CODEOWNERS | 3 +- .github/workflows/build-and-test.yml | 4 + Makefile | 4 + cmd/githubgen/main.go | 208 +++++++++++++++++++++++++++ go.mod | 2 +- 6 files changed, 220 insertions(+), 2 deletions(-) create mode 100644 cmd/githubgen/main.go diff --git a/.github/ALLOWLIST b/.github/ALLOWLIST index 2e4dc945fabd..d28b036b0701 100644 --- a/.github/ALLOWLIST +++ b/.github/ALLOWLIST @@ -1,3 +1,4 @@ +# Code generated by githubgen. DO NOT EDIT. ##################################################### # # List of components in OpenTelemetry Collector Contrib diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 23637843117f..10fb0e6ba7ab 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,3 +1,4 @@ +# Code generated by githubgen. DO NOT EDIT. ##################################################### # # List of approvers for OpenTelemetry Collector Contrib @@ -5,7 +6,7 @@ ##################################################### # # Learn about membership in OpenTelemetry community: -# https://github.com/open-telemetry/community/blob/main/community-membership.md +# https://github.com/open-telemetry/community/blob/main/community-membership.md # # # Learn about CODEOWNERS file format: diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 6e0ac18b3fce..02ac4d0a2947 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -206,6 +206,10 @@ jobs: run: | make -j2 generate git diff --exit-code ':!*go.sum' || (echo 'Generated code is out of date, please run "make generate" and commit the changes in this PR.' && exit 1) + - name: Gen codeowners + run: | + make gengithub + git diff -s --exit-code || (echo 'Generated code is out of date, please run "make gengithub" and commit the changes in this PR.' && exit 1) - name: Check gendependabot run: | make -j2 gendependabot diff --git a/Makefile b/Makefile index e08f9c74e5fc..f9901cf1f57f 100644 --- a/Makefile +++ b/Makefile @@ -253,6 +253,10 @@ mdatagen-test: cd cmd/mdatagen && $(GOCMD) generate ./... cd cmd/mdatagen && $(GOCMD) test ./... +.PHONY: gengithub +gengithub: + $(GOCMD) run cmd/githubgen/main.go . + FILENAME?=$(shell git branch --show-current) .PHONY: chlog-new chlog-new: $(CHLOGGEN) diff --git a/cmd/githubgen/main.go b/cmd/githubgen/main.go new file mode 100644 index 000000000000..d5fab2a24520 --- /dev/null +++ b/cmd/githubgen/main.go @@ -0,0 +1,208 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package main + +import ( + "context" + "flag" + "fmt" + "io/fs" + "log" + "os" + "path/filepath" + "sort" + "strings" + + "go.opentelemetry.io/collector/confmap/provider/fileprovider" +) + +const codeownersHeader = `# Code generated by githubgen. DO NOT EDIT. +##################################################### +# +# List of approvers for OpenTelemetry Collector Contrib +# +##################################################### +# +# Learn about membership in OpenTelemetry community: +# https://github.com/open-telemetry/community/blob/main/community-membership.md +# +# +# Learn about CODEOWNERS file format: +# https://help.github.com/en/articles/about-code-owners +# +# NOTE: Lines should be entered in the following format: +# /.. +# extension/oauth2clientauthextension/ @open-telemetry/collector-contrib-approvers @pavankrish123 @jpkrohling +# Path separator and minimum of 1 space between component path and owners is +# important for validation steps +# + +* @open-telemetry/collector-contrib-approvers +` + +const unmaintainedHeader = ` + +## UNMAINTAINED components +## The Github issue template generation code needs this to generate the corresponding labels. + +` + +const allowlistHeader = `# Code generated by githubgen. DO NOT EDIT. +##################################################### +# +# List of components in OpenTelemetry Collector Contrib +# waiting on owners to be assigned +# +##################################################### +# +# Learn about membership in OpenTelemetry community: +# https://github.com/open-telemetry/community/blob/main/community-membership.md +# +# +# Learn about CODEOWNERS file format: +# https://help.github.com/en/articles/about-code-owners +# + +## +# NOTE: New components MUST have a codeowner. Add new components to the CODEOWNERS file instead of here. +## + +## COMMON & SHARED components +internal/common + +` + +const unmaintainedStatus = "unmaintained" + +// Generates files specific to Github according to status metadata: +// .github/CODEOWNERS +// .github/ALLOWLIST +func main() { + flag.Parse() + folder := flag.Arg(0) + if err := run(folder); err != nil { + log.Fatal(err) + } +} + +type Codeowners struct { + // Active codeowners + Active []string `mapstructure:"active"` + // Emeritus codeowners + Emeritus []string `mapstructure:"emeritus"` +} +type Status struct { + Stability map[string][]string `mapstructure:"stability"` + Distributions []string `mapstructure:"distributions"` + Class string `mapstructure:"class"` + Warnings []string `mapstructure:"warnings"` + Codeowners *Codeowners `mapstructure:"codeowners"` +} +type metadata struct { + // Type of the component. + Type string `mapstructure:"type"` + // Type of the parent component (applicable to subcomponents). + Parent string `mapstructure:"parent"` + // Status information for the component. + Status *Status `mapstructure:"status"` +} + +func loadMetadata(filePath string) (metadata, error) { + cp, err := fileprovider.New().Retrieve(context.Background(), "file:"+filePath, nil) + if err != nil { + return metadata{}, err + } + + conf, err := cp.AsConf() + if err != nil { + return metadata{}, err + } + + md := metadata{} + if err := conf.Unmarshal(&md); err != nil { + return md, err + } + + return md, nil +} + +func run(folder string) error { + components := map[string]metadata{} + foldersList := []string{} + maxLength := 0 + err := filepath.Walk(folder, func(path string, info fs.FileInfo, err error) error { + if info.Name() == "metadata.yaml" { + m, err := loadMetadata(path) + if err != nil { + return err + } + if m.Status == nil { + return nil + } + key := filepath.Dir(path) + "/" + components[key] = m + foldersList = append(foldersList, key) + for stability := range m.Status.Stability { + if stability == unmaintainedStatus { + // do not account for unmaintained status to change the max length of the component line. + return nil + } + } + if len(key) > maxLength { + maxLength = len(key) + } + } + return nil + }) + sort.Strings(foldersList) + if err != nil { + return err + } + codeowners := codeownersHeader + deprecatedList := "## DEPRECATED components\n" + unmaintainedList := "\n## UNMAINTAINED components\n" + + unmaintainedCodeowners := unmaintainedHeader + currentFirstSegment := "" +LOOP: + for _, key := range foldersList { + m := components[key] + for stability := range m.Status.Stability { + if stability == unmaintainedStatus { + unmaintainedList += key + "\n" + unmaintainedCodeowners += fmt.Sprintf("%s%s @open-telemetry/collector-contrib-approvers \n", key, strings.Repeat(" ", maxLength-len(key))) + continue LOOP + } + if stability == "deprecated" && (m.Status.Codeowners == nil || len(m.Status.Codeowners.Active) == 0) { + deprecatedList += key + "\n" + } + } + + if m.Status.Codeowners != nil { + parts := strings.Split(key, string(os.PathSeparator)) + firstSegment := parts[0] + if firstSegment != currentFirstSegment { + currentFirstSegment = firstSegment + codeowners += "\n" + } + owners := "" + for _, owner := range m.Status.Codeowners.Active { + owners += " " + owners += "@" + owner + } + codeowners += fmt.Sprintf("%s%s @open-telemetry/collector-contrib-approvers%s\n", key, strings.Repeat(" ", maxLength-len(key)), owners) + } + } + + err = os.WriteFile(filepath.Join(".github", "CODEOWNERS"), []byte(codeowners+unmaintainedCodeowners), 0600) + if err != nil { + return err + } + err = os.WriteFile(filepath.Join(".github", "ALLOWLIST"), []byte(allowlistHeader+deprecatedList+unmaintainedList), 0600) + if err != nil { + return err + } + + return nil +} diff --git a/go.mod b/go.mod index 678da9639301..6a042fd5b546 100644 --- a/go.mod +++ b/go.mod @@ -169,6 +169,7 @@ require ( github.com/open-telemetry/opentelemetry-collector-contrib/receiver/zipkinreceiver v0.81.0 github.com/open-telemetry/opentelemetry-collector-contrib/receiver/zookeeperreceiver v0.81.0 go.opentelemetry.io/collector v0.81.0 + go.opentelemetry.io/collector/confmap v0.81.0 go.opentelemetry.io/collector/exporter v0.81.0 go.opentelemetry.io/collector/exporter/loggingexporter v0.81.0 go.opentelemetry.io/collector/exporter/otlpexporter v0.81.0 @@ -620,7 +621,6 @@ require ( go.opentelemetry.io/collector/config/configtelemetry v0.81.0 // indirect go.opentelemetry.io/collector/config/configtls v0.81.0 // indirect go.opentelemetry.io/collector/config/internal v0.81.0 // indirect - go.opentelemetry.io/collector/confmap v0.81.0 // indirect go.opentelemetry.io/collector/connector v0.81.0 // indirect go.opentelemetry.io/collector/consumer v0.81.0 // indirect go.opentelemetry.io/collector/extension/auth v0.81.0 // indirect From 6c5baeae3fdf52402a18546d3cfd0721b225cc3b Mon Sep 17 00:00:00 2001 From: ShiranAvidov <48657224+ShiranAvidov@users.noreply.github.com> Date: Tue, 25 Jul 2023 21:28:28 +0300 Subject: [PATCH 32/42] [pkg/stanza/operator/input/windows] [receiver/windowseventlogreceiver] Add exclude providers (#24386) Adds exclude providers array to the config, which tells which events to exclude from processing by their provider name. Gives more control which events not to process. --- .chloggen/add-exclude-providers.yaml | 20 +++++ pkg/stanza/operator/input/windows/operator.go | 59 +++++++++----- receiver/windowseventlogreceiver/README.md | 3 +- .../receiver_windows_test.go | 79 +++++++++++++++++++ 4 files changed, 142 insertions(+), 19 deletions(-) create mode 100755 .chloggen/add-exclude-providers.yaml diff --git a/.chloggen/add-exclude-providers.yaml b/.chloggen/add-exclude-providers.yaml new file mode 100755 index 000000000000..6ad516d6bfdd --- /dev/null +++ b/.chloggen/add-exclude-providers.yaml @@ -0,0 +1,20 @@ +# Use this changelog template to create an entry for release notes. +# If your change doesn't affect end users, such as a test fix or a tooling change, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. + +# 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. filelogreceiver) +component: windowseventlogreceiver + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: "Add `exclude_providers` to the config. One or more event log providers to exclude from processing." + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [21491] + +# (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: diff --git a/pkg/stanza/operator/input/windows/operator.go b/pkg/stanza/operator/input/windows/operator.go index dae249fc3936..5df98bb64cef 100644 --- a/pkg/stanza/operator/input/windows/operator.go +++ b/pkg/stanza/operator/input/windows/operator.go @@ -47,6 +47,7 @@ type Config struct { StartAt string `mapstructure:"start_at,omitempty"` PollInterval time.Duration `mapstructure:"poll_interval,omitempty"` Raw bool `mapstructure:"raw,omitempty"` + ExcludeProviders []string `mapstructure:"exclude_providers,omitempty"` } // Build will build a windows event log operator. @@ -69,30 +70,32 @@ func (c *Config) Build(logger *zap.SugaredLogger) (operator.Operator, error) { } return &Input{ - InputOperator: inputOperator, - buffer: NewBuffer(), - channel: c.Channel, - maxReads: c.MaxReads, - startAt: c.StartAt, - pollInterval: c.PollInterval, - raw: c.Raw, + InputOperator: inputOperator, + buffer: NewBuffer(), + channel: c.Channel, + maxReads: c.MaxReads, + startAt: c.StartAt, + pollInterval: c.PollInterval, + raw: c.Raw, + excludeProviders: c.ExcludeProviders, }, nil } // Input is an operator that creates entries using the windows event log api. type Input struct { helper.InputOperator - bookmark Bookmark - subscription Subscription - buffer Buffer - channel string - maxReads int - startAt string - raw bool - pollInterval time.Duration - persister operator.Persister - cancel context.CancelFunc - wg sync.WaitGroup + bookmark Bookmark + subscription Subscription + buffer Buffer + channel string + maxReads int + startAt string + raw bool + excludeProviders []string + pollInterval time.Duration + persister operator.Persister + cancel context.CancelFunc + wg sync.WaitGroup } // Start will start reading events from a subscription. @@ -194,6 +197,20 @@ func (e *Input) read(ctx context.Context) int { // processEvent will process and send an event retrieved from windows event log. func (e *Input) processEvent(ctx context.Context, event Event) { if e.raw { + if len(e.excludeProviders) > 0 { + simpleEvent, err := event.RenderSimple(e.buffer) + if err != nil { + e.Errorf("Failed to render simple event: %s", err) + return + } + + for _, excludeProvider := range e.excludeProviders { + if simpleEvent.Provider.Name == excludeProvider { + return + } + } + } + rawEvent, err := event.RenderRaw(e.buffer) if err != nil { e.Errorf("Failed to render raw event: %s", err) @@ -208,6 +225,12 @@ func (e *Input) processEvent(ctx context.Context, event Event) { return } + for _, excludeProvider := range e.excludeProviders { + if simpleEvent.Provider.Name == excludeProvider { + return + } + } + publisher := NewPublisher() if err := publisher.Open(simpleEvent.Provider.Name); err != nil { e.Errorf("Failed to open publisher: %s: writing log entry to pipeline without metadata", err) diff --git a/receiver/windowseventlogreceiver/README.md b/receiver/windowseventlogreceiver/README.md index d8535fd9490a..6763a2222592 100644 --- a/receiver/windowseventlogreceiver/README.md +++ b/receiver/windowseventlogreceiver/README.md @@ -27,7 +27,8 @@ Tails and parses logs from windows event log API using the [opentelemetry-log-co | `attributes` | {} | A map of `key: value` pairs to add to the entry's attributes. | | `resource` | {} | A map of `key: value` pairs to add to the entry's resource. | | `operators` | [] | An array of [operators](https://github.com/open-telemetry/opentelemetry-log-collection/blob/main/docs/operators/README.md#what-operators-are-available). See below for more details | -| `raw` | false | If true, the windows events are not processed and sent as XML. | +| `raw` | false | If true, the windows events are not processed and sent as XML. If used in combination with `exclude_providers`, each event will be processed in order to determine its provider name. | +| `exclude_providers` | [] | One or more event log providers to exclude from processing. | | `storage` | none | The ID of a storage extension to be used to store bookmarks. Bookmarks allow the receiver to pick up where it left off in the case of a collector restart. If no storage extension is used, the receiver will manage bookmarks in memory only. | | `retry_on_failure.enabled` | `false` | If `true`, the receiver will pause reading a file and attempt to resend the current batch of logs if it encounters an error from downstream components. | | `retry_on_failure.initial_interval` | `1 second` | Time to wait after the first failure before retrying. | diff --git a/receiver/windowseventlogreceiver/receiver_windows_test.go b/receiver/windowseventlogreceiver/receiver_windows_test.go index cad1d13c9461..f370215657ae 100644 --- a/receiver/windowseventlogreceiver/receiver_windows_test.go +++ b/receiver/windowseventlogreceiver/receiver_windows_test.go @@ -179,6 +179,85 @@ func TestReadWindowsEventLoggerRaw(t *testing.T) { require.Equal(t, logMessage, bodyStruct.Data) } +func TestReadWindowsEventLoggerWithExcludeProvider(t *testing.T) { + logMessage := "Test log" + src := "otel" + + ctx := context.Background() + factory := NewFactory() + createSettings := receivertest.NewNopCreateSettings() + cfg := createTestConfig() + cfg.InputConfig.ExcludeProviders = []string{src} + sink := new(consumertest.LogsSink) + + receiver, err := factory.CreateLogsReceiver(ctx, createSettings, cfg, sink) + require.NoError(t, err) + + err = receiver.Start(ctx, componenttest.NewNopHost()) + require.NoError(t, err) + defer receiver.Shutdown(ctx) + + err = eventlog.InstallAsEventCreate(src, eventlog.Info|eventlog.Warning|eventlog.Error) + require.NoError(t, err) + defer eventlog.Remove(src) + + logger, err := eventlog.Open(src) + require.NoError(t, err) + defer logger.Close() + + err = logger.Info(10, logMessage) + require.NoError(t, err) + + logsReceived := func() bool { + return sink.LogRecordCount() == 0 + } + + // logs sometimes take a while to be written, so a substantial wait buffer is needed + require.Eventually(t, logsReceived, 10*time.Second, 200*time.Millisecond) + results := sink.AllLogs() + require.Len(t, results, 0) +} + +func TestReadWindowsEventLoggerRawWithExcludeProvider(t *testing.T) { + logMessage := "Test log" + src := "otel" + + ctx := context.Background() + factory := NewFactory() + createSettings := receivertest.NewNopCreateSettings() + cfg := createTestConfig() + cfg.InputConfig.Raw = true + cfg.InputConfig.ExcludeProviders = []string{src} + sink := new(consumertest.LogsSink) + + receiver, err := factory.CreateLogsReceiver(ctx, createSettings, cfg, sink) + require.NoError(t, err) + + err = receiver.Start(ctx, componenttest.NewNopHost()) + require.NoError(t, err) + defer receiver.Shutdown(ctx) + + err = eventlog.InstallAsEventCreate(src, eventlog.Info|eventlog.Warning|eventlog.Error) + defer eventlog.Remove(src) + require.NoError(t, err) + + logger, err := eventlog.Open(src) + require.NoError(t, err) + defer logger.Close() + + err = logger.Info(10, logMessage) + require.NoError(t, err) + + logsReceived := func() bool { + return sink.LogRecordCount() == 0 + } + + // logs sometimes take a while to be written, so a substantial wait buffer is needed + require.Eventually(t, logsReceived, 10*time.Second, 200*time.Millisecond) + results := sink.AllLogs() + require.Len(t, results, 0) +} + func createTestConfig() *WindowsLogConfig { return &WindowsLogConfig{ BaseConfig: adapter.BaseConfig{ From a877923c3c3df8bdeb79e98d662369fb3a2ed9d9 Mon Sep 17 00:00:00 2001 From: Dani Louca <59848726+dloucasfx@users.noreply.github.com> Date: Tue, 25 Jul 2023 16:52:32 -0400 Subject: [PATCH 33/42] [processor/resourcedetection] fix when panic when AKS detector is used (#24549) **Description:** Address the following panic when AKS detector is used. This issue was introduced by this change https://github.com/open-telemetry/opentelemetry-collector-contrib/commit/04327f5deaebd5f8abea3b313dd2f45ccef5bf7e ```` panic: interface conversion: internal.DetectorConfig is nil, not aks.Config goroutine 1 [running]: github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/azure/aks.NewDetector({{{0xc0023d5638, 0x11}, {0x0, 0x0}}, {0xc002568fc0, {0x6877700, 0xc0024f1580}, {0x68a1850, 0xc00251b590}, 0x0, ...}, ...}, ...) github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor@v0.81.0/internal/azure/aks/aks.go:34 +0x10a github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal.(*ResourceProviderFactory).getDetectors(0xc00082ffe0, {{{0xc0023d5638, 0x11}, {0x0, 0x0}}, {0xc002568fc0, {0x6877700, 0xc0024f1580}, {0x68a1850, 0xc00251b590}, ...}, ...}, ...) github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor@v0.81.0/internal/resourcedetection.go:73 +0x182 github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal.(*ResourceProviderFactory).CreateResourceProvider(0xc001dbfeb8?, {{{0xc0023d5638, 0x11}, {0x0, 0x0}}, {0xc002568fc0, {0x6877700, 0xc0024f1580}, {0x68a1850, 0xc00251b590}, ...}, ...}, ...) github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor@v0.81.0/internal/resourcedetection.go:49 +0x9d ```` Signed-off-by: Dani Louca --- .chloggen/resourcedetection-aks-panic.yaml | 20 +++++++++++++++++++ .../resourcedetectionprocessor/config.go | 2 ++ .../testdata/config.yaml | 5 +++++ 3 files changed, 27 insertions(+) create mode 100755 .chloggen/resourcedetection-aks-panic.yaml diff --git a/.chloggen/resourcedetection-aks-panic.yaml b/.chloggen/resourcedetection-aks-panic.yaml new file mode 100755 index 000000000000..921ad3c560f1 --- /dev/null +++ b/.chloggen/resourcedetection-aks-panic.yaml @@ -0,0 +1,20 @@ +# Use this changelog template to create an entry for release notes. +# If your change doesn't affect end users, such as a test fix or a tooling change, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: bug_fix + +# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) +component: processor/resourcedetection + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: make sure to use a aks config struct instead of nil to avoid collector panic + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [24549] + +# (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: diff --git a/processor/resourcedetectionprocessor/config.go b/processor/resourcedetectionprocessor/config.go index 6d667edeb455..a2da68ae9591 100644 --- a/processor/resourcedetectionprocessor/config.go +++ b/processor/resourcedetectionprocessor/config.go @@ -116,6 +116,8 @@ func (d *DetectorConfig) GetConfigFromType(detectorType internal.DetectorType) i return d.LambdaConfig case azure.TypeStr: return d.AzureConfig + case aks.TypeStr: + return d.AksConfig case consul.TypeStr: return d.ConsulConfig case docker.TypeStr: diff --git a/processor/resourcedetectionprocessor/testdata/config.yaml b/processor/resourcedetectionprocessor/testdata/config.yaml index 42acce86c364..6cde1f5251c5 100644 --- a/processor/resourcedetectionprocessor/testdata/config.yaml +++ b/processor/resourcedetectionprocessor/testdata/config.yaml @@ -9,6 +9,11 @@ resourcedetection/openshift: tls: insecure: true +resourcedetection/aks: + detectors: [ env, aks ] + timeout: 2s + override: false + resourcedetection/gcp: detectors: [env, gcp] timeout: 2s From 57417bffb3f3d735682314d9eeea86fac1f8b435 Mon Sep 17 00:00:00 2001 From: Dmitrii Anoshin Date: Tue, 25 Jul 2023 15:14:18 -0700 Subject: [PATCH 34/42] [cmd/mdatagen] Consolidate resource building workflow (#24443) Use the recently introduced `ResourceBuilder` in `MetricsBuilder` instead of generating separate logic for resource creation. This consolidation will make all the future improvements to the `ResourceBuilder` applicable to scraping receivers and resource processors, removing the need to make the same improvements in two places. This also opens the door for getting away from the sequential `ResourceMetrics` building using `EmitForResource` towards a better structured map-based approach. The draft PR including the next steps: https://github.com/open-telemetry/opentelemetry-collector-contrib/pull/24444 --- ...gen-apply-resource-builder-on-metrics.yaml | 15 ++ .../metadata/generated_config_test.go | 52 ++++++ .../internal/metadata/generated_metrics.go | 65 +------- .../metadata/generated_metrics_test.go | 45 +----- .../internal/metadata/generated_resource.go | 71 +++++++++ .../metadata/generated_resource_test.go | 64 ++++++++ cmd/mdatagen/main.go | 21 +-- cmd/mdatagen/templates/config.go.tmpl | 8 +- cmd/mdatagen/templates/config_test.go.tmpl | 4 +- cmd/mdatagen/templates/metrics.go.tmpl | 61 ++----- cmd/mdatagen/templates/metrics_test.go.tmpl | 32 +--- cmd/mdatagen/templates/resource.go.tmpl | 2 + .../internal/metadata/generated_resource.go | 2 + .../internal/metadata/generated_resource.go | 2 + .../internal/metadata/generated_resource.go | 2 + .../internal/metadata/generated_resource.go | 2 + .../internal/metadata/generated_resource.go | 2 + .../internal/metadata/generated_resource.go | 2 + .../internal/metadata/generated_resource.go | 2 + .../internal/metadata/generated_resource.go | 2 + .../internal/metadata/generated_resource.go | 2 + .../internal/metadata/generated_resource.go | 2 + .../internal/metadata/generated_resource.go | 2 + .../internal/metadata/generated_resource.go | 2 + .../internal/metadata/generated_resource.go | 2 + .../internal/metadata/generated_resource.go | 2 + .../internal/metadata/generated_metrics.go | 13 +- .../metadata/generated_metrics_test.go | 10 +- .../metadata/generated_config_test.go | 46 ++++++ .../internal/metadata/generated_metrics.go | 33 +--- .../metadata/generated_metrics_test.go | 24 +-- .../internal/metadata/generated_resource.go | 43 +++++ .../metadata/generated_resource_test.go | 46 ++++++ receiver/aerospikereceiver/scraper.go | 9 +- receiver/aerospikereceiver/scraper_test.go | 20 ++- .../metadata/generated_config_test.go | 46 ++++++ .../internal/metadata/generated_metrics.go | 33 +--- .../metadata/generated_metrics_test.go | 24 +-- .../internal/metadata/generated_resource.go | 43 +++++ .../metadata/generated_resource_test.go | 46 ++++++ receiver/apachereceiver/scraper.go | 6 +- .../metadata/generated_config_test.go | 54 +++++++ .../internal/metadata/generated_metrics.go | 69 +------- .../metadata/generated_metrics_test.go | 52 +----- .../internal/metadata/generated_resource.go | 71 +++++++++ .../metadata/generated_resource_test.go | 70 ++++++++ receiver/apachesparkreceiver/scraper.go | 22 ++- .../internal/metadata/generated_resource.go | 2 + .../metadata/generated_config_test.go | 56 +++++++ .../internal/metadata/generated_metrics.go | 78 +-------- .../metadata/generated_metrics_test.go | 59 +------ .../internal/metadata/generated_resource.go | 78 +++++++++ .../metadata/generated_resource_test.go | 76 +++++++++ receiver/bigipreceiver/scraper.go | 32 ++-- .../internal/metadata/generated_metrics.go | 13 +- .../metadata/generated_metrics_test.go | 10 +- .../metadata/generated_config_test.go | 44 +++++ .../internal/metadata/generated_metrics.go | 24 +-- .../metadata/generated_metrics_test.go | 17 +- .../internal/metadata/generated_resource.go | 36 +++++ .../metadata/generated_resource_test.go | 40 +++++ receiver/couchdbreceiver/scraper.go | 5 +- .../metadata/generated_config_test.go | 56 +++++++ .../internal/metadata/generated_metrics.go | 88 ++-------- .../metadata/generated_metrics_test.go | 59 +------ .../internal/metadata/generated_resource.go | 78 +++++++++ .../metadata/generated_resource_test.go | 76 +++++++++ receiver/dockerstatsreceiver/receiver.go | 35 ++-- .../metadata/generated_config_test.go | 50 ++++++ .../internal/metadata/generated_metrics.go | 57 ++----- .../metadata/generated_metrics_test.go | 38 +---- .../internal/metadata/generated_resource.go | 57 +++++++ .../metadata/generated_resource_test.go | 58 +++++++ receiver/elasticsearchreceiver/scraper.go | 20 +-- .../internal/metadata/generated_metrics.go | 13 +- .../metadata/generated_metrics_test.go | 10 +- receiver/filestatsreceiver/factory.go | 3 +- .../metadata/generated_config_test.go | 46 ++++++ .../internal/metadata/generated_metrics.go | 63 +++----- .../metadata/generated_metrics_test.go | 24 +-- .../internal/metadata/generated_resource.go | 43 +++++ .../metadata/generated_resource_test.go | 46 ++++++ receiver/filestatsreceiver/scraper.go | 32 ++-- receiver/filestatsreceiver/scraper_test.go | 9 +- .../metadata/generated_config_test.go | 54 +++++++ .../internal/metadata/generated_metrics.go | 74 +-------- .../metadata/generated_metrics_test.go | 52 +----- .../internal/metadata/generated_resource.go | 78 +++++++++ .../metadata/generated_resource_test.go | 70 ++++++++ receiver/flinkmetricsreceiver/process.go | 36 ++--- receiver/flinkmetricsreceiver/scraper.go | 2 + receiver/haproxyreceiver/factory.go | 4 +- .../metadata/generated_config_test.go | 60 +++++++ .../internal/metadata/generated_metrics.go | 96 +---------- .../metadata/generated_metrics_test.go | 73 +-------- .../internal/metadata/generated_resource.go | 92 +++++++++++ .../metadata/generated_resource_test.go | 88 ++++++++++ receiver/haproxyreceiver/scraper.go | 88 +++++----- receiver/haproxyreceiver/scraper_test.go | 8 +- .../internal/metadata/generated_metrics.go | 13 +- .../metadata/generated_metrics_test.go | 10 +- .../internal/metadata/generated_metrics.go | 13 +- .../metadata/generated_metrics_test.go | 10 +- .../internal/metadata/generated_metrics.go | 13 +- .../metadata/generated_metrics_test.go | 10 +- .../internal/metadata/generated_metrics.go | 13 +- .../metadata/generated_metrics_test.go | 10 +- .../internal/metadata/generated_metrics.go | 13 +- .../metadata/generated_metrics_test.go | 10 +- .../internal/metadata/generated_metrics.go | 13 +- .../metadata/generated_metrics_test.go | 10 +- .../internal/metadata/generated_metrics.go | 13 +- .../metadata/generated_metrics_test.go | 10 +- .../internal/metadata/generated_metrics.go | 13 +- .../metadata/generated_metrics_test.go | 10 +- .../metadata/generated_config_test.go | 56 +++++++ .../internal/metadata/generated_metrics.go | 78 +-------- .../metadata/generated_metrics_test.go | 59 +------ .../internal/metadata/generated_resource.go | 78 +++++++++ .../metadata/generated_resource_test.go | 76 +++++++++ .../scraper/processscraper/process.go | 24 ++- .../scraper/processscraper/process_scraper.go | 6 +- .../internal/metadata/generated_metrics.go | 13 +- .../metadata/generated_metrics_test.go | 10 +- .../metadata/generated_config_test.go | 46 ++++++ .../internal/metadata/generated_metrics.go | 33 +--- .../metadata/generated_metrics_test.go | 24 +-- .../internal/metadata/generated_resource.go | 43 +++++ .../metadata/generated_resource_test.go | 46 ++++++ receiver/iisreceiver/scraper.go | 24 +-- .../clusterresourcequotas.go | 6 +- .../metadata/generated_config_test.go | 48 ++++++ .../internal/metadata/generated_metrics.go | 42 +---- .../metadata/generated_metrics_test.go | 31 +--- .../internal/metadata/generated_resource.go | 50 ++++++ .../metadata/generated_resource_test.go | 52 ++++++ .../internal/container/containers.go | 26 ++- .../metadata/generated_config_test.go | 60 +++++++ .../internal/metadata/generated_metrics.go | 96 +---------- .../metadata/generated_metrics_test.go | 73 +-------- .../internal/metadata/generated_resource.go | 92 +++++++++++ .../metadata/generated_resource_test.go | 88 ++++++++++ .../internal/cronjob/cronjobs.go | 25 ++- .../metadata/generated_config_test.go | 52 ++++++ .../internal/metadata/generated_metrics.go | 60 +------ .../metadata/generated_metrics_test.go | 45 +----- .../internal/metadata/generated_resource.go | 64 ++++++++ .../metadata/generated_resource_test.go | 64 ++++++++ .../internal/demonset/daemonsets.go | 13 +- .../metadata/generated_config_test.go | 50 ++++++ .../internal/metadata/generated_metrics.go | 51 +----- .../metadata/generated_metrics_test.go | 38 +---- .../internal/metadata/generated_resource.go | 57 +++++++ .../metadata/generated_resource_test.go | 58 +++++++ .../internal/deployment/deployments.go | 7 +- .../metadata/generated_config_test.go | 50 ++++++ .../internal/metadata/generated_metrics.go | 51 +----- .../metadata/generated_metrics_test.go | 38 +---- .../internal/metadata/generated_resource.go | 57 +++++++ .../metadata/generated_resource_test.go | 58 +++++++ .../k8sclusterreceiver/internal/hpa/hpa.go | 12 +- .../metadata/generated_config_test.go | 48 ++++++ .../internal/metadata/generated_metrics.go | 42 +---- .../metadata/generated_metrics_test.go | 31 +--- .../internal/metadata/generated_resource.go | 50 ++++++ .../metadata/generated_resource_test.go | 52 ++++++ .../metadata/generated_config_test.go | 50 ++++++ .../internal/metadata/generated_metrics.go | 51 +----- .../metadata/generated_metrics_test.go | 38 +---- .../internal/metadata/generated_resource.go | 57 +++++++ .../metadata/generated_resource_test.go | 58 +++++++ .../k8sclusterreceiver/internal/jobs/jobs.go | 9 +- .../metadata/generated_config_test.go | 48 ++++++ .../internal/metadata/generated_metrics.go | 60 ++----- .../metadata/generated_metrics_test.go | 31 +--- .../internal/metadata/generated_resource.go | 50 ++++++ .../metadata/generated_resource_test.go | 52 ++++++ .../internal/namespace/namespaces.go | 6 +- .../metadata/generated_config_test.go | 48 ++++++ .../internal/metadata/generated_metrics.go | 42 +---- .../metadata/generated_metrics_test.go | 31 +--- .../internal/metadata/generated_resource.go | 50 ++++++ .../metadata/generated_resource_test.go | 52 ++++++ .../k8sclusterreceiver/internal/node/nodes.go | 6 +- .../metadata/generated_config_test.go | 52 ++++++ .../internal/metadata/generated_metrics.go | 78 ++------- .../metadata/generated_metrics_test.go | 45 +----- .../internal/metadata/generated_resource.go | 64 ++++++++ .../metadata/generated_resource_test.go | 64 ++++++++ .../k8sclusterreceiver/internal/pod/pods.go | 8 +- .../metadata/generated_config_test.go | 50 ++++++ .../internal/metadata/generated_metrics.go | 51 +----- .../metadata/generated_metrics_test.go | 38 +---- .../internal/metadata/generated_resource.go | 57 +++++++ .../metadata/generated_resource_test.go | 58 +++++++ .../internal/replicaset/replicasets.go | 9 +- .../metadata/generated_config_test.go | 50 ++++++ .../internal/metadata/generated_metrics.go | 51 +----- .../metadata/generated_metrics_test.go | 38 +---- .../internal/metadata/generated_resource.go | 57 +++++++ .../metadata/generated_resource_test.go | 58 +++++++ .../replicationcontrollers.go | 12 +- .../metadata/generated_config_test.go | 50 ++++++ .../internal/metadata/generated_metrics.go | 51 +----- .../metadata/generated_metrics_test.go | 38 +---- .../internal/metadata/generated_resource.go | 57 +++++++ .../metadata/generated_resource_test.go | 58 +++++++ .../internal/resourcequota/resourcequotas.go | 7 +- .../metadata/generated_config_test.go | 50 ++++++ .../internal/metadata/generated_metrics.go | 51 +----- .../metadata/generated_metrics_test.go | 38 +---- .../internal/metadata/generated_resource.go | 57 +++++++ .../metadata/generated_resource_test.go | 58 +++++++ .../internal/statefulset/statefulsets.go | 7 +- .../internal/metadata/generated_metrics.go | 13 +- .../metadata/generated_metrics_test.go | 10 +- .../internal/kubelet/accumulator.go | 23 +-- .../internal/kubelet/accumulator_test.go | 10 +- .../internal/kubelet/metadata.go | 33 ++-- .../internal/kubelet/metadata_test.go | 31 ++-- .../internal/kubelet/metrics.go | 2 + .../internal/kubelet/metrics_test.go | 8 +- .../internal/kubelet/resource.go | 45 +++--- .../internal/kubelet/volume.go | 74 ++++----- .../internal/kubelet/volume_test.go | 40 ++--- .../metadata/generated_config_test.go | 72 +++++++++ .../internal/metadata/generated_metrics.go | 150 +----------------- .../metadata/generated_metrics_test.go | 115 +------------- .../internal/metadata/generated_resource.go | 134 ++++++++++++++++ .../metadata/generated_resource_test.go | 124 +++++++++++++++ receiver/kubeletstatsreceiver/scraper.go | 31 ++-- .../internal/metadata/generated_metrics.go | 13 +- .../metadata/generated_metrics_test.go | 10 +- .../metadata/generated_config_test.go | 64 ++++++++ .../internal/metadata/generated_metrics.go | 114 +------------ .../metadata/generated_metrics_test.go | 87 +--------- .../internal/metadata/generated_resource.go | 106 +++++++++++++ .../metadata/generated_resource_test.go | 100 ++++++++++++ receiver/mongodbatlasreceiver/receiver.go | 69 ++++---- .../metadata/generated_config_test.go | 44 +++++ .../internal/metadata/generated_metrics.go | 24 +-- .../metadata/generated_metrics_test.go | 17 +- .../internal/metadata/generated_resource.go | 36 +++++ .../metadata/generated_resource_test.go | 40 +++++ receiver/mongodbreceiver/scraper.go | 5 +- .../metadata/generated_config_test.go | 44 +++++ .../internal/metadata/generated_metrics.go | 24 +-- .../metadata/generated_metrics_test.go | 17 +- .../internal/metadata/generated_resource.go | 36 +++++ .../metadata/generated_resource_test.go | 40 +++++ receiver/mysqlreceiver/scraper.go | 5 +- .../internal/metadata/generated_metrics.go | 13 +- .../metadata/generated_metrics_test.go | 10 +- .../metadata/generated_config_test.go | 50 ++++++ .../internal/metadata/generated_metrics.go | 51 +----- .../metadata/generated_metrics_test.go | 38 +---- .../internal/metadata/generated_resource.go | 57 +++++++ .../metadata/generated_resource_test.go | 58 +++++++ receiver/nsxtreceiver/scraper.go | 22 +-- .../metadata/generated_config_test.go | 44 +++++ .../internal/metadata/generated_metrics.go | 24 +-- .../metadata/generated_metrics_test.go | 17 +- .../internal/metadata/generated_resource.go | 36 +++++ .../metadata/generated_resource_test.go | 40 +++++ receiver/oracledbreceiver/scraper.go | 75 +++++---- receiver/oracledbreceiver/scraper_test.go | 6 +- .../metadata/generated_config_test.go | 48 ++++++ .../internal/metadata/generated_metrics.go | 42 +---- .../metadata/generated_metrics_test.go | 31 +--- .../internal/metadata/generated_resource.go | 50 ++++++ .../metadata/generated_resource_test.go | 52 ++++++ receiver/postgresqlreceiver/scraper.go | 21 +-- .../metadata/generated_config_test.go | 48 ++++++ .../internal/metadata/generated_metrics.go | 42 +---- .../metadata/generated_metrics_test.go | 31 +--- .../internal/metadata/generated_resource.go | 50 ++++++ .../metadata/generated_resource_test.go | 52 ++++++ receiver/rabbitmqreceiver/scraper.go | 11 +- .../metadata/generated_config_test.go | 44 +++++ .../internal/metadata/generated_metrics.go | 24 +-- .../metadata/generated_metrics_test.go | 17 +- .../internal/metadata/generated_resource.go | 36 +++++ .../metadata/generated_resource_test.go | 40 +++++ receiver/redisreceiver/redis_scraper.go | 5 +- .../metadata/generated_config_test.go | 44 +++++ .../internal/metadata/generated_metrics.go | 24 +-- .../metadata/generated_metrics_test.go | 17 +- .../internal/metadata/generated_resource.go | 36 +++++ .../metadata/generated_resource_test.go | 40 +++++ receiver/riakreceiver/scraper.go | 5 +- .../metadata/generated_config_test.go | 46 ++++++ .../internal/metadata/generated_metrics.go | 33 +--- .../metadata/generated_metrics_test.go | 24 +-- .../internal/metadata/generated_resource.go | 43 +++++ .../metadata/generated_resource_test.go | 46 ++++++ receiver/saphanareceiver/scraper.go | 8 +- .../metadata/generated_config_test.go | 44 +++++ .../internal/metadata/generated_metrics.go | 24 +-- .../metadata/generated_metrics_test.go | 17 +- .../internal/metadata/generated_resource.go | 36 +++++ .../metadata/generated_resource_test.go | 40 +++++ receiver/snowflakereceiver/scraper.go | 5 +- .../metadata/generated_config_test.go | 48 ++++++ .../internal/metadata/generated_metrics.go | 42 +---- .../metadata/generated_metrics_test.go | 31 +--- .../internal/metadata/generated_resource.go | 50 ++++++ .../metadata/generated_resource_test.go | 52 ++++++ receiver/sqlserverreceiver/scraper.go | 24 +-- .../metadata/generated_config_test.go | 44 +++++ .../internal/metadata/generated_metrics.go | 24 +-- .../metadata/generated_metrics_test.go | 17 +- .../internal/metadata/generated_resource.go | 36 +++++ .../metadata/generated_resource_test.go | 40 +++++ .../metadata/generated_config_test.go | 54 +++++++ .../internal/metadata/generated_metrics.go | 69 +------- .../metadata/generated_metrics_test.go | 52 +----- .../internal/metadata/generated_resource.go | 71 +++++++++ .../metadata/generated_resource_test.go | 70 ++++++++ receiver/vcenterreceiver/scraper.go | 35 ++-- .../metadata/generated_config_test.go | 46 ++++++ .../internal/metadata/generated_metrics.go | 33 +--- .../metadata/generated_metrics_test.go | 24 +-- .../internal/metadata/generated_resource.go | 43 +++++ .../metadata/generated_resource_test.go | 46 ++++++ receiver/zookeeperreceiver/scraper.go | 15 +- 325 files changed, 8588 insertions(+), 4197 deletions(-) create mode 100755 .chloggen/mdatagen-apply-resource-builder-on-metrics.yaml create mode 100644 cmd/mdatagen/internal/metadata/generated_resource.go create mode 100644 cmd/mdatagen/internal/metadata/generated_resource_test.go create mode 100644 receiver/aerospikereceiver/internal/metadata/generated_resource.go create mode 100644 receiver/aerospikereceiver/internal/metadata/generated_resource_test.go create mode 100644 receiver/apachereceiver/internal/metadata/generated_resource.go create mode 100644 receiver/apachereceiver/internal/metadata/generated_resource_test.go create mode 100644 receiver/apachesparkreceiver/internal/metadata/generated_resource.go create mode 100644 receiver/apachesparkreceiver/internal/metadata/generated_resource_test.go create mode 100644 receiver/bigipreceiver/internal/metadata/generated_resource.go create mode 100644 receiver/bigipreceiver/internal/metadata/generated_resource_test.go create mode 100644 receiver/couchdbreceiver/internal/metadata/generated_resource.go create mode 100644 receiver/couchdbreceiver/internal/metadata/generated_resource_test.go create mode 100644 receiver/dockerstatsreceiver/internal/metadata/generated_resource.go create mode 100644 receiver/dockerstatsreceiver/internal/metadata/generated_resource_test.go create mode 100644 receiver/elasticsearchreceiver/internal/metadata/generated_resource.go create mode 100644 receiver/elasticsearchreceiver/internal/metadata/generated_resource_test.go create mode 100644 receiver/filestatsreceiver/internal/metadata/generated_resource.go create mode 100644 receiver/filestatsreceiver/internal/metadata/generated_resource_test.go create mode 100644 receiver/flinkmetricsreceiver/internal/metadata/generated_resource.go create mode 100644 receiver/flinkmetricsreceiver/internal/metadata/generated_resource_test.go create mode 100644 receiver/haproxyreceiver/internal/metadata/generated_resource.go create mode 100644 receiver/haproxyreceiver/internal/metadata/generated_resource_test.go create mode 100644 receiver/hostmetricsreceiver/internal/scraper/processscraper/internal/metadata/generated_resource.go create mode 100644 receiver/hostmetricsreceiver/internal/scraper/processscraper/internal/metadata/generated_resource_test.go create mode 100644 receiver/iisreceiver/internal/metadata/generated_resource.go create mode 100644 receiver/iisreceiver/internal/metadata/generated_resource_test.go create mode 100644 receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_resource.go create mode 100644 receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_resource_test.go create mode 100644 receiver/k8sclusterreceiver/internal/container/internal/metadata/generated_resource.go create mode 100644 receiver/k8sclusterreceiver/internal/container/internal/metadata/generated_resource_test.go create mode 100644 receiver/k8sclusterreceiver/internal/cronjob/internal/metadata/generated_resource.go create mode 100644 receiver/k8sclusterreceiver/internal/cronjob/internal/metadata/generated_resource_test.go create mode 100644 receiver/k8sclusterreceiver/internal/demonset/internal/metadata/generated_resource.go create mode 100644 receiver/k8sclusterreceiver/internal/demonset/internal/metadata/generated_resource_test.go create mode 100644 receiver/k8sclusterreceiver/internal/deployment/internal/metadata/generated_resource.go create mode 100644 receiver/k8sclusterreceiver/internal/deployment/internal/metadata/generated_resource_test.go create mode 100644 receiver/k8sclusterreceiver/internal/hpa/internal/metadata/generated_resource.go create mode 100644 receiver/k8sclusterreceiver/internal/hpa/internal/metadata/generated_resource_test.go create mode 100644 receiver/k8sclusterreceiver/internal/jobs/internal/metadata/generated_resource.go create mode 100644 receiver/k8sclusterreceiver/internal/jobs/internal/metadata/generated_resource_test.go create mode 100644 receiver/k8sclusterreceiver/internal/namespace/internal/metadata/generated_resource.go create mode 100644 receiver/k8sclusterreceiver/internal/namespace/internal/metadata/generated_resource_test.go create mode 100644 receiver/k8sclusterreceiver/internal/node/internal/metadata/generated_resource.go create mode 100644 receiver/k8sclusterreceiver/internal/node/internal/metadata/generated_resource_test.go create mode 100644 receiver/k8sclusterreceiver/internal/pod/internal/metadata/generated_resource.go create mode 100644 receiver/k8sclusterreceiver/internal/pod/internal/metadata/generated_resource_test.go create mode 100644 receiver/k8sclusterreceiver/internal/replicaset/internal/metadata/generated_resource.go create mode 100644 receiver/k8sclusterreceiver/internal/replicaset/internal/metadata/generated_resource_test.go create mode 100644 receiver/k8sclusterreceiver/internal/replicationcontroller/internal/metadata/generated_resource.go create mode 100644 receiver/k8sclusterreceiver/internal/replicationcontroller/internal/metadata/generated_resource_test.go create mode 100644 receiver/k8sclusterreceiver/internal/resourcequota/internal/metadata/generated_resource.go create mode 100644 receiver/k8sclusterreceiver/internal/resourcequota/internal/metadata/generated_resource_test.go create mode 100644 receiver/k8sclusterreceiver/internal/statefulset/internal/metadata/generated_resource.go create mode 100644 receiver/k8sclusterreceiver/internal/statefulset/internal/metadata/generated_resource_test.go create mode 100644 receiver/kubeletstatsreceiver/internal/metadata/generated_resource.go create mode 100644 receiver/kubeletstatsreceiver/internal/metadata/generated_resource_test.go create mode 100644 receiver/mongodbatlasreceiver/internal/metadata/generated_resource.go create mode 100644 receiver/mongodbatlasreceiver/internal/metadata/generated_resource_test.go create mode 100644 receiver/mongodbreceiver/internal/metadata/generated_resource.go create mode 100644 receiver/mongodbreceiver/internal/metadata/generated_resource_test.go create mode 100644 receiver/mysqlreceiver/internal/metadata/generated_resource.go create mode 100644 receiver/mysqlreceiver/internal/metadata/generated_resource_test.go create mode 100644 receiver/nsxtreceiver/internal/metadata/generated_resource.go create mode 100644 receiver/nsxtreceiver/internal/metadata/generated_resource_test.go create mode 100644 receiver/oracledbreceiver/internal/metadata/generated_resource.go create mode 100644 receiver/oracledbreceiver/internal/metadata/generated_resource_test.go create mode 100644 receiver/postgresqlreceiver/internal/metadata/generated_resource.go create mode 100644 receiver/postgresqlreceiver/internal/metadata/generated_resource_test.go create mode 100644 receiver/rabbitmqreceiver/internal/metadata/generated_resource.go create mode 100644 receiver/rabbitmqreceiver/internal/metadata/generated_resource_test.go create mode 100644 receiver/redisreceiver/internal/metadata/generated_resource.go create mode 100644 receiver/redisreceiver/internal/metadata/generated_resource_test.go create mode 100644 receiver/riakreceiver/internal/metadata/generated_resource.go create mode 100644 receiver/riakreceiver/internal/metadata/generated_resource_test.go create mode 100644 receiver/saphanareceiver/internal/metadata/generated_resource.go create mode 100644 receiver/saphanareceiver/internal/metadata/generated_resource_test.go create mode 100644 receiver/snowflakereceiver/internal/metadata/generated_resource.go create mode 100644 receiver/snowflakereceiver/internal/metadata/generated_resource_test.go create mode 100644 receiver/sqlserverreceiver/internal/metadata/generated_resource.go create mode 100644 receiver/sqlserverreceiver/internal/metadata/generated_resource_test.go create mode 100644 receiver/sshcheckreceiver/internal/metadata/generated_resource.go create mode 100644 receiver/sshcheckreceiver/internal/metadata/generated_resource_test.go create mode 100644 receiver/vcenterreceiver/internal/metadata/generated_resource.go create mode 100644 receiver/vcenterreceiver/internal/metadata/generated_resource_test.go create mode 100644 receiver/zookeeperreceiver/internal/metadata/generated_resource.go create mode 100644 receiver/zookeeperreceiver/internal/metadata/generated_resource_test.go diff --git a/.chloggen/mdatagen-apply-resource-builder-on-metrics.yaml b/.chloggen/mdatagen-apply-resource-builder-on-metrics.yaml new file mode 100755 index 000000000000..ea3c93bc74d8 --- /dev/null +++ b/.chloggen/mdatagen-apply-resource-builder-on-metrics.yaml @@ -0,0 +1,15 @@ +# Use this changelog template to create an entry for release notes. +# If your change doesn't affect end users, such as a test fix or a tooling change, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. + +# 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. filelogreceiver) +component: cmd/mdatagen + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Simplify resource building in MetricsBuilder, suggest using ResourceBuilder instead. + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [24443] diff --git a/cmd/mdatagen/internal/metadata/generated_config_test.go b/cmd/mdatagen/internal/metadata/generated_config_test.go index 2d4a8a66df4e..c00d9fcfb48d 100644 --- a/cmd/mdatagen/internal/metadata/generated_config_test.go +++ b/cmd/mdatagen/internal/metadata/generated_config_test.go @@ -76,3 +76,55 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +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}, + }, + }, + { + 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}, + }, + }, + } + 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/cmd/mdatagen/internal/metadata/generated_metrics.go b/cmd/mdatagen/internal/metadata/generated_metrics.go index 05adcb6cf036..37aed9c7877e 100644 --- a/cmd/mdatagen/internal/metadata/generated_metrics.go +++ b/cmd/mdatagen/internal/metadata/generated_metrics.go @@ -207,10 +207,8 @@ func newMetricOptionalMetric(cfg MetricConfig) metricOptionalMetric { type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricDefaultMetric metricDefaultMetric metricDefaultMetricToBeRemoved metricDefaultMetricToBeRemoved metricOptionalMetric metricOptionalMetric @@ -240,7 +238,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricDefaultMetric: newMetricDefaultMetric(mbc.Metrics.DefaultMetric), metricDefaultMetricToBeRemoved: newMetricDefaultMetricToBeRemoved(mbc.Metrics.DefaultMetricToBeRemoved), metricOptionalMetric: newMetricOptionalMetric(mbc.Metrics.OptionalMetric), @@ -256,68 +253,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithMapResourceAttr sets provided value as "map.resource.attr" attribute for current resource. -func WithMapResourceAttr(val map[string]any) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.MapResourceAttr.Enabled { - rm.Resource().Attributes().PutEmptyMap("map.resource.attr").FromRaw(val) - } - } -} - -// WithOptionalResourceAttr sets provided value as "optional.resource.attr" attribute for current resource. -func WithOptionalResourceAttr(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.OptionalResourceAttr.Enabled { - rm.Resource().Attributes().PutStr("optional.resource.attr", val) - } - } -} - -// WithSliceResourceAttr sets provided value as "slice.resource.attr" attribute for current resource. -func WithSliceResourceAttr(val []any) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.SliceResourceAttr.Enabled { - rm.Resource().Attributes().PutEmptySlice("slice.resource.attr").FromRaw(val) - } - } -} - -// WithStringEnumResourceAttrOne sets "string.enum.resource.attr=one" attribute for current resource. -func WithStringEnumResourceAttrOne(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.StringEnumResourceAttr.Enabled { - rm.Resource().Attributes().PutStr("string.enum.resource.attr", "one") - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithStringEnumResourceAttrTwo sets "string.enum.resource.attr=two" attribute for current resource. -func WithStringEnumResourceAttrTwo(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.StringEnumResourceAttr.Enabled { - rm.Resource().Attributes().PutStr("string.enum.resource.attr", "two") - } -} - -// WithStringResourceAttr sets provided value as "string.resource.attr" attribute for current resource. -func WithStringResourceAttr(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.StringResourceAttr.Enabled { - rm.Resource().Attributes().PutStr("string.resource.attr", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -342,7 +294,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() rm.SetSchemaUrl(conventions.SchemaURL) - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -352,7 +303,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricOptionalMetric.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/cmd/mdatagen/internal/metadata/generated_metrics_test.go b/cmd/mdatagen/internal/metadata/generated_metrics_test.go index 678be0575b9a..9ce810cfaee6 100644 --- a/cmd/mdatagen/internal/metadata/generated_metrics_test.go +++ b/cmd/mdatagen/internal/metadata/generated_metrics_test.go @@ -77,7 +77,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordOptionalMetricDataPoint(ts, 1, "string_attr-val", true) - metrics := mb.Emit(WithMapResourceAttr(map[string]any{"key1": "map.resource.attr-val1", "key2": "map.resource.attr-val2"}), WithOptionalResourceAttr("optional.resource.attr-val"), WithSliceResourceAttr([]any{"slice.resource.attr-item1", "slice.resource.attr-item2"}), WithStringEnumResourceAttrOne, WithStringResourceAttr("string.resource.attr-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -86,46 +88,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("map.resource.attr") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.MapResourceAttr.Enabled, ok) - if mb.resourceAttributesConfig.MapResourceAttr.Enabled { - enabledAttrCount++ - assert.EqualValues(t, map[string]any{"key1": "map.resource.attr-val1", "key2": "map.resource.attr-val2"}, attrVal.Map().AsRaw()) - } - attrVal, ok = rm.Resource().Attributes().Get("optional.resource.attr") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.OptionalResourceAttr.Enabled, ok) - if mb.resourceAttributesConfig.OptionalResourceAttr.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "optional.resource.attr-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("slice.resource.attr") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.SliceResourceAttr.Enabled, ok) - if mb.resourceAttributesConfig.SliceResourceAttr.Enabled { - enabledAttrCount++ - assert.EqualValues(t, []any{"slice.resource.attr-item1", "slice.resource.attr-item2"}, attrVal.Slice().AsRaw()) - } - attrVal, ok = rm.Resource().Attributes().Get("string.enum.resource.attr") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.StringEnumResourceAttr.Enabled, ok) - if mb.resourceAttributesConfig.StringEnumResourceAttr.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "one", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("string.resource.attr") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.StringResourceAttr.Enabled, ok) - if mb.resourceAttributesConfig.StringResourceAttr.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "string.resource.attr-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 5) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/cmd/mdatagen/internal/metadata/generated_resource.go b/cmd/mdatagen/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..7f22618828fc --- /dev/null +++ b/cmd/mdatagen/internal/metadata/generated_resource.go @@ -0,0 +1,71 @@ +// 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) + } +} + +// 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/metadata/generated_resource_test.go b/cmd/mdatagen/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..8b64ebacb2b5 --- /dev/null +++ b/cmd/mdatagen/internal/metadata/generated_resource_test.go @@ -0,0 +1,64 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + 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") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 4, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 5, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + 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, test == "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()) + } + }) + } +} diff --git a/cmd/mdatagen/main.go b/cmd/mdatagen/main.go index 9a56b1ade1eb..e841f8a31219 100644 --- a/cmd/mdatagen/main.go +++ b/cmd/mdatagen/main.go @@ -91,17 +91,18 @@ func run(ymlPath string) error { return err } - if len(md.Metrics) == 0 { - if len(md.ResourceAttributes) > 0 { - if err = generateFile(filepath.Join(tmplDir, "resource.go.tmpl"), - filepath.Join(codeDir, "generated_resource.go"), md); err != nil { - return err - } - if err = generateFile(filepath.Join(tmplDir, "resource_test.go.tmpl"), - filepath.Join(codeDir, "generated_resource_test.go"), md); err != nil { - return err - } + if len(md.ResourceAttributes) > 0 { + if err = generateFile(filepath.Join(tmplDir, "resource.go.tmpl"), + filepath.Join(codeDir, "generated_resource.go"), md); err != nil { + return err } + if err = generateFile(filepath.Join(tmplDir, "resource_test.go.tmpl"), + filepath.Join(codeDir, "generated_resource_test.go"), md); err != nil { + return err + } + } + + if len(md.Metrics) == 0 { return nil } diff --git a/cmd/mdatagen/templates/config.go.tmpl b/cmd/mdatagen/templates/config.go.tmpl index 546fbedc11aa..e0d8be2b1303 100644 --- a/cmd/mdatagen/templates/config.go.tmpl +++ b/cmd/mdatagen/templates/config.go.tmpl @@ -69,10 +69,10 @@ func DefaultResourceAttributesConfig() ResourceAttributesConfig { {{ if .Metrics -}} // MetricsBuilderConfig is a configuration for {{ .Type }} metrics builder. type MetricsBuilderConfig struct { - Metrics MetricsConfig `mapstructure:"metrics"` - {{- if .ResourceAttributes }} - ResourceAttributes ResourceAttributesConfig `mapstructure:"resource_attributes"` - {{- end }} + Metrics MetricsConfig `mapstructure:"metrics"` + {{- if .ResourceAttributes }} + ResourceAttributes ResourceAttributesConfig `mapstructure:"resource_attributes"` + {{- end }} } func DefaultMetricsBuilderConfig() MetricsBuilderConfig { diff --git a/cmd/mdatagen/templates/config_test.go.tmpl b/cmd/mdatagen/templates/config_test.go.tmpl index 5fe8140377bf..3f6a636bc6ec 100644 --- a/cmd/mdatagen/templates/config_test.go.tmpl +++ b/cmd/mdatagen/templates/config_test.go.tmpl @@ -78,9 +78,9 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } +{{- end }} -{{- else }} - +{{ if .ResourceAttributes -}} func TestResourceAttributesConfig(t *testing.T) { tests := []struct { name string diff --git a/cmd/mdatagen/templates/metrics.go.tmpl b/cmd/mdatagen/templates/metrics.go.tmpl index ba11db6b3983..6462f75cc0d0 100644 --- a/cmd/mdatagen/templates/metrics.go.tmpl +++ b/cmd/mdatagen/templates/metrics.go.tmpl @@ -127,14 +127,10 @@ func newMetric{{ $name.Render }}(cfg MetricConfig) metric{{ $name.Render }} { // MetricsBuilder provides an interface for scrapers to report metrics while taking care of all the transformations // required to produce metric representation defined in metadata and user config. type MetricsBuilder struct { - startTime pcommon.Timestamp // start time that will be applied to all recorded data points. - metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. - metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. - buildInfo component.BuildInfo // contains version information - {{- if .ResourceAttributes }} - resourceAttributesConfig ResourceAttributesConfig - {{- end }} + startTime pcommon.Timestamp // start time that will be applied to all recorded data points. + metricsCapacity int // maximum observed number of metrics per resource. + metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. + buildInfo component.BuildInfo // contains version information {{- range $name, $metric := .Metrics }} metric{{ $name.Render }} metric{{ $name.Render }} {{- end }} @@ -169,12 +165,9 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting {{- end }} {{- end }} mb := &MetricsBuilder{ - startTime: pcommon.NewTimestampFromTime(time.Now()), - metricsBuffer: pmetric.NewMetrics(), - buildInfo: settings.BuildInfo, - {{- if .ResourceAttributes }} - resourceAttributesConfig: mbc.ResourceAttributes, - {{- end }} + startTime: pcommon.NewTimestampFromTime(time.Now()), + metricsBuffer: pmetric.NewMetrics(), + buildInfo: settings.BuildInfo, {{- range $name, $metric := .Metrics }} metric{{ $name.Render }}: newMetric{{ $name.Render }}(mbc.Metrics.{{ $name.Render }}), {{- end }} @@ -190,46 +183,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func({{ if .ResourceAttributes }}ResourceAttributesConfig, {{ end }}pmetric.ResourceMetrics) +type ResourceMetricsOption func(pmetric.ResourceMetrics) -{{- range $name, $attr := .ResourceAttributes }} -{{- range $attr.Enum }} -// With{{ $name.Render }}{{ . | publicVar }} sets "{{ $attr.Name }}={{ . }}" attribute for current resource. -func With{{ $name.Render }}{{ . | publicVar }}(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.{{ $name.Render }}.Enabled { - rm.Resource().Attributes().PutStr("{{ $attr.Name }}", "{{ . }}") - } -} -{{- else }} -// With{{ $name.Render }} sets provided value as "{{ $name }}" attribute for current resource. -func With{{ $name.Render }}(val {{ $attr.Type.Primitive }}) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.{{ $name.Render }}.Enabled { - {{- if eq $attr.Type.Primitive "[]byte" }} - rm.Resource().Attributes().PutEmptyBytes("{{ $attr.Name }}").FromRaw(val) - {{- else if eq $attr.Type.Primitive "[]any" }} - rm.Resource().Attributes().PutEmptySlice("{{ $attr.Name }}").FromRaw(val) - {{- else if eq $attr.Type.Primitive "map[string]any" }} - rm.Resource().Attributes().PutEmptyMap("{{ $attr.Name }}").FromRaw(val) - {{- else }} - rm.Resource().Attributes().Put{{ $attr.Type }}("{{ $attr.Name }}", val) - {{- end }} - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } -{{- end }} -{{ end }} // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func({{ if .ResourceAttributes }}_ ResourceAttributesConfig, {{ end }}rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -256,7 +226,6 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { {{- if .SemConvVersion }} rm.SetSchemaUrl(conventions.SchemaURL) {{- end }} - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("{{ .ScopeName }}") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -266,7 +235,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { {{- end }} for _, op := range rmo { - op({{ if .ResourceAttributes }}mb.resourceAttributesConfig, {{ end }}rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/cmd/mdatagen/templates/metrics_test.go.tmpl b/cmd/mdatagen/templates/metrics_test.go.tmpl index a33ff52030ba..3a50dca8cc7b 100644 --- a/cmd/mdatagen/templates/metrics_test.go.tmpl +++ b/cmd/mdatagen/templates/metrics_test.go.tmpl @@ -24,7 +24,7 @@ const ( func TestMetricsBuilder(t *testing.T) { tests := []struct { - name string + name string configSet testConfigCollection }{ { @@ -84,14 +84,9 @@ func TestMetricsBuilder(t *testing.T) { {{- end }}) {{- end }} - metrics := mb.Emit( - {{- $sep := "" }} - {{- range $name, $info := .ResourceAttributes -}} - {{- $sep }}With{{ $name.Render }} - {{- if $info.Enum }}{{ index $info.Enum 0 | publicVar }}{{ else }}({{- $info.TestValue }}){{ end }} - {{- $sep = ", " }} - {{- end -}} - ) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -100,24 +95,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - {{- $assignSign := ":=" }} - attrCount := 0 - enabledAttrCount := 0 - {{- range $name, $info := .ResourceAttributes }} - attrVal, ok {{ $assignSign }} rm.Resource().Attributes().Get("{{ $name }}") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.{{ $name.Render }}.Enabled, ok) - if mb.resourceAttributesConfig.{{ $name.Render }}.Enabled { - enabledAttrCount++ - assert.EqualValues(t, {{ $info.TestValue }}, attrVal.{{ $info.Type }}() - {{- if or (eq $info.Type.String "Slice") (eq $info.Type.String "Map") }}.AsRaw(){{ end }}) - } - - {{- $assignSign = "=" }} - {{- end }} - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, {{ len .ResourceAttributes }}) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/cmd/mdatagen/templates/resource.go.tmpl b/cmd/mdatagen/templates/resource.go.tmpl index 661c4c265827..aa6b8e8b685b 100644 --- a/cmd/mdatagen/templates/resource.go.tmpl +++ b/cmd/mdatagen/templates/resource.go.tmpl @@ -7,11 +7,13 @@ import ( ) // 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, diff --git a/processor/k8sattributesprocessor/internal/metadata/generated_resource.go b/processor/k8sattributesprocessor/internal/metadata/generated_resource.go index b8c3ea5ec12d..d8981673d707 100644 --- a/processor/k8sattributesprocessor/internal/metadata/generated_resource.go +++ b/processor/k8sattributesprocessor/internal/metadata/generated_resource.go @@ -7,11 +7,13 @@ import ( ) // 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, diff --git a/processor/resourcedetectionprocessor/internal/aws/ec2/internal/metadata/generated_resource.go b/processor/resourcedetectionprocessor/internal/aws/ec2/internal/metadata/generated_resource.go index 089fc809ebce..9c280774dc31 100644 --- a/processor/resourcedetectionprocessor/internal/aws/ec2/internal/metadata/generated_resource.go +++ b/processor/resourcedetectionprocessor/internal/aws/ec2/internal/metadata/generated_resource.go @@ -7,11 +7,13 @@ import ( ) // 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, diff --git a/processor/resourcedetectionprocessor/internal/aws/ecs/internal/metadata/generated_resource.go b/processor/resourcedetectionprocessor/internal/aws/ecs/internal/metadata/generated_resource.go index 2584951c8104..0a8434146709 100644 --- a/processor/resourcedetectionprocessor/internal/aws/ecs/internal/metadata/generated_resource.go +++ b/processor/resourcedetectionprocessor/internal/aws/ecs/internal/metadata/generated_resource.go @@ -7,11 +7,13 @@ import ( ) // 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, diff --git a/processor/resourcedetectionprocessor/internal/aws/eks/internal/metadata/generated_resource.go b/processor/resourcedetectionprocessor/internal/aws/eks/internal/metadata/generated_resource.go index 34c69060802b..aff8c18f53ad 100644 --- a/processor/resourcedetectionprocessor/internal/aws/eks/internal/metadata/generated_resource.go +++ b/processor/resourcedetectionprocessor/internal/aws/eks/internal/metadata/generated_resource.go @@ -7,11 +7,13 @@ import ( ) // 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, diff --git a/processor/resourcedetectionprocessor/internal/aws/elasticbeanstalk/internal/metadata/generated_resource.go b/processor/resourcedetectionprocessor/internal/aws/elasticbeanstalk/internal/metadata/generated_resource.go index bde141a67748..5c21111cd5b6 100644 --- a/processor/resourcedetectionprocessor/internal/aws/elasticbeanstalk/internal/metadata/generated_resource.go +++ b/processor/resourcedetectionprocessor/internal/aws/elasticbeanstalk/internal/metadata/generated_resource.go @@ -7,11 +7,13 @@ import ( ) // 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, diff --git a/processor/resourcedetectionprocessor/internal/aws/lambda/internal/metadata/generated_resource.go b/processor/resourcedetectionprocessor/internal/aws/lambda/internal/metadata/generated_resource.go index ff52cc56e884..c1b38afe4771 100644 --- a/processor/resourcedetectionprocessor/internal/aws/lambda/internal/metadata/generated_resource.go +++ b/processor/resourcedetectionprocessor/internal/aws/lambda/internal/metadata/generated_resource.go @@ -7,11 +7,13 @@ import ( ) // 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, diff --git a/processor/resourcedetectionprocessor/internal/azure/aks/internal/metadata/generated_resource.go b/processor/resourcedetectionprocessor/internal/azure/aks/internal/metadata/generated_resource.go index 34c69060802b..aff8c18f53ad 100644 --- a/processor/resourcedetectionprocessor/internal/azure/aks/internal/metadata/generated_resource.go +++ b/processor/resourcedetectionprocessor/internal/azure/aks/internal/metadata/generated_resource.go @@ -7,11 +7,13 @@ import ( ) // 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, diff --git a/processor/resourcedetectionprocessor/internal/azure/internal/metadata/generated_resource.go b/processor/resourcedetectionprocessor/internal/azure/internal/metadata/generated_resource.go index 32c04e340056..3ed9f08abc82 100644 --- a/processor/resourcedetectionprocessor/internal/azure/internal/metadata/generated_resource.go +++ b/processor/resourcedetectionprocessor/internal/azure/internal/metadata/generated_resource.go @@ -7,11 +7,13 @@ import ( ) // 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, diff --git a/processor/resourcedetectionprocessor/internal/consul/internal/metadata/generated_resource.go b/processor/resourcedetectionprocessor/internal/consul/internal/metadata/generated_resource.go index 32c04e340056..3ed9f08abc82 100644 --- a/processor/resourcedetectionprocessor/internal/consul/internal/metadata/generated_resource.go +++ b/processor/resourcedetectionprocessor/internal/consul/internal/metadata/generated_resource.go @@ -7,11 +7,13 @@ import ( ) // 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, diff --git a/processor/resourcedetectionprocessor/internal/docker/internal/metadata/generated_resource.go b/processor/resourcedetectionprocessor/internal/docker/internal/metadata/generated_resource.go index 27c8edac41e8..865734882c35 100644 --- a/processor/resourcedetectionprocessor/internal/docker/internal/metadata/generated_resource.go +++ b/processor/resourcedetectionprocessor/internal/docker/internal/metadata/generated_resource.go @@ -7,11 +7,13 @@ import ( ) // 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, diff --git a/processor/resourcedetectionprocessor/internal/gcp/internal/metadata/generated_resource.go b/processor/resourcedetectionprocessor/internal/gcp/internal/metadata/generated_resource.go index 434706c61835..45ef70e5e232 100644 --- a/processor/resourcedetectionprocessor/internal/gcp/internal/metadata/generated_resource.go +++ b/processor/resourcedetectionprocessor/internal/gcp/internal/metadata/generated_resource.go @@ -7,11 +7,13 @@ import ( ) // 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, diff --git a/processor/resourcedetectionprocessor/internal/heroku/internal/metadata/generated_resource.go b/processor/resourcedetectionprocessor/internal/heroku/internal/metadata/generated_resource.go index dc829cb4dad1..47a9a4d2a802 100644 --- a/processor/resourcedetectionprocessor/internal/heroku/internal/metadata/generated_resource.go +++ b/processor/resourcedetectionprocessor/internal/heroku/internal/metadata/generated_resource.go @@ -7,11 +7,13 @@ import ( ) // 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, diff --git a/processor/resourcedetectionprocessor/internal/openshift/internal/metadata/generated_resource.go b/processor/resourcedetectionprocessor/internal/openshift/internal/metadata/generated_resource.go index a0ecb7f56a65..102cad37a6c7 100644 --- a/processor/resourcedetectionprocessor/internal/openshift/internal/metadata/generated_resource.go +++ b/processor/resourcedetectionprocessor/internal/openshift/internal/metadata/generated_resource.go @@ -7,11 +7,13 @@ import ( ) // 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, diff --git a/processor/resourcedetectionprocessor/internal/system/internal/metadata/generated_resource.go b/processor/resourcedetectionprocessor/internal/system/internal/metadata/generated_resource.go index f4dd04fbb8b8..4c3acdf9edb7 100644 --- a/processor/resourcedetectionprocessor/internal/system/internal/metadata/generated_resource.go +++ b/processor/resourcedetectionprocessor/internal/system/internal/metadata/generated_resource.go @@ -7,11 +7,13 @@ import ( ) // 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, diff --git a/receiver/activedirectorydsreceiver/internal/metadata/generated_metrics.go b/receiver/activedirectorydsreceiver/internal/metadata/generated_metrics.go index 98d3ab915e38..a64c8b68b0d4 100644 --- a/receiver/activedirectorydsreceiver/internal/metadata/generated_metrics.go +++ b/receiver/activedirectorydsreceiver/internal/metadata/generated_metrics.go @@ -1138,7 +1138,6 @@ func newMetricActiveDirectoryDsThreadCount(cfg MetricConfig) metricActiveDirecto type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information metricActiveDirectoryDsBindRate metricActiveDirectoryDsBindRate @@ -1206,14 +1205,19 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. type ResourceMetricsOption func(pmetric.ResourceMetrics) +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) + } +} + // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { @@ -1241,7 +1245,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/activedirectorydsreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) diff --git a/receiver/activedirectorydsreceiver/internal/metadata/generated_metrics_test.go b/receiver/activedirectorydsreceiver/internal/metadata/generated_metrics_test.go index 92e2e3cfcc4b..4119260e0bcd 100644 --- a/receiver/activedirectorydsreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/activedirectorydsreceiver/internal/metadata/generated_metrics_test.go @@ -126,7 +126,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordActiveDirectoryDsThreadCountDataPoint(ts, 1) - metrics := mb.Emit() + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -135,11 +137,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 0) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/aerospikereceiver/internal/metadata/generated_config_test.go b/receiver/aerospikereceiver/internal/metadata/generated_config_test.go index e59e0165562a..8992f9d38ad9 100644 --- a/receiver/aerospikereceiver/internal/metadata/generated_config_test.go +++ b/receiver/aerospikereceiver/internal/metadata/generated_config_test.go @@ -92,3 +92,49 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + AerospikeNamespace: ResourceAttributeConfig{Enabled: true}, + AerospikeNodeName: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + AerospikeNamespace: ResourceAttributeConfig{Enabled: false}, + AerospikeNodeName: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/aerospikereceiver/internal/metadata/generated_metrics.go b/receiver/aerospikereceiver/internal/metadata/generated_metrics.go index a5500be2f287..694c52dd28a3 100644 --- a/receiver/aerospikereceiver/internal/metadata/generated_metrics.go +++ b/receiver/aerospikereceiver/internal/metadata/generated_metrics.go @@ -1075,10 +1075,8 @@ func newMetricAerospikeNodeQueryTracked(cfg MetricConfig) metricAerospikeNodeQue type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricAerospikeNamespaceDiskAvailable metricAerospikeNamespaceDiskAvailable metricAerospikeNamespaceGeojsonRegionQueryCells metricAerospikeNamespaceGeojsonRegionQueryCells metricAerospikeNamespaceGeojsonRegionQueryFalsePositive metricAerospikeNamespaceGeojsonRegionQueryFalsePositive @@ -1110,7 +1108,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricAerospikeNamespaceDiskAvailable: newMetricAerospikeNamespaceDiskAvailable(mbc.Metrics.AerospikeNamespaceDiskAvailable), metricAerospikeNamespaceGeojsonRegionQueryCells: newMetricAerospikeNamespaceGeojsonRegionQueryCells(mbc.Metrics.AerospikeNamespaceGeojsonRegionQueryCells), metricAerospikeNamespaceGeojsonRegionQueryFalsePositive: newMetricAerospikeNamespaceGeojsonRegionQueryFalsePositive(mbc.Metrics.AerospikeNamespaceGeojsonRegionQueryFalsePositive), @@ -1137,36 +1134,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithAerospikeNamespace sets provided value as "aerospike.namespace" attribute for current resource. -func WithAerospikeNamespace(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.AerospikeNamespace.Enabled { - rm.Resource().Attributes().PutStr("aerospike.namespace", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithAerospikeNodeName sets provided value as "aerospike.node.name" attribute for current resource. -func WithAerospikeNodeName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.AerospikeNodeName.Enabled { - rm.Resource().Attributes().PutStr("aerospike.node.name", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -1190,7 +1174,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/aerospikereceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -1211,7 +1194,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricAerospikeNodeQueryTracked.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/aerospikereceiver/internal/metadata/generated_metrics_test.go b/receiver/aerospikereceiver/internal/metadata/generated_metrics_test.go index 303c7fa726d3..e58a339185bf 100644 --- a/receiver/aerospikereceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/aerospikereceiver/internal/metadata/generated_metrics_test.go @@ -110,7 +110,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordAerospikeNodeQueryTrackedDataPoint(ts, "1") - metrics := mb.Emit(WithAerospikeNamespace("aerospike.namespace-val"), WithAerospikeNodeName("aerospike.node.name-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -119,25 +121,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("aerospike.namespace") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.AerospikeNamespace.Enabled, ok) - if mb.resourceAttributesConfig.AerospikeNamespace.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "aerospike.namespace-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("aerospike.node.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.AerospikeNodeName.Enabled, ok) - if mb.resourceAttributesConfig.AerospikeNodeName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "aerospike.node.name-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 2) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/aerospikereceiver/internal/metadata/generated_resource.go b/receiver/aerospikereceiver/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..e6e93afd2bdb --- /dev/null +++ b/receiver/aerospikereceiver/internal/metadata/generated_resource.go @@ -0,0 +1,43 @@ +// 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(), + } +} + +// SetAerospikeNamespace sets provided value as "aerospike.namespace" attribute. +func (rb *ResourceBuilder) SetAerospikeNamespace(val string) { + if rb.config.AerospikeNamespace.Enabled { + rb.res.Attributes().PutStr("aerospike.namespace", val) + } +} + +// SetAerospikeNodeName sets provided value as "aerospike.node.name" attribute. +func (rb *ResourceBuilder) SetAerospikeNodeName(val string) { + if rb.config.AerospikeNodeName.Enabled { + rb.res.Attributes().PutStr("aerospike.node.name", 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/receiver/aerospikereceiver/internal/metadata/generated_resource_test.go b/receiver/aerospikereceiver/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..f9afb81e9b5e --- /dev/null +++ b/receiver/aerospikereceiver/internal/metadata/generated_resource_test.go @@ -0,0 +1,46 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetAerospikeNamespace("aerospike.namespace-val") + rb.SetAerospikeNodeName("aerospike.node.name-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 2, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 2, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("aerospike.namespace") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "aerospike.namespace-val", val.Str()) + } + val, ok = res.Attributes().Get("aerospike.node.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "aerospike.node.name-val", val.Str()) + } + }) + } +} diff --git a/receiver/aerospikereceiver/scraper.go b/receiver/aerospikereceiver/scraper.go index f69a9380baab..4d1f5b27fa33 100644 --- a/receiver/aerospikereceiver/scraper.go +++ b/receiver/aerospikereceiver/scraper.go @@ -29,6 +29,7 @@ type aerospikeReceiver struct { consumer consumer.Metrics clientFactory clientFactoryFunc client Aerospike + rb *metadata.ResourceBuilder mb *metadata.MetricsBuilder logger *zap.SugaredLogger } @@ -82,6 +83,7 @@ func newAerospikeReceiver(params receiver.CreateSettings, cfg *Config, consumer nodeGetterFactory, ) }, + rb: metadata.NewResourceBuilder(cfg.MetricsBuilderConfig.ResourceAttributes), mb: metadata.NewMetricsBuilder(cfg.MetricsBuilderConfig, params), }, nil } @@ -166,7 +168,8 @@ func (r *aerospikeReceiver) emitNode(info map[string]string, now pcommon.Timesta } } - r.mb.EmitForResource(metadata.WithAerospikeNodeName(info["node"])) + r.rb.SetAerospikeNodeName(info["node"]) + r.mb.EmitForResource(metadata.WithResource(r.rb.Emit())) r.logger.Debug("finished emitNode") } @@ -385,7 +388,9 @@ func (r *aerospikeReceiver) emitNamespace(info map[string]string, now pcommon.Ti } } - r.mb.EmitForResource(metadata.WithAerospikeNamespace(info["name"]), metadata.WithAerospikeNodeName(info["node"])) + r.rb.SetAerospikeNamespace(info["name"]) + r.rb.SetAerospikeNodeName(info["node"]) + r.mb.EmitForResource(metadata.WithResource(r.rb.Emit())) r.logger.Debug("finished emitNamespace") } diff --git a/receiver/aerospikereceiver/scraper_test.go b/receiver/aerospikereceiver/scraper_test.go index 96acc133ca88..203f53c65297 100644 --- a/receiver/aerospikereceiver/scraper_test.go +++ b/receiver/aerospikereceiver/scraper_test.go @@ -64,21 +64,30 @@ func TestScrape_CollectClusterMetrics(t *testing.T) { now := pcommon.NewTimestampFromTime(time.Now().UTC()) expectedMB := metadata.NewMetricsBuilder(metadata.DefaultMetricsBuilderConfig(), receivertest.NewNopCreateSettings()) + rb := metadata.NewResourceBuilder(metadata.DefaultResourceAttributesConfig()) require.NoError(t, expectedMB.RecordAerospikeNodeConnectionOpenDataPoint(now, "22", metadata.AttributeConnectionTypeClient)) - expectedMB.EmitForResource(metadata.WithAerospikeNodeName("BB990C28F270008")) + rb.SetAerospikeNodeName("BB990C28F270008") + expectedMB.EmitForResource(metadata.WithResource(rb.Emit())) require.NoError(t, expectedMB.RecordAerospikeNamespaceMemoryFreeDataPoint(now, "45")) - expectedMB.EmitForResource(metadata.WithAerospikeNamespace("test"), metadata.WithAerospikeNodeName("BB990C28F270008")) + rb.SetAerospikeNamespace("test") + rb.SetAerospikeNodeName("BB990C28F270008") + expectedMB.EmitForResource(metadata.WithResource(rb.Emit())) require.NoError(t, expectedMB.RecordAerospikeNamespaceMemoryFreeDataPoint(now, "30")) - expectedMB.EmitForResource(metadata.WithAerospikeNamespace("bar"), metadata.WithAerospikeNodeName("BB990C28F270008")) + rb.SetAerospikeNamespace("bar") + rb.SetAerospikeNodeName("BB990C28F270008") + expectedMB.EmitForResource(metadata.WithResource(rb.Emit())) require.NoError(t, expectedMB.RecordAerospikeNodeConnectionOpenDataPoint(now, "1", metadata.AttributeConnectionTypeClient)) - expectedMB.EmitForResource(metadata.WithAerospikeNodeName("BB990C28F270009")) + rb.SetAerospikeNodeName("BB990C28F270009") + expectedMB.EmitForResource(metadata.WithResource(rb.Emit())) require.NoError(t, expectedMB.RecordAerospikeNamespaceMemoryUsageDataPoint(now, "128", metadata.AttributeNamespaceComponentData)) - expectedMB.EmitForResource(metadata.WithAerospikeNamespace("test"), metadata.WithAerospikeNodeName("BB990C28F270009")) + rb.SetAerospikeNamespace("test") + rb.SetAerospikeNodeName("BB990C28F270009") + expectedMB.EmitForResource(metadata.WithResource(rb.Emit())) // require.NoError(t, expectedMB.RecordAerospikeNamespaceMemoryUsageDataPoint(now, "badval", metadata.AttributeNamespaceComponentData)) // expectedMB.EmitForResource(metadata.WithAerospikeNamespace("bar"), metadata.WithAerospikeNodeName("BB990C28F270009")) @@ -129,6 +138,7 @@ func TestScrape_CollectClusterMetrics(t *testing.T) { receiver := &aerospikeReceiver{ clientFactory: clientFactory, + rb: metadata.NewResourceBuilder(metadata.DefaultResourceAttributesConfig()), mb: metadata.NewMetricsBuilder(metadata.DefaultMetricsBuilderConfig(), receivertest.NewNopCreateSettings()), logger: logger.Sugar(), config: &Config{ diff --git a/receiver/apachereceiver/internal/metadata/generated_config_test.go b/receiver/apachereceiver/internal/metadata/generated_config_test.go index 62b1d89d7939..952442d94609 100644 --- a/receiver/apachereceiver/internal/metadata/generated_config_test.go +++ b/receiver/apachereceiver/internal/metadata/generated_config_test.go @@ -88,3 +88,49 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + ApacheServerName: ResourceAttributeConfig{Enabled: true}, + ApacheServerPort: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + ApacheServerName: ResourceAttributeConfig{Enabled: false}, + ApacheServerPort: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/apachereceiver/internal/metadata/generated_metrics.go b/receiver/apachereceiver/internal/metadata/generated_metrics.go index 694810377b65..52039dcf2632 100644 --- a/receiver/apachereceiver/internal/metadata/generated_metrics.go +++ b/receiver/apachereceiver/internal/metadata/generated_metrics.go @@ -773,10 +773,8 @@ func newMetricApacheWorkers(cfg MetricConfig) metricApacheWorkers { type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricApacheCPULoad metricApacheCPULoad metricApacheCPUTime metricApacheCPUTime metricApacheCurrentConnections metricApacheCurrentConnections @@ -806,7 +804,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricApacheCPULoad: newMetricApacheCPULoad(mbc.Metrics.ApacheCPULoad), metricApacheCPUTime: newMetricApacheCPUTime(mbc.Metrics.ApacheCPUTime), metricApacheCurrentConnections: newMetricApacheCurrentConnections(mbc.Metrics.ApacheCurrentConnections), @@ -831,36 +828,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithApacheServerName sets provided value as "apache.server.name" attribute for current resource. -func WithApacheServerName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.ApacheServerName.Enabled { - rm.Resource().Attributes().PutStr("apache.server.name", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithApacheServerPort sets provided value as "apache.server.port" attribute for current resource. -func WithApacheServerPort(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.ApacheServerPort.Enabled { - rm.Resource().Attributes().PutStr("apache.server.port", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -884,7 +868,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/apachereceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -903,7 +886,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricApacheWorkers.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/apachereceiver/internal/metadata/generated_metrics_test.go b/receiver/apachereceiver/internal/metadata/generated_metrics_test.go index 4914162d356b..e1d01104be4d 100644 --- a/receiver/apachereceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/apachereceiver/internal/metadata/generated_metrics_test.go @@ -102,7 +102,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordApacheWorkersDataPoint(ts, "1", AttributeWorkersStateBusy) - metrics := mb.Emit(WithApacheServerName("apache.server.name-val"), WithApacheServerPort("apache.server.port-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -111,25 +113,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("apache.server.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.ApacheServerName.Enabled, ok) - if mb.resourceAttributesConfig.ApacheServerName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "apache.server.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("apache.server.port") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.ApacheServerPort.Enabled, ok) - if mb.resourceAttributesConfig.ApacheServerPort.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "apache.server.port-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 2) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/apachereceiver/internal/metadata/generated_resource.go b/receiver/apachereceiver/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..238762dc95d8 --- /dev/null +++ b/receiver/apachereceiver/internal/metadata/generated_resource.go @@ -0,0 +1,43 @@ +// 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(), + } +} + +// SetApacheServerName sets provided value as "apache.server.name" attribute. +func (rb *ResourceBuilder) SetApacheServerName(val string) { + if rb.config.ApacheServerName.Enabled { + rb.res.Attributes().PutStr("apache.server.name", val) + } +} + +// SetApacheServerPort sets provided value as "apache.server.port" attribute. +func (rb *ResourceBuilder) SetApacheServerPort(val string) { + if rb.config.ApacheServerPort.Enabled { + rb.res.Attributes().PutStr("apache.server.port", 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/receiver/apachereceiver/internal/metadata/generated_resource_test.go b/receiver/apachereceiver/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..b422da8e54b0 --- /dev/null +++ b/receiver/apachereceiver/internal/metadata/generated_resource_test.go @@ -0,0 +1,46 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetApacheServerName("apache.server.name-val") + rb.SetApacheServerPort("apache.server.port-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 2, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 2, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("apache.server.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "apache.server.name-val", val.Str()) + } + val, ok = res.Attributes().Get("apache.server.port") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "apache.server.port-val", val.Str()) + } + }) + } +} diff --git a/receiver/apachereceiver/scraper.go b/receiver/apachereceiver/scraper.go index 2c84e2298214..0fa7ff1a4069 100644 --- a/receiver/apachereceiver/scraper.go +++ b/receiver/apachereceiver/scraper.go @@ -26,6 +26,7 @@ type apacheScraper struct { settings component.TelemetrySettings cfg *Config httpClient *http.Client + rb *metadata.ResourceBuilder mb *metadata.MetricsBuilder serverName string port string @@ -40,6 +41,7 @@ func newApacheScraper( a := &apacheScraper{ settings: settings.TelemetrySettings, cfg: cfg, + rb: metadata.NewResourceBuilder(cfg.MetricsBuilderConfig.ResourceAttributes), mb: metadata.NewMetricsBuilder(cfg.MetricsBuilderConfig, settings), serverName: serverName, port: port, @@ -127,7 +129,9 @@ func (r *apacheScraper) scrape(context.Context) (pmetric.Metrics, error) { } } - return r.mb.Emit(metadata.WithApacheServerName(r.serverName), metadata.WithApacheServerPort(r.port)), errs.Combine() + r.rb.SetApacheServerName(r.serverName) + r.rb.SetApacheServerPort(r.port) + return r.mb.Emit(metadata.WithResource(r.rb.Emit())), errs.Combine() } func addPartialIfError(errs *scrapererror.ScrapeErrors, err error) { diff --git a/receiver/apachesparkreceiver/internal/metadata/generated_config_test.go b/receiver/apachesparkreceiver/internal/metadata/generated_config_test.go index 80ca78b04632..3068a2690af4 100644 --- a/receiver/apachesparkreceiver/internal/metadata/generated_config_test.go +++ b/receiver/apachesparkreceiver/internal/metadata/generated_config_test.go @@ -198,3 +198,57 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + SparkApplicationID: ResourceAttributeConfig{Enabled: true}, + SparkApplicationName: ResourceAttributeConfig{Enabled: true}, + SparkExecutorID: ResourceAttributeConfig{Enabled: true}, + SparkJobID: ResourceAttributeConfig{Enabled: true}, + SparkStageAttemptID: ResourceAttributeConfig{Enabled: true}, + SparkStageID: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + SparkApplicationID: ResourceAttributeConfig{Enabled: false}, + SparkApplicationName: ResourceAttributeConfig{Enabled: false}, + SparkExecutorID: ResourceAttributeConfig{Enabled: false}, + SparkJobID: ResourceAttributeConfig{Enabled: false}, + SparkStageAttemptID: ResourceAttributeConfig{Enabled: false}, + SparkStageID: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/apachesparkreceiver/internal/metadata/generated_metrics.go b/receiver/apachesparkreceiver/internal/metadata/generated_metrics.go index d87a6e886af2..3f1c682b67d7 100644 --- a/receiver/apachesparkreceiver/internal/metadata/generated_metrics.go +++ b/receiver/apachesparkreceiver/internal/metadata/generated_metrics.go @@ -3532,10 +3532,8 @@ func newMetricSparkStageTaskResultSize(cfg MetricConfig) metricSparkStageTaskRes type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricSparkDriverBlockManagerDiskUsage metricSparkDriverBlockManagerDiskUsage metricSparkDriverBlockManagerMemoryUsage metricSparkDriverBlockManagerMemoryUsage metricSparkDriverCodeGeneratorCompilationAverageTime metricSparkDriverCodeGeneratorCompilationAverageTime @@ -3616,7 +3614,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricSparkDriverBlockManagerDiskUsage: newMetricSparkDriverBlockManagerDiskUsage(mbc.Metrics.SparkDriverBlockManagerDiskUsage), metricSparkDriverBlockManagerMemoryUsage: newMetricSparkDriverBlockManagerMemoryUsage(mbc.Metrics.SparkDriverBlockManagerMemoryUsage), metricSparkDriverCodeGeneratorCompilationAverageTime: newMetricSparkDriverCodeGeneratorCompilationAverageTime(mbc.Metrics.SparkDriverCodeGeneratorCompilationAverageTime), @@ -3692,72 +3689,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithSparkApplicationID sets provided value as "spark.application.id" attribute for current resource. -func WithSparkApplicationID(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.SparkApplicationID.Enabled { - rm.Resource().Attributes().PutStr("spark.application.id", val) - } - } -} - -// WithSparkApplicationName sets provided value as "spark.application.name" attribute for current resource. -func WithSparkApplicationName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.SparkApplicationName.Enabled { - rm.Resource().Attributes().PutStr("spark.application.name", val) - } - } -} - -// WithSparkExecutorID sets provided value as "spark.executor.id" attribute for current resource. -func WithSparkExecutorID(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.SparkExecutorID.Enabled { - rm.Resource().Attributes().PutStr("spark.executor.id", val) - } - } -} - -// WithSparkJobID sets provided value as "spark.job.id" attribute for current resource. -func WithSparkJobID(val int64) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.SparkJobID.Enabled { - rm.Resource().Attributes().PutInt("spark.job.id", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithSparkStageAttemptID sets provided value as "spark.stage.attempt.id" attribute for current resource. -func WithSparkStageAttemptID(val int64) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.SparkStageAttemptID.Enabled { - rm.Resource().Attributes().PutInt("spark.stage.attempt.id", val) - } - } -} - -// WithSparkStageID sets provided value as "spark.stage.id" attribute for current resource. -func WithSparkStageID(val int64) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.SparkStageID.Enabled { - rm.Resource().Attributes().PutInt("spark.stage.id", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -3781,7 +3729,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/apachesparkreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -3851,7 +3798,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricSparkStageTaskResultSize.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/apachesparkreceiver/internal/metadata/generated_metrics_test.go b/receiver/apachesparkreceiver/internal/metadata/generated_metrics_test.go index 1362ddae03fc..b1a3a31c2a6b 100644 --- a/receiver/apachesparkreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/apachesparkreceiver/internal/metadata/generated_metrics_test.go @@ -306,7 +306,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordSparkStageTaskResultSizeDataPoint(ts, 1) - metrics := mb.Emit(WithSparkApplicationID("spark.application.id-val"), WithSparkApplicationName("spark.application.name-val"), WithSparkExecutorID("spark.executor.id-val"), WithSparkJobID(12), WithSparkStageAttemptID(22), WithSparkStageID(14)) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -315,53 +317,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("spark.application.id") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.SparkApplicationID.Enabled, ok) - if mb.resourceAttributesConfig.SparkApplicationID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "spark.application.id-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("spark.application.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.SparkApplicationName.Enabled, ok) - if mb.resourceAttributesConfig.SparkApplicationName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "spark.application.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("spark.executor.id") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.SparkExecutorID.Enabled, ok) - if mb.resourceAttributesConfig.SparkExecutorID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "spark.executor.id-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("spark.job.id") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.SparkJobID.Enabled, ok) - if mb.resourceAttributesConfig.SparkJobID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, 12, attrVal.Int()) - } - attrVal, ok = rm.Resource().Attributes().Get("spark.stage.attempt.id") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.SparkStageAttemptID.Enabled, ok) - if mb.resourceAttributesConfig.SparkStageAttemptID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, 22, attrVal.Int()) - } - attrVal, ok = rm.Resource().Attributes().Get("spark.stage.id") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.SparkStageID.Enabled, ok) - if mb.resourceAttributesConfig.SparkStageID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, 14, attrVal.Int()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 6) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/apachesparkreceiver/internal/metadata/generated_resource.go b/receiver/apachesparkreceiver/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..b8d7ebe7a9f6 --- /dev/null +++ b/receiver/apachesparkreceiver/internal/metadata/generated_resource.go @@ -0,0 +1,71 @@ +// 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(), + } +} + +// SetSparkApplicationID sets provided value as "spark.application.id" attribute. +func (rb *ResourceBuilder) SetSparkApplicationID(val string) { + if rb.config.SparkApplicationID.Enabled { + rb.res.Attributes().PutStr("spark.application.id", val) + } +} + +// SetSparkApplicationName sets provided value as "spark.application.name" attribute. +func (rb *ResourceBuilder) SetSparkApplicationName(val string) { + if rb.config.SparkApplicationName.Enabled { + rb.res.Attributes().PutStr("spark.application.name", val) + } +} + +// SetSparkExecutorID sets provided value as "spark.executor.id" attribute. +func (rb *ResourceBuilder) SetSparkExecutorID(val string) { + if rb.config.SparkExecutorID.Enabled { + rb.res.Attributes().PutStr("spark.executor.id", val) + } +} + +// SetSparkJobID sets provided value as "spark.job.id" attribute. +func (rb *ResourceBuilder) SetSparkJobID(val int64) { + if rb.config.SparkJobID.Enabled { + rb.res.Attributes().PutInt("spark.job.id", val) + } +} + +// SetSparkStageAttemptID sets provided value as "spark.stage.attempt.id" attribute. +func (rb *ResourceBuilder) SetSparkStageAttemptID(val int64) { + if rb.config.SparkStageAttemptID.Enabled { + rb.res.Attributes().PutInt("spark.stage.attempt.id", val) + } +} + +// SetSparkStageID sets provided value as "spark.stage.id" attribute. +func (rb *ResourceBuilder) SetSparkStageID(val int64) { + if rb.config.SparkStageID.Enabled { + rb.res.Attributes().PutInt("spark.stage.id", 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/receiver/apachesparkreceiver/internal/metadata/generated_resource_test.go b/receiver/apachesparkreceiver/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..79b71260a0ae --- /dev/null +++ b/receiver/apachesparkreceiver/internal/metadata/generated_resource_test.go @@ -0,0 +1,70 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetSparkApplicationID("spark.application.id-val") + rb.SetSparkApplicationName("spark.application.name-val") + rb.SetSparkExecutorID("spark.executor.id-val") + rb.SetSparkJobID(12) + rb.SetSparkStageAttemptID(22) + rb.SetSparkStageID(14) + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 5, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 6, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("spark.application.id") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "spark.application.id-val", val.Str()) + } + val, ok = res.Attributes().Get("spark.application.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "spark.application.name-val", val.Str()) + } + val, ok = res.Attributes().Get("spark.executor.id") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "spark.executor.id-val", val.Str()) + } + val, ok = res.Attributes().Get("spark.job.id") + assert.True(t, ok) + if ok { + assert.EqualValues(t, 12, val.Int()) + } + val, ok = res.Attributes().Get("spark.stage.attempt.id") + assert.Equal(t, test == "all_set", ok) + if ok { + assert.EqualValues(t, 22, val.Int()) + } + val, ok = res.Attributes().Get("spark.stage.id") + assert.True(t, ok) + if ok { + assert.EqualValues(t, 14, val.Int()) + } + }) + } +} diff --git a/receiver/apachesparkreceiver/scraper.go b/receiver/apachesparkreceiver/scraper.go index 64953443377c..08681c2893d7 100644 --- a/receiver/apachesparkreceiver/scraper.go +++ b/receiver/apachesparkreceiver/scraper.go @@ -30,6 +30,7 @@ type sparkScraper struct { logger *zap.Logger config *Config settings component.TelemetrySettings + rb *metadata.ResourceBuilder mb *metadata.MetricsBuilder } @@ -38,6 +39,7 @@ func newSparkScraper(logger *zap.Logger, cfg *Config, settings receiver.CreateSe logger: logger, config: cfg, settings: settings.TelemetrySettings, + rb: metadata.NewResourceBuilder(cfg.MetricsBuilderConfig.ResourceAttributes), mb: metadata.NewMetricsBuilder(cfg.MetricsBuilderConfig, settings), } } @@ -245,7 +247,9 @@ func (s *sparkScraper) recordCluster(clusterStats *models.ClusterProperties, now s.mb.RecordSparkDriverExecutorGcTimeDataPoint(now, int64(stat.Value), metadata.AttributeGcTypeMajor) } - s.mb.EmitForResource(metadata.WithSparkApplicationID(appID), metadata.WithSparkApplicationName(appName)) + s.rb.SetSparkApplicationID(appID) + s.rb.SetSparkApplicationName(appName) + s.mb.EmitForResource(metadata.WithResource(s.rb.Emit())) } func (s *sparkScraper) recordStages(stageStats []models.Stage, now pcommon.Timestamp, appID string, appName string) { @@ -290,7 +294,11 @@ func (s *sparkScraper) recordStages(stageStats []models.Stage, now pcommon.Times s.mb.RecordSparkStageShuffleIoRecordsDataPoint(now, stage.ShuffleWriteRecords, metadata.AttributeDirectionOut) s.mb.RecordSparkStageShuffleWriteTimeDataPoint(now, stage.ShuffleWriteTime) - s.mb.EmitForResource(metadata.WithSparkApplicationID(appID), metadata.WithSparkApplicationName(appName), metadata.WithSparkStageID(stage.StageID), metadata.WithSparkStageAttemptID(stage.AttemptID)) + s.rb.SetSparkApplicationID(appID) + s.rb.SetSparkApplicationName(appName) + s.rb.SetSparkStageID(stage.StageID) + s.rb.SetSparkStageAttemptID(stage.AttemptID) + s.mb.EmitForResource(metadata.WithResource(s.rb.Emit())) } } @@ -314,7 +322,10 @@ func (s *sparkScraper) recordExecutors(executorStats []models.Executor, now pcom s.mb.RecordSparkExecutorStorageMemoryUsageDataPoint(now, used, metadata.AttributeLocationOffHeap, metadata.AttributeStateUsed) s.mb.RecordSparkExecutorStorageMemoryUsageDataPoint(now, executor.TotalOffHeapStorageMemory-used, metadata.AttributeLocationOffHeap, metadata.AttributeStateFree) - s.mb.EmitForResource(metadata.WithSparkApplicationID(appID), metadata.WithSparkApplicationName(appName), metadata.WithSparkExecutorID(executor.ExecutorID)) + s.rb.SetSparkApplicationID(appID) + s.rb.SetSparkApplicationName(appName) + s.rb.SetSparkExecutorID(executor.ExecutorID) + s.mb.EmitForResource(metadata.WithResource(s.rb.Emit())) } } @@ -329,6 +340,9 @@ func (s *sparkScraper) recordJobs(jobStats []models.Job, now pcommon.Timestamp, s.mb.RecordSparkJobStageResultDataPoint(now, job.NumSkippedStages, metadata.AttributeJobResultSkipped) s.mb.RecordSparkJobStageResultDataPoint(now, job.NumFailedStages, metadata.AttributeJobResultFailed) - s.mb.EmitForResource(metadata.WithSparkApplicationID(appID), metadata.WithSparkApplicationName(appName), metadata.WithSparkJobID(job.JobID)) + s.rb.SetSparkApplicationID(appID) + s.rb.SetSparkApplicationName(appName) + s.rb.SetSparkJobID(job.JobID) + s.mb.EmitForResource(metadata.WithResource(s.rb.Emit())) } } diff --git a/receiver/azuremonitorreceiver/internal/metadata/generated_resource.go b/receiver/azuremonitorreceiver/internal/metadata/generated_resource.go index c9bfc9e2c011..9ccaf9c199c5 100644 --- a/receiver/azuremonitorreceiver/internal/metadata/generated_resource.go +++ b/receiver/azuremonitorreceiver/internal/metadata/generated_resource.go @@ -7,11 +7,13 @@ import ( ) // 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, diff --git a/receiver/bigipreceiver/internal/metadata/generated_config_test.go b/receiver/bigipreceiver/internal/metadata/generated_config_test.go index 5bb19ac5d5c7..ce43fc76b3d5 100644 --- a/receiver/bigipreceiver/internal/metadata/generated_config_test.go +++ b/receiver/bigipreceiver/internal/metadata/generated_config_test.go @@ -128,3 +128,59 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + BigipNodeIPAddress: ResourceAttributeConfig{Enabled: true}, + BigipNodeName: ResourceAttributeConfig{Enabled: true}, + BigipPoolName: ResourceAttributeConfig{Enabled: true}, + BigipPoolMemberIPAddress: ResourceAttributeConfig{Enabled: true}, + BigipPoolMemberName: ResourceAttributeConfig{Enabled: true}, + BigipVirtualServerDestination: ResourceAttributeConfig{Enabled: true}, + BigipVirtualServerName: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + BigipNodeIPAddress: ResourceAttributeConfig{Enabled: false}, + BigipNodeName: ResourceAttributeConfig{Enabled: false}, + BigipPoolName: ResourceAttributeConfig{Enabled: false}, + BigipPoolMemberIPAddress: ResourceAttributeConfig{Enabled: false}, + BigipPoolMemberName: ResourceAttributeConfig{Enabled: false}, + BigipVirtualServerDestination: ResourceAttributeConfig{Enabled: false}, + BigipVirtualServerName: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/bigipreceiver/internal/metadata/generated_metrics.go b/receiver/bigipreceiver/internal/metadata/generated_metrics.go index 6e55f0c2b8a6..e91738c78bc2 100644 --- a/receiver/bigipreceiver/internal/metadata/generated_metrics.go +++ b/receiver/bigipreceiver/internal/metadata/generated_metrics.go @@ -1519,10 +1519,8 @@ func newMetricBigipVirtualServerRequestCount(cfg MetricConfig) metricBigipVirtua type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricBigipNodeAvailability metricBigipNodeAvailability metricBigipNodeConnectionCount metricBigipNodeConnectionCount metricBigipNodeDataTransmitted metricBigipNodeDataTransmitted @@ -1567,7 +1565,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricBigipNodeAvailability: newMetricBigipNodeAvailability(mbc.Metrics.BigipNodeAvailability), metricBigipNodeConnectionCount: newMetricBigipNodeConnectionCount(mbc.Metrics.BigipNodeConnectionCount), metricBigipNodeDataTransmitted: newMetricBigipNodeDataTransmitted(mbc.Metrics.BigipNodeDataTransmitted), @@ -1607,81 +1604,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithBigipNodeIPAddress sets provided value as "bigip.node.ip_address" attribute for current resource. -func WithBigipNodeIPAddress(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.BigipNodeIPAddress.Enabled { - rm.Resource().Attributes().PutStr("bigip.node.ip_address", val) - } - } -} - -// WithBigipNodeName sets provided value as "bigip.node.name" attribute for current resource. -func WithBigipNodeName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.BigipNodeName.Enabled { - rm.Resource().Attributes().PutStr("bigip.node.name", val) - } - } -} - -// WithBigipPoolName sets provided value as "bigip.pool.name" attribute for current resource. -func WithBigipPoolName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.BigipPoolName.Enabled { - rm.Resource().Attributes().PutStr("bigip.pool.name", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithBigipPoolMemberIPAddress sets provided value as "bigip.pool_member.ip_address" attribute for current resource. -func WithBigipPoolMemberIPAddress(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.BigipPoolMemberIPAddress.Enabled { - rm.Resource().Attributes().PutStr("bigip.pool_member.ip_address", val) - } - } -} - -// WithBigipPoolMemberName sets provided value as "bigip.pool_member.name" attribute for current resource. -func WithBigipPoolMemberName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.BigipPoolMemberName.Enabled { - rm.Resource().Attributes().PutStr("bigip.pool_member.name", val) - } - } -} - -// WithBigipVirtualServerDestination sets provided value as "bigip.virtual_server.destination" attribute for current resource. -func WithBigipVirtualServerDestination(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.BigipVirtualServerDestination.Enabled { - rm.Resource().Attributes().PutStr("bigip.virtual_server.destination", val) - } - } -} - -// WithBigipVirtualServerName sets provided value as "bigip.virtual_server.name" attribute for current resource. -func WithBigipVirtualServerName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.BigipVirtualServerName.Enabled { - rm.Resource().Attributes().PutStr("bigip.virtual_server.name", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -1705,7 +1644,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/bigipreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -1739,7 +1677,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricBigipVirtualServerRequestCount.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/bigipreceiver/internal/metadata/generated_metrics_test.go b/receiver/bigipreceiver/internal/metadata/generated_metrics_test.go index d5b227d0bd2e..b7d22a09b853 100644 --- a/receiver/bigipreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/bigipreceiver/internal/metadata/generated_metrics_test.go @@ -162,7 +162,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordBigipVirtualServerRequestCountDataPoint(ts, 1) - metrics := mb.Emit(WithBigipNodeIPAddress("bigip.node.ip_address-val"), WithBigipNodeName("bigip.node.name-val"), WithBigipPoolName("bigip.pool.name-val"), WithBigipPoolMemberIPAddress("bigip.pool_member.ip_address-val"), WithBigipPoolMemberName("bigip.pool_member.name-val"), WithBigipVirtualServerDestination("bigip.virtual_server.destination-val"), WithBigipVirtualServerName("bigip.virtual_server.name-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -171,60 +173,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("bigip.node.ip_address") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.BigipNodeIPAddress.Enabled, ok) - if mb.resourceAttributesConfig.BigipNodeIPAddress.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "bigip.node.ip_address-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("bigip.node.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.BigipNodeName.Enabled, ok) - if mb.resourceAttributesConfig.BigipNodeName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "bigip.node.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("bigip.pool.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.BigipPoolName.Enabled, ok) - if mb.resourceAttributesConfig.BigipPoolName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "bigip.pool.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("bigip.pool_member.ip_address") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.BigipPoolMemberIPAddress.Enabled, ok) - if mb.resourceAttributesConfig.BigipPoolMemberIPAddress.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "bigip.pool_member.ip_address-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("bigip.pool_member.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.BigipPoolMemberName.Enabled, ok) - if mb.resourceAttributesConfig.BigipPoolMemberName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "bigip.pool_member.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("bigip.virtual_server.destination") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.BigipVirtualServerDestination.Enabled, ok) - if mb.resourceAttributesConfig.BigipVirtualServerDestination.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "bigip.virtual_server.destination-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("bigip.virtual_server.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.BigipVirtualServerName.Enabled, ok) - if mb.resourceAttributesConfig.BigipVirtualServerName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "bigip.virtual_server.name-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 7) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/bigipreceiver/internal/metadata/generated_resource.go b/receiver/bigipreceiver/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..a10450903165 --- /dev/null +++ b/receiver/bigipreceiver/internal/metadata/generated_resource.go @@ -0,0 +1,78 @@ +// 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(), + } +} + +// SetBigipNodeIPAddress sets provided value as "bigip.node.ip_address" attribute. +func (rb *ResourceBuilder) SetBigipNodeIPAddress(val string) { + if rb.config.BigipNodeIPAddress.Enabled { + rb.res.Attributes().PutStr("bigip.node.ip_address", val) + } +} + +// SetBigipNodeName sets provided value as "bigip.node.name" attribute. +func (rb *ResourceBuilder) SetBigipNodeName(val string) { + if rb.config.BigipNodeName.Enabled { + rb.res.Attributes().PutStr("bigip.node.name", val) + } +} + +// SetBigipPoolName sets provided value as "bigip.pool.name" attribute. +func (rb *ResourceBuilder) SetBigipPoolName(val string) { + if rb.config.BigipPoolName.Enabled { + rb.res.Attributes().PutStr("bigip.pool.name", val) + } +} + +// SetBigipPoolMemberIPAddress sets provided value as "bigip.pool_member.ip_address" attribute. +func (rb *ResourceBuilder) SetBigipPoolMemberIPAddress(val string) { + if rb.config.BigipPoolMemberIPAddress.Enabled { + rb.res.Attributes().PutStr("bigip.pool_member.ip_address", val) + } +} + +// SetBigipPoolMemberName sets provided value as "bigip.pool_member.name" attribute. +func (rb *ResourceBuilder) SetBigipPoolMemberName(val string) { + if rb.config.BigipPoolMemberName.Enabled { + rb.res.Attributes().PutStr("bigip.pool_member.name", val) + } +} + +// SetBigipVirtualServerDestination sets provided value as "bigip.virtual_server.destination" attribute. +func (rb *ResourceBuilder) SetBigipVirtualServerDestination(val string) { + if rb.config.BigipVirtualServerDestination.Enabled { + rb.res.Attributes().PutStr("bigip.virtual_server.destination", val) + } +} + +// SetBigipVirtualServerName sets provided value as "bigip.virtual_server.name" attribute. +func (rb *ResourceBuilder) SetBigipVirtualServerName(val string) { + if rb.config.BigipVirtualServerName.Enabled { + rb.res.Attributes().PutStr("bigip.virtual_server.name", 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/receiver/bigipreceiver/internal/metadata/generated_resource_test.go b/receiver/bigipreceiver/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..3e89ddce5c1c --- /dev/null +++ b/receiver/bigipreceiver/internal/metadata/generated_resource_test.go @@ -0,0 +1,76 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetBigipNodeIPAddress("bigip.node.ip_address-val") + rb.SetBigipNodeName("bigip.node.name-val") + rb.SetBigipPoolName("bigip.pool.name-val") + rb.SetBigipPoolMemberIPAddress("bigip.pool_member.ip_address-val") + rb.SetBigipPoolMemberName("bigip.pool_member.name-val") + rb.SetBigipVirtualServerDestination("bigip.virtual_server.destination-val") + rb.SetBigipVirtualServerName("bigip.virtual_server.name-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 7, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 7, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("bigip.node.ip_address") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "bigip.node.ip_address-val", val.Str()) + } + val, ok = res.Attributes().Get("bigip.node.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "bigip.node.name-val", val.Str()) + } + val, ok = res.Attributes().Get("bigip.pool.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "bigip.pool.name-val", val.Str()) + } + val, ok = res.Attributes().Get("bigip.pool_member.ip_address") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "bigip.pool_member.ip_address-val", val.Str()) + } + val, ok = res.Attributes().Get("bigip.pool_member.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "bigip.pool_member.name-val", val.Str()) + } + val, ok = res.Attributes().Get("bigip.virtual_server.destination") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "bigip.virtual_server.destination-val", val.Str()) + } + val, ok = res.Attributes().Get("bigip.virtual_server.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "bigip.virtual_server.name-val", val.Str()) + } + }) + } +} diff --git a/receiver/bigipreceiver/scraper.go b/receiver/bigipreceiver/scraper.go index f35a49f535dd..197de5ed1e0f 100644 --- a/receiver/bigipreceiver/scraper.go +++ b/receiver/bigipreceiver/scraper.go @@ -33,6 +33,7 @@ type bigipScraper struct { logger *zap.Logger cfg *Config settings component.TelemetrySettings + rb *metadata.ResourceBuilder mb *metadata.MetricsBuilder } @@ -42,6 +43,7 @@ func newScraper(logger *zap.Logger, cfg *Config, settings receiver.CreateSetting logger: logger, cfg: cfg, settings: settings.TelemetrySettings, + rb: metadata.NewResourceBuilder(cfg.MetricsBuilderConfig.ResourceAttributes), mb: metadata.NewMetricsBuilder(cfg.MetricsBuilderConfig, settings), } } @@ -168,11 +170,10 @@ func (s *bigipScraper) collectVirtualServers(virtualServerStats *models.VirtualS s.mb.RecordBigipVirtualServerEnabledDataPoint(now, 0, metadata.AttributeEnabledStatusEnabled) } - s.mb.EmitForResource( - metadata.WithBigipVirtualServerName(virtualServerStats.NestedStats.Entries.Name.Description), - metadata.WithBigipVirtualServerDestination(virtualServerStats.NestedStats.Entries.Destination.Description), - metadata.WithBigipPoolName(virtualServerStats.NestedStats.Entries.PoolName.Description), - ) + s.rb.SetBigipVirtualServerName(virtualServerStats.NestedStats.Entries.Name.Description) + s.rb.SetBigipVirtualServerDestination(virtualServerStats.NestedStats.Entries.Destination.Description) + s.rb.SetBigipPoolName(virtualServerStats.NestedStats.Entries.PoolName.Description) + s.mb.EmitForResource(metadata.WithResource(s.rb.Emit())) } // collectPools collects pool metrics @@ -212,9 +213,8 @@ func (s *bigipScraper) collectPools(poolStats *models.PoolStats, now pcommon.Tim s.mb.RecordBigipPoolEnabledDataPoint(now, 0, metadata.AttributeEnabledStatusEnabled) } - s.mb.EmitForResource( - metadata.WithBigipPoolName(poolStats.NestedStats.Entries.Name.Description), - ) + s.rb.SetBigipPoolName(poolStats.NestedStats.Entries.Name.Description) + s.mb.EmitForResource(metadata.WithResource(s.rb.Emit())) } // collectPoolMembers collects pool member metrics @@ -252,11 +252,10 @@ func (s *bigipScraper) collectPoolMembers(poolMemberStats *models.PoolMemberStat s.mb.RecordBigipPoolMemberEnabledDataPoint(now, 0, metadata.AttributeEnabledStatusEnabled) } - s.mb.EmitForResource( - metadata.WithBigipPoolMemberName(fmt.Sprintf("%s:%d", poolMemberStats.NestedStats.Entries.Name.Description, poolMemberStats.NestedStats.Entries.Port.Value)), - metadata.WithBigipPoolMemberIPAddress(poolMemberStats.NestedStats.Entries.IPAddress.Description), - metadata.WithBigipPoolName(poolMemberStats.NestedStats.Entries.PoolName.Description), - ) + s.rb.SetBigipPoolMemberName(fmt.Sprintf("%s:%d", poolMemberStats.NestedStats.Entries.Name.Description, poolMemberStats.NestedStats.Entries.Port.Value)) + s.rb.SetBigipPoolMemberIPAddress(poolMemberStats.NestedStats.Entries.IPAddress.Description) + s.rb.SetBigipPoolName(poolMemberStats.NestedStats.Entries.PoolName.Description) + s.mb.EmitForResource(metadata.WithResource(s.rb.Emit())) } // collectNodes collects node metrics @@ -294,8 +293,7 @@ func (s *bigipScraper) collectNodes(nodeStats *models.NodeStats, now pcommon.Tim s.mb.RecordBigipNodeEnabledDataPoint(now, 0, metadata.AttributeEnabledStatusEnabled) } - s.mb.EmitForResource( - metadata.WithBigipNodeName(nodeStats.NestedStats.Entries.Name.Description), - metadata.WithBigipNodeIPAddress(nodeStats.NestedStats.Entries.IPAddress.Description), - ) + s.rb.SetBigipNodeName(nodeStats.NestedStats.Entries.Name.Description) + s.rb.SetBigipNodeIPAddress(nodeStats.NestedStats.Entries.IPAddress.Description) + s.mb.EmitForResource(metadata.WithResource(s.rb.Emit())) } diff --git a/receiver/chronyreceiver/internal/metadata/generated_metrics.go b/receiver/chronyreceiver/internal/metadata/generated_metrics.go index 8d80a06b8c1b..a5bce67d9002 100644 --- a/receiver/chronyreceiver/internal/metadata/generated_metrics.go +++ b/receiver/chronyreceiver/internal/metadata/generated_metrics.go @@ -403,7 +403,6 @@ func newMetricNtpTimeRootDelay(cfg MetricConfig) metricNtpTimeRootDelay { type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information metricNtpFrequencyOffset metricNtpFrequencyOffset @@ -449,14 +448,19 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. type ResourceMetricsOption func(pmetric.ResourceMetrics) +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) + } +} + // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { @@ -484,7 +488,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/chronyreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) diff --git a/receiver/chronyreceiver/internal/metadata/generated_metrics_test.go b/receiver/chronyreceiver/internal/metadata/generated_metrics_test.go index c04bd89634f5..cd271fdf4c9c 100644 --- a/receiver/chronyreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/chronyreceiver/internal/metadata/generated_metrics_test.go @@ -78,7 +78,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordNtpTimeRootDelayDataPoint(ts, 1, AttributeLeapStatusNormal) - metrics := mb.Emit() + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -87,11 +89,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 0) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/couchdbreceiver/internal/metadata/generated_config_test.go b/receiver/couchdbreceiver/internal/metadata/generated_config_test.go index cc901772576b..0b3e1f66e877 100644 --- a/receiver/couchdbreceiver/internal/metadata/generated_config_test.go +++ b/receiver/couchdbreceiver/internal/metadata/generated_config_test.go @@ -78,3 +78,47 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + CouchdbNodeName: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + CouchdbNodeName: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/couchdbreceiver/internal/metadata/generated_metrics.go b/receiver/couchdbreceiver/internal/metadata/generated_metrics.go index 2464f8411ebc..245f84d9c8c2 100644 --- a/receiver/couchdbreceiver/internal/metadata/generated_metrics.go +++ b/receiver/couchdbreceiver/internal/metadata/generated_metrics.go @@ -528,10 +528,8 @@ func newMetricCouchdbHttpdViews(cfg MetricConfig) metricCouchdbHttpdViews { type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricCouchdbAverageRequestTime metricCouchdbAverageRequestTime metricCouchdbDatabaseOpen metricCouchdbDatabaseOpen metricCouchdbDatabaseOperations metricCouchdbDatabaseOperations @@ -557,7 +555,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricCouchdbAverageRequestTime: newMetricCouchdbAverageRequestTime(mbc.Metrics.CouchdbAverageRequestTime), metricCouchdbDatabaseOpen: newMetricCouchdbDatabaseOpen(mbc.Metrics.CouchdbDatabaseOpen), metricCouchdbDatabaseOperations: newMetricCouchdbDatabaseOperations(mbc.Metrics.CouchdbDatabaseOperations), @@ -578,27 +575,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithCouchdbNodeName sets provided value as "couchdb.node.name" attribute for current resource. -func WithCouchdbNodeName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.CouchdbNodeName.Enabled { - rm.Resource().Attributes().PutStr("couchdb.node.name", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -622,7 +615,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/couchdbreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -637,7 +629,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricCouchdbHttpdViews.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/couchdbreceiver/internal/metadata/generated_metrics_test.go b/receiver/couchdbreceiver/internal/metadata/generated_metrics_test.go index ef022ae5cc87..e4b836367e63 100644 --- a/receiver/couchdbreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/couchdbreceiver/internal/metadata/generated_metrics_test.go @@ -86,7 +86,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordCouchdbHttpdViewsDataPoint(ts, 1, AttributeViewTemporaryViewReads) - metrics := mb.Emit(WithCouchdbNodeName("couchdb.node.name-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -95,18 +97,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("couchdb.node.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.CouchdbNodeName.Enabled, ok) - if mb.resourceAttributesConfig.CouchdbNodeName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "couchdb.node.name-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 1) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/couchdbreceiver/internal/metadata/generated_resource.go b/receiver/couchdbreceiver/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..0430d5f7e879 --- /dev/null +++ b/receiver/couchdbreceiver/internal/metadata/generated_resource.go @@ -0,0 +1,36 @@ +// 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(), + } +} + +// SetCouchdbNodeName sets provided value as "couchdb.node.name" attribute. +func (rb *ResourceBuilder) SetCouchdbNodeName(val string) { + if rb.config.CouchdbNodeName.Enabled { + rb.res.Attributes().PutStr("couchdb.node.name", 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/receiver/couchdbreceiver/internal/metadata/generated_resource_test.go b/receiver/couchdbreceiver/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..ff74ac73e27a --- /dev/null +++ b/receiver/couchdbreceiver/internal/metadata/generated_resource_test.go @@ -0,0 +1,40 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetCouchdbNodeName("couchdb.node.name-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 1, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 1, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("couchdb.node.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "couchdb.node.name-val", val.Str()) + } + }) + } +} diff --git a/receiver/couchdbreceiver/scraper.go b/receiver/couchdbreceiver/scraper.go index ace95a8aaf4c..cd78bcad240f 100644 --- a/receiver/couchdbreceiver/scraper.go +++ b/receiver/couchdbreceiver/scraper.go @@ -23,6 +23,7 @@ type couchdbScraper struct { client client config *Config settings component.TelemetrySettings + rb *metadata.ResourceBuilder mb *metadata.MetricsBuilder } @@ -30,6 +31,7 @@ func newCouchdbScraper(settings receiver.CreateSettings, config *Config) *couchd return &couchdbScraper{ settings: settings.TelemetrySettings, config: config, + rb: metadata.NewResourceBuilder(config.ResourceAttributes), mb: metadata.NewMetricsBuilder(config.MetricsBuilderConfig, settings), } } @@ -71,5 +73,6 @@ func (c *couchdbScraper) scrape(context.Context) (pmetric.Metrics, error) { c.recordCouchdbFileDescriptorOpenDataPoint(now, stats, errs) c.recordCouchdbDatabaseOperationsDataPoint(now, stats, errs) - return c.mb.Emit(metadata.WithCouchdbNodeName(c.config.Endpoint)), errs.Combine() + c.rb.SetCouchdbNodeName(c.config.Endpoint) + return c.mb.Emit(metadata.WithResource(c.rb.Emit())), errs.Combine() } diff --git a/receiver/dockerstatsreceiver/internal/metadata/generated_config_test.go b/receiver/dockerstatsreceiver/internal/metadata/generated_config_test.go index e48235ddb89f..5d11b8e18d4a 100644 --- a/receiver/dockerstatsreceiver/internal/metadata/generated_config_test.go +++ b/receiver/dockerstatsreceiver/internal/metadata/generated_config_test.go @@ -208,3 +208,59 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + ContainerCommandLine: ResourceAttributeConfig{Enabled: true}, + ContainerHostname: ResourceAttributeConfig{Enabled: true}, + ContainerID: ResourceAttributeConfig{Enabled: true}, + ContainerImageID: ResourceAttributeConfig{Enabled: true}, + ContainerImageName: ResourceAttributeConfig{Enabled: true}, + ContainerName: ResourceAttributeConfig{Enabled: true}, + ContainerRuntime: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + ContainerCommandLine: ResourceAttributeConfig{Enabled: false}, + ContainerHostname: ResourceAttributeConfig{Enabled: false}, + ContainerID: ResourceAttributeConfig{Enabled: false}, + ContainerImageID: ResourceAttributeConfig{Enabled: false}, + ContainerImageName: ResourceAttributeConfig{Enabled: false}, + ContainerName: ResourceAttributeConfig{Enabled: false}, + ContainerRuntime: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/dockerstatsreceiver/internal/metadata/generated_metrics.go b/receiver/dockerstatsreceiver/internal/metadata/generated_metrics.go index 5cad6471a7fc..fae79080d60a 100644 --- a/receiver/dockerstatsreceiver/internal/metadata/generated_metrics.go +++ b/receiver/dockerstatsreceiver/internal/metadata/generated_metrics.go @@ -3476,10 +3476,8 @@ func newMetricContainerUptime(cfg MetricConfig) metricContainerUptime { type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricContainerBlockioIoMergedRecursive metricContainerBlockioIoMergedRecursive metricContainerBlockioIoQueuedRecursive metricContainerBlockioIoQueuedRecursive metricContainerBlockioIoServiceBytesRecursive metricContainerBlockioIoServiceBytesRecursive @@ -3567,12 +3565,11 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting settings.Logger.Warn("[WARNING] Please set `enabled` field explicitly for `container.cpu.utilization`: This metric will be enabled by default in v0.82.0.") } mb := &MetricsBuilder{ - startTime: pcommon.NewTimestampFromTime(time.Now()), - metricsBuffer: pmetric.NewMetrics(), - buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, - metricContainerBlockioIoMergedRecursive: newMetricContainerBlockioIoMergedRecursive(mbc.Metrics.ContainerBlockioIoMergedRecursive), - metricContainerBlockioIoQueuedRecursive: newMetricContainerBlockioIoQueuedRecursive(mbc.Metrics.ContainerBlockioIoQueuedRecursive), + startTime: pcommon.NewTimestampFromTime(time.Now()), + metricsBuffer: pmetric.NewMetrics(), + buildInfo: settings.BuildInfo, + metricContainerBlockioIoMergedRecursive: newMetricContainerBlockioIoMergedRecursive(mbc.Metrics.ContainerBlockioIoMergedRecursive), + metricContainerBlockioIoQueuedRecursive: newMetricContainerBlockioIoQueuedRecursive(mbc.Metrics.ContainerBlockioIoQueuedRecursive), metricContainerBlockioIoServiceBytesRecursive: newMetricContainerBlockioIoServiceBytesRecursive(mbc.Metrics.ContainerBlockioIoServiceBytesRecursive), metricContainerBlockioIoServiceTimeRecursive: newMetricContainerBlockioIoServiceTimeRecursive(mbc.Metrics.ContainerBlockioIoServiceTimeRecursive), metricContainerBlockioIoServicedRecursive: newMetricContainerBlockioIoServicedRecursive(mbc.Metrics.ContainerBlockioIoServicedRecursive), @@ -3650,81 +3647,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithContainerCommandLine sets provided value as "container.command_line" attribute for current resource. -func WithContainerCommandLine(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.ContainerCommandLine.Enabled { - rm.Resource().Attributes().PutStr("container.command_line", val) - } - } -} - -// WithContainerHostname sets provided value as "container.hostname" attribute for current resource. -func WithContainerHostname(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.ContainerHostname.Enabled { - rm.Resource().Attributes().PutStr("container.hostname", val) - } - } -} - -// WithContainerID sets provided value as "container.id" attribute for current resource. -func WithContainerID(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.ContainerID.Enabled { - rm.Resource().Attributes().PutStr("container.id", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithContainerImageID sets provided value as "container.image.id" attribute for current resource. -func WithContainerImageID(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.ContainerImageID.Enabled { - rm.Resource().Attributes().PutStr("container.image.id", val) - } - } -} - -// WithContainerImageName sets provided value as "container.image.name" attribute for current resource. -func WithContainerImageName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.ContainerImageName.Enabled { - rm.Resource().Attributes().PutStr("container.image.name", val) - } - } -} - -// WithContainerName sets provided value as "container.name" attribute for current resource. -func WithContainerName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.ContainerName.Enabled { - rm.Resource().Attributes().PutStr("container.name", val) - } - } -} - -// WithContainerRuntime sets provided value as "container.runtime" attribute for current resource. -func WithContainerRuntime(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.ContainerRuntime.Enabled { - rm.Resource().Attributes().PutStr("container.runtime", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -3749,7 +3688,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() rm.SetSchemaUrl(conventions.SchemaURL) - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/dockerstatsreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -3823,7 +3761,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricContainerUptime.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/dockerstatsreceiver/internal/metadata/generated_metrics_test.go b/receiver/dockerstatsreceiver/internal/metadata/generated_metrics_test.go index 15b71bc518a2..55786fd688b7 100644 --- a/receiver/dockerstatsreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/dockerstatsreceiver/internal/metadata/generated_metrics_test.go @@ -277,7 +277,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordContainerUptimeDataPoint(ts, 1) - metrics := mb.Emit(WithContainerCommandLine("container.command_line-val"), WithContainerHostname("container.hostname-val"), WithContainerID("container.id-val"), WithContainerImageID("container.image.id-val"), WithContainerImageName("container.image.name-val"), WithContainerName("container.name-val"), WithContainerRuntime("container.runtime-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -286,60 +288,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("container.command_line") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.ContainerCommandLine.Enabled, ok) - if mb.resourceAttributesConfig.ContainerCommandLine.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "container.command_line-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("container.hostname") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.ContainerHostname.Enabled, ok) - if mb.resourceAttributesConfig.ContainerHostname.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "container.hostname-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("container.id") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.ContainerID.Enabled, ok) - if mb.resourceAttributesConfig.ContainerID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "container.id-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("container.image.id") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.ContainerImageID.Enabled, ok) - if mb.resourceAttributesConfig.ContainerImageID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "container.image.id-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("container.image.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.ContainerImageName.Enabled, ok) - if mb.resourceAttributesConfig.ContainerImageName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "container.image.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("container.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.ContainerName.Enabled, ok) - if mb.resourceAttributesConfig.ContainerName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "container.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("container.runtime") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.ContainerRuntime.Enabled, ok) - if mb.resourceAttributesConfig.ContainerRuntime.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "container.runtime-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 7) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/dockerstatsreceiver/internal/metadata/generated_resource.go b/receiver/dockerstatsreceiver/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..7b0c03fd65b5 --- /dev/null +++ b/receiver/dockerstatsreceiver/internal/metadata/generated_resource.go @@ -0,0 +1,78 @@ +// 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(), + } +} + +// SetContainerCommandLine sets provided value as "container.command_line" attribute. +func (rb *ResourceBuilder) SetContainerCommandLine(val string) { + if rb.config.ContainerCommandLine.Enabled { + rb.res.Attributes().PutStr("container.command_line", val) + } +} + +// SetContainerHostname sets provided value as "container.hostname" attribute. +func (rb *ResourceBuilder) SetContainerHostname(val string) { + if rb.config.ContainerHostname.Enabled { + rb.res.Attributes().PutStr("container.hostname", val) + } +} + +// SetContainerID sets provided value as "container.id" attribute. +func (rb *ResourceBuilder) SetContainerID(val string) { + if rb.config.ContainerID.Enabled { + rb.res.Attributes().PutStr("container.id", val) + } +} + +// SetContainerImageID sets provided value as "container.image.id" attribute. +func (rb *ResourceBuilder) SetContainerImageID(val string) { + if rb.config.ContainerImageID.Enabled { + rb.res.Attributes().PutStr("container.image.id", val) + } +} + +// SetContainerImageName sets provided value as "container.image.name" attribute. +func (rb *ResourceBuilder) SetContainerImageName(val string) { + if rb.config.ContainerImageName.Enabled { + rb.res.Attributes().PutStr("container.image.name", val) + } +} + +// SetContainerName sets provided value as "container.name" attribute. +func (rb *ResourceBuilder) SetContainerName(val string) { + if rb.config.ContainerName.Enabled { + rb.res.Attributes().PutStr("container.name", val) + } +} + +// SetContainerRuntime sets provided value as "container.runtime" attribute. +func (rb *ResourceBuilder) SetContainerRuntime(val string) { + if rb.config.ContainerRuntime.Enabled { + rb.res.Attributes().PutStr("container.runtime", 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/receiver/dockerstatsreceiver/internal/metadata/generated_resource_test.go b/receiver/dockerstatsreceiver/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..58ffcf5c7a74 --- /dev/null +++ b/receiver/dockerstatsreceiver/internal/metadata/generated_resource_test.go @@ -0,0 +1,76 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetContainerCommandLine("container.command_line-val") + rb.SetContainerHostname("container.hostname-val") + rb.SetContainerID("container.id-val") + rb.SetContainerImageID("container.image.id-val") + rb.SetContainerImageName("container.image.name-val") + rb.SetContainerName("container.name-val") + rb.SetContainerRuntime("container.runtime-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 5, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 7, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("container.command_line") + assert.Equal(t, test == "all_set", ok) + if ok { + assert.EqualValues(t, "container.command_line-val", val.Str()) + } + val, ok = res.Attributes().Get("container.hostname") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "container.hostname-val", val.Str()) + } + val, ok = res.Attributes().Get("container.id") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "container.id-val", val.Str()) + } + val, ok = res.Attributes().Get("container.image.id") + assert.Equal(t, test == "all_set", ok) + if ok { + assert.EqualValues(t, "container.image.id-val", val.Str()) + } + val, ok = res.Attributes().Get("container.image.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "container.image.name-val", val.Str()) + } + val, ok = res.Attributes().Get("container.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "container.name-val", val.Str()) + } + val, ok = res.Attributes().Get("container.runtime") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "container.runtime-val", val.Str()) + } + }) + } +} diff --git a/receiver/dockerstatsreceiver/receiver.go b/receiver/dockerstatsreceiver/receiver.go index 47309ca3bd56..5e8b8f37e828 100644 --- a/receiver/dockerstatsreceiver/receiver.go +++ b/receiver/dockerstatsreceiver/receiver.go @@ -24,8 +24,6 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/dockerstatsreceiver/internal/metadata" ) -const defaultResourcesLen = 5 - const ( defaultDockerAPIVersion = 1.23 minimalRequiredDockerAPIVersion = 1.22 @@ -41,6 +39,7 @@ type receiver struct { config *Config settings rcvr.CreateSettings client *docker.Client + rb *metadata.ResourceBuilder mb *metadata.MetricsBuilder } @@ -48,6 +47,7 @@ func newReceiver(set rcvr.CreateSettings, config *Config) *receiver { return &receiver{ config: config, settings: set, + rb: metadata.NewResourceBuilder(config.ResourceAttributes), mb: metadata.NewMetricsBuilder(config.MetricsBuilderConfig, set), } } @@ -125,36 +125,27 @@ func (r *receiver) recordContainerStats(now pcommon.Timestamp, containerStats *d } // Always-present resource attrs + the user-configured resource attrs - resourceCapacity := defaultResourcesLen + len(r.config.EnvVarsToMetricLabels) + len(r.config.ContainerLabelsToMetricLabels) - resourceMetricsOptions := make([]metadata.ResourceMetricsOption, 0, resourceCapacity) - resourceMetricsOptions = append(resourceMetricsOptions, - metadata.WithContainerRuntime("docker"), - metadata.WithContainerHostname(container.Config.Hostname), - metadata.WithContainerID(container.ID), - metadata.WithContainerImageName(container.Config.Image), - metadata.WithContainerName(strings.TrimPrefix(container.Name, "/")), - metadata.WithContainerImageID(container.Image), - metadata.WithContainerCommandLine(strings.Join(container.Config.Cmd, " ")), - ) + r.rb.SetContainerRuntime("docker") + r.rb.SetContainerHostname(container.Config.Hostname) + r.rb.SetContainerID(container.ID) + r.rb.SetContainerImageName(container.Config.Image) + r.rb.SetContainerName(strings.TrimPrefix(container.Name, "/")) + r.rb.SetContainerImageID(container.Image) + r.rb.SetContainerCommandLine(strings.Join(container.Config.Cmd, " ")) + resource := r.rb.Emit() for k, label := range r.config.EnvVarsToMetricLabels { - label := label if v := container.EnvMap[k]; v != "" { - resourceMetricsOptions = append(resourceMetricsOptions, func(ras metadata.ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - rm.Resource().Attributes().PutStr(label, v) - }) + resource.Attributes().PutStr(label, v) } } for k, label := range r.config.ContainerLabelsToMetricLabels { - label := label if v := container.Config.Labels[k]; v != "" { - resourceMetricsOptions = append(resourceMetricsOptions, func(ras metadata.ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - rm.Resource().Attributes().PutStr(label, v) - }) + resource.Attributes().PutStr(label, v) } } - r.mb.EmitForResource(resourceMetricsOptions...) + r.mb.EmitForResource(metadata.WithResource(resource)) return errs } diff --git a/receiver/elasticsearchreceiver/internal/metadata/generated_config_test.go b/receiver/elasticsearchreceiver/internal/metadata/generated_config_test.go index ec4fec73a764..78899b77c853 100644 --- a/receiver/elasticsearchreceiver/internal/metadata/generated_config_test.go +++ b/receiver/elasticsearchreceiver/internal/metadata/generated_config_test.go @@ -250,3 +250,53 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + ElasticsearchClusterName: ResourceAttributeConfig{Enabled: true}, + ElasticsearchIndexName: ResourceAttributeConfig{Enabled: true}, + ElasticsearchNodeName: ResourceAttributeConfig{Enabled: true}, + ElasticsearchNodeVersion: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + ElasticsearchClusterName: ResourceAttributeConfig{Enabled: false}, + ElasticsearchIndexName: ResourceAttributeConfig{Enabled: false}, + ElasticsearchNodeName: ResourceAttributeConfig{Enabled: false}, + ElasticsearchNodeVersion: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/elasticsearchreceiver/internal/metadata/generated_metrics.go b/receiver/elasticsearchreceiver/internal/metadata/generated_metrics.go index a0a23af78a2d..8146d05b58c2 100644 --- a/receiver/elasticsearchreceiver/internal/metadata/generated_metrics.go +++ b/receiver/elasticsearchreceiver/internal/metadata/generated_metrics.go @@ -5248,10 +5248,8 @@ func newMetricJvmThreadsCount(cfg MetricConfig) metricJvmThreadsCount { type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricElasticsearchBreakerMemoryEstimated metricElasticsearchBreakerMemoryEstimated metricElasticsearchBreakerMemoryLimit metricElasticsearchBreakerMemoryLimit metricElasticsearchBreakerTripped metricElasticsearchBreakerTripped @@ -5357,10 +5355,9 @@ func WithStartTime(startTime pcommon.Timestamp) metricBuilderOption { func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSettings, options ...metricBuilderOption) *MetricsBuilder { mb := &MetricsBuilder{ - startTime: pcommon.NewTimestampFromTime(time.Now()), - metricsBuffer: pmetric.NewMetrics(), - buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, + startTime: pcommon.NewTimestampFromTime(time.Now()), + metricsBuffer: pmetric.NewMetrics(), + buildInfo: settings.BuildInfo, metricElasticsearchBreakerMemoryEstimated: newMetricElasticsearchBreakerMemoryEstimated(mbc.Metrics.ElasticsearchBreakerMemoryEstimated), metricElasticsearchBreakerMemoryLimit: newMetricElasticsearchBreakerMemoryLimit(mbc.Metrics.ElasticsearchBreakerMemoryLimit), metricElasticsearchBreakerTripped: newMetricElasticsearchBreakerTripped(mbc.Metrics.ElasticsearchBreakerTripped), @@ -5464,54 +5461,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithElasticsearchClusterName sets provided value as "elasticsearch.cluster.name" attribute for current resource. -func WithElasticsearchClusterName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.ElasticsearchClusterName.Enabled { - rm.Resource().Attributes().PutStr("elasticsearch.cluster.name", val) - } - } -} - -// WithElasticsearchIndexName sets provided value as "elasticsearch.index.name" attribute for current resource. -func WithElasticsearchIndexName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.ElasticsearchIndexName.Enabled { - rm.Resource().Attributes().PutStr("elasticsearch.index.name", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithElasticsearchNodeName sets provided value as "elasticsearch.node.name" attribute for current resource. -func WithElasticsearchNodeName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.ElasticsearchNodeName.Enabled { - rm.Resource().Attributes().PutStr("elasticsearch.node.name", val) - } - } -} - -// WithElasticsearchNodeVersion sets provided value as "elasticsearch.node.version" attribute for current resource. -func WithElasticsearchNodeVersion(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.ElasticsearchNodeVersion.Enabled { - rm.Resource().Attributes().PutStr("elasticsearch.node.version", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -5535,7 +5501,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/elasticsearchreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -5633,7 +5598,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricJvmThreadsCount.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/elasticsearchreceiver/internal/metadata/generated_metrics_test.go b/receiver/elasticsearchreceiver/internal/metadata/generated_metrics_test.go index 515a1ecb1c50..c8d1cf5592a4 100644 --- a/receiver/elasticsearchreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/elasticsearchreceiver/internal/metadata/generated_metrics_test.go @@ -397,7 +397,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordJvmThreadsCountDataPoint(ts, 1) - metrics := mb.Emit(WithElasticsearchClusterName("elasticsearch.cluster.name-val"), WithElasticsearchIndexName("elasticsearch.index.name-val"), WithElasticsearchNodeName("elasticsearch.node.name-val"), WithElasticsearchNodeVersion("elasticsearch.node.version-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -406,39 +408,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("elasticsearch.cluster.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.ElasticsearchClusterName.Enabled, ok) - if mb.resourceAttributesConfig.ElasticsearchClusterName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "elasticsearch.cluster.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("elasticsearch.index.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.ElasticsearchIndexName.Enabled, ok) - if mb.resourceAttributesConfig.ElasticsearchIndexName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "elasticsearch.index.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("elasticsearch.node.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.ElasticsearchNodeName.Enabled, ok) - if mb.resourceAttributesConfig.ElasticsearchNodeName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "elasticsearch.node.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("elasticsearch.node.version") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.ElasticsearchNodeVersion.Enabled, ok) - if mb.resourceAttributesConfig.ElasticsearchNodeVersion.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "elasticsearch.node.version-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 4) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/elasticsearchreceiver/internal/metadata/generated_resource.go b/receiver/elasticsearchreceiver/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..c0ce3b0d7750 --- /dev/null +++ b/receiver/elasticsearchreceiver/internal/metadata/generated_resource.go @@ -0,0 +1,57 @@ +// 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(), + } +} + +// SetElasticsearchClusterName sets provided value as "elasticsearch.cluster.name" attribute. +func (rb *ResourceBuilder) SetElasticsearchClusterName(val string) { + if rb.config.ElasticsearchClusterName.Enabled { + rb.res.Attributes().PutStr("elasticsearch.cluster.name", val) + } +} + +// SetElasticsearchIndexName sets provided value as "elasticsearch.index.name" attribute. +func (rb *ResourceBuilder) SetElasticsearchIndexName(val string) { + if rb.config.ElasticsearchIndexName.Enabled { + rb.res.Attributes().PutStr("elasticsearch.index.name", val) + } +} + +// SetElasticsearchNodeName sets provided value as "elasticsearch.node.name" attribute. +func (rb *ResourceBuilder) SetElasticsearchNodeName(val string) { + if rb.config.ElasticsearchNodeName.Enabled { + rb.res.Attributes().PutStr("elasticsearch.node.name", val) + } +} + +// SetElasticsearchNodeVersion sets provided value as "elasticsearch.node.version" attribute. +func (rb *ResourceBuilder) SetElasticsearchNodeVersion(val string) { + if rb.config.ElasticsearchNodeVersion.Enabled { + rb.res.Attributes().PutStr("elasticsearch.node.version", 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/receiver/elasticsearchreceiver/internal/metadata/generated_resource_test.go b/receiver/elasticsearchreceiver/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..0d0ae2f23ca1 --- /dev/null +++ b/receiver/elasticsearchreceiver/internal/metadata/generated_resource_test.go @@ -0,0 +1,58 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetElasticsearchClusterName("elasticsearch.cluster.name-val") + rb.SetElasticsearchIndexName("elasticsearch.index.name-val") + rb.SetElasticsearchNodeName("elasticsearch.node.name-val") + rb.SetElasticsearchNodeVersion("elasticsearch.node.version-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 4, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 4, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("elasticsearch.cluster.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "elasticsearch.cluster.name-val", val.Str()) + } + val, ok = res.Attributes().Get("elasticsearch.index.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "elasticsearch.index.name-val", val.Str()) + } + val, ok = res.Attributes().Get("elasticsearch.node.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "elasticsearch.node.name-val", val.Str()) + } + val, ok = res.Attributes().Get("elasticsearch.node.version") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "elasticsearch.node.version-val", val.Str()) + } + }) + } +} diff --git a/receiver/elasticsearchreceiver/scraper.go b/receiver/elasticsearchreceiver/scraper.go index 94ee36ed7161..044d4cffbb60 100644 --- a/receiver/elasticsearchreceiver/scraper.go +++ b/receiver/elasticsearchreceiver/scraper.go @@ -46,6 +46,7 @@ type elasticsearchScraper struct { client elasticsearchClient settings component.TelemetrySettings cfg *Config + rb *metadata.ResourceBuilder mb *metadata.MetricsBuilder version *version.Version clusterName string @@ -58,6 +59,7 @@ func newElasticSearchScraper( return &elasticsearchScraper{ settings: settings.TelemetrySettings, cfg: cfg, + rb: metadata.NewResourceBuilder(cfg.ResourceAttributes), mb: metadata.NewMetricsBuilder(cfg.MetricsBuilderConfig, settings), } } @@ -320,17 +322,14 @@ func (r *elasticsearchScraper) scrapeNodeMetrics(ctx context.Context, now pcommo now, info.Indices.SegmentsStats.TermsMemoryInBy, metadata.AttributeSegmentsMemoryObjectTypeTerm, ) - // Define nodeMetadata slice to store all metadata. New metadata can be easily introduced by appending to the slice. - nodeMetadata := []metadata.ResourceMetricsOption{ - metadata.WithElasticsearchClusterName(nodeStats.ClusterName), - metadata.WithElasticsearchNodeName(info.Name), - } + r.rb.SetElasticsearchClusterName(nodeStats.ClusterName) + r.rb.SetElasticsearchNodeName(info.Name) if node, ok := nodesInfo.Nodes[id]; ok { - nodeMetadata = append(nodeMetadata, metadata.WithElasticsearchNodeVersion(node.Version)) + r.rb.SetElasticsearchNodeVersion(node.Version) } - r.mb.EmitForResource(nodeMetadata...) + r.mb.EmitForResource(metadata.WithResource(r.rb.Emit())) } } @@ -342,7 +341,8 @@ func (r *elasticsearchScraper) scrapeClusterMetrics(ctx context.Context, now pco r.scrapeClusterHealthMetrics(ctx, now, errs) r.scrapeClusterStatsMetrics(ctx, now, errs) - r.mb.EmitForResource(metadata.WithElasticsearchClusterName(r.clusterName)) + r.rb.SetElasticsearchClusterName(r.clusterName) + r.mb.EmitForResource(metadata.WithResource(r.rb.Emit())) } func (r *elasticsearchScraper) scrapeClusterStatsMetrics(ctx context.Context, now pcommon.Timestamp, errs *scrapererror.ScrapeErrors) { @@ -677,5 +677,7 @@ func (r *elasticsearchScraper) scrapeOneIndexMetrics(now pcommon.Timestamp, name now, stats.Total.DocumentStats.ActiveCount, metadata.AttributeDocumentStateActive, metadata.AttributeIndexAggregationTypeTotal, ) - r.mb.EmitForResource(metadata.WithElasticsearchIndexName(name), metadata.WithElasticsearchClusterName(r.clusterName)) + r.rb.SetElasticsearchIndexName(name) + r.rb.SetElasticsearchClusterName(r.clusterName) + r.mb.EmitForResource(metadata.WithResource(r.rb.Emit())) } diff --git a/receiver/expvarreceiver/internal/metadata/generated_metrics.go b/receiver/expvarreceiver/internal/metadata/generated_metrics.go index 4897788a40f3..189210917c79 100644 --- a/receiver/expvarreceiver/internal/metadata/generated_metrics.go +++ b/receiver/expvarreceiver/internal/metadata/generated_metrics.go @@ -1338,7 +1338,6 @@ func newMetricProcessRuntimeMemstatsTotalAlloc(cfg MetricConfig) metricProcessRu type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information metricProcessRuntimeMemstatsBuckHashSys metricProcessRuntimeMemstatsBuckHashSys @@ -1422,14 +1421,19 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. type ResourceMetricsOption func(pmetric.ResourceMetrics) +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) + } +} + // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { @@ -1457,7 +1461,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/expvarreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) diff --git a/receiver/expvarreceiver/internal/metadata/generated_metrics_test.go b/receiver/expvarreceiver/internal/metadata/generated_metrics_test.go index b53add776e23..0de580cfc88a 100644 --- a/receiver/expvarreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/expvarreceiver/internal/metadata/generated_metrics_test.go @@ -156,7 +156,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordProcessRuntimeMemstatsTotalAllocDataPoint(ts, 1) - metrics := mb.Emit() + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -165,11 +167,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 0) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/filestatsreceiver/factory.go b/receiver/filestatsreceiver/factory.go index c6780fb904ca..1179aae09f52 100644 --- a/receiver/filestatsreceiver/factory.go +++ b/receiver/filestatsreceiver/factory.go @@ -36,9 +36,8 @@ func newReceiver( consumer consumer.Metrics, ) (receiver.Metrics, error) { fileStatsConfig := cfg.(*Config) - metricsBuilder := metadata.NewMetricsBuilder(fileStatsConfig.MetricsBuilderConfig, settings) - mp := newScraper(metricsBuilder, fileStatsConfig, settings.TelemetrySettings.Logger) + mp := newScraper(fileStatsConfig, settings) s, err := scraperhelper.NewScraper(settings.ID.Name(), mp.scrape) if err != nil { return nil, err diff --git a/receiver/filestatsreceiver/internal/metadata/generated_config_test.go b/receiver/filestatsreceiver/internal/metadata/generated_config_test.go index e19f1117f520..ec3952ce3ba1 100644 --- a/receiver/filestatsreceiver/internal/metadata/generated_config_test.go +++ b/receiver/filestatsreceiver/internal/metadata/generated_config_test.go @@ -72,3 +72,49 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + FileName: ResourceAttributeConfig{Enabled: true}, + FilePath: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + FileName: ResourceAttributeConfig{Enabled: false}, + FilePath: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/filestatsreceiver/internal/metadata/generated_metrics.go b/receiver/filestatsreceiver/internal/metadata/generated_metrics.go index 74d38ac4d3f1..df3a9786cba1 100644 --- a/receiver/filestatsreceiver/internal/metadata/generated_metrics.go +++ b/receiver/filestatsreceiver/internal/metadata/generated_metrics.go @@ -218,16 +218,14 @@ func newMetricFileSize(cfg MetricConfig) metricFileSize { // MetricsBuilder provides an interface for scrapers to report metrics while taking care of all the transformations // required to produce metric representation defined in metadata and user config. type MetricsBuilder struct { - startTime pcommon.Timestamp // start time that will be applied to all recorded data points. - metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. - metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. - buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig - metricFileAtime metricFileAtime - metricFileCtime metricFileCtime - metricFileMtime metricFileMtime - metricFileSize metricFileSize + startTime pcommon.Timestamp // start time that will be applied to all recorded data points. + metricsCapacity int // maximum observed number of metrics per resource. + metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. + buildInfo component.BuildInfo // contains version information + metricFileAtime metricFileAtime + metricFileCtime metricFileCtime + metricFileMtime metricFileMtime + metricFileSize metricFileSize } // metricBuilderOption applies changes to default metrics builder. @@ -242,14 +240,13 @@ func WithStartTime(startTime pcommon.Timestamp) metricBuilderOption { func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSettings, options ...metricBuilderOption) *MetricsBuilder { mb := &MetricsBuilder{ - startTime: pcommon.NewTimestampFromTime(time.Now()), - metricsBuffer: pmetric.NewMetrics(), - buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, - metricFileAtime: newMetricFileAtime(mbc.Metrics.FileAtime), - metricFileCtime: newMetricFileCtime(mbc.Metrics.FileCtime), - metricFileMtime: newMetricFileMtime(mbc.Metrics.FileMtime), - metricFileSize: newMetricFileSize(mbc.Metrics.FileSize), + startTime: pcommon.NewTimestampFromTime(time.Now()), + metricsBuffer: pmetric.NewMetrics(), + buildInfo: settings.BuildInfo, + metricFileAtime: newMetricFileAtime(mbc.Metrics.FileAtime), + metricFileCtime: newMetricFileCtime(mbc.Metrics.FileCtime), + metricFileMtime: newMetricFileMtime(mbc.Metrics.FileMtime), + metricFileSize: newMetricFileSize(mbc.Metrics.FileSize), } for _, op := range options { op(mb) @@ -262,36 +259,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithFileName sets provided value as "file.name" attribute for current resource. -func WithFileName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.FileName.Enabled { - rm.Resource().Attributes().PutStr("file.name", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithFilePath sets provided value as "file.path" attribute for current resource. -func WithFilePath(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.FilePath.Enabled { - rm.Resource().Attributes().PutStr("file.path", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -315,7 +299,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/filestatsreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -326,7 +309,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricFileSize.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/filestatsreceiver/internal/metadata/generated_metrics_test.go b/receiver/filestatsreceiver/internal/metadata/generated_metrics_test.go index 45fa9dfae945..8a5f3b5e5a56 100644 --- a/receiver/filestatsreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/filestatsreceiver/internal/metadata/generated_metrics_test.go @@ -68,7 +68,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordFileSizeDataPoint(ts, 1) - metrics := mb.Emit(WithFileName("file.name-val"), WithFilePath("file.path-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -77,25 +79,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("file.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.FileName.Enabled, ok) - if mb.resourceAttributesConfig.FileName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "file.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("file.path") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.FilePath.Enabled, ok) - if mb.resourceAttributesConfig.FilePath.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "file.path-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 2) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/filestatsreceiver/internal/metadata/generated_resource.go b/receiver/filestatsreceiver/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..77e618071ca3 --- /dev/null +++ b/receiver/filestatsreceiver/internal/metadata/generated_resource.go @@ -0,0 +1,43 @@ +// 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(), + } +} + +// SetFileName sets provided value as "file.name" attribute. +func (rb *ResourceBuilder) SetFileName(val string) { + if rb.config.FileName.Enabled { + rb.res.Attributes().PutStr("file.name", val) + } +} + +// SetFilePath sets provided value as "file.path" attribute. +func (rb *ResourceBuilder) SetFilePath(val string) { + if rb.config.FilePath.Enabled { + rb.res.Attributes().PutStr("file.path", 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/receiver/filestatsreceiver/internal/metadata/generated_resource_test.go b/receiver/filestatsreceiver/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..56eec7d30d8e --- /dev/null +++ b/receiver/filestatsreceiver/internal/metadata/generated_resource_test.go @@ -0,0 +1,46 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetFileName("file.name-val") + rb.SetFilePath("file.path-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 1, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 2, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("file.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "file.name-val", val.Str()) + } + val, ok = res.Attributes().Get("file.path") + assert.Equal(t, test == "all_set", ok) + if ok { + assert.EqualValues(t, "file.path-val", val.Str()) + } + }) + } +} diff --git a/receiver/filestatsreceiver/scraper.go b/receiver/filestatsreceiver/scraper.go index a389dd5541a6..dc220c50aca7 100644 --- a/receiver/filestatsreceiver/scraper.go +++ b/receiver/filestatsreceiver/scraper.go @@ -12,6 +12,7 @@ import ( "github.com/bmatcuk/doublestar/v4" "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/pdata/pmetric" + "go.opentelemetry.io/collector/receiver" "go.opentelemetry.io/collector/receiver/scrapererror" "go.uber.org/multierr" "go.uber.org/zap" @@ -20,9 +21,10 @@ import ( ) type scraper struct { - include string - logger *zap.Logger - metricsBuilder *metadata.MetricsBuilder + include string + logger *zap.Logger + rb *metadata.ResourceBuilder + mb *metadata.MetricsBuilder } func (s *scraper) scrape(_ context.Context) (pmetric.Metrics, error) { @@ -46,22 +48,26 @@ func (s *scraper) scrape(_ context.Context) (pmetric.Metrics, error) { scrapeErrors = append(scrapeErrors, err) continue } - s.metricsBuilder.RecordFileSizeDataPoint(now, fileinfo.Size()) - s.metricsBuilder.RecordFileMtimeDataPoint(now, fileinfo.ModTime().Unix()) - collectStats(now, fileinfo, s.metricsBuilder, s.logger) - s.metricsBuilder.EmitForResource(metadata.WithFileName(fileinfo.Name()), metadata.WithFilePath(path)) + s.mb.RecordFileSizeDataPoint(now, fileinfo.Size()) + s.mb.RecordFileMtimeDataPoint(now, fileinfo.ModTime().Unix()) + collectStats(now, fileinfo, s.mb, s.logger) + + s.rb.SetFileName(fileinfo.Name()) + s.rb.SetFilePath(path) + s.mb.EmitForResource(metadata.WithResource(s.rb.Emit())) } if len(scrapeErrors) > 0 { - return s.metricsBuilder.Emit(), scrapererror.NewPartialScrapeError(multierr.Combine(scrapeErrors...), len(scrapeErrors)) + return s.mb.Emit(), scrapererror.NewPartialScrapeError(multierr.Combine(scrapeErrors...), len(scrapeErrors)) } - return s.metricsBuilder.Emit(), nil + return s.mb.Emit(), nil } -func newScraper(metricsBuilder *metadata.MetricsBuilder, cfg *Config, logger *zap.Logger) *scraper { +func newScraper(cfg *Config, settings receiver.CreateSettings) *scraper { return &scraper{ - include: cfg.Include, - logger: logger, - metricsBuilder: metricsBuilder, + include: cfg.Include, + logger: settings.TelemetrySettings.Logger, + rb: metadata.NewResourceBuilder(cfg.ResourceAttributes), + mb: metadata.NewMetricsBuilder(cfg.MetricsBuilderConfig, settings), } } diff --git a/receiver/filestatsreceiver/scraper_test.go b/receiver/filestatsreceiver/scraper_test.go index 3cfa14400068..0390a73866b5 100644 --- a/receiver/filestatsreceiver/scraper_test.go +++ b/receiver/filestatsreceiver/scraper_test.go @@ -12,17 +12,13 @@ import ( "github.com/bmatcuk/doublestar/v4" "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/receiver/receivertest" - "go.uber.org/zap" - - "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/filestatsreceiver/internal/metadata" ) func Test_Scrape(t *testing.T) { tmpDir := t.TempDir() cfg := newDefaultConfig().(*Config) cfg.Include = filepath.Join(tmpDir, "*.log") - metricsBuilder := metadata.NewMetricsBuilder(cfg.MetricsBuilderConfig, receivertest.NewNopCreateSettings()) - s := newScraper(metricsBuilder, cfg, zap.NewNop()) + s := newScraper(cfg, receivertest.NewNopCreateSettings()) metrics, err := s.scrape(context.Background()) require.NoError(t, err) require.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -57,8 +53,7 @@ func Test_Scrape_All(t *testing.T) { cfg.Metrics.FileAtime.Enabled = true cfg.Metrics.FileCtime.Enabled = true - metricsBuilder := metadata.NewMetricsBuilder(cfg.MetricsBuilderConfig, receivertest.NewNopCreateSettings()) - s := newScraper(metricsBuilder, cfg, zap.NewNop()) + s := newScraper(cfg, receivertest.NewNopCreateSettings()) metrics, err := s.scrape(context.Background()) require.NoError(t, err) require.Equal(t, 0, metrics.ResourceMetrics().Len()) diff --git a/receiver/flinkmetricsreceiver/internal/metadata/generated_config_test.go b/receiver/flinkmetricsreceiver/internal/metadata/generated_config_test.go index 92ab1ae55e2e..42f9a29f138a 100644 --- a/receiver/flinkmetricsreceiver/internal/metadata/generated_config_test.go +++ b/receiver/flinkmetricsreceiver/internal/metadata/generated_config_test.go @@ -130,3 +130,57 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + FlinkJobName: ResourceAttributeConfig{Enabled: true}, + FlinkResourceType: ResourceAttributeConfig{Enabled: true}, + FlinkSubtaskIndex: ResourceAttributeConfig{Enabled: true}, + FlinkTaskName: ResourceAttributeConfig{Enabled: true}, + FlinkTaskmanagerID: ResourceAttributeConfig{Enabled: true}, + HostName: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + FlinkJobName: ResourceAttributeConfig{Enabled: false}, + FlinkResourceType: ResourceAttributeConfig{Enabled: false}, + FlinkSubtaskIndex: ResourceAttributeConfig{Enabled: false}, + FlinkTaskName: ResourceAttributeConfig{Enabled: false}, + FlinkTaskmanagerID: ResourceAttributeConfig{Enabled: false}, + HostName: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/flinkmetricsreceiver/internal/metadata/generated_metrics.go b/receiver/flinkmetricsreceiver/internal/metadata/generated_metrics.go index 0dd6a99270f3..33d05cf9b60b 100644 --- a/receiver/flinkmetricsreceiver/internal/metadata/generated_metrics.go +++ b/receiver/flinkmetricsreceiver/internal/metadata/generated_metrics.go @@ -1596,10 +1596,8 @@ func newMetricFlinkTaskRecordCount(cfg MetricConfig) metricFlinkTaskRecordCount type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricFlinkJobCheckpointCount metricFlinkJobCheckpointCount metricFlinkJobCheckpointInProgress metricFlinkJobCheckpointInProgress metricFlinkJobLastCheckpointSize metricFlinkJobLastCheckpointSize @@ -1646,7 +1644,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricFlinkJobCheckpointCount: newMetricFlinkJobCheckpointCount(mbc.Metrics.FlinkJobCheckpointCount), metricFlinkJobCheckpointInProgress: newMetricFlinkJobCheckpointInProgress(mbc.Metrics.FlinkJobCheckpointInProgress), metricFlinkJobLastCheckpointSize: newMetricFlinkJobLastCheckpointSize(mbc.Metrics.FlinkJobLastCheckpointSize), @@ -1688,77 +1685,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithFlinkJobName sets provided value as "flink.job.name" attribute for current resource. -func WithFlinkJobName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.FlinkJobName.Enabled { - rm.Resource().Attributes().PutStr("flink.job.name", val) - } - } -} - -// WithFlinkResourceTypeJobmanager sets "flink.resource.type=jobmanager" attribute for current resource. -func WithFlinkResourceTypeJobmanager(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.FlinkResourceType.Enabled { - rm.Resource().Attributes().PutStr("flink.resource.type", "jobmanager") - } -} - -// WithFlinkResourceTypeTaskmanager sets "flink.resource.type=taskmanager" attribute for current resource. -func WithFlinkResourceTypeTaskmanager(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.FlinkResourceType.Enabled { - rm.Resource().Attributes().PutStr("flink.resource.type", "taskmanager") - } -} - -// WithFlinkSubtaskIndex sets provided value as "flink.subtask.index" attribute for current resource. -func WithFlinkSubtaskIndex(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.FlinkSubtaskIndex.Enabled { - rm.Resource().Attributes().PutStr("flink.subtask.index", val) - } - } -} - -// WithFlinkTaskName sets provided value as "flink.task.name" attribute for current resource. -func WithFlinkTaskName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.FlinkTaskName.Enabled { - rm.Resource().Attributes().PutStr("flink.task.name", val) - } - } -} - -// WithFlinkTaskmanagerID sets provided value as "flink.taskmanager.id" attribute for current resource. -func WithFlinkTaskmanagerID(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.FlinkTaskmanagerID.Enabled { - rm.Resource().Attributes().PutStr("flink.taskmanager.id", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithHostName sets provided value as "host.name" attribute for current resource. -func WithHostName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.HostName.Enabled { - rm.Resource().Attributes().PutStr("host.name", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -1782,7 +1725,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/flinkmetricsreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -1818,7 +1760,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricFlinkTaskRecordCount.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/flinkmetricsreceiver/internal/metadata/generated_metrics_test.go b/receiver/flinkmetricsreceiver/internal/metadata/generated_metrics_test.go index e37e0e486b7f..19e1b0e3fe92 100644 --- a/receiver/flinkmetricsreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/flinkmetricsreceiver/internal/metadata/generated_metrics_test.go @@ -170,7 +170,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordFlinkTaskRecordCountDataPoint(ts, "1", AttributeRecordIn) - metrics := mb.Emit(WithFlinkJobName("flink.job.name-val"), WithFlinkResourceTypeJobmanager, WithFlinkSubtaskIndex("flink.subtask.index-val"), WithFlinkTaskName("flink.task.name-val"), WithFlinkTaskmanagerID("flink.taskmanager.id-val"), WithHostName("host.name-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -179,53 +181,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("flink.job.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.FlinkJobName.Enabled, ok) - if mb.resourceAttributesConfig.FlinkJobName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "flink.job.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("flink.resource.type") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.FlinkResourceType.Enabled, ok) - if mb.resourceAttributesConfig.FlinkResourceType.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "jobmanager", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("flink.subtask.index") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.FlinkSubtaskIndex.Enabled, ok) - if mb.resourceAttributesConfig.FlinkSubtaskIndex.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "flink.subtask.index-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("flink.task.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.FlinkTaskName.Enabled, ok) - if mb.resourceAttributesConfig.FlinkTaskName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "flink.task.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("flink.taskmanager.id") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.FlinkTaskmanagerID.Enabled, ok) - if mb.resourceAttributesConfig.FlinkTaskmanagerID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "flink.taskmanager.id-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("host.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.HostName.Enabled, ok) - if mb.resourceAttributesConfig.HostName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "host.name-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 6) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/flinkmetricsreceiver/internal/metadata/generated_resource.go b/receiver/flinkmetricsreceiver/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..131bbc8a52c2 --- /dev/null +++ b/receiver/flinkmetricsreceiver/internal/metadata/generated_resource.go @@ -0,0 +1,78 @@ +// 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(), + } +} + +// SetFlinkJobName sets provided value as "flink.job.name" attribute. +func (rb *ResourceBuilder) SetFlinkJobName(val string) { + if rb.config.FlinkJobName.Enabled { + rb.res.Attributes().PutStr("flink.job.name", val) + } +} + +// SetFlinkResourceTypeJobmanager sets "flink.resource.type=jobmanager" attribute. +func (rb *ResourceBuilder) SetFlinkResourceTypeJobmanager() { + if rb.config.FlinkResourceType.Enabled { + rb.res.Attributes().PutStr("flink.resource.type", "jobmanager") + } +} + +// SetFlinkResourceTypeTaskmanager sets "flink.resource.type=taskmanager" attribute. +func (rb *ResourceBuilder) SetFlinkResourceTypeTaskmanager() { + if rb.config.FlinkResourceType.Enabled { + rb.res.Attributes().PutStr("flink.resource.type", "taskmanager") + } +} + +// SetFlinkSubtaskIndex sets provided value as "flink.subtask.index" attribute. +func (rb *ResourceBuilder) SetFlinkSubtaskIndex(val string) { + if rb.config.FlinkSubtaskIndex.Enabled { + rb.res.Attributes().PutStr("flink.subtask.index", val) + } +} + +// SetFlinkTaskName sets provided value as "flink.task.name" attribute. +func (rb *ResourceBuilder) SetFlinkTaskName(val string) { + if rb.config.FlinkTaskName.Enabled { + rb.res.Attributes().PutStr("flink.task.name", val) + } +} + +// SetFlinkTaskmanagerID sets provided value as "flink.taskmanager.id" attribute. +func (rb *ResourceBuilder) SetFlinkTaskmanagerID(val string) { + if rb.config.FlinkTaskmanagerID.Enabled { + rb.res.Attributes().PutStr("flink.taskmanager.id", val) + } +} + +// SetHostName sets provided value as "host.name" attribute. +func (rb *ResourceBuilder) SetHostName(val string) { + if rb.config.HostName.Enabled { + rb.res.Attributes().PutStr("host.name", 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/receiver/flinkmetricsreceiver/internal/metadata/generated_resource_test.go b/receiver/flinkmetricsreceiver/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..6dbf022b4216 --- /dev/null +++ b/receiver/flinkmetricsreceiver/internal/metadata/generated_resource_test.go @@ -0,0 +1,70 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetFlinkJobName("flink.job.name-val") + rb.SetFlinkResourceTypeJobmanager() + rb.SetFlinkSubtaskIndex("flink.subtask.index-val") + rb.SetFlinkTaskName("flink.task.name-val") + rb.SetFlinkTaskmanagerID("flink.taskmanager.id-val") + rb.SetHostName("host.name-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 6, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 6, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("flink.job.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "flink.job.name-val", val.Str()) + } + val, ok = res.Attributes().Get("flink.resource.type") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "jobmanager", val.Str()) + } + val, ok = res.Attributes().Get("flink.subtask.index") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "flink.subtask.index-val", val.Str()) + } + val, ok = res.Attributes().Get("flink.task.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "flink.task.name-val", val.Str()) + } + val, ok = res.Attributes().Get("flink.taskmanager.id") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "flink.taskmanager.id-val", val.Str()) + } + val, ok = res.Attributes().Get("host.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "host.name-val", val.Str()) + } + }) + } +} diff --git a/receiver/flinkmetricsreceiver/process.go b/receiver/flinkmetricsreceiver/process.go index f208c500b581..38cf5ca32153 100644 --- a/receiver/flinkmetricsreceiver/process.go +++ b/receiver/flinkmetricsreceiver/process.go @@ -66,10 +66,9 @@ func (s *flinkmetricsScraper) processJobmanagerMetrics(now pcommon.Timestamp, jo _ = s.mb.RecordFlinkJvmMemoryHeapUsedDataPoint(now, metric.Value) } } - s.mb.EmitForResource( - metadata.WithHostName(jobmanagerMetrics.Host), - metadata.WithFlinkResourceTypeJobmanager, - ) + s.rb.SetHostName(jobmanagerMetrics.Host) + s.rb.SetFlinkResourceTypeJobmanager() + s.mb.EmitForResource(metadata.WithResource(s.rb.Emit())) } func (s *flinkmetricsScraper) processTaskmanagerMetrics(now pcommon.Timestamp, taskmanagerMetricInstances []*models.TaskmanagerMetrics) { @@ -124,11 +123,10 @@ func (s *flinkmetricsScraper) processTaskmanagerMetrics(now pcommon.Timestamp, t _ = s.mb.RecordFlinkJvmMemoryHeapUsedDataPoint(now, metric.Value) } } - s.mb.EmitForResource( - metadata.WithHostName(taskmanagerMetrics.Host), - metadata.WithFlinkTaskmanagerID(taskmanagerMetrics.TaskmanagerID), - metadata.WithFlinkResourceTypeTaskmanager, - ) + s.rb.SetHostName(taskmanagerMetrics.Host) + s.rb.SetFlinkTaskmanagerID(taskmanagerMetrics.TaskmanagerID) + s.rb.SetFlinkResourceTypeTaskmanager() + s.mb.EmitForResource(metadata.WithResource(s.rb.Emit())) } } @@ -150,10 +148,9 @@ func (s *flinkmetricsScraper) processJobsMetrics(now pcommon.Timestamp, jobsMetr _ = s.mb.RecordFlinkJobCheckpointCountDataPoint(now, metric.Value, metadata.AttributeCheckpointFailed) } } - s.mb.EmitForResource( - metadata.WithHostName(jobsMetrics.Host), - metadata.WithFlinkJobName(jobsMetrics.JobName), - ) + s.rb.SetHostName(jobsMetrics.Host) + s.rb.SetFlinkJobName(jobsMetrics.JobName) + s.mb.EmitForResource(metadata.WithResource(s.rb.Emit())) } } @@ -183,12 +180,11 @@ func (s *flinkmetricsScraper) processSubtaskMetrics(now pcommon.Timestamp, subta _ = s.mb.RecordFlinkOperatorWatermarkOutputDataPoint(now, metric.Value, operatorName[0]) } } - s.mb.EmitForResource( - metadata.WithHostName(subtaskMetrics.Host), - metadata.WithFlinkTaskmanagerID(subtaskMetrics.TaskmanagerID), - metadata.WithFlinkJobName(subtaskMetrics.JobName), - metadata.WithFlinkTaskName(subtaskMetrics.TaskName), - metadata.WithFlinkSubtaskIndex(subtaskMetrics.SubtaskIndex), - ) + s.rb.SetHostName(subtaskMetrics.Host) + s.rb.SetFlinkTaskmanagerID(subtaskMetrics.TaskmanagerID) + s.rb.SetFlinkJobName(subtaskMetrics.JobName) + s.rb.SetFlinkTaskName(subtaskMetrics.TaskName) + s.rb.SetFlinkSubtaskIndex(subtaskMetrics.SubtaskIndex) + s.mb.EmitForResource(metadata.WithResource(s.rb.Emit())) } } diff --git a/receiver/flinkmetricsreceiver/scraper.go b/receiver/flinkmetricsreceiver/scraper.go index 9306cf1edace..77e167551774 100644 --- a/receiver/flinkmetricsreceiver/scraper.go +++ b/receiver/flinkmetricsreceiver/scraper.go @@ -31,6 +31,7 @@ type flinkmetricsScraper struct { client client cfg *Config settings component.TelemetrySettings + rb *metadata.ResourceBuilder mb *metadata.MetricsBuilder } @@ -38,6 +39,7 @@ func newflinkScraper(config *Config, settings receiver.CreateSettings) *flinkmet return &flinkmetricsScraper{ settings: settings.TelemetrySettings, cfg: config, + rb: metadata.NewResourceBuilder(config.ResourceAttributes), mb: metadata.NewMetricsBuilder(config.MetricsBuilderConfig, settings), } } diff --git a/receiver/haproxyreceiver/factory.go b/receiver/haproxyreceiver/factory.go index 9db9c75d100a..8f660c4ad2ab 100644 --- a/receiver/haproxyreceiver/factory.go +++ b/receiver/haproxyreceiver/factory.go @@ -36,9 +36,7 @@ func newReceiver( consumer consumer.Metrics, ) (receiver.Metrics, error) { haProxyCfg := cfg.(*Config) - metricsBuilder := metadata.NewMetricsBuilder(haProxyCfg.MetricsBuilderConfig, settings) - - mp := newScraper(metricsBuilder, haProxyCfg, settings.TelemetrySettings.Logger) + mp := newScraper(haProxyCfg, settings) s, err := scraperhelper.NewScraper(settings.ID.Name(), mp.scrape) if err != nil { return nil, err diff --git a/receiver/haproxyreceiver/internal/metadata/generated_config_test.go b/receiver/haproxyreceiver/internal/metadata/generated_config_test.go index 3f1b7c86a02d..639f1b647474 100644 --- a/receiver/haproxyreceiver/internal/metadata/generated_config_test.go +++ b/receiver/haproxyreceiver/internal/metadata/generated_config_test.go @@ -130,3 +130,63 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + HaproxyAddr: ResourceAttributeConfig{Enabled: true}, + HaproxyAlgo: ResourceAttributeConfig{Enabled: true}, + HaproxyIid: ResourceAttributeConfig{Enabled: true}, + HaproxyPid: ResourceAttributeConfig{Enabled: true}, + HaproxySid: ResourceAttributeConfig{Enabled: true}, + HaproxyType: ResourceAttributeConfig{Enabled: true}, + HaproxyURL: ResourceAttributeConfig{Enabled: true}, + ProxyName: ResourceAttributeConfig{Enabled: true}, + ServiceName: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + HaproxyAddr: ResourceAttributeConfig{Enabled: false}, + HaproxyAlgo: ResourceAttributeConfig{Enabled: false}, + HaproxyIid: ResourceAttributeConfig{Enabled: false}, + HaproxyPid: ResourceAttributeConfig{Enabled: false}, + HaproxySid: ResourceAttributeConfig{Enabled: false}, + HaproxyType: ResourceAttributeConfig{Enabled: false}, + HaproxyURL: ResourceAttributeConfig{Enabled: false}, + ProxyName: ResourceAttributeConfig{Enabled: false}, + ServiceName: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/haproxyreceiver/internal/metadata/generated_metrics.go b/receiver/haproxyreceiver/internal/metadata/generated_metrics.go index c594e5f99cb3..77b65f2b0a7b 100644 --- a/receiver/haproxyreceiver/internal/metadata/generated_metrics.go +++ b/receiver/haproxyreceiver/internal/metadata/generated_metrics.go @@ -1378,10 +1378,8 @@ func newMetricHaproxySessionsTotal(cfg MetricConfig) metricHaproxySessionsTotal type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricHaproxyBytesInput metricHaproxyBytesInput metricHaproxyBytesOutput metricHaproxyBytesOutput metricHaproxyClientsCanceled metricHaproxyClientsCanceled @@ -1425,7 +1423,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricHaproxyBytesInput: newMetricHaproxyBytesInput(mbc.Metrics.HaproxyBytesInput), metricHaproxyBytesOutput: newMetricHaproxyBytesOutput(mbc.Metrics.HaproxyBytesOutput), metricHaproxyClientsCanceled: newMetricHaproxyClientsCanceled(mbc.Metrics.HaproxyClientsCanceled), @@ -1464,99 +1461,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithHaproxyAddr sets provided value as "haproxy.addr" attribute for current resource. -func WithHaproxyAddr(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.HaproxyAddr.Enabled { - rm.Resource().Attributes().PutStr("haproxy.addr", val) - } - } -} - -// WithHaproxyAlgo sets provided value as "haproxy.algo" attribute for current resource. -func WithHaproxyAlgo(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.HaproxyAlgo.Enabled { - rm.Resource().Attributes().PutStr("haproxy.algo", val) - } - } -} - -// WithHaproxyIid sets provided value as "haproxy.iid" attribute for current resource. -func WithHaproxyIid(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.HaproxyIid.Enabled { - rm.Resource().Attributes().PutStr("haproxy.iid", val) - } - } -} - -// WithHaproxyPid sets provided value as "haproxy.pid" attribute for current resource. -func WithHaproxyPid(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.HaproxyPid.Enabled { - rm.Resource().Attributes().PutStr("haproxy.pid", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithHaproxySid sets provided value as "haproxy.sid" attribute for current resource. -func WithHaproxySid(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.HaproxySid.Enabled { - rm.Resource().Attributes().PutStr("haproxy.sid", val) - } - } -} - -// WithHaproxyType sets provided value as "haproxy.type" attribute for current resource. -func WithHaproxyType(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.HaproxyType.Enabled { - rm.Resource().Attributes().PutStr("haproxy.type", val) - } - } -} - -// WithHaproxyURL sets provided value as "haproxy.url" attribute for current resource. -func WithHaproxyURL(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.HaproxyURL.Enabled { - rm.Resource().Attributes().PutStr("haproxy.url", val) - } - } -} - -// WithProxyName sets provided value as "proxy_name" attribute for current resource. -func WithProxyName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.ProxyName.Enabled { - rm.Resource().Attributes().PutStr("proxy_name", val) - } - } -} - -// WithServiceName sets provided value as "service_name" attribute for current resource. -func WithServiceName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.ServiceName.Enabled { - rm.Resource().Attributes().PutStr("service_name", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -1580,7 +1501,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/haproxyreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -1613,7 +1533,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricHaproxySessionsTotal.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/haproxyreceiver/internal/metadata/generated_metrics_test.go b/receiver/haproxyreceiver/internal/metadata/generated_metrics_test.go index 6d3e2fa0b61d..a50404f93650 100644 --- a/receiver/haproxyreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/haproxyreceiver/internal/metadata/generated_metrics_test.go @@ -149,7 +149,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordHaproxySessionsTotalDataPoint(ts, "1") - metrics := mb.Emit(WithHaproxyAddr("haproxy.addr-val"), WithHaproxyAlgo("haproxy.algo-val"), WithHaproxyIid("haproxy.iid-val"), WithHaproxyPid("haproxy.pid-val"), WithHaproxySid("haproxy.sid-val"), WithHaproxyType("haproxy.type-val"), WithHaproxyURL("haproxy.url-val"), WithProxyName("proxy_name-val"), WithServiceName("service_name-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -158,74 +160,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("haproxy.addr") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.HaproxyAddr.Enabled, ok) - if mb.resourceAttributesConfig.HaproxyAddr.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "haproxy.addr-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("haproxy.algo") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.HaproxyAlgo.Enabled, ok) - if mb.resourceAttributesConfig.HaproxyAlgo.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "haproxy.algo-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("haproxy.iid") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.HaproxyIid.Enabled, ok) - if mb.resourceAttributesConfig.HaproxyIid.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "haproxy.iid-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("haproxy.pid") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.HaproxyPid.Enabled, ok) - if mb.resourceAttributesConfig.HaproxyPid.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "haproxy.pid-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("haproxy.sid") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.HaproxySid.Enabled, ok) - if mb.resourceAttributesConfig.HaproxySid.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "haproxy.sid-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("haproxy.type") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.HaproxyType.Enabled, ok) - if mb.resourceAttributesConfig.HaproxyType.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "haproxy.type-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("haproxy.url") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.HaproxyURL.Enabled, ok) - if mb.resourceAttributesConfig.HaproxyURL.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "haproxy.url-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("proxy_name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.ProxyName.Enabled, ok) - if mb.resourceAttributesConfig.ProxyName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "proxy_name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("service_name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.ServiceName.Enabled, ok) - if mb.resourceAttributesConfig.ServiceName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "service_name-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 9) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/haproxyreceiver/internal/metadata/generated_resource.go b/receiver/haproxyreceiver/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..5f5d282c060b --- /dev/null +++ b/receiver/haproxyreceiver/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(), + } +} + +// SetHaproxyAddr sets provided value as "haproxy.addr" attribute. +func (rb *ResourceBuilder) SetHaproxyAddr(val string) { + if rb.config.HaproxyAddr.Enabled { + rb.res.Attributes().PutStr("haproxy.addr", val) + } +} + +// SetHaproxyAlgo sets provided value as "haproxy.algo" attribute. +func (rb *ResourceBuilder) SetHaproxyAlgo(val string) { + if rb.config.HaproxyAlgo.Enabled { + rb.res.Attributes().PutStr("haproxy.algo", val) + } +} + +// SetHaproxyIid sets provided value as "haproxy.iid" attribute. +func (rb *ResourceBuilder) SetHaproxyIid(val string) { + if rb.config.HaproxyIid.Enabled { + rb.res.Attributes().PutStr("haproxy.iid", val) + } +} + +// SetHaproxyPid sets provided value as "haproxy.pid" attribute. +func (rb *ResourceBuilder) SetHaproxyPid(val string) { + if rb.config.HaproxyPid.Enabled { + rb.res.Attributes().PutStr("haproxy.pid", val) + } +} + +// SetHaproxySid sets provided value as "haproxy.sid" attribute. +func (rb *ResourceBuilder) SetHaproxySid(val string) { + if rb.config.HaproxySid.Enabled { + rb.res.Attributes().PutStr("haproxy.sid", val) + } +} + +// SetHaproxyType sets provided value as "haproxy.type" attribute. +func (rb *ResourceBuilder) SetHaproxyType(val string) { + if rb.config.HaproxyType.Enabled { + rb.res.Attributes().PutStr("haproxy.type", val) + } +} + +// SetHaproxyURL sets provided value as "haproxy.url" attribute. +func (rb *ResourceBuilder) SetHaproxyURL(val string) { + if rb.config.HaproxyURL.Enabled { + rb.res.Attributes().PutStr("haproxy.url", val) + } +} + +// SetProxyName sets provided value as "proxy_name" attribute. +func (rb *ResourceBuilder) SetProxyName(val string) { + if rb.config.ProxyName.Enabled { + rb.res.Attributes().PutStr("proxy_name", val) + } +} + +// SetServiceName sets provided value as "service_name" attribute. +func (rb *ResourceBuilder) SetServiceName(val string) { + if rb.config.ServiceName.Enabled { + rb.res.Attributes().PutStr("service_name", 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/receiver/haproxyreceiver/internal/metadata/generated_resource_test.go b/receiver/haproxyreceiver/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..a01973a335f2 --- /dev/null +++ b/receiver/haproxyreceiver/internal/metadata/generated_resource_test.go @@ -0,0 +1,88 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetHaproxyAddr("haproxy.addr-val") + rb.SetHaproxyAlgo("haproxy.algo-val") + rb.SetHaproxyIid("haproxy.iid-val") + rb.SetHaproxyPid("haproxy.pid-val") + rb.SetHaproxySid("haproxy.sid-val") + rb.SetHaproxyType("haproxy.type-val") + rb.SetHaproxyURL("haproxy.url-val") + rb.SetProxyName("proxy_name-val") + rb.SetServiceName("service_name-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 7, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 9, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("haproxy.addr") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "haproxy.addr-val", val.Str()) + } + val, ok = res.Attributes().Get("haproxy.algo") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "haproxy.algo-val", val.Str()) + } + val, ok = res.Attributes().Get("haproxy.iid") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "haproxy.iid-val", val.Str()) + } + val, ok = res.Attributes().Get("haproxy.pid") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "haproxy.pid-val", val.Str()) + } + val, ok = res.Attributes().Get("haproxy.sid") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "haproxy.sid-val", val.Str()) + } + val, ok = res.Attributes().Get("haproxy.type") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "haproxy.type-val", val.Str()) + } + val, ok = res.Attributes().Get("haproxy.url") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "haproxy.url-val", val.Str()) + } + val, ok = res.Attributes().Get("proxy_name") + assert.Equal(t, test == "all_set", ok) + if ok { + assert.EqualValues(t, "proxy_name-val", val.Str()) + } + val, ok = res.Attributes().Get("service_name") + assert.Equal(t, test == "all_set", ok) + if ok { + assert.EqualValues(t, "service_name-val", val.Str()) + } + }) + } +} diff --git a/receiver/haproxyreceiver/scraper.go b/receiver/haproxyreceiver/scraper.go index 51405622564a..0706f923d95d 100644 --- a/receiver/haproxyreceiver/scraper.go +++ b/receiver/haproxyreceiver/scraper.go @@ -15,6 +15,7 @@ import ( "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/pdata/pmetric" + "go.opentelemetry.io/collector/receiver" "go.opentelemetry.io/collector/receiver/scrapererror" "go.uber.org/multierr" "go.uber.org/zap" @@ -27,9 +28,10 @@ var ( ) type scraper struct { - endpoint string - logger *zap.Logger - metricsBuilder *metadata.MetricsBuilder + endpoint string + logger *zap.Logger + rb *metadata.ResourceBuilder + mb *metadata.MetricsBuilder } func (s *scraper) scrape(ctx context.Context) (pmetric.Metrics, error) { @@ -50,92 +52,92 @@ func (s *scraper) scrape(ctx context.Context) (pmetric.Metrics, error) { now := pcommon.NewTimestampFromTime(time.Now()) for _, record := range records { - err = s.metricsBuilder.RecordHaproxySessionsCountDataPoint(now, record["scur"]) + err = s.mb.RecordHaproxySessionsCountDataPoint(now, record["scur"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } if record["conn_rate"] != "" { - err = s.metricsBuilder.RecordHaproxyConnectionsRateDataPoint(now, record["conn_rate"]) + err = s.mb.RecordHaproxyConnectionsRateDataPoint(now, record["conn_rate"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } } if record["conn_tot"] != "" { - err = s.metricsBuilder.RecordHaproxyConnectionsTotalDataPoint(now, record["conn_tot"]) + err = s.mb.RecordHaproxyConnectionsTotalDataPoint(now, record["conn_tot"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } } if record["lbtot"] != "" { - err = s.metricsBuilder.RecordHaproxyServerSelectedTotalDataPoint(now, record["lbtot"]) + err = s.mb.RecordHaproxyServerSelectedTotalDataPoint(now, record["lbtot"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } } - err = s.metricsBuilder.RecordHaproxyBytesInputDataPoint(now, record["bin"]) + err = s.mb.RecordHaproxyBytesInputDataPoint(now, record["bin"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } - err = s.metricsBuilder.RecordHaproxyBytesOutputDataPoint(now, record["bout"]) + err = s.mb.RecordHaproxyBytesOutputDataPoint(now, record["bout"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } if record["cli_abrt"] != "" { - err = s.metricsBuilder.RecordHaproxyClientsCanceledDataPoint(now, record["cli_abrt"]) + err = s.mb.RecordHaproxyClientsCanceledDataPoint(now, record["cli_abrt"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } } if record["comp_byp"] != "" { - err = s.metricsBuilder.RecordHaproxyCompressionBypassDataPoint(now, record["comp_byp"]) + err = s.mb.RecordHaproxyCompressionBypassDataPoint(now, record["comp_byp"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } } if record["comp_in"] != "" { - err = s.metricsBuilder.RecordHaproxyCompressionInputDataPoint(now, record["comp_in"]) + err = s.mb.RecordHaproxyCompressionInputDataPoint(now, record["comp_in"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } } if record["comp_out"] != "" { - err = s.metricsBuilder.RecordHaproxyCompressionOutputDataPoint(now, record["comp_out"]) + err = s.mb.RecordHaproxyCompressionOutputDataPoint(now, record["comp_out"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } } if record["comp_rsp"] != "" { - err = s.metricsBuilder.RecordHaproxyCompressionCountDataPoint(now, record["comp_rsp"]) + err = s.mb.RecordHaproxyCompressionCountDataPoint(now, record["comp_rsp"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } } if record["dreq"] != "" { - err = s.metricsBuilder.RecordHaproxyRequestsDeniedDataPoint(now, record["dreq"]) + err = s.mb.RecordHaproxyRequestsDeniedDataPoint(now, record["dreq"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } } if record["dresp"] != "" { - err = s.metricsBuilder.RecordHaproxyResponsesDeniedDataPoint(now, record["dresp"]) + err = s.mb.RecordHaproxyResponsesDeniedDataPoint(now, record["dresp"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } } if record["downtime"] != "" { - err = s.metricsBuilder.RecordHaproxyDowntimeDataPoint(now, record["downtime"]) + err = s.mb.RecordHaproxyDowntimeDataPoint(now, record["downtime"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } } if record["econ"] != "" { - err = s.metricsBuilder.RecordHaproxyConnectionsErrorsDataPoint(now, record["econ"]) + err = s.mb.RecordHaproxyConnectionsErrorsDataPoint(now, record["econ"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } } if record["ereq"] != "" { - err = s.metricsBuilder.RecordHaproxyRequestsErrorsDataPoint(now, record["ereq"]) + err = s.mb.RecordHaproxyRequestsErrorsDataPoint(now, record["ereq"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } @@ -151,83 +153,86 @@ func (s *scraper) scrape(ctx context.Context) (pmetric.Metrics, error) { if err2 != nil { scrapeErrors = append(scrapeErrors, fmt.Errorf("failed to parse int64 for HaproxyResponsesErrors, value was %s: %w", eresp, err2)) } - s.metricsBuilder.RecordHaproxyResponsesErrorsDataPoint(now, abortsVal+erespVal) + s.mb.RecordHaproxyResponsesErrorsDataPoint(now, abortsVal+erespVal) } if record["chkfail"] != "" { - err = s.metricsBuilder.RecordHaproxyFailedChecksDataPoint(now, record["chkfail"]) + err = s.mb.RecordHaproxyFailedChecksDataPoint(now, record["chkfail"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } } if record["wredis"] != "" { - err = s.metricsBuilder.RecordHaproxyRequestsRedispatchedDataPoint(now, record["wredis"]) + err = s.mb.RecordHaproxyRequestsRedispatchedDataPoint(now, record["wredis"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } } - err = s.metricsBuilder.RecordHaproxyRequestsTotalDataPoint(now, record["hrsp_1xx"], metadata.AttributeStatusCode1xx) + err = s.mb.RecordHaproxyRequestsTotalDataPoint(now, record["hrsp_1xx"], metadata.AttributeStatusCode1xx) if err != nil { scrapeErrors = append(scrapeErrors, err) } - err = s.metricsBuilder.RecordHaproxyRequestsTotalDataPoint(now, record["hrsp_2xx"], metadata.AttributeStatusCode2xx) + err = s.mb.RecordHaproxyRequestsTotalDataPoint(now, record["hrsp_2xx"], metadata.AttributeStatusCode2xx) if err != nil { scrapeErrors = append(scrapeErrors, err) } - err = s.metricsBuilder.RecordHaproxyRequestsTotalDataPoint(now, record["hrsp_3xx"], metadata.AttributeStatusCode3xx) + err = s.mb.RecordHaproxyRequestsTotalDataPoint(now, record["hrsp_3xx"], metadata.AttributeStatusCode3xx) if err != nil { scrapeErrors = append(scrapeErrors, err) } - err = s.metricsBuilder.RecordHaproxyRequestsTotalDataPoint(now, record["hrsp_4xx"], metadata.AttributeStatusCode4xx) + err = s.mb.RecordHaproxyRequestsTotalDataPoint(now, record["hrsp_4xx"], metadata.AttributeStatusCode4xx) if err != nil { scrapeErrors = append(scrapeErrors, err) } - err = s.metricsBuilder.RecordHaproxyRequestsTotalDataPoint(now, record["hrsp_5xx"], metadata.AttributeStatusCode5xx) + err = s.mb.RecordHaproxyRequestsTotalDataPoint(now, record["hrsp_5xx"], metadata.AttributeStatusCode5xx) if err != nil { scrapeErrors = append(scrapeErrors, err) } - err = s.metricsBuilder.RecordHaproxyRequestsTotalDataPoint(now, record["hrsp_other"], metadata.AttributeStatusCodeOther) + err = s.mb.RecordHaproxyRequestsTotalDataPoint(now, record["hrsp_other"], metadata.AttributeStatusCodeOther) if err != nil { scrapeErrors = append(scrapeErrors, err) } if record["wretr"] != "" { - err = s.metricsBuilder.RecordHaproxyConnectionsRetriesDataPoint(now, record["wretr"]) + err = s.mb.RecordHaproxyConnectionsRetriesDataPoint(now, record["wretr"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } } - err = s.metricsBuilder.RecordHaproxySessionsTotalDataPoint(now, record["stot"]) + err = s.mb.RecordHaproxySessionsTotalDataPoint(now, record["stot"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } if record["qcur"] != "" { - err = s.metricsBuilder.RecordHaproxyRequestsQueuedDataPoint(now, record["qcur"]) + err = s.mb.RecordHaproxyRequestsQueuedDataPoint(now, record["qcur"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } } if record["req_rate"] != "" { - err = s.metricsBuilder.RecordHaproxyRequestsRateDataPoint(now, record["req_rate"]) + err = s.mb.RecordHaproxyRequestsRateDataPoint(now, record["req_rate"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } } if record["ttime"] != "" { - err = s.metricsBuilder.RecordHaproxySessionsAverageDataPoint(now, record["ttime"]) + err = s.mb.RecordHaproxySessionsAverageDataPoint(now, record["ttime"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } } - err = s.metricsBuilder.RecordHaproxySessionsRateDataPoint(now, record["rate"]) + err = s.mb.RecordHaproxySessionsRateDataPoint(now, record["rate"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } - s.metricsBuilder.EmitForResource(metadata.WithProxyName(record["pxname"]), metadata.WithServiceName(record["svname"]), metadata.WithHaproxyAddr(s.endpoint)) + s.rb.SetProxyName(record["pxname"]) + s.rb.SetServiceName(record["svname"]) + s.rb.SetHaproxyAddr(s.endpoint) + s.mb.EmitForResource(metadata.WithResource(s.rb.Emit())) } if len(scrapeErrors) > 0 { - return s.metricsBuilder.Emit(), scrapererror.NewPartialScrapeError(multierr.Combine(scrapeErrors...), len(scrapeErrors)) + return s.mb.Emit(), scrapererror.NewPartialScrapeError(multierr.Combine(scrapeErrors...), len(scrapeErrors)) } - return s.metricsBuilder.Emit(), nil + return s.mb.Emit(), nil } func (s *scraper) readStats(c net.Conn) ([]map[string]string, error) { @@ -263,10 +268,11 @@ func (s *scraper) readStats(c net.Conn) ([]map[string]string, error) { return results, err } -func newScraper(metricsBuilder *metadata.MetricsBuilder, cfg *Config, logger *zap.Logger) *scraper { +func newScraper(cfg *Config, settings receiver.CreateSettings) *scraper { return &scraper{ - endpoint: cfg.Endpoint, - logger: logger, - metricsBuilder: metricsBuilder, + endpoint: cfg.Endpoint, + logger: settings.TelemetrySettings.Logger, + rb: metadata.NewResourceBuilder(cfg.ResourceAttributes), + mb: metadata.NewMetricsBuilder(cfg.MetricsBuilderConfig, settings), } } diff --git a/receiver/haproxyreceiver/scraper_test.go b/receiver/haproxyreceiver/scraper_test.go index efb12901fbd5..f536b78a1cd3 100644 --- a/receiver/haproxyreceiver/scraper_test.go +++ b/receiver/haproxyreceiver/scraper_test.go @@ -14,9 +14,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/receiver/receivertest" - "go.uber.org/zap" - - "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/haproxyreceiver/internal/metadata" ) func Test_scraper_readStats(t *testing.T) { @@ -49,10 +46,7 @@ func Test_scraper_readStats(t *testing.T) { haProxyCfg := newDefaultConfig().(*Config) haProxyCfg.Endpoint = socketAddr - settings := receivertest.NewNopCreateSettings() - metricsBuilder := metadata.NewMetricsBuilder(haProxyCfg.MetricsBuilderConfig, settings) - - s := newScraper(metricsBuilder, haProxyCfg, zap.NewNop()) + s := newScraper(haProxyCfg, receivertest.NewNopCreateSettings()) m, err := s.scrape(context.Background()) require.NoError(t, err) require.NotNil(t, m) diff --git a/receiver/hostmetricsreceiver/internal/scraper/cpuscraper/internal/metadata/generated_metrics.go b/receiver/hostmetricsreceiver/internal/scraper/cpuscraper/internal/metadata/generated_metrics.go index 647712480491..3500bceaa228 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/cpuscraper/internal/metadata/generated_metrics.go +++ b/receiver/hostmetricsreceiver/internal/scraper/cpuscraper/internal/metadata/generated_metrics.go @@ -173,7 +173,6 @@ func newMetricSystemCPUUtilization(cfg MetricConfig) metricSystemCPUUtilization type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information metricSystemCPUTime metricSystemCPUTime @@ -209,14 +208,19 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. type ResourceMetricsOption func(pmetric.ResourceMetrics) +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) + } +} + // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { @@ -245,7 +249,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() rm.SetSchemaUrl(conventions.SchemaURL) - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/hostmetricsreceiver/cpu") ils.Scope().SetVersion(mb.buildInfo.Version) diff --git a/receiver/hostmetricsreceiver/internal/scraper/cpuscraper/internal/metadata/generated_metrics_test.go b/receiver/hostmetricsreceiver/internal/scraper/cpuscraper/internal/metadata/generated_metrics_test.go index b4705498a962..92ef5db23b55 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/cpuscraper/internal/metadata/generated_metrics_test.go +++ b/receiver/hostmetricsreceiver/internal/scraper/cpuscraper/internal/metadata/generated_metrics_test.go @@ -61,7 +61,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordSystemCPUUtilizationDataPoint(ts, 1, "cpu-val", AttributeStateIdle) - metrics := mb.Emit() + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -70,11 +72,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 0) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/hostmetricsreceiver/internal/scraper/diskscraper/internal/metadata/generated_metrics.go b/receiver/hostmetricsreceiver/internal/scraper/diskscraper/internal/metadata/generated_metrics.go index 5d51d756775c..fb56820510d3 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/diskscraper/internal/metadata/generated_metrics.go +++ b/receiver/hostmetricsreceiver/internal/scraper/diskscraper/internal/metadata/generated_metrics.go @@ -418,7 +418,6 @@ func newMetricSystemDiskWeightedIoTime(cfg MetricConfig) metricSystemDiskWeighte type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information metricSystemDiskIo metricSystemDiskIo @@ -464,14 +463,19 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. type ResourceMetricsOption func(pmetric.ResourceMetrics) +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) + } +} + // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { @@ -500,7 +504,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() rm.SetSchemaUrl(conventions.SchemaURL) - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/hostmetricsreceiver/disk") ils.Scope().SetVersion(mb.buildInfo.Version) diff --git a/receiver/hostmetricsreceiver/internal/scraper/diskscraper/internal/metadata/generated_metrics_test.go b/receiver/hostmetricsreceiver/internal/scraper/diskscraper/internal/metadata/generated_metrics_test.go index 95692df272ed..3be0f0d3a6c2 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/diskscraper/internal/metadata/generated_metrics_test.go +++ b/receiver/hostmetricsreceiver/internal/scraper/diskscraper/internal/metadata/generated_metrics_test.go @@ -82,7 +82,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordSystemDiskWeightedIoTimeDataPoint(ts, 1, "device-val") - metrics := mb.Emit() + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -91,11 +93,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 0) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper/internal/metadata/generated_metrics.go b/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper/internal/metadata/generated_metrics.go index 69c23254d38a..4c7c4ba3c42e 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper/internal/metadata/generated_metrics.go +++ b/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper/internal/metadata/generated_metrics.go @@ -215,7 +215,6 @@ func newMetricSystemFilesystemUtilization(cfg MetricConfig) metricSystemFilesyst type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information metricSystemFilesystemInodesUsage metricSystemFilesystemInodesUsage @@ -253,14 +252,19 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. type ResourceMetricsOption func(pmetric.ResourceMetrics) +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) + } +} + // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { @@ -289,7 +293,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() rm.SetSchemaUrl(conventions.SchemaURL) - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/hostmetricsreceiver/filesystem") ils.Scope().SetVersion(mb.buildInfo.Version) diff --git a/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper/internal/metadata/generated_metrics_test.go b/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper/internal/metadata/generated_metrics_test.go index b8afc9975f91..9aaba62e81d3 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper/internal/metadata/generated_metrics_test.go +++ b/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper/internal/metadata/generated_metrics_test.go @@ -65,7 +65,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordSystemFilesystemUtilizationDataPoint(ts, 1, "device-val", "mode-val", "mountpoint-val", "type-val") - metrics := mb.Emit() + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -74,11 +76,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 0) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/hostmetricsreceiver/internal/scraper/loadscraper/internal/metadata/generated_metrics.go b/receiver/hostmetricsreceiver/internal/scraper/loadscraper/internal/metadata/generated_metrics.go index bbab6bffa280..1c3053aecb96 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/loadscraper/internal/metadata/generated_metrics.go +++ b/receiver/hostmetricsreceiver/internal/scraper/loadscraper/internal/metadata/generated_metrics.go @@ -164,7 +164,6 @@ func newMetricSystemCPULoadAverage5m(cfg MetricConfig) metricSystemCPULoadAverag type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information metricSystemCPULoadAverage15m metricSystemCPULoadAverage15m @@ -202,14 +201,19 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. type ResourceMetricsOption func(pmetric.ResourceMetrics) +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) + } +} + // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { @@ -238,7 +242,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() rm.SetSchemaUrl(conventions.SchemaURL) - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/hostmetricsreceiver/load") ils.Scope().SetVersion(mb.buildInfo.Version) diff --git a/receiver/hostmetricsreceiver/internal/scraper/loadscraper/internal/metadata/generated_metrics_test.go b/receiver/hostmetricsreceiver/internal/scraper/loadscraper/internal/metadata/generated_metrics_test.go index c4a0a5897c17..5e991dc90db1 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/loadscraper/internal/metadata/generated_metrics_test.go +++ b/receiver/hostmetricsreceiver/internal/scraper/loadscraper/internal/metadata/generated_metrics_test.go @@ -66,7 +66,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordSystemCPULoadAverage5mDataPoint(ts, 1) - metrics := mb.Emit() + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -75,11 +77,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 0) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/hostmetricsreceiver/internal/scraper/memoryscraper/internal/metadata/generated_metrics.go b/receiver/hostmetricsreceiver/internal/scraper/memoryscraper/internal/metadata/generated_metrics.go index fa58b8896647..2d23f82b836a 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/memoryscraper/internal/metadata/generated_metrics.go +++ b/receiver/hostmetricsreceiver/internal/scraper/memoryscraper/internal/metadata/generated_metrics.go @@ -167,7 +167,6 @@ func newMetricSystemMemoryUtilization(cfg MetricConfig) metricSystemMemoryUtiliz type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information metricSystemMemoryUsage metricSystemMemoryUsage @@ -203,14 +202,19 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. type ResourceMetricsOption func(pmetric.ResourceMetrics) +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) + } +} + // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { @@ -239,7 +243,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() rm.SetSchemaUrl(conventions.SchemaURL) - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/hostmetricsreceiver/memory") ils.Scope().SetVersion(mb.buildInfo.Version) diff --git a/receiver/hostmetricsreceiver/internal/scraper/memoryscraper/internal/metadata/generated_metrics_test.go b/receiver/hostmetricsreceiver/internal/scraper/memoryscraper/internal/metadata/generated_metrics_test.go index 16fb3da47aca..58a7f4b12403 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/memoryscraper/internal/metadata/generated_metrics_test.go +++ b/receiver/hostmetricsreceiver/internal/scraper/memoryscraper/internal/metadata/generated_metrics_test.go @@ -61,7 +61,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordSystemMemoryUtilizationDataPoint(ts, 1, AttributeStateBuffered) - metrics := mb.Emit() + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -70,11 +72,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 0) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/hostmetricsreceiver/internal/scraper/networkscraper/internal/metadata/generated_metrics.go b/receiver/hostmetricsreceiver/internal/scraper/networkscraper/internal/metadata/generated_metrics.go index 19eb0ffd539c..866ce15273be 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/networkscraper/internal/metadata/generated_metrics.go +++ b/receiver/hostmetricsreceiver/internal/scraper/networkscraper/internal/metadata/generated_metrics.go @@ -437,7 +437,6 @@ func newMetricSystemNetworkPackets(cfg MetricConfig) metricSystemNetworkPackets type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information metricSystemNetworkConnections metricSystemNetworkConnections @@ -483,14 +482,19 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. type ResourceMetricsOption func(pmetric.ResourceMetrics) +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) + } +} + // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { @@ -519,7 +523,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() rm.SetSchemaUrl(conventions.SchemaURL) - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/hostmetricsreceiver/network") ils.Scope().SetVersion(mb.buildInfo.Version) diff --git a/receiver/hostmetricsreceiver/internal/scraper/networkscraper/internal/metadata/generated_metrics_test.go b/receiver/hostmetricsreceiver/internal/scraper/networkscraper/internal/metadata/generated_metrics_test.go index 1e80b55fb2fb..d5a5bd48c6af 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/networkscraper/internal/metadata/generated_metrics_test.go +++ b/receiver/hostmetricsreceiver/internal/scraper/networkscraper/internal/metadata/generated_metrics_test.go @@ -80,7 +80,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordSystemNetworkPacketsDataPoint(ts, 1, "device-val", AttributeDirectionReceive) - metrics := mb.Emit() + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -89,11 +91,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 0) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/hostmetricsreceiver/internal/scraper/pagingscraper/internal/metadata/generated_metrics.go b/receiver/hostmetricsreceiver/internal/scraper/pagingscraper/internal/metadata/generated_metrics.go index 65b5fa0609ff..4ddb39ff9164 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/pagingscraper/internal/metadata/generated_metrics.go +++ b/receiver/hostmetricsreceiver/internal/scraper/pagingscraper/internal/metadata/generated_metrics.go @@ -312,7 +312,6 @@ func newMetricSystemPagingUtilization(cfg MetricConfig) metricSystemPagingUtiliz type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information metricSystemPagingFaults metricSystemPagingFaults @@ -352,14 +351,19 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. type ResourceMetricsOption func(pmetric.ResourceMetrics) +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) + } +} + // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { @@ -388,7 +392,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() rm.SetSchemaUrl(conventions.SchemaURL) - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/hostmetricsreceiver/paging") ils.Scope().SetVersion(mb.buildInfo.Version) diff --git a/receiver/hostmetricsreceiver/internal/scraper/pagingscraper/internal/metadata/generated_metrics_test.go b/receiver/hostmetricsreceiver/internal/scraper/pagingscraper/internal/metadata/generated_metrics_test.go index b6c09b55e6ef..228afd59e2fe 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/pagingscraper/internal/metadata/generated_metrics_test.go +++ b/receiver/hostmetricsreceiver/internal/scraper/pagingscraper/internal/metadata/generated_metrics_test.go @@ -69,7 +69,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordSystemPagingUtilizationDataPoint(ts, 1, "device-val", AttributeStateCached) - metrics := mb.Emit() + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -78,11 +80,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 0) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/hostmetricsreceiver/internal/scraper/processesscraper/internal/metadata/generated_metrics.go b/receiver/hostmetricsreceiver/internal/scraper/processesscraper/internal/metadata/generated_metrics.go index e5725e42ae8d..8afc01d8c3eb 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/processesscraper/internal/metadata/generated_metrics.go +++ b/receiver/hostmetricsreceiver/internal/scraper/processesscraper/internal/metadata/generated_metrics.go @@ -191,7 +191,6 @@ func newMetricSystemProcessesCreated(cfg MetricConfig) metricSystemProcessesCrea type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information metricSystemProcessesCount metricSystemProcessesCount @@ -227,14 +226,19 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. type ResourceMetricsOption func(pmetric.ResourceMetrics) +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) + } +} + // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { @@ -263,7 +267,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() rm.SetSchemaUrl(conventions.SchemaURL) - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/hostmetricsreceiver/processes") ils.Scope().SetVersion(mb.buildInfo.Version) diff --git a/receiver/hostmetricsreceiver/internal/scraper/processesscraper/internal/metadata/generated_metrics_test.go b/receiver/hostmetricsreceiver/internal/scraper/processesscraper/internal/metadata/generated_metrics_test.go index f8741feff9cd..03e707156e2b 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/processesscraper/internal/metadata/generated_metrics_test.go +++ b/receiver/hostmetricsreceiver/internal/scraper/processesscraper/internal/metadata/generated_metrics_test.go @@ -62,7 +62,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordSystemProcessesCreatedDataPoint(ts, 1) - metrics := mb.Emit() + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -71,11 +73,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 0) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/hostmetricsreceiver/internal/scraper/processscraper/internal/metadata/generated_config_test.go b/receiver/hostmetricsreceiver/internal/scraper/processscraper/internal/metadata/generated_config_test.go index de5de1413c13..007ffa2ec44a 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/processscraper/internal/metadata/generated_config_test.go +++ b/receiver/hostmetricsreceiver/internal/scraper/processscraper/internal/metadata/generated_config_test.go @@ -100,3 +100,59 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + ProcessCommand: ResourceAttributeConfig{Enabled: true}, + ProcessCommandLine: ResourceAttributeConfig{Enabled: true}, + ProcessExecutableName: ResourceAttributeConfig{Enabled: true}, + ProcessExecutablePath: ResourceAttributeConfig{Enabled: true}, + ProcessOwner: ResourceAttributeConfig{Enabled: true}, + ProcessParentPid: ResourceAttributeConfig{Enabled: true}, + ProcessPid: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + ProcessCommand: ResourceAttributeConfig{Enabled: false}, + ProcessCommandLine: ResourceAttributeConfig{Enabled: false}, + ProcessExecutableName: ResourceAttributeConfig{Enabled: false}, + ProcessExecutablePath: ResourceAttributeConfig{Enabled: false}, + ProcessOwner: ResourceAttributeConfig{Enabled: false}, + ProcessParentPid: ResourceAttributeConfig{Enabled: false}, + ProcessPid: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/hostmetricsreceiver/internal/scraper/processscraper/internal/metadata/generated_metrics.go b/receiver/hostmetricsreceiver/internal/scraper/processscraper/internal/metadata/generated_metrics.go index da2a80ad1630..bd7bb532fca5 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/processscraper/internal/metadata/generated_metrics.go +++ b/receiver/hostmetricsreceiver/internal/scraper/processscraper/internal/metadata/generated_metrics.go @@ -796,10 +796,8 @@ func newMetricProcessThreads(cfg MetricConfig) metricProcessThreads { type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricProcessContextSwitches metricProcessContextSwitches metricProcessCPUTime metricProcessCPUTime metricProcessCPUUtilization metricProcessCPUUtilization @@ -830,7 +828,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricProcessContextSwitches: newMetricProcessContextSwitches(mbc.Metrics.ProcessContextSwitches), metricProcessCPUTime: newMetricProcessCPUTime(mbc.Metrics.ProcessCPUTime), metricProcessCPUUtilization: newMetricProcessCPUUtilization(mbc.Metrics.ProcessCPUUtilization), @@ -856,81 +853,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithProcessCommand sets provided value as "process.command" attribute for current resource. -func WithProcessCommand(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.ProcessCommand.Enabled { - rm.Resource().Attributes().PutStr("process.command", val) - } - } -} - -// WithProcessCommandLine sets provided value as "process.command_line" attribute for current resource. -func WithProcessCommandLine(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.ProcessCommandLine.Enabled { - rm.Resource().Attributes().PutStr("process.command_line", val) - } - } -} - -// WithProcessExecutableName sets provided value as "process.executable.name" attribute for current resource. -func WithProcessExecutableName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.ProcessExecutableName.Enabled { - rm.Resource().Attributes().PutStr("process.executable.name", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithProcessExecutablePath sets provided value as "process.executable.path" attribute for current resource. -func WithProcessExecutablePath(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.ProcessExecutablePath.Enabled { - rm.Resource().Attributes().PutStr("process.executable.path", val) - } - } -} - -// WithProcessOwner sets provided value as "process.owner" attribute for current resource. -func WithProcessOwner(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.ProcessOwner.Enabled { - rm.Resource().Attributes().PutStr("process.owner", val) - } - } -} - -// WithProcessParentPid sets provided value as "process.parent_pid" attribute for current resource. -func WithProcessParentPid(val int64) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.ProcessParentPid.Enabled { - rm.Resource().Attributes().PutInt("process.parent_pid", val) - } - } -} - -// WithProcessPid sets provided value as "process.pid" attribute for current resource. -func WithProcessPid(val int64) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.ProcessPid.Enabled { - rm.Resource().Attributes().PutInt("process.pid", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -955,7 +894,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() rm.SetSchemaUrl(conventions.SchemaURL) - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/hostmetricsreceiver/process") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -975,7 +913,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricProcessThreads.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/hostmetricsreceiver/internal/scraper/processscraper/internal/metadata/generated_metrics_test.go b/receiver/hostmetricsreceiver/internal/scraper/processscraper/internal/metadata/generated_metrics_test.go index e69090850f6f..7a2a610d4ceb 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/processscraper/internal/metadata/generated_metrics_test.go +++ b/receiver/hostmetricsreceiver/internal/scraper/processscraper/internal/metadata/generated_metrics_test.go @@ -97,7 +97,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordProcessThreadsDataPoint(ts, 1) - metrics := mb.Emit(WithProcessCommand("process.command-val"), WithProcessCommandLine("process.command_line-val"), WithProcessExecutableName("process.executable.name-val"), WithProcessExecutablePath("process.executable.path-val"), WithProcessOwner("process.owner-val"), WithProcessParentPid(18), WithProcessPid(11)) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -106,60 +108,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("process.command") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.ProcessCommand.Enabled, ok) - if mb.resourceAttributesConfig.ProcessCommand.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "process.command-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("process.command_line") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.ProcessCommandLine.Enabled, ok) - if mb.resourceAttributesConfig.ProcessCommandLine.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "process.command_line-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("process.executable.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.ProcessExecutableName.Enabled, ok) - if mb.resourceAttributesConfig.ProcessExecutableName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "process.executable.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("process.executable.path") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.ProcessExecutablePath.Enabled, ok) - if mb.resourceAttributesConfig.ProcessExecutablePath.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "process.executable.path-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("process.owner") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.ProcessOwner.Enabled, ok) - if mb.resourceAttributesConfig.ProcessOwner.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "process.owner-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("process.parent_pid") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.ProcessParentPid.Enabled, ok) - if mb.resourceAttributesConfig.ProcessParentPid.Enabled { - enabledAttrCount++ - assert.EqualValues(t, 18, attrVal.Int()) - } - attrVal, ok = rm.Resource().Attributes().Get("process.pid") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.ProcessPid.Enabled, ok) - if mb.resourceAttributesConfig.ProcessPid.Enabled { - enabledAttrCount++ - assert.EqualValues(t, 11, attrVal.Int()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 7) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/hostmetricsreceiver/internal/scraper/processscraper/internal/metadata/generated_resource.go b/receiver/hostmetricsreceiver/internal/scraper/processscraper/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..65440eb8560d --- /dev/null +++ b/receiver/hostmetricsreceiver/internal/scraper/processscraper/internal/metadata/generated_resource.go @@ -0,0 +1,78 @@ +// 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(), + } +} + +// SetProcessCommand sets provided value as "process.command" attribute. +func (rb *ResourceBuilder) SetProcessCommand(val string) { + if rb.config.ProcessCommand.Enabled { + rb.res.Attributes().PutStr("process.command", val) + } +} + +// SetProcessCommandLine sets provided value as "process.command_line" attribute. +func (rb *ResourceBuilder) SetProcessCommandLine(val string) { + if rb.config.ProcessCommandLine.Enabled { + rb.res.Attributes().PutStr("process.command_line", val) + } +} + +// SetProcessExecutableName sets provided value as "process.executable.name" attribute. +func (rb *ResourceBuilder) SetProcessExecutableName(val string) { + if rb.config.ProcessExecutableName.Enabled { + rb.res.Attributes().PutStr("process.executable.name", val) + } +} + +// SetProcessExecutablePath sets provided value as "process.executable.path" attribute. +func (rb *ResourceBuilder) SetProcessExecutablePath(val string) { + if rb.config.ProcessExecutablePath.Enabled { + rb.res.Attributes().PutStr("process.executable.path", val) + } +} + +// SetProcessOwner sets provided value as "process.owner" attribute. +func (rb *ResourceBuilder) SetProcessOwner(val string) { + if rb.config.ProcessOwner.Enabled { + rb.res.Attributes().PutStr("process.owner", val) + } +} + +// SetProcessParentPid sets provided value as "process.parent_pid" attribute. +func (rb *ResourceBuilder) SetProcessParentPid(val int64) { + if rb.config.ProcessParentPid.Enabled { + rb.res.Attributes().PutInt("process.parent_pid", val) + } +} + +// SetProcessPid sets provided value as "process.pid" attribute. +func (rb *ResourceBuilder) SetProcessPid(val int64) { + if rb.config.ProcessPid.Enabled { + rb.res.Attributes().PutInt("process.pid", 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/receiver/hostmetricsreceiver/internal/scraper/processscraper/internal/metadata/generated_resource_test.go b/receiver/hostmetricsreceiver/internal/scraper/processscraper/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..3e81c16f5deb --- /dev/null +++ b/receiver/hostmetricsreceiver/internal/scraper/processscraper/internal/metadata/generated_resource_test.go @@ -0,0 +1,76 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetProcessCommand("process.command-val") + rb.SetProcessCommandLine("process.command_line-val") + rb.SetProcessExecutableName("process.executable.name-val") + rb.SetProcessExecutablePath("process.executable.path-val") + rb.SetProcessOwner("process.owner-val") + rb.SetProcessParentPid(18) + rb.SetProcessPid(11) + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 7, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 7, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("process.command") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "process.command-val", val.Str()) + } + val, ok = res.Attributes().Get("process.command_line") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "process.command_line-val", val.Str()) + } + val, ok = res.Attributes().Get("process.executable.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "process.executable.name-val", val.Str()) + } + val, ok = res.Attributes().Get("process.executable.path") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "process.executable.path-val", val.Str()) + } + val, ok = res.Attributes().Get("process.owner") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "process.owner-val", val.Str()) + } + val, ok = res.Attributes().Get("process.parent_pid") + assert.True(t, ok) + if ok { + assert.EqualValues(t, 18, val.Int()) + } + val, ok = res.Attributes().Get("process.pid") + assert.True(t, ok) + if ok { + assert.EqualValues(t, 11, val.Int()) + } + }) + } +} diff --git a/receiver/hostmetricsreceiver/internal/scraper/processscraper/process.go b/receiver/hostmetricsreceiver/internal/scraper/processscraper/process.go index 4c83b324a0f5..8746fabb1ffc 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/processscraper/process.go +++ b/receiver/hostmetricsreceiver/internal/scraper/processscraper/process.go @@ -10,6 +10,7 @@ import ( "github.com/shirou/gopsutil/v3/cpu" "github.com/shirou/gopsutil/v3/process" + "go.opentelemetry.io/collector/pdata/pcommon" "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/scraper/processscraper/internal/metadata" ) @@ -39,28 +40,25 @@ type commandMetadata struct { commandLineSlice []string } -func (m *processMetadata) resourceOptions() []metadata.ResourceMetricsOption { - opts := make([]metadata.ResourceMetricsOption, 0, 6) - opts = append(opts, - metadata.WithProcessPid(int64(m.pid)), - metadata.WithProcessParentPid(int64(m.parentPid)), - metadata.WithProcessExecutableName(m.executable.name), - metadata.WithProcessExecutablePath(m.executable.path), - ) +func (m *processMetadata) buildResource(rb *metadata.ResourceBuilder) pcommon.Resource { + rb.SetProcessPid(int64(m.pid)) + rb.SetProcessParentPid(int64(m.parentPid)) + rb.SetProcessExecutableName(m.executable.name) + rb.SetProcessExecutablePath(m.executable.path) if m.command != nil { - opts = append(opts, metadata.WithProcessCommand(m.command.command)) + rb.SetProcessCommand(m.command.command) if m.command.commandLineSlice != nil { // TODO insert slice here once this is supported by the data model // (see https://github.com/open-telemetry/opentelemetry-collector/pull/1142) - opts = append(opts, metadata.WithProcessCommandLine(strings.Join(m.command.commandLineSlice, " "))) + rb.SetProcessCommandLine(strings.Join(m.command.commandLineSlice, " ")) } else { - opts = append(opts, metadata.WithProcessCommandLine(m.command.commandLine)) + rb.SetProcessCommandLine(m.command.commandLine) } } if m.username != "" { - opts = append(opts, metadata.WithProcessOwner(m.username)) + rb.SetProcessOwner(m.username) } - return opts + return rb.Emit() } // processHandles provides a wrapper around []*process.Process diff --git a/receiver/hostmetricsreceiver/internal/scraper/processscraper/process_scraper.go b/receiver/hostmetricsreceiver/internal/scraper/processscraper/process_scraper.go index b31f02b22104..c62f51f1b36e 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/processscraper/process_scraper.go +++ b/receiver/hostmetricsreceiver/internal/scraper/processscraper/process_scraper.go @@ -42,6 +42,7 @@ const ( type scraper struct { settings receiver.CreateSettings config *Config + rb *metadata.ResourceBuilder mb *metadata.MetricsBuilder includeFS filterset.FilterSet excludeFS filterset.FilterSet @@ -86,6 +87,7 @@ func newProcessScraper(settings receiver.CreateSettings, cfg *Config) (*scraper, } func (s *scraper) start(context.Context, component.Host) error { + s.rb = metadata.NewResourceBuilder(s.config.ResourceAttributes) s.mb = metadata.NewMetricsBuilder(s.config.MetricsBuilderConfig, s.settings) return nil } @@ -150,8 +152,8 @@ func (s *scraper) scrape(_ context.Context) (pmetric.Metrics, error) { errs.AddPartial(signalMetricsLen, fmt.Errorf("error reading pending signals for process %q (pid %v): %w", md.executable.name, md.pid, err)) } - options := append(md.resourceOptions(), metadata.WithStartTimeOverride(pcommon.Timestamp(md.createTime*1e6))) - s.mb.EmitForResource(options...) + s.mb.EmitForResource(metadata.WithResource(md.buildResource(s.rb)), + metadata.WithStartTimeOverride(pcommon.Timestamp(md.createTime*1e6))) } // Cleanup any [ucal.CPUUtilizationCalculator]s for PIDs that are no longer present diff --git a/receiver/httpcheckreceiver/internal/metadata/generated_metrics.go b/receiver/httpcheckreceiver/internal/metadata/generated_metrics.go index 56b7e7e0c9e8..cdf0e2700ba1 100644 --- a/receiver/httpcheckreceiver/internal/metadata/generated_metrics.go +++ b/receiver/httpcheckreceiver/internal/metadata/generated_metrics.go @@ -177,7 +177,6 @@ func newMetricHttpcheckStatus(cfg MetricConfig) metricHttpcheckStatus { type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information metricHttpcheckDuration metricHttpcheckDuration @@ -215,14 +214,19 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. type ResourceMetricsOption func(pmetric.ResourceMetrics) +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) + } +} + // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { @@ -250,7 +254,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/httpcheckreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) diff --git a/receiver/httpcheckreceiver/internal/metadata/generated_metrics_test.go b/receiver/httpcheckreceiver/internal/metadata/generated_metrics_test.go index d0cf28defa98..6fd2efb64948 100644 --- a/receiver/httpcheckreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/httpcheckreceiver/internal/metadata/generated_metrics_test.go @@ -66,7 +66,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordHttpcheckStatusDataPoint(ts, 1, "http.url-val", 16, "http.method-val", "http.status_class-val") - metrics := mb.Emit() + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -75,11 +77,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 0) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/iisreceiver/internal/metadata/generated_config_test.go b/receiver/iisreceiver/internal/metadata/generated_config_test.go index 5322841f1eba..55859087249b 100644 --- a/receiver/iisreceiver/internal/metadata/generated_config_test.go +++ b/receiver/iisreceiver/internal/metadata/generated_config_test.go @@ -88,3 +88,49 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + IisApplicationPool: ResourceAttributeConfig{Enabled: true}, + IisSite: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + IisApplicationPool: ResourceAttributeConfig{Enabled: false}, + IisSite: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/iisreceiver/internal/metadata/generated_metrics.go b/receiver/iisreceiver/internal/metadata/generated_metrics.go index 0ee14f4ccb16..a7c7f04c1c35 100644 --- a/receiver/iisreceiver/internal/metadata/generated_metrics.go +++ b/receiver/iisreceiver/internal/metadata/generated_metrics.go @@ -702,10 +702,8 @@ func newMetricIisUptime(cfg MetricConfig) metricIisUptime { type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricIisConnectionActive metricIisConnectionActive metricIisConnectionAnonymous metricIisConnectionAnonymous metricIisConnectionAttemptCount metricIisConnectionAttemptCount @@ -735,7 +733,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricIisConnectionActive: newMetricIisConnectionActive(mbc.Metrics.IisConnectionActive), metricIisConnectionAnonymous: newMetricIisConnectionAnonymous(mbc.Metrics.IisConnectionAnonymous), metricIisConnectionAttemptCount: newMetricIisConnectionAttemptCount(mbc.Metrics.IisConnectionAttemptCount), @@ -760,36 +757,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithIisApplicationPool sets provided value as "iis.application_pool" attribute for current resource. -func WithIisApplicationPool(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.IisApplicationPool.Enabled { - rm.Resource().Attributes().PutStr("iis.application_pool", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithIisSite sets provided value as "iis.site" attribute for current resource. -func WithIisSite(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.IisSite.Enabled { - rm.Resource().Attributes().PutStr("iis.site", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -813,7 +797,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/iisreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -832,7 +815,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricIisUptime.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/iisreceiver/internal/metadata/generated_metrics_test.go b/receiver/iisreceiver/internal/metadata/generated_metrics_test.go index 3489ffcf6744..4c4f883d7e1b 100644 --- a/receiver/iisreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/iisreceiver/internal/metadata/generated_metrics_test.go @@ -102,7 +102,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordIisUptimeDataPoint(ts, 1) - metrics := mb.Emit(WithIisApplicationPool("iis.application_pool-val"), WithIisSite("iis.site-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -111,25 +113,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("iis.application_pool") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.IisApplicationPool.Enabled, ok) - if mb.resourceAttributesConfig.IisApplicationPool.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "iis.application_pool-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("iis.site") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.IisSite.Enabled, ok) - if mb.resourceAttributesConfig.IisSite.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "iis.site-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 2) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/iisreceiver/internal/metadata/generated_resource.go b/receiver/iisreceiver/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..dc89b503f0e4 --- /dev/null +++ b/receiver/iisreceiver/internal/metadata/generated_resource.go @@ -0,0 +1,43 @@ +// 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(), + } +} + +// SetIisApplicationPool sets provided value as "iis.application_pool" attribute. +func (rb *ResourceBuilder) SetIisApplicationPool(val string) { + if rb.config.IisApplicationPool.Enabled { + rb.res.Attributes().PutStr("iis.application_pool", val) + } +} + +// SetIisSite sets provided value as "iis.site" attribute. +func (rb *ResourceBuilder) SetIisSite(val string) { + if rb.config.IisSite.Enabled { + rb.res.Attributes().PutStr("iis.site", 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/receiver/iisreceiver/internal/metadata/generated_resource_test.go b/receiver/iisreceiver/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..1bb32a42dcc7 --- /dev/null +++ b/receiver/iisreceiver/internal/metadata/generated_resource_test.go @@ -0,0 +1,46 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetIisApplicationPool("iis.application_pool-val") + rb.SetIisSite("iis.site-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 2, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 2, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("iis.application_pool") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "iis.application_pool-val", val.Str()) + } + val, ok = res.Attributes().Get("iis.site") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "iis.site-val", val.Str()) + } + }) + } +} diff --git a/receiver/iisreceiver/scraper.go b/receiver/iisreceiver/scraper.go index b901f816a7d3..2bc8fcdbbdfc 100644 --- a/receiver/iisreceiver/scraper.go +++ b/receiver/iisreceiver/scraper.go @@ -34,7 +34,8 @@ type iisReceiver struct { siteWatcherRecorders []watcherRecorder appPoolWatcherRecorders []watcherRecorder queueMaxAgeWatchers []instanceWatcher - metricBuilder *metadata.MetricsBuilder + rb *metadata.ResourceBuilder + mb *metadata.MetricsBuilder // for mocking newWatcher func(string, string, string) (winperfcounters.PerfCounterWatcher, error) @@ -60,7 +61,8 @@ func newIisReceiver(settings receiver.CreateSettings, cfg *Config, consumer cons params: settings.TelemetrySettings, config: cfg, consumer: consumer, - metricBuilder: metadata.NewMetricsBuilder(cfg.MetricsBuilderConfig, settings), + rb: metadata.NewResourceBuilder(cfg.ResourceAttributes), + mb: metadata.NewMetricsBuilder(cfg.MetricsBuilderConfig, settings), newWatcher: winperfcounters.NewWatcher, newWatcherFromPath: winperfcounters.NewWatcherFromPath, expandWildcardPath: winperfcounters.ExpandWildCardPath, @@ -90,16 +92,16 @@ func (rcvr *iisReceiver) scrape(ctx context.Context) (pmetric.Metrics, error) { siteToRecorders := map[string][]valRecorder{} rcvr.scrapeInstanceMetrics(rcvr.siteWatcherRecorders, siteToRecorders) - rcvr.emitInstanceMap(now, siteToRecorders, metadata.WithIisSite) + rcvr.emitInstanceMap(now, siteToRecorders, rcvr.rb.SetIisSite) appToRecorders := map[string][]valRecorder{} rcvr.scrapeInstanceMetrics(rcvr.appPoolWatcherRecorders, appToRecorders) rcvr.scrapeMaxQueueAgeMetrics(appToRecorders) - rcvr.emitInstanceMap(now, appToRecorders, metadata.WithIisApplicationPool) + rcvr.emitInstanceMap(now, appToRecorders, rcvr.rb.SetIisApplicationPool) rcvr.scrapeTotalMetrics(now) - return rcvr.metricBuilder.Emit(), errs + return rcvr.mb.Emit(), errs } func (rcvr *iisReceiver) scrapeTotalMetrics(now pcommon.Timestamp) { @@ -113,12 +115,12 @@ func (rcvr *iisReceiver) scrapeTotalMetrics(now pcommon.Timestamp) { for _, counterValue := range counterValues { value += counterValue.Value } - wr.recorder(rcvr.metricBuilder, now, value) + wr.recorder(rcvr.mb, now, value) } // resource for total metrics is empty // this makes it so that the order that the scrape functions are called doesn't matter - rcvr.metricBuilder.EmitForResource() + rcvr.mb.EmitForResource() } type valRecorder struct { @@ -184,13 +186,13 @@ func (rcvr *iisReceiver) scrapeMaxQueueAgeMetrics(appToRecorders map[string][]va } // emitInstanceMap records all metrics for each instance, then emits them all as a single resource metric -func (rcvr *iisReceiver) emitInstanceMap(now pcommon.Timestamp, instanceToRecorders map[string][]valRecorder, resourceOption func(string) metadata.ResourceMetricsOption) { +func (rcvr *iisReceiver) emitInstanceMap(now pcommon.Timestamp, instanceToRecorders map[string][]valRecorder, resourceSetter func(string)) { for instanceName, recorders := range instanceToRecorders { for _, recorder := range recorders { - recorder.record(rcvr.metricBuilder, now, recorder.val) + recorder.record(rcvr.mb, now, recorder.val) } - - rcvr.metricBuilder.EmitForResource(resourceOption(instanceName)) + resourceSetter(instanceName) + rcvr.mb.EmitForResource(metadata.WithResource(rcvr.rb.Emit())) } } diff --git a/receiver/k8sclusterreceiver/internal/clusterresourcequota/clusterresourcequotas.go b/receiver/k8sclusterreceiver/internal/clusterresourcequota/clusterresourcequotas.go index 687dac5c6cb4..2c6a882a5c6e 100644 --- a/receiver/k8sclusterreceiver/internal/clusterresourcequota/clusterresourcequotas.go +++ b/receiver/k8sclusterreceiver/internal/clusterresourcequota/clusterresourcequotas.go @@ -43,7 +43,11 @@ func GetMetrics(set receiver.CreateSettings, crq *quotav1.ClusterResourceQuota) } } - return mbphase.Emit(imetadataphase.WithOpenshiftClusterquotaName(crq.Name), imetadataphase.WithOpenshiftClusterquotaUID(string(crq.UID)), imetadataphase.WithOpencensusResourcetype("k8s")) + rb := imetadataphase.NewResourceBuilder(imetadataphase.DefaultResourceAttributesConfig()) + rb.SetOpenshiftClusterquotaName(crq.Name) + rb.SetOpenshiftClusterquotaUID(string(crq.UID)) + rb.SetOpencensusResourcetype("k8s") + return mbphase.Emit(imetadataphase.WithResource(rb.Emit())) } func extractValue(k v1.ResourceName, v resource.Quantity) int64 { diff --git a/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_config_test.go b/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_config_test.go index 5758ce83ebc8..1745ef36b815 100644 --- a/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_config_test.go +++ b/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_config_test.go @@ -74,3 +74,51 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + OpencensusResourcetype: ResourceAttributeConfig{Enabled: true}, + OpenshiftClusterquotaName: ResourceAttributeConfig{Enabled: true}, + OpenshiftClusterquotaUID: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + OpencensusResourcetype: ResourceAttributeConfig{Enabled: false}, + OpenshiftClusterquotaName: ResourceAttributeConfig{Enabled: false}, + OpenshiftClusterquotaUID: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_metrics.go b/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_metrics.go index 08e3431d9572..ce4e0a0a6c05 100644 --- a/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_metrics.go +++ b/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_metrics.go @@ -223,10 +223,8 @@ func newMetricOpenshiftClusterquotaUsed(cfg MetricConfig) metricOpenshiftCluster type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricOpenshiftAppliedclusterquotaLimit metricOpenshiftAppliedclusterquotaLimit metricOpenshiftAppliedclusterquotaUsed metricOpenshiftAppliedclusterquotaUsed metricOpenshiftClusterquotaLimit metricOpenshiftClusterquotaLimit @@ -248,7 +246,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricOpenshiftAppliedclusterquotaLimit: newMetricOpenshiftAppliedclusterquotaLimit(mbc.Metrics.OpenshiftAppliedclusterquotaLimit), metricOpenshiftAppliedclusterquotaUsed: newMetricOpenshiftAppliedclusterquotaUsed(mbc.Metrics.OpenshiftAppliedclusterquotaUsed), metricOpenshiftClusterquotaLimit: newMetricOpenshiftClusterquotaLimit(mbc.Metrics.OpenshiftClusterquotaLimit), @@ -265,45 +262,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithOpencensusResourcetype sets provided value as "opencensus.resourcetype" attribute for current resource. -func WithOpencensusResourcetype(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.OpencensusResourcetype.Enabled { - rm.Resource().Attributes().PutStr("opencensus.resourcetype", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithOpenshiftClusterquotaName sets provided value as "openshift.clusterquota.name" attribute for current resource. -func WithOpenshiftClusterquotaName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.OpenshiftClusterquotaName.Enabled { - rm.Resource().Attributes().PutStr("openshift.clusterquota.name", val) - } - } -} - -// WithOpenshiftClusterquotaUID sets provided value as "openshift.clusterquota.uid" attribute for current resource. -func WithOpenshiftClusterquotaUID(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.OpenshiftClusterquotaUID.Enabled { - rm.Resource().Attributes().PutStr("openshift.clusterquota.uid", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -328,7 +303,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() rm.SetSchemaUrl(conventions.SchemaURL) - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/k8sclusterreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -339,7 +313,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricOpenshiftClusterquotaUsed.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_metrics_test.go b/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_metrics_test.go index 88afbd526cc3..b1797a905319 100644 --- a/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_metrics_test.go +++ b/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_metrics_test.go @@ -70,7 +70,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordOpenshiftClusterquotaUsedDataPoint(ts, 1, "resource-val") - metrics := mb.Emit(WithOpencensusResourcetype("opencensus.resourcetype-val"), WithOpenshiftClusterquotaName("openshift.clusterquota.name-val"), WithOpenshiftClusterquotaUID("openshift.clusterquota.uid-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -79,32 +81,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("opencensus.resourcetype") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.OpencensusResourcetype.Enabled, ok) - if mb.resourceAttributesConfig.OpencensusResourcetype.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "opencensus.resourcetype-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("openshift.clusterquota.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.OpenshiftClusterquotaName.Enabled, ok) - if mb.resourceAttributesConfig.OpenshiftClusterquotaName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "openshift.clusterquota.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("openshift.clusterquota.uid") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.OpenshiftClusterquotaUID.Enabled, ok) - if mb.resourceAttributesConfig.OpenshiftClusterquotaUID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "openshift.clusterquota.uid-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 3) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_resource.go b/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..32fae6f79056 --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_resource.go @@ -0,0 +1,50 @@ +// 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(), + } +} + +// SetOpencensusResourcetype sets provided value as "opencensus.resourcetype" attribute. +func (rb *ResourceBuilder) SetOpencensusResourcetype(val string) { + if rb.config.OpencensusResourcetype.Enabled { + rb.res.Attributes().PutStr("opencensus.resourcetype", val) + } +} + +// SetOpenshiftClusterquotaName sets provided value as "openshift.clusterquota.name" attribute. +func (rb *ResourceBuilder) SetOpenshiftClusterquotaName(val string) { + if rb.config.OpenshiftClusterquotaName.Enabled { + rb.res.Attributes().PutStr("openshift.clusterquota.name", val) + } +} + +// SetOpenshiftClusterquotaUID sets provided value as "openshift.clusterquota.uid" attribute. +func (rb *ResourceBuilder) SetOpenshiftClusterquotaUID(val string) { + if rb.config.OpenshiftClusterquotaUID.Enabled { + rb.res.Attributes().PutStr("openshift.clusterquota.uid", 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/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_resource_test.go b/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..45faff064cab --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/clusterresourcequota/internal/metadata/generated_resource_test.go @@ -0,0 +1,52 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetOpencensusResourcetype("opencensus.resourcetype-val") + rb.SetOpenshiftClusterquotaName("openshift.clusterquota.name-val") + rb.SetOpenshiftClusterquotaUID("openshift.clusterquota.uid-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 3, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 3, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("opencensus.resourcetype") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "opencensus.resourcetype-val", val.Str()) + } + val, ok = res.Attributes().Get("openshift.clusterquota.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "openshift.clusterquota.name-val", val.Str()) + } + val, ok = res.Attributes().Get("openshift.clusterquota.uid") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "openshift.clusterquota.uid-val", val.Str()) + } + }) + } +} diff --git a/receiver/k8sclusterreceiver/internal/container/containers.go b/receiver/k8sclusterreceiver/internal/container/containers.go index 879d4bf0d668..b8671ad05435 100644 --- a/receiver/k8sclusterreceiver/internal/container/containers.go +++ b/receiver/k8sclusterreceiver/internal/container/containers.go @@ -78,26 +78,22 @@ func GetSpecMetrics(set receiver.CreateSettings, c corev1.Container, pod *corev1 } } - resourceOptions := []imetadata.ResourceMetricsOption{ - imetadata.WithK8sPodUID(string(pod.UID)), - imetadata.WithK8sPodName(pod.Name), - imetadata.WithK8sNodeName(pod.Spec.NodeName), - imetadata.WithK8sNamespaceName(pod.Namespace), - imetadata.WithOpencensusResourcetype("container"), - imetadata.WithContainerID(utils.StripContainerID(containerID)), - imetadata.WithK8sContainerName(c.Name), - } + rb := imetadata.NewResourceBuilder(imetadata.DefaultResourceAttributesConfig()) + rb.SetK8sPodUID(string(pod.UID)) + rb.SetK8sPodName(pod.Name) + rb.SetK8sNodeName(pod.Spec.NodeName) + rb.SetK8sNamespaceName(pod.Namespace) + rb.SetOpencensusResourcetype("container") + rb.SetContainerID(utils.StripContainerID(containerID)) + rb.SetK8sContainerName(c.Name) image, err := docker.ParseImageName(imageStr) if err != nil { docker.LogParseError(err, imageStr, set.Logger) } else { - resourceOptions = append(resourceOptions, - imetadata.WithContainerImageName(image.Repository), - imetadata.WithContainerImageTag(image.Tag)) + rb.SetContainerImageName(image.Repository) + rb.SetContainerImageTag(image.Tag) } - return mb.Emit( - resourceOptions..., - ) + return mb.Emit(imetadata.WithResource(rb.Emit())) } func GetMetadata(cs corev1.ContainerStatus) *metadata.KubernetesMetadata { diff --git a/receiver/k8sclusterreceiver/internal/container/internal/metadata/generated_config_test.go b/receiver/k8sclusterreceiver/internal/container/internal/metadata/generated_config_test.go index d41e09165290..5f2a11813bdd 100644 --- a/receiver/k8sclusterreceiver/internal/container/internal/metadata/generated_config_test.go +++ b/receiver/k8sclusterreceiver/internal/container/internal/metadata/generated_config_test.go @@ -98,3 +98,63 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + ContainerID: ResourceAttributeConfig{Enabled: true}, + ContainerImageName: ResourceAttributeConfig{Enabled: true}, + ContainerImageTag: ResourceAttributeConfig{Enabled: true}, + K8sContainerName: ResourceAttributeConfig{Enabled: true}, + K8sNamespaceName: ResourceAttributeConfig{Enabled: true}, + K8sNodeName: ResourceAttributeConfig{Enabled: true}, + K8sPodName: ResourceAttributeConfig{Enabled: true}, + K8sPodUID: ResourceAttributeConfig{Enabled: true}, + OpencensusResourcetype: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + ContainerID: ResourceAttributeConfig{Enabled: false}, + ContainerImageName: ResourceAttributeConfig{Enabled: false}, + ContainerImageTag: ResourceAttributeConfig{Enabled: false}, + K8sContainerName: ResourceAttributeConfig{Enabled: false}, + K8sNamespaceName: ResourceAttributeConfig{Enabled: false}, + K8sNodeName: ResourceAttributeConfig{Enabled: false}, + K8sPodName: ResourceAttributeConfig{Enabled: false}, + K8sPodUID: ResourceAttributeConfig{Enabled: false}, + OpencensusResourcetype: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/k8sclusterreceiver/internal/container/internal/metadata/generated_metrics.go b/receiver/k8sclusterreceiver/internal/container/internal/metadata/generated_metrics.go index 5f83bdbf6a28..e735c9cb5b74 100644 --- a/receiver/k8sclusterreceiver/internal/container/internal/metadata/generated_metrics.go +++ b/receiver/k8sclusterreceiver/internal/container/internal/metadata/generated_metrics.go @@ -507,10 +507,8 @@ func newMetricK8sContainerStorageRequest(cfg MetricConfig) metricK8sContainerSto type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricK8sContainerCPULimit metricK8sContainerCPULimit metricK8sContainerCPURequest metricK8sContainerCPURequest metricK8sContainerEphemeralstorageLimit metricK8sContainerEphemeralstorageLimit @@ -538,7 +536,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricK8sContainerCPULimit: newMetricK8sContainerCPULimit(mbc.Metrics.K8sContainerCPULimit), metricK8sContainerCPURequest: newMetricK8sContainerCPURequest(mbc.Metrics.K8sContainerCPURequest), metricK8sContainerEphemeralstorageLimit: newMetricK8sContainerEphemeralstorageLimit(mbc.Metrics.K8sContainerEphemeralstorageLimit), @@ -561,99 +558,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithContainerID sets provided value as "container.id" attribute for current resource. -func WithContainerID(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.ContainerID.Enabled { - rm.Resource().Attributes().PutStr("container.id", val) - } - } -} - -// WithContainerImageName sets provided value as "container.image.name" attribute for current resource. -func WithContainerImageName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.ContainerImageName.Enabled { - rm.Resource().Attributes().PutStr("container.image.name", val) - } - } -} - -// WithContainerImageTag sets provided value as "container.image.tag" attribute for current resource. -func WithContainerImageTag(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.ContainerImageTag.Enabled { - rm.Resource().Attributes().PutStr("container.image.tag", val) - } - } -} - -// WithK8sContainerName sets provided value as "k8s.container.name" attribute for current resource. -func WithK8sContainerName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sContainerName.Enabled { - rm.Resource().Attributes().PutStr("k8s.container.name", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithK8sNamespaceName sets provided value as "k8s.namespace.name" attribute for current resource. -func WithK8sNamespaceName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sNamespaceName.Enabled { - rm.Resource().Attributes().PutStr("k8s.namespace.name", val) - } - } -} - -// WithK8sNodeName sets provided value as "k8s.node.name" attribute for current resource. -func WithK8sNodeName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sNodeName.Enabled { - rm.Resource().Attributes().PutStr("k8s.node.name", val) - } - } -} - -// WithK8sPodName sets provided value as "k8s.pod.name" attribute for current resource. -func WithK8sPodName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sPodName.Enabled { - rm.Resource().Attributes().PutStr("k8s.pod.name", val) - } - } -} - -// WithK8sPodUID sets provided value as "k8s.pod.uid" attribute for current resource. -func WithK8sPodUID(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sPodUID.Enabled { - rm.Resource().Attributes().PutStr("k8s.pod.uid", val) - } - } -} - -// WithOpencensusResourcetype sets provided value as "opencensus.resourcetype" attribute for current resource. -func WithOpencensusResourcetype(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.OpencensusResourcetype.Enabled { - rm.Resource().Attributes().PutStr("opencensus.resourcetype", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -678,7 +599,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() rm.SetSchemaUrl(conventions.SchemaURL) - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/k8sclusterreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -695,7 +615,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricK8sContainerStorageRequest.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/k8sclusterreceiver/internal/container/internal/metadata/generated_metrics_test.go b/receiver/k8sclusterreceiver/internal/container/internal/metadata/generated_metrics_test.go index cf0e51015ff3..c65920e5bed6 100644 --- a/receiver/k8sclusterreceiver/internal/container/internal/metadata/generated_metrics_test.go +++ b/receiver/k8sclusterreceiver/internal/container/internal/metadata/generated_metrics_test.go @@ -94,7 +94,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordK8sContainerStorageRequestDataPoint(ts, 1) - metrics := mb.Emit(WithContainerID("container.id-val"), WithContainerImageName("container.image.name-val"), WithContainerImageTag("container.image.tag-val"), WithK8sContainerName("k8s.container.name-val"), WithK8sNamespaceName("k8s.namespace.name-val"), WithK8sNodeName("k8s.node.name-val"), WithK8sPodName("k8s.pod.name-val"), WithK8sPodUID("k8s.pod.uid-val"), WithOpencensusResourcetype("opencensus.resourcetype-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -103,74 +105,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("container.id") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.ContainerID.Enabled, ok) - if mb.resourceAttributesConfig.ContainerID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "container.id-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("container.image.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.ContainerImageName.Enabled, ok) - if mb.resourceAttributesConfig.ContainerImageName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "container.image.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("container.image.tag") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.ContainerImageTag.Enabled, ok) - if mb.resourceAttributesConfig.ContainerImageTag.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "container.image.tag-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.container.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sContainerName.Enabled, ok) - if mb.resourceAttributesConfig.K8sContainerName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.container.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.namespace.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sNamespaceName.Enabled, ok) - if mb.resourceAttributesConfig.K8sNamespaceName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.namespace.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.node.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sNodeName.Enabled, ok) - if mb.resourceAttributesConfig.K8sNodeName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.node.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.pod.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sPodName.Enabled, ok) - if mb.resourceAttributesConfig.K8sPodName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.pod.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.pod.uid") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sPodUID.Enabled, ok) - if mb.resourceAttributesConfig.K8sPodUID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.pod.uid-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("opencensus.resourcetype") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.OpencensusResourcetype.Enabled, ok) - if mb.resourceAttributesConfig.OpencensusResourcetype.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "opencensus.resourcetype-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 9) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/k8sclusterreceiver/internal/container/internal/metadata/generated_resource.go b/receiver/k8sclusterreceiver/internal/container/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..af723a739cd3 --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/container/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(), + } +} + +// SetContainerID sets provided value as "container.id" attribute. +func (rb *ResourceBuilder) SetContainerID(val string) { + if rb.config.ContainerID.Enabled { + rb.res.Attributes().PutStr("container.id", val) + } +} + +// SetContainerImageName sets provided value as "container.image.name" attribute. +func (rb *ResourceBuilder) SetContainerImageName(val string) { + if rb.config.ContainerImageName.Enabled { + rb.res.Attributes().PutStr("container.image.name", val) + } +} + +// SetContainerImageTag sets provided value as "container.image.tag" attribute. +func (rb *ResourceBuilder) SetContainerImageTag(val string) { + if rb.config.ContainerImageTag.Enabled { + rb.res.Attributes().PutStr("container.image.tag", val) + } +} + +// SetK8sContainerName sets provided value as "k8s.container.name" attribute. +func (rb *ResourceBuilder) SetK8sContainerName(val string) { + if rb.config.K8sContainerName.Enabled { + rb.res.Attributes().PutStr("k8s.container.name", val) + } +} + +// SetK8sNamespaceName sets provided value as "k8s.namespace.name" attribute. +func (rb *ResourceBuilder) SetK8sNamespaceName(val string) { + if rb.config.K8sNamespaceName.Enabled { + rb.res.Attributes().PutStr("k8s.namespace.name", val) + } +} + +// SetK8sNodeName sets provided value as "k8s.node.name" attribute. +func (rb *ResourceBuilder) SetK8sNodeName(val string) { + if rb.config.K8sNodeName.Enabled { + rb.res.Attributes().PutStr("k8s.node.name", val) + } +} + +// SetK8sPodName sets provided value as "k8s.pod.name" attribute. +func (rb *ResourceBuilder) SetK8sPodName(val string) { + if rb.config.K8sPodName.Enabled { + rb.res.Attributes().PutStr("k8s.pod.name", val) + } +} + +// SetK8sPodUID sets provided value as "k8s.pod.uid" attribute. +func (rb *ResourceBuilder) SetK8sPodUID(val string) { + if rb.config.K8sPodUID.Enabled { + rb.res.Attributes().PutStr("k8s.pod.uid", val) + } +} + +// SetOpencensusResourcetype sets provided value as "opencensus.resourcetype" attribute. +func (rb *ResourceBuilder) SetOpencensusResourcetype(val string) { + if rb.config.OpencensusResourcetype.Enabled { + rb.res.Attributes().PutStr("opencensus.resourcetype", 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/receiver/k8sclusterreceiver/internal/container/internal/metadata/generated_resource_test.go b/receiver/k8sclusterreceiver/internal/container/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..a4763d958d3b --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/container/internal/metadata/generated_resource_test.go @@ -0,0 +1,88 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetContainerID("container.id-val") + rb.SetContainerImageName("container.image.name-val") + rb.SetContainerImageTag("container.image.tag-val") + rb.SetK8sContainerName("k8s.container.name-val") + rb.SetK8sNamespaceName("k8s.namespace.name-val") + rb.SetK8sNodeName("k8s.node.name-val") + rb.SetK8sPodName("k8s.pod.name-val") + rb.SetK8sPodUID("k8s.pod.uid-val") + rb.SetOpencensusResourcetype("opencensus.resourcetype-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 9, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 9, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("container.id") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "container.id-val", val.Str()) + } + val, ok = res.Attributes().Get("container.image.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "container.image.name-val", val.Str()) + } + val, ok = res.Attributes().Get("container.image.tag") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "container.image.tag-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.container.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.container.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.namespace.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.namespace.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.node.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.node.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.pod.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.pod.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.pod.uid") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.pod.uid-val", val.Str()) + } + val, ok = res.Attributes().Get("opencensus.resourcetype") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "opencensus.resourcetype-val", val.Str()) + } + }) + } +} diff --git a/receiver/k8sclusterreceiver/internal/cronjob/cronjobs.go b/receiver/k8sclusterreceiver/internal/cronjob/cronjobs.go index 07b289a6ffa4..52ee038be2e0 100644 --- a/receiver/k8sclusterreceiver/internal/cronjob/cronjobs.go +++ b/receiver/k8sclusterreceiver/internal/cronjob/cronjobs.go @@ -30,12 +30,12 @@ func GetMetrics(set receiver.CreateSettings, cj *batchv1.CronJob) pmetric.Metric mbphase.RecordK8sCronjobActiveJobsDataPoint(ts, int64(len(cj.Status.Active))) - return mbphase.Emit( - imetadataphase.WithK8sNamespaceName(cj.Namespace), - imetadataphase.WithK8sCronjobUID(string(cj.UID)), - imetadataphase.WithK8sCronjobName(cj.Name), - imetadataphase.WithOpencensusResourcetype("k8s"), - ) + rb := imetadataphase.NewResourceBuilder(imetadataphase.DefaultResourceAttributesConfig()) + rb.SetK8sNamespaceName(cj.Namespace) + rb.SetK8sCronjobUID(string(cj.UID)) + rb.SetK8sCronjobName(cj.Name) + rb.SetOpencensusResourcetype("k8s") + return mbphase.Emit(imetadataphase.WithResource(rb.Emit())) } func GetMetricsBeta(set receiver.CreateSettings, cj *batchv1beta1.CronJob) pmetric.Metrics { @@ -44,13 +44,12 @@ func GetMetricsBeta(set receiver.CreateSettings, cj *batchv1beta1.CronJob) pmetr mbphase.RecordK8sCronjobActiveJobsDataPoint(ts, int64(len(cj.Status.Active))) - return mbphase.Emit( - imetadataphase.WithK8sNamespaceName(cj.Namespace), - imetadataphase.WithK8sCronjobUID(string(cj.UID)), - imetadataphase.WithK8sCronjobName(cj.Name), - imetadataphase.WithOpencensusResourcetype("k8s"), - ) - + rb := imetadataphase.NewResourceBuilder(imetadataphase.DefaultResourceAttributesConfig()) + rb.SetK8sNamespaceName(cj.Namespace) + rb.SetK8sCronjobUID(string(cj.UID)) + rb.SetK8sCronjobName(cj.Name) + rb.SetOpencensusResourcetype("k8s") + return mbphase.Emit(imetadataphase.WithResource(rb.Emit())) } func GetMetadata(cj *batchv1.CronJob) map[experimentalmetricmetadata.ResourceID]*metadata.KubernetesMetadata { diff --git a/receiver/k8sclusterreceiver/internal/cronjob/internal/metadata/generated_config_test.go b/receiver/k8sclusterreceiver/internal/cronjob/internal/metadata/generated_config_test.go index fa1c834077dc..ada69541df7b 100644 --- a/receiver/k8sclusterreceiver/internal/cronjob/internal/metadata/generated_config_test.go +++ b/receiver/k8sclusterreceiver/internal/cronjob/internal/metadata/generated_config_test.go @@ -72,3 +72,55 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + K8sCronjobName: ResourceAttributeConfig{Enabled: true}, + K8sCronjobUID: ResourceAttributeConfig{Enabled: true}, + K8sNamespaceName: ResourceAttributeConfig{Enabled: true}, + K8sNodeName: ResourceAttributeConfig{Enabled: true}, + OpencensusResourcetype: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + K8sCronjobName: ResourceAttributeConfig{Enabled: false}, + K8sCronjobUID: ResourceAttributeConfig{Enabled: false}, + K8sNamespaceName: ResourceAttributeConfig{Enabled: false}, + K8sNodeName: ResourceAttributeConfig{Enabled: false}, + OpencensusResourcetype: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/k8sclusterreceiver/internal/cronjob/internal/metadata/generated_metrics.go b/receiver/k8sclusterreceiver/internal/cronjob/internal/metadata/generated_metrics.go index 80b96962e224..c703cda4d12d 100644 --- a/receiver/k8sclusterreceiver/internal/cronjob/internal/metadata/generated_metrics.go +++ b/receiver/k8sclusterreceiver/internal/cronjob/internal/metadata/generated_metrics.go @@ -66,10 +66,8 @@ func newMetricK8sCronjobActiveJobs(cfg MetricConfig) metricK8sCronjobActiveJobs type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricK8sCronjobActiveJobs metricK8sCronjobActiveJobs } @@ -88,7 +86,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricK8sCronjobActiveJobs: newMetricK8sCronjobActiveJobs(mbc.Metrics.K8sCronjobActiveJobs), } for _, op := range options { @@ -102,63 +99,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithK8sCronjobName sets provided value as "k8s.cronjob.name" attribute for current resource. -func WithK8sCronjobName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sCronjobName.Enabled { - rm.Resource().Attributes().PutStr("k8s.cronjob.name", val) - } - } -} - -// WithK8sCronjobUID sets provided value as "k8s.cronjob.uid" attribute for current resource. -func WithK8sCronjobUID(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sCronjobUID.Enabled { - rm.Resource().Attributes().PutStr("k8s.cronjob.uid", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithK8sNamespaceName sets provided value as "k8s.namespace.name" attribute for current resource. -func WithK8sNamespaceName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sNamespaceName.Enabled { - rm.Resource().Attributes().PutStr("k8s.namespace.name", val) - } - } -} - -// WithK8sNodeName sets provided value as "k8s.node.name" attribute for current resource. -func WithK8sNodeName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sNodeName.Enabled { - rm.Resource().Attributes().PutStr("k8s.node.name", val) - } - } -} - -// WithOpencensusResourcetype sets provided value as "opencensus.resourcetype" attribute for current resource. -func WithOpencensusResourcetype(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.OpencensusResourcetype.Enabled { - rm.Resource().Attributes().PutStr("opencensus.resourcetype", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -183,7 +140,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() rm.SetSchemaUrl(conventions.SchemaURL) - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/k8sclusterreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -191,7 +147,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricK8sCronjobActiveJobs.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/k8sclusterreceiver/internal/cronjob/internal/metadata/generated_metrics_test.go b/receiver/k8sclusterreceiver/internal/cronjob/internal/metadata/generated_metrics_test.go index 7fcca95cb75b..39974d446446 100644 --- a/receiver/k8sclusterreceiver/internal/cronjob/internal/metadata/generated_metrics_test.go +++ b/receiver/k8sclusterreceiver/internal/cronjob/internal/metadata/generated_metrics_test.go @@ -58,7 +58,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordK8sCronjobActiveJobsDataPoint(ts, 1) - metrics := mb.Emit(WithK8sCronjobName("k8s.cronjob.name-val"), WithK8sCronjobUID("k8s.cronjob.uid-val"), WithK8sNamespaceName("k8s.namespace.name-val"), WithK8sNodeName("k8s.node.name-val"), WithOpencensusResourcetype("opencensus.resourcetype-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -67,46 +69,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("k8s.cronjob.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sCronjobName.Enabled, ok) - if mb.resourceAttributesConfig.K8sCronjobName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.cronjob.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.cronjob.uid") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sCronjobUID.Enabled, ok) - if mb.resourceAttributesConfig.K8sCronjobUID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.cronjob.uid-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.namespace.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sNamespaceName.Enabled, ok) - if mb.resourceAttributesConfig.K8sNamespaceName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.namespace.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.node.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sNodeName.Enabled, ok) - if mb.resourceAttributesConfig.K8sNodeName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.node.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("opencensus.resourcetype") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.OpencensusResourcetype.Enabled, ok) - if mb.resourceAttributesConfig.OpencensusResourcetype.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "opencensus.resourcetype-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 5) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/k8sclusterreceiver/internal/cronjob/internal/metadata/generated_resource.go b/receiver/k8sclusterreceiver/internal/cronjob/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..7806390eee7b --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/cronjob/internal/metadata/generated_resource.go @@ -0,0 +1,64 @@ +// 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(), + } +} + +// SetK8sCronjobName sets provided value as "k8s.cronjob.name" attribute. +func (rb *ResourceBuilder) SetK8sCronjobName(val string) { + if rb.config.K8sCronjobName.Enabled { + rb.res.Attributes().PutStr("k8s.cronjob.name", val) + } +} + +// SetK8sCronjobUID sets provided value as "k8s.cronjob.uid" attribute. +func (rb *ResourceBuilder) SetK8sCronjobUID(val string) { + if rb.config.K8sCronjobUID.Enabled { + rb.res.Attributes().PutStr("k8s.cronjob.uid", val) + } +} + +// SetK8sNamespaceName sets provided value as "k8s.namespace.name" attribute. +func (rb *ResourceBuilder) SetK8sNamespaceName(val string) { + if rb.config.K8sNamespaceName.Enabled { + rb.res.Attributes().PutStr("k8s.namespace.name", val) + } +} + +// SetK8sNodeName sets provided value as "k8s.node.name" attribute. +func (rb *ResourceBuilder) SetK8sNodeName(val string) { + if rb.config.K8sNodeName.Enabled { + rb.res.Attributes().PutStr("k8s.node.name", val) + } +} + +// SetOpencensusResourcetype sets provided value as "opencensus.resourcetype" attribute. +func (rb *ResourceBuilder) SetOpencensusResourcetype(val string) { + if rb.config.OpencensusResourcetype.Enabled { + rb.res.Attributes().PutStr("opencensus.resourcetype", 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/receiver/k8sclusterreceiver/internal/cronjob/internal/metadata/generated_resource_test.go b/receiver/k8sclusterreceiver/internal/cronjob/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..79ca377c716b --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/cronjob/internal/metadata/generated_resource_test.go @@ -0,0 +1,64 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetK8sCronjobName("k8s.cronjob.name-val") + rb.SetK8sCronjobUID("k8s.cronjob.uid-val") + rb.SetK8sNamespaceName("k8s.namespace.name-val") + rb.SetK8sNodeName("k8s.node.name-val") + rb.SetOpencensusResourcetype("opencensus.resourcetype-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 5, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 5, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("k8s.cronjob.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.cronjob.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.cronjob.uid") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.cronjob.uid-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.namespace.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.namespace.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.node.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.node.name-val", val.Str()) + } + val, ok = res.Attributes().Get("opencensus.resourcetype") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "opencensus.resourcetype-val", val.Str()) + } + }) + } +} diff --git a/receiver/k8sclusterreceiver/internal/demonset/daemonsets.go b/receiver/k8sclusterreceiver/internal/demonset/daemonsets.go index d14b17cb739a..3ad5ff9fcf97 100644 --- a/receiver/k8sclusterreceiver/internal/demonset/daemonsets.go +++ b/receiver/k8sclusterreceiver/internal/demonset/daemonsets.go @@ -39,13 +39,12 @@ func GetMetrics(set receiver.CreateSettings, ds *appsv1.DaemonSet) pmetric.Metri mbphase.RecordK8sDaemonsetMisscheduledNodesDataPoint(ts, int64(ds.Status.NumberMisscheduled)) mbphase.RecordK8sDaemonsetReadyNodesDataPoint(ts, int64(ds.Status.NumberReady)) - return mbphase.Emit( - imetadataphase.WithK8sNamespaceName(ds.Namespace), - imetadataphase.WithK8sDaemonsetName(ds.Name), - imetadataphase.WithK8sDaemonsetUID(string(ds.UID)), - imetadataphase.WithOpencensusResourcetype("k8s"), - ) - + rb := imetadataphase.NewResourceBuilder(imetadataphase.DefaultResourceAttributesConfig()) + rb.SetK8sNamespaceName(ds.Namespace) + rb.SetK8sDaemonsetName(ds.Name) + rb.SetK8sDaemonsetUID(string(ds.UID)) + rb.SetOpencensusResourcetype("k8s") + return mbphase.Emit(imetadataphase.WithResource(rb.Emit())) } func GetMetadata(ds *appsv1.DaemonSet) map[experimentalmetricmetadata.ResourceID]*metadata.KubernetesMetadata { diff --git a/receiver/k8sclusterreceiver/internal/demonset/internal/metadata/generated_config_test.go b/receiver/k8sclusterreceiver/internal/demonset/internal/metadata/generated_config_test.go index 242cea723fa4..db98ec0411e2 100644 --- a/receiver/k8sclusterreceiver/internal/demonset/internal/metadata/generated_config_test.go +++ b/receiver/k8sclusterreceiver/internal/demonset/internal/metadata/generated_config_test.go @@ -76,3 +76,53 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + K8sDaemonsetName: ResourceAttributeConfig{Enabled: true}, + K8sDaemonsetUID: ResourceAttributeConfig{Enabled: true}, + K8sNamespaceName: ResourceAttributeConfig{Enabled: true}, + OpencensusResourcetype: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + K8sDaemonsetName: ResourceAttributeConfig{Enabled: false}, + K8sDaemonsetUID: ResourceAttributeConfig{Enabled: false}, + K8sNamespaceName: ResourceAttributeConfig{Enabled: false}, + OpencensusResourcetype: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/k8sclusterreceiver/internal/demonset/internal/metadata/generated_metrics.go b/receiver/k8sclusterreceiver/internal/demonset/internal/metadata/generated_metrics.go index 11457703d18d..f6dead0e711e 100644 --- a/receiver/k8sclusterreceiver/internal/demonset/internal/metadata/generated_metrics.go +++ b/receiver/k8sclusterreceiver/internal/demonset/internal/metadata/generated_metrics.go @@ -213,10 +213,8 @@ func newMetricK8sDaemonsetReadyNodes(cfg MetricConfig) metricK8sDaemonsetReadyNo type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricK8sDaemonsetCurrentScheduledNodes metricK8sDaemonsetCurrentScheduledNodes metricK8sDaemonsetDesiredScheduledNodes metricK8sDaemonsetDesiredScheduledNodes metricK8sDaemonsetMisscheduledNodes metricK8sDaemonsetMisscheduledNodes @@ -238,7 +236,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricK8sDaemonsetCurrentScheduledNodes: newMetricK8sDaemonsetCurrentScheduledNodes(mbc.Metrics.K8sDaemonsetCurrentScheduledNodes), metricK8sDaemonsetDesiredScheduledNodes: newMetricK8sDaemonsetDesiredScheduledNodes(mbc.Metrics.K8sDaemonsetDesiredScheduledNodes), metricK8sDaemonsetMisscheduledNodes: newMetricK8sDaemonsetMisscheduledNodes(mbc.Metrics.K8sDaemonsetMisscheduledNodes), @@ -255,54 +252,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithK8sDaemonsetName sets provided value as "k8s.daemonset.name" attribute for current resource. -func WithK8sDaemonsetName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sDaemonsetName.Enabled { - rm.Resource().Attributes().PutStr("k8s.daemonset.name", val) - } - } -} - -// WithK8sDaemonsetUID sets provided value as "k8s.daemonset.uid" attribute for current resource. -func WithK8sDaemonsetUID(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sDaemonsetUID.Enabled { - rm.Resource().Attributes().PutStr("k8s.daemonset.uid", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithK8sNamespaceName sets provided value as "k8s.namespace.name" attribute for current resource. -func WithK8sNamespaceName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sNamespaceName.Enabled { - rm.Resource().Attributes().PutStr("k8s.namespace.name", val) - } - } -} - -// WithOpencensusResourcetype sets provided value as "opencensus.resourcetype" attribute for current resource. -func WithOpencensusResourcetype(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.OpencensusResourcetype.Enabled { - rm.Resource().Attributes().PutStr("opencensus.resourcetype", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -327,7 +293,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() rm.SetSchemaUrl(conventions.SchemaURL) - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/k8sclusterreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -338,7 +303,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricK8sDaemonsetReadyNodes.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/k8sclusterreceiver/internal/demonset/internal/metadata/generated_metrics_test.go b/receiver/k8sclusterreceiver/internal/demonset/internal/metadata/generated_metrics_test.go index e96e6c0c62d3..5f6c78c39588 100644 --- a/receiver/k8sclusterreceiver/internal/demonset/internal/metadata/generated_metrics_test.go +++ b/receiver/k8sclusterreceiver/internal/demonset/internal/metadata/generated_metrics_test.go @@ -70,7 +70,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordK8sDaemonsetReadyNodesDataPoint(ts, 1) - metrics := mb.Emit(WithK8sDaemonsetName("k8s.daemonset.name-val"), WithK8sDaemonsetUID("k8s.daemonset.uid-val"), WithK8sNamespaceName("k8s.namespace.name-val"), WithOpencensusResourcetype("opencensus.resourcetype-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -79,39 +81,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("k8s.daemonset.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sDaemonsetName.Enabled, ok) - if mb.resourceAttributesConfig.K8sDaemonsetName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.daemonset.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.daemonset.uid") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sDaemonsetUID.Enabled, ok) - if mb.resourceAttributesConfig.K8sDaemonsetUID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.daemonset.uid-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.namespace.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sNamespaceName.Enabled, ok) - if mb.resourceAttributesConfig.K8sNamespaceName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.namespace.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("opencensus.resourcetype") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.OpencensusResourcetype.Enabled, ok) - if mb.resourceAttributesConfig.OpencensusResourcetype.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "opencensus.resourcetype-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 4) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/k8sclusterreceiver/internal/demonset/internal/metadata/generated_resource.go b/receiver/k8sclusterreceiver/internal/demonset/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..32b39ac9e7e1 --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/demonset/internal/metadata/generated_resource.go @@ -0,0 +1,57 @@ +// 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(), + } +} + +// SetK8sDaemonsetName sets provided value as "k8s.daemonset.name" attribute. +func (rb *ResourceBuilder) SetK8sDaemonsetName(val string) { + if rb.config.K8sDaemonsetName.Enabled { + rb.res.Attributes().PutStr("k8s.daemonset.name", val) + } +} + +// SetK8sDaemonsetUID sets provided value as "k8s.daemonset.uid" attribute. +func (rb *ResourceBuilder) SetK8sDaemonsetUID(val string) { + if rb.config.K8sDaemonsetUID.Enabled { + rb.res.Attributes().PutStr("k8s.daemonset.uid", val) + } +} + +// SetK8sNamespaceName sets provided value as "k8s.namespace.name" attribute. +func (rb *ResourceBuilder) SetK8sNamespaceName(val string) { + if rb.config.K8sNamespaceName.Enabled { + rb.res.Attributes().PutStr("k8s.namespace.name", val) + } +} + +// SetOpencensusResourcetype sets provided value as "opencensus.resourcetype" attribute. +func (rb *ResourceBuilder) SetOpencensusResourcetype(val string) { + if rb.config.OpencensusResourcetype.Enabled { + rb.res.Attributes().PutStr("opencensus.resourcetype", 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/receiver/k8sclusterreceiver/internal/demonset/internal/metadata/generated_resource_test.go b/receiver/k8sclusterreceiver/internal/demonset/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..75f0959d0d78 --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/demonset/internal/metadata/generated_resource_test.go @@ -0,0 +1,58 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetK8sDaemonsetName("k8s.daemonset.name-val") + rb.SetK8sDaemonsetUID("k8s.daemonset.uid-val") + rb.SetK8sNamespaceName("k8s.namespace.name-val") + rb.SetOpencensusResourcetype("opencensus.resourcetype-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 4, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 4, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("k8s.daemonset.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.daemonset.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.daemonset.uid") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.daemonset.uid-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.namespace.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.namespace.name-val", val.Str()) + } + val, ok = res.Attributes().Get("opencensus.resourcetype") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "opencensus.resourcetype-val", val.Str()) + } + }) + } +} diff --git a/receiver/k8sclusterreceiver/internal/deployment/deployments.go b/receiver/k8sclusterreceiver/internal/deployment/deployments.go index daef5f5ab3e6..05786a0cfced 100644 --- a/receiver/k8sclusterreceiver/internal/deployment/deployments.go +++ b/receiver/k8sclusterreceiver/internal/deployment/deployments.go @@ -37,7 +37,12 @@ func GetMetrics(set receiver.CreateSettings, dep *appsv1.Deployment) pmetric.Met ts := pcommon.NewTimestampFromTime(time.Now()) mb.RecordK8sDeploymentDesiredDataPoint(ts, int64(*dep.Spec.Replicas)) mb.RecordK8sDeploymentAvailableDataPoint(ts, int64(dep.Status.AvailableReplicas)) - return mb.Emit(imetadata.WithK8sDeploymentName(dep.Name), imetadata.WithK8sDeploymentUID(string(dep.UID)), imetadata.WithK8sNamespaceName(dep.Namespace), imetadata.WithOpencensusResourcetype("k8s")) + rb := imetadata.NewResourceBuilder(imetadata.DefaultResourceAttributesConfig()) + rb.SetK8sDeploymentName(dep.Name) + rb.SetK8sDeploymentUID(string(dep.UID)) + rb.SetK8sNamespaceName(dep.Namespace) + rb.SetOpencensusResourcetype("k8s") + return mb.Emit(imetadata.WithResource(rb.Emit())) } func GetMetadata(dep *appsv1.Deployment) map[experimentalmetricmetadata.ResourceID]*metadata.KubernetesMetadata { diff --git a/receiver/k8sclusterreceiver/internal/deployment/internal/metadata/generated_config_test.go b/receiver/k8sclusterreceiver/internal/deployment/internal/metadata/generated_config_test.go index 86cc32765dba..24cc629129c6 100644 --- a/receiver/k8sclusterreceiver/internal/deployment/internal/metadata/generated_config_test.go +++ b/receiver/k8sclusterreceiver/internal/deployment/internal/metadata/generated_config_test.go @@ -72,3 +72,53 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + K8sDeploymentName: ResourceAttributeConfig{Enabled: true}, + K8sDeploymentUID: ResourceAttributeConfig{Enabled: true}, + K8sNamespaceName: ResourceAttributeConfig{Enabled: true}, + OpencensusResourcetype: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + K8sDeploymentName: ResourceAttributeConfig{Enabled: false}, + K8sDeploymentUID: ResourceAttributeConfig{Enabled: false}, + K8sNamespaceName: ResourceAttributeConfig{Enabled: false}, + OpencensusResourcetype: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/k8sclusterreceiver/internal/deployment/internal/metadata/generated_metrics.go b/receiver/k8sclusterreceiver/internal/deployment/internal/metadata/generated_metrics.go index 5f6c8c27ebce..af971e4ea0e0 100644 --- a/receiver/k8sclusterreceiver/internal/deployment/internal/metadata/generated_metrics.go +++ b/receiver/k8sclusterreceiver/internal/deployment/internal/metadata/generated_metrics.go @@ -115,10 +115,8 @@ func newMetricK8sDeploymentDesired(cfg MetricConfig) metricK8sDeploymentDesired type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricK8sDeploymentAvailable metricK8sDeploymentAvailable metricK8sDeploymentDesired metricK8sDeploymentDesired } @@ -138,7 +136,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricK8sDeploymentAvailable: newMetricK8sDeploymentAvailable(mbc.Metrics.K8sDeploymentAvailable), metricK8sDeploymentDesired: newMetricK8sDeploymentDesired(mbc.Metrics.K8sDeploymentDesired), } @@ -153,54 +150,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithK8sDeploymentName sets provided value as "k8s.deployment.name" attribute for current resource. -func WithK8sDeploymentName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sDeploymentName.Enabled { - rm.Resource().Attributes().PutStr("k8s.deployment.name", val) - } - } -} - -// WithK8sDeploymentUID sets provided value as "k8s.deployment.uid" attribute for current resource. -func WithK8sDeploymentUID(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sDeploymentUID.Enabled { - rm.Resource().Attributes().PutStr("k8s.deployment.uid", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithK8sNamespaceName sets provided value as "k8s.namespace.name" attribute for current resource. -func WithK8sNamespaceName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sNamespaceName.Enabled { - rm.Resource().Attributes().PutStr("k8s.namespace.name", val) - } - } -} - -// WithOpencensusResourcetype sets provided value as "opencensus.resourcetype" attribute for current resource. -func WithOpencensusResourcetype(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.OpencensusResourcetype.Enabled { - rm.Resource().Attributes().PutStr("opencensus.resourcetype", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -225,7 +191,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() rm.SetSchemaUrl(conventions.SchemaURL) - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/k8sclusterreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -234,7 +199,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricK8sDeploymentDesired.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/k8sclusterreceiver/internal/deployment/internal/metadata/generated_metrics_test.go b/receiver/k8sclusterreceiver/internal/deployment/internal/metadata/generated_metrics_test.go index 72d90b5dadad..6529a90e5f4e 100644 --- a/receiver/k8sclusterreceiver/internal/deployment/internal/metadata/generated_metrics_test.go +++ b/receiver/k8sclusterreceiver/internal/deployment/internal/metadata/generated_metrics_test.go @@ -62,7 +62,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordK8sDeploymentDesiredDataPoint(ts, 1) - metrics := mb.Emit(WithK8sDeploymentName("k8s.deployment.name-val"), WithK8sDeploymentUID("k8s.deployment.uid-val"), WithK8sNamespaceName("k8s.namespace.name-val"), WithOpencensusResourcetype("opencensus.resourcetype-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -71,39 +73,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("k8s.deployment.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sDeploymentName.Enabled, ok) - if mb.resourceAttributesConfig.K8sDeploymentName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.deployment.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.deployment.uid") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sDeploymentUID.Enabled, ok) - if mb.resourceAttributesConfig.K8sDeploymentUID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.deployment.uid-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.namespace.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sNamespaceName.Enabled, ok) - if mb.resourceAttributesConfig.K8sNamespaceName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.namespace.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("opencensus.resourcetype") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.OpencensusResourcetype.Enabled, ok) - if mb.resourceAttributesConfig.OpencensusResourcetype.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "opencensus.resourcetype-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 4) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/k8sclusterreceiver/internal/deployment/internal/metadata/generated_resource.go b/receiver/k8sclusterreceiver/internal/deployment/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..40bf3cbadb32 --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/deployment/internal/metadata/generated_resource.go @@ -0,0 +1,57 @@ +// 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(), + } +} + +// SetK8sDeploymentName sets provided value as "k8s.deployment.name" attribute. +func (rb *ResourceBuilder) SetK8sDeploymentName(val string) { + if rb.config.K8sDeploymentName.Enabled { + rb.res.Attributes().PutStr("k8s.deployment.name", val) + } +} + +// SetK8sDeploymentUID sets provided value as "k8s.deployment.uid" attribute. +func (rb *ResourceBuilder) SetK8sDeploymentUID(val string) { + if rb.config.K8sDeploymentUID.Enabled { + rb.res.Attributes().PutStr("k8s.deployment.uid", val) + } +} + +// SetK8sNamespaceName sets provided value as "k8s.namespace.name" attribute. +func (rb *ResourceBuilder) SetK8sNamespaceName(val string) { + if rb.config.K8sNamespaceName.Enabled { + rb.res.Attributes().PutStr("k8s.namespace.name", val) + } +} + +// SetOpencensusResourcetype sets provided value as "opencensus.resourcetype" attribute. +func (rb *ResourceBuilder) SetOpencensusResourcetype(val string) { + if rb.config.OpencensusResourcetype.Enabled { + rb.res.Attributes().PutStr("opencensus.resourcetype", 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/receiver/k8sclusterreceiver/internal/deployment/internal/metadata/generated_resource_test.go b/receiver/k8sclusterreceiver/internal/deployment/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..726f0db04a49 --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/deployment/internal/metadata/generated_resource_test.go @@ -0,0 +1,58 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetK8sDeploymentName("k8s.deployment.name-val") + rb.SetK8sDeploymentUID("k8s.deployment.uid-val") + rb.SetK8sNamespaceName("k8s.namespace.name-val") + rb.SetOpencensusResourcetype("opencensus.resourcetype-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 4, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 4, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("k8s.deployment.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.deployment.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.deployment.uid") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.deployment.uid-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.namespace.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.namespace.name-val", val.Str()) + } + val, ok = res.Attributes().Get("opencensus.resourcetype") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "opencensus.resourcetype-val", val.Str()) + } + }) + } +} diff --git a/receiver/k8sclusterreceiver/internal/hpa/hpa.go b/receiver/k8sclusterreceiver/internal/hpa/hpa.go index 433b52c7b634..b18f57e4795d 100644 --- a/receiver/k8sclusterreceiver/internal/hpa/hpa.go +++ b/receiver/k8sclusterreceiver/internal/hpa/hpa.go @@ -24,7 +24,11 @@ func GetMetricsBeta(set receiver.CreateSettings, hpa *autoscalingv2beta2.Horizon mb.RecordK8sHpaMinReplicasDataPoint(ts, int64(*hpa.Spec.MinReplicas)) mb.RecordK8sHpaCurrentReplicasDataPoint(ts, int64(hpa.Status.CurrentReplicas)) mb.RecordK8sHpaDesiredReplicasDataPoint(ts, int64(hpa.Status.DesiredReplicas)) - return mb.Emit(imetadata.WithK8sHpaUID(string(hpa.UID)), imetadata.WithK8sHpaName(hpa.Name), imetadata.WithK8sNamespaceName(hpa.Namespace)) + rb := imetadata.NewResourceBuilder(imetadata.DefaultResourceAttributesConfig()) + rb.SetK8sHpaUID(string(hpa.UID)) + rb.SetK8sHpaName(hpa.Name) + rb.SetK8sNamespaceName(hpa.Namespace) + return mb.Emit(imetadata.WithResource(rb.Emit())) } func GetMetrics(set receiver.CreateSettings, hpa *autoscalingv2.HorizontalPodAutoscaler) pmetric.Metrics { @@ -34,7 +38,11 @@ func GetMetrics(set receiver.CreateSettings, hpa *autoscalingv2.HorizontalPodAut mb.RecordK8sHpaMinReplicasDataPoint(ts, int64(*hpa.Spec.MinReplicas)) mb.RecordK8sHpaCurrentReplicasDataPoint(ts, int64(hpa.Status.CurrentReplicas)) mb.RecordK8sHpaDesiredReplicasDataPoint(ts, int64(hpa.Status.DesiredReplicas)) - return mb.Emit(imetadata.WithK8sHpaUID(string(hpa.UID)), imetadata.WithK8sHpaName(hpa.Name), imetadata.WithK8sNamespaceName(hpa.Namespace)) + rb := imetadata.NewResourceBuilder(imetadata.DefaultResourceAttributesConfig()) + rb.SetK8sHpaUID(string(hpa.UID)) + rb.SetK8sHpaName(hpa.Name) + rb.SetK8sNamespaceName(hpa.Namespace) + return mb.Emit(imetadata.WithResource(rb.Emit())) } func GetMetadata(hpa *autoscalingv2.HorizontalPodAutoscaler) map[experimentalmetricmetadata.ResourceID]*metadata.KubernetesMetadata { diff --git a/receiver/k8sclusterreceiver/internal/hpa/internal/metadata/generated_config_test.go b/receiver/k8sclusterreceiver/internal/hpa/internal/metadata/generated_config_test.go index caa61e51a42a..5379f55c6879 100644 --- a/receiver/k8sclusterreceiver/internal/hpa/internal/metadata/generated_config_test.go +++ b/receiver/k8sclusterreceiver/internal/hpa/internal/metadata/generated_config_test.go @@ -74,3 +74,51 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + K8sHpaName: ResourceAttributeConfig{Enabled: true}, + K8sHpaUID: ResourceAttributeConfig{Enabled: true}, + K8sNamespaceName: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + K8sHpaName: ResourceAttributeConfig{Enabled: false}, + K8sHpaUID: ResourceAttributeConfig{Enabled: false}, + K8sNamespaceName: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/k8sclusterreceiver/internal/hpa/internal/metadata/generated_metrics.go b/receiver/k8sclusterreceiver/internal/hpa/internal/metadata/generated_metrics.go index 69f783026dc2..a33119526a3f 100644 --- a/receiver/k8sclusterreceiver/internal/hpa/internal/metadata/generated_metrics.go +++ b/receiver/k8sclusterreceiver/internal/hpa/internal/metadata/generated_metrics.go @@ -213,10 +213,8 @@ func newMetricK8sHpaMinReplicas(cfg MetricConfig) metricK8sHpaMinReplicas { type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricK8sHpaCurrentReplicas metricK8sHpaCurrentReplicas metricK8sHpaDesiredReplicas metricK8sHpaDesiredReplicas metricK8sHpaMaxReplicas metricK8sHpaMaxReplicas @@ -238,7 +236,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricK8sHpaCurrentReplicas: newMetricK8sHpaCurrentReplicas(mbc.Metrics.K8sHpaCurrentReplicas), metricK8sHpaDesiredReplicas: newMetricK8sHpaDesiredReplicas(mbc.Metrics.K8sHpaDesiredReplicas), metricK8sHpaMaxReplicas: newMetricK8sHpaMaxReplicas(mbc.Metrics.K8sHpaMaxReplicas), @@ -255,45 +252,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithK8sHpaName sets provided value as "k8s.hpa.name" attribute for current resource. -func WithK8sHpaName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sHpaName.Enabled { - rm.Resource().Attributes().PutStr("k8s.hpa.name", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithK8sHpaUID sets provided value as "k8s.hpa.uid" attribute for current resource. -func WithK8sHpaUID(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sHpaUID.Enabled { - rm.Resource().Attributes().PutStr("k8s.hpa.uid", val) - } - } -} - -// WithK8sNamespaceName sets provided value as "k8s.namespace.name" attribute for current resource. -func WithK8sNamespaceName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sNamespaceName.Enabled { - rm.Resource().Attributes().PutStr("k8s.namespace.name", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -318,7 +293,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() rm.SetSchemaUrl(conventions.SchemaURL) - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/k8sclusterreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -329,7 +303,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricK8sHpaMinReplicas.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/k8sclusterreceiver/internal/hpa/internal/metadata/generated_metrics_test.go b/receiver/k8sclusterreceiver/internal/hpa/internal/metadata/generated_metrics_test.go index 7bbd145ff5aa..b3262e48aab4 100644 --- a/receiver/k8sclusterreceiver/internal/hpa/internal/metadata/generated_metrics_test.go +++ b/receiver/k8sclusterreceiver/internal/hpa/internal/metadata/generated_metrics_test.go @@ -70,7 +70,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordK8sHpaMinReplicasDataPoint(ts, 1) - metrics := mb.Emit(WithK8sHpaName("k8s.hpa.name-val"), WithK8sHpaUID("k8s.hpa.uid-val"), WithK8sNamespaceName("k8s.namespace.name-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -79,32 +81,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("k8s.hpa.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sHpaName.Enabled, ok) - if mb.resourceAttributesConfig.K8sHpaName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.hpa.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.hpa.uid") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sHpaUID.Enabled, ok) - if mb.resourceAttributesConfig.K8sHpaUID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.hpa.uid-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.namespace.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sNamespaceName.Enabled, ok) - if mb.resourceAttributesConfig.K8sNamespaceName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.namespace.name-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 3) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/k8sclusterreceiver/internal/hpa/internal/metadata/generated_resource.go b/receiver/k8sclusterreceiver/internal/hpa/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..a54f01e3ee04 --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/hpa/internal/metadata/generated_resource.go @@ -0,0 +1,50 @@ +// 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(), + } +} + +// SetK8sHpaName sets provided value as "k8s.hpa.name" attribute. +func (rb *ResourceBuilder) SetK8sHpaName(val string) { + if rb.config.K8sHpaName.Enabled { + rb.res.Attributes().PutStr("k8s.hpa.name", val) + } +} + +// SetK8sHpaUID sets provided value as "k8s.hpa.uid" attribute. +func (rb *ResourceBuilder) SetK8sHpaUID(val string) { + if rb.config.K8sHpaUID.Enabled { + rb.res.Attributes().PutStr("k8s.hpa.uid", val) + } +} + +// SetK8sNamespaceName sets provided value as "k8s.namespace.name" attribute. +func (rb *ResourceBuilder) SetK8sNamespaceName(val string) { + if rb.config.K8sNamespaceName.Enabled { + rb.res.Attributes().PutStr("k8s.namespace.name", 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/receiver/k8sclusterreceiver/internal/hpa/internal/metadata/generated_resource_test.go b/receiver/k8sclusterreceiver/internal/hpa/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..dd74b63135f7 --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/hpa/internal/metadata/generated_resource_test.go @@ -0,0 +1,52 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetK8sHpaName("k8s.hpa.name-val") + rb.SetK8sHpaUID("k8s.hpa.uid-val") + rb.SetK8sNamespaceName("k8s.namespace.name-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 3, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 3, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("k8s.hpa.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.hpa.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.hpa.uid") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.hpa.uid-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.namespace.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.namespace.name-val", val.Str()) + } + }) + } +} diff --git a/receiver/k8sclusterreceiver/internal/jobs/internal/metadata/generated_config_test.go b/receiver/k8sclusterreceiver/internal/jobs/internal/metadata/generated_config_test.go index 1f793bb62203..79ff490cf5fe 100644 --- a/receiver/k8sclusterreceiver/internal/jobs/internal/metadata/generated_config_test.go +++ b/receiver/k8sclusterreceiver/internal/jobs/internal/metadata/generated_config_test.go @@ -78,3 +78,53 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + K8sJobName: ResourceAttributeConfig{Enabled: true}, + K8sJobUID: ResourceAttributeConfig{Enabled: true}, + K8sNamespaceName: ResourceAttributeConfig{Enabled: true}, + OpencensusResourcetype: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + K8sJobName: ResourceAttributeConfig{Enabled: false}, + K8sJobUID: ResourceAttributeConfig{Enabled: false}, + K8sNamespaceName: ResourceAttributeConfig{Enabled: false}, + OpencensusResourcetype: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/k8sclusterreceiver/internal/jobs/internal/metadata/generated_metrics.go b/receiver/k8sclusterreceiver/internal/jobs/internal/metadata/generated_metrics.go index c726569bf97d..138a33263a5d 100644 --- a/receiver/k8sclusterreceiver/internal/jobs/internal/metadata/generated_metrics.go +++ b/receiver/k8sclusterreceiver/internal/jobs/internal/metadata/generated_metrics.go @@ -262,10 +262,8 @@ func newMetricK8sJobSuccessfulPods(cfg MetricConfig) metricK8sJobSuccessfulPods type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricK8sJobActivePods metricK8sJobActivePods metricK8sJobDesiredSuccessfulPods metricK8sJobDesiredSuccessfulPods metricK8sJobFailedPods metricK8sJobFailedPods @@ -288,7 +286,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricK8sJobActivePods: newMetricK8sJobActivePods(mbc.Metrics.K8sJobActivePods), metricK8sJobDesiredSuccessfulPods: newMetricK8sJobDesiredSuccessfulPods(mbc.Metrics.K8sJobDesiredSuccessfulPods), metricK8sJobFailedPods: newMetricK8sJobFailedPods(mbc.Metrics.K8sJobFailedPods), @@ -306,54 +303,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithK8sJobName sets provided value as "k8s.job.name" attribute for current resource. -func WithK8sJobName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sJobName.Enabled { - rm.Resource().Attributes().PutStr("k8s.job.name", val) - } - } -} - -// WithK8sJobUID sets provided value as "k8s.job.uid" attribute for current resource. -func WithK8sJobUID(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sJobUID.Enabled { - rm.Resource().Attributes().PutStr("k8s.job.uid", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithK8sNamespaceName sets provided value as "k8s.namespace.name" attribute for current resource. -func WithK8sNamespaceName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sNamespaceName.Enabled { - rm.Resource().Attributes().PutStr("k8s.namespace.name", val) - } - } -} - -// WithOpencensusResourcetype sets provided value as "opencensus.resourcetype" attribute for current resource. -func WithOpencensusResourcetype(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.OpencensusResourcetype.Enabled { - rm.Resource().Attributes().PutStr("opencensus.resourcetype", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -378,7 +344,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() rm.SetSchemaUrl(conventions.SchemaURL) - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/k8sclusterreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -390,7 +355,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricK8sJobSuccessfulPods.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/k8sclusterreceiver/internal/jobs/internal/metadata/generated_metrics_test.go b/receiver/k8sclusterreceiver/internal/jobs/internal/metadata/generated_metrics_test.go index 58975c9bc1e7..f486c3cbe634 100644 --- a/receiver/k8sclusterreceiver/internal/jobs/internal/metadata/generated_metrics_test.go +++ b/receiver/k8sclusterreceiver/internal/jobs/internal/metadata/generated_metrics_test.go @@ -74,7 +74,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordK8sJobSuccessfulPodsDataPoint(ts, 1) - metrics := mb.Emit(WithK8sJobName("k8s.job.name-val"), WithK8sJobUID("k8s.job.uid-val"), WithK8sNamespaceName("k8s.namespace.name-val"), WithOpencensusResourcetype("opencensus.resourcetype-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -83,39 +85,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("k8s.job.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sJobName.Enabled, ok) - if mb.resourceAttributesConfig.K8sJobName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.job.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.job.uid") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sJobUID.Enabled, ok) - if mb.resourceAttributesConfig.K8sJobUID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.job.uid-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.namespace.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sNamespaceName.Enabled, ok) - if mb.resourceAttributesConfig.K8sNamespaceName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.namespace.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("opencensus.resourcetype") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.OpencensusResourcetype.Enabled, ok) - if mb.resourceAttributesConfig.OpencensusResourcetype.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "opencensus.resourcetype-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 4) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/k8sclusterreceiver/internal/jobs/internal/metadata/generated_resource.go b/receiver/k8sclusterreceiver/internal/jobs/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..407f18ae0fcb --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/jobs/internal/metadata/generated_resource.go @@ -0,0 +1,57 @@ +// 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(), + } +} + +// SetK8sJobName sets provided value as "k8s.job.name" attribute. +func (rb *ResourceBuilder) SetK8sJobName(val string) { + if rb.config.K8sJobName.Enabled { + rb.res.Attributes().PutStr("k8s.job.name", val) + } +} + +// SetK8sJobUID sets provided value as "k8s.job.uid" attribute. +func (rb *ResourceBuilder) SetK8sJobUID(val string) { + if rb.config.K8sJobUID.Enabled { + rb.res.Attributes().PutStr("k8s.job.uid", val) + } +} + +// SetK8sNamespaceName sets provided value as "k8s.namespace.name" attribute. +func (rb *ResourceBuilder) SetK8sNamespaceName(val string) { + if rb.config.K8sNamespaceName.Enabled { + rb.res.Attributes().PutStr("k8s.namespace.name", val) + } +} + +// SetOpencensusResourcetype sets provided value as "opencensus.resourcetype" attribute. +func (rb *ResourceBuilder) SetOpencensusResourcetype(val string) { + if rb.config.OpencensusResourcetype.Enabled { + rb.res.Attributes().PutStr("opencensus.resourcetype", 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/receiver/k8sclusterreceiver/internal/jobs/internal/metadata/generated_resource_test.go b/receiver/k8sclusterreceiver/internal/jobs/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..1e539b554ea3 --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/jobs/internal/metadata/generated_resource_test.go @@ -0,0 +1,58 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetK8sJobName("k8s.job.name-val") + rb.SetK8sJobUID("k8s.job.uid-val") + rb.SetK8sNamespaceName("k8s.namespace.name-val") + rb.SetOpencensusResourcetype("opencensus.resourcetype-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 4, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 4, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("k8s.job.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.job.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.job.uid") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.job.uid-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.namespace.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.namespace.name-val", val.Str()) + } + val, ok = res.Attributes().Get("opencensus.resourcetype") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "opencensus.resourcetype-val", val.Str()) + } + }) + } +} diff --git a/receiver/k8sclusterreceiver/internal/jobs/jobs.go b/receiver/k8sclusterreceiver/internal/jobs/jobs.go index 992d402b9961..245c0b99fed7 100644 --- a/receiver/k8sclusterreceiver/internal/jobs/jobs.go +++ b/receiver/k8sclusterreceiver/internal/jobs/jobs.go @@ -32,9 +32,12 @@ func GetMetrics(set receiver.CreateSettings, j *batchv1.Job) pmetric.Metrics { mbphase.RecordK8sJobMaxParallelPodsDataPoint(ts, int64(*j.Spec.Parallelism)) } - metrics := mbphase.Emit(imetadataphase.WithK8sNamespaceName(j.Namespace), imetadataphase.WithK8sJobName(j.Name), imetadataphase.WithK8sJobUID(string(j.UID)), imetadataphase.WithOpencensusResourcetype("k8s")) - - return metrics + rb := imetadataphase.NewResourceBuilder(imetadataphase.DefaultResourceAttributesConfig()) + rb.SetK8sNamespaceName(j.Namespace) + rb.SetK8sJobName(j.Name) + rb.SetK8sJobUID(string(j.UID)) + rb.SetOpencensusResourcetype("k8s") + return mbphase.Emit(imetadataphase.WithResource(rb.Emit())) } // Transform transforms the job to remove the fields that we don't use to reduce RAM utilization. diff --git a/receiver/k8sclusterreceiver/internal/namespace/internal/metadata/generated_config_test.go b/receiver/k8sclusterreceiver/internal/namespace/internal/metadata/generated_config_test.go index 46a3b57d9192..f665a3b6618a 100644 --- a/receiver/k8sclusterreceiver/internal/namespace/internal/metadata/generated_config_test.go +++ b/receiver/k8sclusterreceiver/internal/namespace/internal/metadata/generated_config_test.go @@ -68,3 +68,51 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + K8sNamespaceName: ResourceAttributeConfig{Enabled: true}, + K8sNamespaceUID: ResourceAttributeConfig{Enabled: true}, + OpencensusResourcetype: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + K8sNamespaceName: ResourceAttributeConfig{Enabled: false}, + K8sNamespaceUID: ResourceAttributeConfig{Enabled: false}, + OpencensusResourcetype: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/k8sclusterreceiver/internal/namespace/internal/metadata/generated_metrics.go b/receiver/k8sclusterreceiver/internal/namespace/internal/metadata/generated_metrics.go index bc691162ce3a..5ccd519577ae 100644 --- a/receiver/k8sclusterreceiver/internal/namespace/internal/metadata/generated_metrics.go +++ b/receiver/k8sclusterreceiver/internal/namespace/internal/metadata/generated_metrics.go @@ -64,13 +64,11 @@ func newMetricK8sNamespacePhase(cfg MetricConfig) metricK8sNamespacePhase { // MetricsBuilder provides an interface for scrapers to report metrics while taking care of all the transformations // required to produce metric representation defined in metadata and user config. type MetricsBuilder struct { - startTime pcommon.Timestamp // start time that will be applied to all recorded data points. - metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. - metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. - buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig - metricK8sNamespacePhase metricK8sNamespacePhase + startTime pcommon.Timestamp // start time that will be applied to all recorded data points. + metricsCapacity int // maximum observed number of metrics per resource. + metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. + buildInfo component.BuildInfo // contains version information + metricK8sNamespacePhase metricK8sNamespacePhase } // metricBuilderOption applies changes to default metrics builder. @@ -85,11 +83,10 @@ func WithStartTime(startTime pcommon.Timestamp) metricBuilderOption { func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSettings, options ...metricBuilderOption) *MetricsBuilder { mb := &MetricsBuilder{ - startTime: pcommon.NewTimestampFromTime(time.Now()), - metricsBuffer: pmetric.NewMetrics(), - buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, - metricK8sNamespacePhase: newMetricK8sNamespacePhase(mbc.Metrics.K8sNamespacePhase), + startTime: pcommon.NewTimestampFromTime(time.Now()), + metricsBuffer: pmetric.NewMetrics(), + buildInfo: settings.BuildInfo, + metricK8sNamespacePhase: newMetricK8sNamespacePhase(mbc.Metrics.K8sNamespacePhase), } for _, op := range options { op(mb) @@ -102,45 +99,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithK8sNamespaceName sets provided value as "k8s.namespace.name" attribute for current resource. -func WithK8sNamespaceName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sNamespaceName.Enabled { - rm.Resource().Attributes().PutStr("k8s.namespace.name", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithK8sNamespaceUID sets provided value as "k8s.namespace.uid" attribute for current resource. -func WithK8sNamespaceUID(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sNamespaceUID.Enabled { - rm.Resource().Attributes().PutStr("k8s.namespace.uid", val) - } - } -} - -// WithOpencensusResourcetype sets provided value as "opencensus.resourcetype" attribute for current resource. -func WithOpencensusResourcetype(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.OpencensusResourcetype.Enabled { - rm.Resource().Attributes().PutStr("opencensus.resourcetype", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -165,7 +140,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() rm.SetSchemaUrl(conventions.SchemaURL) - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/k8sclusterreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -173,7 +147,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricK8sNamespacePhase.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/k8sclusterreceiver/internal/namespace/internal/metadata/generated_metrics_test.go b/receiver/k8sclusterreceiver/internal/namespace/internal/metadata/generated_metrics_test.go index 05412a1c4cd0..dd6dca883a69 100644 --- a/receiver/k8sclusterreceiver/internal/namespace/internal/metadata/generated_metrics_test.go +++ b/receiver/k8sclusterreceiver/internal/namespace/internal/metadata/generated_metrics_test.go @@ -58,7 +58,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordK8sNamespacePhaseDataPoint(ts, 1) - metrics := mb.Emit(WithK8sNamespaceName("k8s.namespace.name-val"), WithK8sNamespaceUID("k8s.namespace.uid-val"), WithOpencensusResourcetype("opencensus.resourcetype-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -67,32 +69,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("k8s.namespace.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sNamespaceName.Enabled, ok) - if mb.resourceAttributesConfig.K8sNamespaceName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.namespace.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.namespace.uid") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sNamespaceUID.Enabled, ok) - if mb.resourceAttributesConfig.K8sNamespaceUID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.namespace.uid-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("opencensus.resourcetype") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.OpencensusResourcetype.Enabled, ok) - if mb.resourceAttributesConfig.OpencensusResourcetype.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "opencensus.resourcetype-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 3) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/k8sclusterreceiver/internal/namespace/internal/metadata/generated_resource.go b/receiver/k8sclusterreceiver/internal/namespace/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..e09764301450 --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/namespace/internal/metadata/generated_resource.go @@ -0,0 +1,50 @@ +// 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(), + } +} + +// SetK8sNamespaceName sets provided value as "k8s.namespace.name" attribute. +func (rb *ResourceBuilder) SetK8sNamespaceName(val string) { + if rb.config.K8sNamespaceName.Enabled { + rb.res.Attributes().PutStr("k8s.namespace.name", val) + } +} + +// SetK8sNamespaceUID sets provided value as "k8s.namespace.uid" attribute. +func (rb *ResourceBuilder) SetK8sNamespaceUID(val string) { + if rb.config.K8sNamespaceUID.Enabled { + rb.res.Attributes().PutStr("k8s.namespace.uid", val) + } +} + +// SetOpencensusResourcetype sets provided value as "opencensus.resourcetype" attribute. +func (rb *ResourceBuilder) SetOpencensusResourcetype(val string) { + if rb.config.OpencensusResourcetype.Enabled { + rb.res.Attributes().PutStr("opencensus.resourcetype", 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/receiver/k8sclusterreceiver/internal/namespace/internal/metadata/generated_resource_test.go b/receiver/k8sclusterreceiver/internal/namespace/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..142f35f186b7 --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/namespace/internal/metadata/generated_resource_test.go @@ -0,0 +1,52 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetK8sNamespaceName("k8s.namespace.name-val") + rb.SetK8sNamespaceUID("k8s.namespace.uid-val") + rb.SetOpencensusResourcetype("opencensus.resourcetype-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 3, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 3, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("k8s.namespace.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.namespace.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.namespace.uid") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.namespace.uid-val", val.Str()) + } + val, ok = res.Attributes().Get("opencensus.resourcetype") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "opencensus.resourcetype-val", val.Str()) + } + }) + } +} diff --git a/receiver/k8sclusterreceiver/internal/namespace/namespaces.go b/receiver/k8sclusterreceiver/internal/namespace/namespaces.go index fd7b22b18ee8..27c33ea58dcb 100644 --- a/receiver/k8sclusterreceiver/internal/namespace/namespaces.go +++ b/receiver/k8sclusterreceiver/internal/namespace/namespaces.go @@ -18,7 +18,11 @@ func GetMetrics(set receiver.CreateSettings, ns *corev1.Namespace) pmetric.Metri mb := imetadata.NewMetricsBuilder(imetadata.DefaultMetricsBuilderConfig(), set) ts := pcommon.NewTimestampFromTime(time.Now()) mb.RecordK8sNamespacePhaseDataPoint(ts, int64(namespacePhaseValues[ns.Status.Phase])) - return mb.Emit(imetadata.WithK8sNamespaceUID(string(ns.UID)), imetadata.WithK8sNamespaceName(ns.Name), imetadata.WithOpencensusResourcetype("k8s")) + rb := imetadata.NewResourceBuilder(imetadata.DefaultResourceAttributesConfig()) + rb.SetK8sNamespaceUID(string(ns.UID)) + rb.SetK8sNamespaceName(ns.Name) + rb.SetOpencensusResourcetype("k8s") + return mb.Emit(imetadata.WithResource(rb.Emit())) } var namespacePhaseValues = map[corev1.NamespacePhase]int32{ diff --git a/receiver/k8sclusterreceiver/internal/node/internal/metadata/generated_config_test.go b/receiver/k8sclusterreceiver/internal/node/internal/metadata/generated_config_test.go index 82498096bea4..961e41ee24e1 100644 --- a/receiver/k8sclusterreceiver/internal/node/internal/metadata/generated_config_test.go +++ b/receiver/k8sclusterreceiver/internal/node/internal/metadata/generated_config_test.go @@ -86,3 +86,51 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + K8sNodeName: ResourceAttributeConfig{Enabled: true}, + K8sNodeUID: ResourceAttributeConfig{Enabled: true}, + OpencensusResourcetype: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + K8sNodeName: ResourceAttributeConfig{Enabled: false}, + K8sNodeUID: ResourceAttributeConfig{Enabled: false}, + OpencensusResourcetype: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/k8sclusterreceiver/internal/node/internal/metadata/generated_metrics.go b/receiver/k8sclusterreceiver/internal/node/internal/metadata/generated_metrics.go index f49ff24ea46c..2a3dff57eaf8 100644 --- a/receiver/k8sclusterreceiver/internal/node/internal/metadata/generated_metrics.go +++ b/receiver/k8sclusterreceiver/internal/node/internal/metadata/generated_metrics.go @@ -507,10 +507,8 @@ func newMetricK8sNodeConditionReady(cfg MetricConfig) metricK8sNodeConditionRead type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricK8sNodeAllocatableCPU metricK8sNodeAllocatableCPU metricK8sNodeAllocatableEphemeralStorage metricK8sNodeAllocatableEphemeralStorage metricK8sNodeAllocatableMemory metricK8sNodeAllocatableMemory @@ -538,7 +536,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricK8sNodeAllocatableCPU: newMetricK8sNodeAllocatableCPU(mbc.Metrics.K8sNodeAllocatableCPU), metricK8sNodeAllocatableEphemeralStorage: newMetricK8sNodeAllocatableEphemeralStorage(mbc.Metrics.K8sNodeAllocatableEphemeralStorage), metricK8sNodeAllocatableMemory: newMetricK8sNodeAllocatableMemory(mbc.Metrics.K8sNodeAllocatableMemory), @@ -561,45 +558,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithK8sNodeName sets provided value as "k8s.node.name" attribute for current resource. -func WithK8sNodeName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sNodeName.Enabled { - rm.Resource().Attributes().PutStr("k8s.node.name", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithK8sNodeUID sets provided value as "k8s.node.uid" attribute for current resource. -func WithK8sNodeUID(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sNodeUID.Enabled { - rm.Resource().Attributes().PutStr("k8s.node.uid", val) - } - } -} - -// WithOpencensusResourcetype sets provided value as "opencensus.resourcetype" attribute for current resource. -func WithOpencensusResourcetype(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.OpencensusResourcetype.Enabled { - rm.Resource().Attributes().PutStr("opencensus.resourcetype", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -624,7 +599,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() rm.SetSchemaUrl(conventions.SchemaURL) - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/k8sclusterreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -641,7 +615,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricK8sNodeConditionReady.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/k8sclusterreceiver/internal/node/internal/metadata/generated_metrics_test.go b/receiver/k8sclusterreceiver/internal/node/internal/metadata/generated_metrics_test.go index e05b9022a088..25c0f6b0e2f7 100644 --- a/receiver/k8sclusterreceiver/internal/node/internal/metadata/generated_metrics_test.go +++ b/receiver/k8sclusterreceiver/internal/node/internal/metadata/generated_metrics_test.go @@ -94,7 +94,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordK8sNodeConditionReadyDataPoint(ts, 1) - metrics := mb.Emit(WithK8sNodeName("k8s.node.name-val"), WithK8sNodeUID("k8s.node.uid-val"), WithOpencensusResourcetype("opencensus.resourcetype-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -103,32 +105,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("k8s.node.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sNodeName.Enabled, ok) - if mb.resourceAttributesConfig.K8sNodeName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.node.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.node.uid") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sNodeUID.Enabled, ok) - if mb.resourceAttributesConfig.K8sNodeUID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.node.uid-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("opencensus.resourcetype") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.OpencensusResourcetype.Enabled, ok) - if mb.resourceAttributesConfig.OpencensusResourcetype.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "opencensus.resourcetype-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 3) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/k8sclusterreceiver/internal/node/internal/metadata/generated_resource.go b/receiver/k8sclusterreceiver/internal/node/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..8bd52fa6e3ca --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/node/internal/metadata/generated_resource.go @@ -0,0 +1,50 @@ +// 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(), + } +} + +// SetK8sNodeName sets provided value as "k8s.node.name" attribute. +func (rb *ResourceBuilder) SetK8sNodeName(val string) { + if rb.config.K8sNodeName.Enabled { + rb.res.Attributes().PutStr("k8s.node.name", val) + } +} + +// SetK8sNodeUID sets provided value as "k8s.node.uid" attribute. +func (rb *ResourceBuilder) SetK8sNodeUID(val string) { + if rb.config.K8sNodeUID.Enabled { + rb.res.Attributes().PutStr("k8s.node.uid", val) + } +} + +// SetOpencensusResourcetype sets provided value as "opencensus.resourcetype" attribute. +func (rb *ResourceBuilder) SetOpencensusResourcetype(val string) { + if rb.config.OpencensusResourcetype.Enabled { + rb.res.Attributes().PutStr("opencensus.resourcetype", 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/receiver/k8sclusterreceiver/internal/node/internal/metadata/generated_resource_test.go b/receiver/k8sclusterreceiver/internal/node/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..d6f736675a24 --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/node/internal/metadata/generated_resource_test.go @@ -0,0 +1,52 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetK8sNodeName("k8s.node.name-val") + rb.SetK8sNodeUID("k8s.node.uid-val") + rb.SetOpencensusResourcetype("opencensus.resourcetype-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 3, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 3, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("k8s.node.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.node.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.node.uid") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.node.uid-val", val.Str()) + } + val, ok = res.Attributes().Get("opencensus.resourcetype") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "opencensus.resourcetype-val", val.Str()) + } + }) + } +} diff --git a/receiver/k8sclusterreceiver/internal/node/nodes.go b/receiver/k8sclusterreceiver/internal/node/nodes.go index ed3717b93f46..308024e2250b 100644 --- a/receiver/k8sclusterreceiver/internal/node/nodes.go +++ b/receiver/k8sclusterreceiver/internal/node/nodes.go @@ -104,7 +104,11 @@ func GetMetrics(set receiver.CreateSettings, node *corev1.Node, nodeConditionTyp dp.SetTimestamp(ts) } } - m := mb.Emit(imetadata.WithK8sNodeUID(string(node.UID)), imetadata.WithK8sNodeName(node.Name), imetadata.WithOpencensusResourcetype("k8s")) + rb := imetadata.NewResourceBuilder(imetadata.DefaultResourceAttributesConfig()) + rb.SetK8sNodeUID(string(node.UID)) + rb.SetK8sNodeName(node.Name) + rb.SetOpencensusResourcetype("k8s") + m := mb.Emit(imetadata.WithResource(rb.Emit())) customMetrics.MoveAndAppendTo(m.ResourceMetrics().At(0).ScopeMetrics().At(0).Metrics()) return m diff --git a/receiver/k8sclusterreceiver/internal/pod/internal/metadata/generated_config_test.go b/receiver/k8sclusterreceiver/internal/pod/internal/metadata/generated_config_test.go index e8ebeec5b9f8..6191933b0d6b 100644 --- a/receiver/k8sclusterreceiver/internal/pod/internal/metadata/generated_config_test.go +++ b/receiver/k8sclusterreceiver/internal/pod/internal/metadata/generated_config_test.go @@ -72,3 +72,55 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + K8sNamespaceName: ResourceAttributeConfig{Enabled: true}, + K8sNodeName: ResourceAttributeConfig{Enabled: true}, + K8sPodName: ResourceAttributeConfig{Enabled: true}, + K8sPodUID: ResourceAttributeConfig{Enabled: true}, + OpencensusResourcetype: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + K8sNamespaceName: ResourceAttributeConfig{Enabled: false}, + K8sNodeName: ResourceAttributeConfig{Enabled: false}, + K8sPodName: ResourceAttributeConfig{Enabled: false}, + K8sPodUID: ResourceAttributeConfig{Enabled: false}, + OpencensusResourcetype: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/k8sclusterreceiver/internal/pod/internal/metadata/generated_metrics.go b/receiver/k8sclusterreceiver/internal/pod/internal/metadata/generated_metrics.go index 28137ef4183f..f3669c0af86b 100644 --- a/receiver/k8sclusterreceiver/internal/pod/internal/metadata/generated_metrics.go +++ b/receiver/k8sclusterreceiver/internal/pod/internal/metadata/generated_metrics.go @@ -64,13 +64,11 @@ func newMetricK8sPodPhase(cfg MetricConfig) metricK8sPodPhase { // MetricsBuilder provides an interface for scrapers to report metrics while taking care of all the transformations // required to produce metric representation defined in metadata and user config. type MetricsBuilder struct { - startTime pcommon.Timestamp // start time that will be applied to all recorded data points. - metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. - metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. - buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig - metricK8sPodPhase metricK8sPodPhase + startTime pcommon.Timestamp // start time that will be applied to all recorded data points. + metricsCapacity int // maximum observed number of metrics per resource. + metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. + buildInfo component.BuildInfo // contains version information + metricK8sPodPhase metricK8sPodPhase } // metricBuilderOption applies changes to default metrics builder. @@ -85,11 +83,10 @@ func WithStartTime(startTime pcommon.Timestamp) metricBuilderOption { func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSettings, options ...metricBuilderOption) *MetricsBuilder { mb := &MetricsBuilder{ - startTime: pcommon.NewTimestampFromTime(time.Now()), - metricsBuffer: pmetric.NewMetrics(), - buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, - metricK8sPodPhase: newMetricK8sPodPhase(mbc.Metrics.K8sPodPhase), + startTime: pcommon.NewTimestampFromTime(time.Now()), + metricsBuffer: pmetric.NewMetrics(), + buildInfo: settings.BuildInfo, + metricK8sPodPhase: newMetricK8sPodPhase(mbc.Metrics.K8sPodPhase), } for _, op := range options { op(mb) @@ -102,63 +99,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithK8sNamespaceName sets provided value as "k8s.namespace.name" attribute for current resource. -func WithK8sNamespaceName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sNamespaceName.Enabled { - rm.Resource().Attributes().PutStr("k8s.namespace.name", val) - } - } -} - -// WithK8sNodeName sets provided value as "k8s.node.name" attribute for current resource. -func WithK8sNodeName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sNodeName.Enabled { - rm.Resource().Attributes().PutStr("k8s.node.name", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithK8sPodName sets provided value as "k8s.pod.name" attribute for current resource. -func WithK8sPodName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sPodName.Enabled { - rm.Resource().Attributes().PutStr("k8s.pod.name", val) - } - } -} - -// WithK8sPodUID sets provided value as "k8s.pod.uid" attribute for current resource. -func WithK8sPodUID(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sPodUID.Enabled { - rm.Resource().Attributes().PutStr("k8s.pod.uid", val) - } - } -} - -// WithOpencensusResourcetype sets provided value as "opencensus.resourcetype" attribute for current resource. -func WithOpencensusResourcetype(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.OpencensusResourcetype.Enabled { - rm.Resource().Attributes().PutStr("opencensus.resourcetype", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -183,7 +140,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() rm.SetSchemaUrl(conventions.SchemaURL) - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/k8sclusterreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -191,7 +147,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricK8sPodPhase.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/k8sclusterreceiver/internal/pod/internal/metadata/generated_metrics_test.go b/receiver/k8sclusterreceiver/internal/pod/internal/metadata/generated_metrics_test.go index 82e0d0cf2b7a..1e5dc4ef133e 100644 --- a/receiver/k8sclusterreceiver/internal/pod/internal/metadata/generated_metrics_test.go +++ b/receiver/k8sclusterreceiver/internal/pod/internal/metadata/generated_metrics_test.go @@ -58,7 +58,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordK8sPodPhaseDataPoint(ts, 1) - metrics := mb.Emit(WithK8sNamespaceName("k8s.namespace.name-val"), WithK8sNodeName("k8s.node.name-val"), WithK8sPodName("k8s.pod.name-val"), WithK8sPodUID("k8s.pod.uid-val"), WithOpencensusResourcetype("opencensus.resourcetype-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -67,46 +69,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("k8s.namespace.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sNamespaceName.Enabled, ok) - if mb.resourceAttributesConfig.K8sNamespaceName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.namespace.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.node.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sNodeName.Enabled, ok) - if mb.resourceAttributesConfig.K8sNodeName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.node.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.pod.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sPodName.Enabled, ok) - if mb.resourceAttributesConfig.K8sPodName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.pod.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.pod.uid") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sPodUID.Enabled, ok) - if mb.resourceAttributesConfig.K8sPodUID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.pod.uid-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("opencensus.resourcetype") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.OpencensusResourcetype.Enabled, ok) - if mb.resourceAttributesConfig.OpencensusResourcetype.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "opencensus.resourcetype-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 5) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/k8sclusterreceiver/internal/pod/internal/metadata/generated_resource.go b/receiver/k8sclusterreceiver/internal/pod/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..9b0feaf5d6a3 --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/pod/internal/metadata/generated_resource.go @@ -0,0 +1,64 @@ +// 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(), + } +} + +// SetK8sNamespaceName sets provided value as "k8s.namespace.name" attribute. +func (rb *ResourceBuilder) SetK8sNamespaceName(val string) { + if rb.config.K8sNamespaceName.Enabled { + rb.res.Attributes().PutStr("k8s.namespace.name", val) + } +} + +// SetK8sNodeName sets provided value as "k8s.node.name" attribute. +func (rb *ResourceBuilder) SetK8sNodeName(val string) { + if rb.config.K8sNodeName.Enabled { + rb.res.Attributes().PutStr("k8s.node.name", val) + } +} + +// SetK8sPodName sets provided value as "k8s.pod.name" attribute. +func (rb *ResourceBuilder) SetK8sPodName(val string) { + if rb.config.K8sPodName.Enabled { + rb.res.Attributes().PutStr("k8s.pod.name", val) + } +} + +// SetK8sPodUID sets provided value as "k8s.pod.uid" attribute. +func (rb *ResourceBuilder) SetK8sPodUID(val string) { + if rb.config.K8sPodUID.Enabled { + rb.res.Attributes().PutStr("k8s.pod.uid", val) + } +} + +// SetOpencensusResourcetype sets provided value as "opencensus.resourcetype" attribute. +func (rb *ResourceBuilder) SetOpencensusResourcetype(val string) { + if rb.config.OpencensusResourcetype.Enabled { + rb.res.Attributes().PutStr("opencensus.resourcetype", 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/receiver/k8sclusterreceiver/internal/pod/internal/metadata/generated_resource_test.go b/receiver/k8sclusterreceiver/internal/pod/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..7b23e77624d5 --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/pod/internal/metadata/generated_resource_test.go @@ -0,0 +1,64 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetK8sNamespaceName("k8s.namespace.name-val") + rb.SetK8sNodeName("k8s.node.name-val") + rb.SetK8sPodName("k8s.pod.name-val") + rb.SetK8sPodUID("k8s.pod.uid-val") + rb.SetOpencensusResourcetype("opencensus.resourcetype-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 5, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 5, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("k8s.namespace.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.namespace.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.node.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.node.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.pod.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.pod.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.pod.uid") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.pod.uid-val", val.Str()) + } + val, ok = res.Attributes().Get("opencensus.resourcetype") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "opencensus.resourcetype-val", val.Str()) + } + }) + } +} diff --git a/receiver/k8sclusterreceiver/internal/pod/pods.go b/receiver/k8sclusterreceiver/internal/pod/pods.go index 7cc186e02f29..1885cb28a1bc 100644 --- a/receiver/k8sclusterreceiver/internal/pod/pods.go +++ b/receiver/k8sclusterreceiver/internal/pod/pods.go @@ -75,7 +75,13 @@ func GetMetrics(set receiver.CreateSettings, pod *corev1.Pod) pmetric.Metrics { mbphase := imetadataphase.NewMetricsBuilder(imetadataphase.DefaultMetricsBuilderConfig(), set) ts := pcommon.NewTimestampFromTime(time.Now()) mbphase.RecordK8sPodPhaseDataPoint(ts, int64(phaseToInt(pod.Status.Phase))) - metrics := mbphase.Emit(imetadataphase.WithK8sNamespaceName(pod.Namespace), imetadataphase.WithK8sNodeName(pod.Spec.NodeName), imetadataphase.WithK8sPodName(pod.Name), imetadataphase.WithK8sPodUID(string(pod.UID)), imetadataphase.WithOpencensusResourcetype("k8s")) + rb := imetadataphase.NewResourceBuilder(imetadataphase.DefaultResourceAttributesConfig()) + rb.SetK8sNamespaceName(pod.Namespace) + rb.SetK8sNodeName(pod.Spec.NodeName) + rb.SetK8sPodName(pod.Name) + rb.SetK8sPodUID(string(pod.UID)) + rb.SetOpencensusResourcetype("k8s") + metrics := mbphase.Emit(imetadataphase.WithResource(rb.Emit())) for _, c := range pod.Spec.Containers { specMetrics := container.GetSpecMetrics(set, c, pod) diff --git a/receiver/k8sclusterreceiver/internal/replicaset/internal/metadata/generated_config_test.go b/receiver/k8sclusterreceiver/internal/replicaset/internal/metadata/generated_config_test.go index 5b036ebe52b4..d7062096fd11 100644 --- a/receiver/k8sclusterreceiver/internal/replicaset/internal/metadata/generated_config_test.go +++ b/receiver/k8sclusterreceiver/internal/replicaset/internal/metadata/generated_config_test.go @@ -72,3 +72,53 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + K8sNamespaceName: ResourceAttributeConfig{Enabled: true}, + K8sReplicasetName: ResourceAttributeConfig{Enabled: true}, + K8sReplicasetUID: ResourceAttributeConfig{Enabled: true}, + OpencensusResourcetype: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + K8sNamespaceName: ResourceAttributeConfig{Enabled: false}, + K8sReplicasetName: ResourceAttributeConfig{Enabled: false}, + K8sReplicasetUID: ResourceAttributeConfig{Enabled: false}, + OpencensusResourcetype: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/k8sclusterreceiver/internal/replicaset/internal/metadata/generated_metrics.go b/receiver/k8sclusterreceiver/internal/replicaset/internal/metadata/generated_metrics.go index 1f658ce87a3c..ab5c17472ba3 100644 --- a/receiver/k8sclusterreceiver/internal/replicaset/internal/metadata/generated_metrics.go +++ b/receiver/k8sclusterreceiver/internal/replicaset/internal/metadata/generated_metrics.go @@ -115,10 +115,8 @@ func newMetricK8sReplicasetDesired(cfg MetricConfig) metricK8sReplicasetDesired type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricK8sReplicasetAvailable metricK8sReplicasetAvailable metricK8sReplicasetDesired metricK8sReplicasetDesired } @@ -138,7 +136,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricK8sReplicasetAvailable: newMetricK8sReplicasetAvailable(mbc.Metrics.K8sReplicasetAvailable), metricK8sReplicasetDesired: newMetricK8sReplicasetDesired(mbc.Metrics.K8sReplicasetDesired), } @@ -153,54 +150,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithK8sNamespaceName sets provided value as "k8s.namespace.name" attribute for current resource. -func WithK8sNamespaceName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sNamespaceName.Enabled { - rm.Resource().Attributes().PutStr("k8s.namespace.name", val) - } - } -} - -// WithK8sReplicasetName sets provided value as "k8s.replicaset.name" attribute for current resource. -func WithK8sReplicasetName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sReplicasetName.Enabled { - rm.Resource().Attributes().PutStr("k8s.replicaset.name", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithK8sReplicasetUID sets provided value as "k8s.replicaset.uid" attribute for current resource. -func WithK8sReplicasetUID(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sReplicasetUID.Enabled { - rm.Resource().Attributes().PutStr("k8s.replicaset.uid", val) - } - } -} - -// WithOpencensusResourcetype sets provided value as "opencensus.resourcetype" attribute for current resource. -func WithOpencensusResourcetype(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.OpencensusResourcetype.Enabled { - rm.Resource().Attributes().PutStr("opencensus.resourcetype", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -225,7 +191,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() rm.SetSchemaUrl(conventions.SchemaURL) - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/k8sclusterreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -234,7 +199,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricK8sReplicasetDesired.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/k8sclusterreceiver/internal/replicaset/internal/metadata/generated_metrics_test.go b/receiver/k8sclusterreceiver/internal/replicaset/internal/metadata/generated_metrics_test.go index 92f19437f5e4..3adc82e9c2f4 100644 --- a/receiver/k8sclusterreceiver/internal/replicaset/internal/metadata/generated_metrics_test.go +++ b/receiver/k8sclusterreceiver/internal/replicaset/internal/metadata/generated_metrics_test.go @@ -62,7 +62,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordK8sReplicasetDesiredDataPoint(ts, 1) - metrics := mb.Emit(WithK8sNamespaceName("k8s.namespace.name-val"), WithK8sReplicasetName("k8s.replicaset.name-val"), WithK8sReplicasetUID("k8s.replicaset.uid-val"), WithOpencensusResourcetype("opencensus.resourcetype-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -71,39 +73,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("k8s.namespace.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sNamespaceName.Enabled, ok) - if mb.resourceAttributesConfig.K8sNamespaceName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.namespace.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.replicaset.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sReplicasetName.Enabled, ok) - if mb.resourceAttributesConfig.K8sReplicasetName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.replicaset.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.replicaset.uid") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sReplicasetUID.Enabled, ok) - if mb.resourceAttributesConfig.K8sReplicasetUID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.replicaset.uid-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("opencensus.resourcetype") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.OpencensusResourcetype.Enabled, ok) - if mb.resourceAttributesConfig.OpencensusResourcetype.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "opencensus.resourcetype-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 4) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/k8sclusterreceiver/internal/replicaset/internal/metadata/generated_resource.go b/receiver/k8sclusterreceiver/internal/replicaset/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..a08e77ee3d0e --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/replicaset/internal/metadata/generated_resource.go @@ -0,0 +1,57 @@ +// 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(), + } +} + +// SetK8sNamespaceName sets provided value as "k8s.namespace.name" attribute. +func (rb *ResourceBuilder) SetK8sNamespaceName(val string) { + if rb.config.K8sNamespaceName.Enabled { + rb.res.Attributes().PutStr("k8s.namespace.name", val) + } +} + +// SetK8sReplicasetName sets provided value as "k8s.replicaset.name" attribute. +func (rb *ResourceBuilder) SetK8sReplicasetName(val string) { + if rb.config.K8sReplicasetName.Enabled { + rb.res.Attributes().PutStr("k8s.replicaset.name", val) + } +} + +// SetK8sReplicasetUID sets provided value as "k8s.replicaset.uid" attribute. +func (rb *ResourceBuilder) SetK8sReplicasetUID(val string) { + if rb.config.K8sReplicasetUID.Enabled { + rb.res.Attributes().PutStr("k8s.replicaset.uid", val) + } +} + +// SetOpencensusResourcetype sets provided value as "opencensus.resourcetype" attribute. +func (rb *ResourceBuilder) SetOpencensusResourcetype(val string) { + if rb.config.OpencensusResourcetype.Enabled { + rb.res.Attributes().PutStr("opencensus.resourcetype", 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/receiver/k8sclusterreceiver/internal/replicaset/internal/metadata/generated_resource_test.go b/receiver/k8sclusterreceiver/internal/replicaset/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..4fae1b9b6620 --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/replicaset/internal/metadata/generated_resource_test.go @@ -0,0 +1,58 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetK8sNamespaceName("k8s.namespace.name-val") + rb.SetK8sReplicasetName("k8s.replicaset.name-val") + rb.SetK8sReplicasetUID("k8s.replicaset.uid-val") + rb.SetOpencensusResourcetype("opencensus.resourcetype-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 4, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 4, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("k8s.namespace.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.namespace.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.replicaset.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.replicaset.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.replicaset.uid") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.replicaset.uid-val", val.Str()) + } + val, ok = res.Attributes().Get("opencensus.resourcetype") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "opencensus.resourcetype-val", val.Str()) + } + }) + } +} diff --git a/receiver/k8sclusterreceiver/internal/replicaset/replicasets.go b/receiver/k8sclusterreceiver/internal/replicaset/replicasets.go index 968e9df9a9eb..9113abebe740 100644 --- a/receiver/k8sclusterreceiver/internal/replicaset/replicasets.go +++ b/receiver/k8sclusterreceiver/internal/replicaset/replicasets.go @@ -40,9 +40,12 @@ func GetMetrics(set receiver.CreateSettings, rs *appsv1.ReplicaSet) pmetric.Metr mbphase.RecordK8sReplicasetAvailableDataPoint(ts, int64(rs.Status.AvailableReplicas)) } - metrics := mbphase.Emit(imetadataphase.WithK8sNamespaceName(rs.Namespace), imetadataphase.WithK8sReplicasetName(rs.Name), imetadataphase.WithK8sReplicasetUID(string(rs.UID)), imetadataphase.WithOpencensusResourcetype("k8s")) - - return metrics + rb := imetadataphase.NewResourceBuilder(imetadataphase.DefaultResourceAttributesConfig()) + rb.SetK8sNamespaceName(rs.Namespace) + rb.SetK8sReplicasetName(rs.Name) + rb.SetK8sReplicasetUID(string(rs.UID)) + rb.SetOpencensusResourcetype("k8s") + return mbphase.Emit(imetadataphase.WithResource(rb.Emit())) } func GetMetadata(rs *appsv1.ReplicaSet) map[experimentalmetricmetadata.ResourceID]*metadata.KubernetesMetadata { diff --git a/receiver/k8sclusterreceiver/internal/replicationcontroller/internal/metadata/generated_config_test.go b/receiver/k8sclusterreceiver/internal/replicationcontroller/internal/metadata/generated_config_test.go index 416031768f16..5aba71c0ddb3 100644 --- a/receiver/k8sclusterreceiver/internal/replicationcontroller/internal/metadata/generated_config_test.go +++ b/receiver/k8sclusterreceiver/internal/replicationcontroller/internal/metadata/generated_config_test.go @@ -72,3 +72,53 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + K8sNamespaceName: ResourceAttributeConfig{Enabled: true}, + K8sReplicationcontrollerName: ResourceAttributeConfig{Enabled: true}, + K8sReplicationcontrollerUID: ResourceAttributeConfig{Enabled: true}, + OpencensusResourcetype: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + K8sNamespaceName: ResourceAttributeConfig{Enabled: false}, + K8sReplicationcontrollerName: ResourceAttributeConfig{Enabled: false}, + K8sReplicationcontrollerUID: ResourceAttributeConfig{Enabled: false}, + OpencensusResourcetype: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/k8sclusterreceiver/internal/replicationcontroller/internal/metadata/generated_metrics.go b/receiver/k8sclusterreceiver/internal/replicationcontroller/internal/metadata/generated_metrics.go index 6b29b21b3842..a658186ec643 100644 --- a/receiver/k8sclusterreceiver/internal/replicationcontroller/internal/metadata/generated_metrics.go +++ b/receiver/k8sclusterreceiver/internal/replicationcontroller/internal/metadata/generated_metrics.go @@ -115,10 +115,8 @@ func newMetricK8sReplicationControllerDesired(cfg MetricConfig) metricK8sReplica type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricK8sReplicationControllerAvailable metricK8sReplicationControllerAvailable metricK8sReplicationControllerDesired metricK8sReplicationControllerDesired } @@ -138,7 +136,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricK8sReplicationControllerAvailable: newMetricK8sReplicationControllerAvailable(mbc.Metrics.K8sReplicationControllerAvailable), metricK8sReplicationControllerDesired: newMetricK8sReplicationControllerDesired(mbc.Metrics.K8sReplicationControllerDesired), } @@ -153,54 +150,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithK8sNamespaceName sets provided value as "k8s.namespace.name" attribute for current resource. -func WithK8sNamespaceName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sNamespaceName.Enabled { - rm.Resource().Attributes().PutStr("k8s.namespace.name", val) - } - } -} - -// WithK8sReplicationcontrollerName sets provided value as "k8s.replicationcontroller.name" attribute for current resource. -func WithK8sReplicationcontrollerName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sReplicationcontrollerName.Enabled { - rm.Resource().Attributes().PutStr("k8s.replicationcontroller.name", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithK8sReplicationcontrollerUID sets provided value as "k8s.replicationcontroller.uid" attribute for current resource. -func WithK8sReplicationcontrollerUID(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sReplicationcontrollerUID.Enabled { - rm.Resource().Attributes().PutStr("k8s.replicationcontroller.uid", val) - } - } -} - -// WithOpencensusResourcetype sets provided value as "opencensus.resourcetype" attribute for current resource. -func WithOpencensusResourcetype(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.OpencensusResourcetype.Enabled { - rm.Resource().Attributes().PutStr("opencensus.resourcetype", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -225,7 +191,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() rm.SetSchemaUrl(conventions.SchemaURL) - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/k8sclusterreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -234,7 +199,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricK8sReplicationControllerDesired.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/k8sclusterreceiver/internal/replicationcontroller/internal/metadata/generated_metrics_test.go b/receiver/k8sclusterreceiver/internal/replicationcontroller/internal/metadata/generated_metrics_test.go index 358f79691bfb..98ce1fa0313f 100644 --- a/receiver/k8sclusterreceiver/internal/replicationcontroller/internal/metadata/generated_metrics_test.go +++ b/receiver/k8sclusterreceiver/internal/replicationcontroller/internal/metadata/generated_metrics_test.go @@ -62,7 +62,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordK8sReplicationControllerDesiredDataPoint(ts, 1) - metrics := mb.Emit(WithK8sNamespaceName("k8s.namespace.name-val"), WithK8sReplicationcontrollerName("k8s.replicationcontroller.name-val"), WithK8sReplicationcontrollerUID("k8s.replicationcontroller.uid-val"), WithOpencensusResourcetype("opencensus.resourcetype-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -71,39 +73,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("k8s.namespace.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sNamespaceName.Enabled, ok) - if mb.resourceAttributesConfig.K8sNamespaceName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.namespace.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.replicationcontroller.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sReplicationcontrollerName.Enabled, ok) - if mb.resourceAttributesConfig.K8sReplicationcontrollerName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.replicationcontroller.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.replicationcontroller.uid") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sReplicationcontrollerUID.Enabled, ok) - if mb.resourceAttributesConfig.K8sReplicationcontrollerUID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.replicationcontroller.uid-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("opencensus.resourcetype") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.OpencensusResourcetype.Enabled, ok) - if mb.resourceAttributesConfig.OpencensusResourcetype.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "opencensus.resourcetype-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 4) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/k8sclusterreceiver/internal/replicationcontroller/internal/metadata/generated_resource.go b/receiver/k8sclusterreceiver/internal/replicationcontroller/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..f3c2b7f418ee --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/replicationcontroller/internal/metadata/generated_resource.go @@ -0,0 +1,57 @@ +// 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(), + } +} + +// SetK8sNamespaceName sets provided value as "k8s.namespace.name" attribute. +func (rb *ResourceBuilder) SetK8sNamespaceName(val string) { + if rb.config.K8sNamespaceName.Enabled { + rb.res.Attributes().PutStr("k8s.namespace.name", val) + } +} + +// SetK8sReplicationcontrollerName sets provided value as "k8s.replicationcontroller.name" attribute. +func (rb *ResourceBuilder) SetK8sReplicationcontrollerName(val string) { + if rb.config.K8sReplicationcontrollerName.Enabled { + rb.res.Attributes().PutStr("k8s.replicationcontroller.name", val) + } +} + +// SetK8sReplicationcontrollerUID sets provided value as "k8s.replicationcontroller.uid" attribute. +func (rb *ResourceBuilder) SetK8sReplicationcontrollerUID(val string) { + if rb.config.K8sReplicationcontrollerUID.Enabled { + rb.res.Attributes().PutStr("k8s.replicationcontroller.uid", val) + } +} + +// SetOpencensusResourcetype sets provided value as "opencensus.resourcetype" attribute. +func (rb *ResourceBuilder) SetOpencensusResourcetype(val string) { + if rb.config.OpencensusResourcetype.Enabled { + rb.res.Attributes().PutStr("opencensus.resourcetype", 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/receiver/k8sclusterreceiver/internal/replicationcontroller/internal/metadata/generated_resource_test.go b/receiver/k8sclusterreceiver/internal/replicationcontroller/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..5793ed8a0874 --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/replicationcontroller/internal/metadata/generated_resource_test.go @@ -0,0 +1,58 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetK8sNamespaceName("k8s.namespace.name-val") + rb.SetK8sReplicationcontrollerName("k8s.replicationcontroller.name-val") + rb.SetK8sReplicationcontrollerUID("k8s.replicationcontroller.uid-val") + rb.SetOpencensusResourcetype("opencensus.resourcetype-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 4, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 4, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("k8s.namespace.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.namespace.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.replicationcontroller.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.replicationcontroller.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.replicationcontroller.uid") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.replicationcontroller.uid-val", val.Str()) + } + val, ok = res.Attributes().Get("opencensus.resourcetype") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "opencensus.resourcetype-val", val.Str()) + } + }) + } +} diff --git a/receiver/k8sclusterreceiver/internal/replicationcontroller/replicationcontrollers.go b/receiver/k8sclusterreceiver/internal/replicationcontroller/replicationcontrollers.go index 8d297d55e53e..e15cf1840e59 100644 --- a/receiver/k8sclusterreceiver/internal/replicationcontroller/replicationcontrollers.go +++ b/receiver/k8sclusterreceiver/internal/replicationcontroller/replicationcontrollers.go @@ -26,12 +26,12 @@ func GetMetrics(set receiver.CreateSettings, rc *corev1.ReplicationController) p mbphase.RecordK8sReplicationControllerAvailableDataPoint(ts, int64(rc.Status.AvailableReplicas)) } - return mbphase.Emit( - imetadataphase.WithK8sNamespaceName(rc.Namespace), - imetadataphase.WithK8sReplicationcontrollerName(rc.Name), - imetadataphase.WithK8sReplicationcontrollerUID(string(rc.UID)), - imetadataphase.WithOpencensusResourcetype("k8s"), - ) + rb := imetadataphase.NewResourceBuilder(imetadataphase.DefaultResourceAttributesConfig()) + rb.SetK8sNamespaceName(rc.Namespace) + rb.SetK8sReplicationcontrollerName(rc.Name) + rb.SetK8sReplicationcontrollerUID(string(rc.UID)) + rb.SetOpencensusResourcetype("k8s") + return mbphase.Emit(imetadataphase.WithResource(rb.Emit())) } func GetMetadata(rc *corev1.ReplicationController) map[experimentalmetricmetadata.ResourceID]*metadata.KubernetesMetadata { diff --git a/receiver/k8sclusterreceiver/internal/resourcequota/internal/metadata/generated_config_test.go b/receiver/k8sclusterreceiver/internal/resourcequota/internal/metadata/generated_config_test.go index 0c8cac3a4744..1b693bc6dfb8 100644 --- a/receiver/k8sclusterreceiver/internal/resourcequota/internal/metadata/generated_config_test.go +++ b/receiver/k8sclusterreceiver/internal/resourcequota/internal/metadata/generated_config_test.go @@ -72,3 +72,53 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + K8sNamespaceName: ResourceAttributeConfig{Enabled: true}, + K8sResourcequotaName: ResourceAttributeConfig{Enabled: true}, + K8sResourcequotaUID: ResourceAttributeConfig{Enabled: true}, + OpencensusResourcetype: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + K8sNamespaceName: ResourceAttributeConfig{Enabled: false}, + K8sResourcequotaName: ResourceAttributeConfig{Enabled: false}, + K8sResourcequotaUID: ResourceAttributeConfig{Enabled: false}, + OpencensusResourcetype: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/k8sclusterreceiver/internal/resourcequota/internal/metadata/generated_metrics.go b/receiver/k8sclusterreceiver/internal/resourcequota/internal/metadata/generated_metrics.go index 9906fb6f256a..5bb46a2ea249 100644 --- a/receiver/k8sclusterreceiver/internal/resourcequota/internal/metadata/generated_metrics.go +++ b/receiver/k8sclusterreceiver/internal/resourcequota/internal/metadata/generated_metrics.go @@ -119,10 +119,8 @@ func newMetricK8sResourceQuotaUsed(cfg MetricConfig) metricK8sResourceQuotaUsed type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricK8sResourceQuotaHardLimit metricK8sResourceQuotaHardLimit metricK8sResourceQuotaUsed metricK8sResourceQuotaUsed } @@ -142,7 +140,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricK8sResourceQuotaHardLimit: newMetricK8sResourceQuotaHardLimit(mbc.Metrics.K8sResourceQuotaHardLimit), metricK8sResourceQuotaUsed: newMetricK8sResourceQuotaUsed(mbc.Metrics.K8sResourceQuotaUsed), } @@ -157,54 +154,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithK8sNamespaceName sets provided value as "k8s.namespace.name" attribute for current resource. -func WithK8sNamespaceName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sNamespaceName.Enabled { - rm.Resource().Attributes().PutStr("k8s.namespace.name", val) - } - } -} - -// WithK8sResourcequotaName sets provided value as "k8s.resourcequota.name" attribute for current resource. -func WithK8sResourcequotaName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sResourcequotaName.Enabled { - rm.Resource().Attributes().PutStr("k8s.resourcequota.name", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithK8sResourcequotaUID sets provided value as "k8s.resourcequota.uid" attribute for current resource. -func WithK8sResourcequotaUID(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sResourcequotaUID.Enabled { - rm.Resource().Attributes().PutStr("k8s.resourcequota.uid", val) - } - } -} - -// WithOpencensusResourcetype sets provided value as "opencensus.resourcetype" attribute for current resource. -func WithOpencensusResourcetype(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.OpencensusResourcetype.Enabled { - rm.Resource().Attributes().PutStr("opencensus.resourcetype", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -229,7 +195,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() rm.SetSchemaUrl(conventions.SchemaURL) - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/k8sclusterreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -238,7 +203,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricK8sResourceQuotaUsed.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/k8sclusterreceiver/internal/resourcequota/internal/metadata/generated_metrics_test.go b/receiver/k8sclusterreceiver/internal/resourcequota/internal/metadata/generated_metrics_test.go index 5f58b231f3e4..a742cec42640 100644 --- a/receiver/k8sclusterreceiver/internal/resourcequota/internal/metadata/generated_metrics_test.go +++ b/receiver/k8sclusterreceiver/internal/resourcequota/internal/metadata/generated_metrics_test.go @@ -62,7 +62,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordK8sResourceQuotaUsedDataPoint(ts, 1, "resource-val") - metrics := mb.Emit(WithK8sNamespaceName("k8s.namespace.name-val"), WithK8sResourcequotaName("k8s.resourcequota.name-val"), WithK8sResourcequotaUID("k8s.resourcequota.uid-val"), WithOpencensusResourcetype("opencensus.resourcetype-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -71,39 +73,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("k8s.namespace.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sNamespaceName.Enabled, ok) - if mb.resourceAttributesConfig.K8sNamespaceName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.namespace.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.resourcequota.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sResourcequotaName.Enabled, ok) - if mb.resourceAttributesConfig.K8sResourcequotaName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.resourcequota.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.resourcequota.uid") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sResourcequotaUID.Enabled, ok) - if mb.resourceAttributesConfig.K8sResourcequotaUID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.resourcequota.uid-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("opencensus.resourcetype") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.OpencensusResourcetype.Enabled, ok) - if mb.resourceAttributesConfig.OpencensusResourcetype.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "opencensus.resourcetype-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 4) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/k8sclusterreceiver/internal/resourcequota/internal/metadata/generated_resource.go b/receiver/k8sclusterreceiver/internal/resourcequota/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..fff23e6145cd --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/resourcequota/internal/metadata/generated_resource.go @@ -0,0 +1,57 @@ +// 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(), + } +} + +// SetK8sNamespaceName sets provided value as "k8s.namespace.name" attribute. +func (rb *ResourceBuilder) SetK8sNamespaceName(val string) { + if rb.config.K8sNamespaceName.Enabled { + rb.res.Attributes().PutStr("k8s.namespace.name", val) + } +} + +// SetK8sResourcequotaName sets provided value as "k8s.resourcequota.name" attribute. +func (rb *ResourceBuilder) SetK8sResourcequotaName(val string) { + if rb.config.K8sResourcequotaName.Enabled { + rb.res.Attributes().PutStr("k8s.resourcequota.name", val) + } +} + +// SetK8sResourcequotaUID sets provided value as "k8s.resourcequota.uid" attribute. +func (rb *ResourceBuilder) SetK8sResourcequotaUID(val string) { + if rb.config.K8sResourcequotaUID.Enabled { + rb.res.Attributes().PutStr("k8s.resourcequota.uid", val) + } +} + +// SetOpencensusResourcetype sets provided value as "opencensus.resourcetype" attribute. +func (rb *ResourceBuilder) SetOpencensusResourcetype(val string) { + if rb.config.OpencensusResourcetype.Enabled { + rb.res.Attributes().PutStr("opencensus.resourcetype", 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/receiver/k8sclusterreceiver/internal/resourcequota/internal/metadata/generated_resource_test.go b/receiver/k8sclusterreceiver/internal/resourcequota/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..d18aae1f332e --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/resourcequota/internal/metadata/generated_resource_test.go @@ -0,0 +1,58 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetK8sNamespaceName("k8s.namespace.name-val") + rb.SetK8sResourcequotaName("k8s.resourcequota.name-val") + rb.SetK8sResourcequotaUID("k8s.resourcequota.uid-val") + rb.SetOpencensusResourcetype("opencensus.resourcetype-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 4, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 4, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("k8s.namespace.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.namespace.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.resourcequota.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.resourcequota.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.resourcequota.uid") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.resourcequota.uid-val", val.Str()) + } + val, ok = res.Attributes().Get("opencensus.resourcetype") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "opencensus.resourcetype-val", val.Str()) + } + }) + } +} diff --git a/receiver/k8sclusterreceiver/internal/resourcequota/resourcequotas.go b/receiver/k8sclusterreceiver/internal/resourcequota/resourcequotas.go index 332cc9f6af8a..c00176c5a4dc 100644 --- a/receiver/k8sclusterreceiver/internal/resourcequota/resourcequotas.go +++ b/receiver/k8sclusterreceiver/internal/resourcequota/resourcequotas.go @@ -35,5 +35,10 @@ func GetMetrics(set receiver.CreateSettings, rq *corev1.ResourceQuota) pmetric.M mb.RecordK8sResourceQuotaUsedDataPoint(ts, val, string(k)) } - return mb.Emit(imetadata.WithK8sResourcequotaUID(string(rq.UID)), imetadata.WithK8sResourcequotaName(rq.Name), imetadata.WithK8sNamespaceName(rq.Namespace), imetadata.WithOpencensusResourcetype("k8s")) + rb := imetadata.NewResourceBuilder(imetadata.DefaultResourceAttributesConfig()) + rb.SetK8sResourcequotaUID(string(rq.UID)) + rb.SetK8sResourcequotaName(rq.Name) + rb.SetK8sNamespaceName(rq.Namespace) + rb.SetOpencensusResourcetype("k8s") + return mb.Emit(imetadata.WithResource(rb.Emit())) } diff --git a/receiver/k8sclusterreceiver/internal/statefulset/internal/metadata/generated_config_test.go b/receiver/k8sclusterreceiver/internal/statefulset/internal/metadata/generated_config_test.go index 15440502a191..69af754e8853 100644 --- a/receiver/k8sclusterreceiver/internal/statefulset/internal/metadata/generated_config_test.go +++ b/receiver/k8sclusterreceiver/internal/statefulset/internal/metadata/generated_config_test.go @@ -76,3 +76,53 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + K8sNamespaceName: ResourceAttributeConfig{Enabled: true}, + K8sStatefulsetName: ResourceAttributeConfig{Enabled: true}, + K8sStatefulsetUID: ResourceAttributeConfig{Enabled: true}, + OpencensusResourcetype: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + K8sNamespaceName: ResourceAttributeConfig{Enabled: false}, + K8sStatefulsetName: ResourceAttributeConfig{Enabled: false}, + K8sStatefulsetUID: ResourceAttributeConfig{Enabled: false}, + OpencensusResourcetype: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/k8sclusterreceiver/internal/statefulset/internal/metadata/generated_metrics.go b/receiver/k8sclusterreceiver/internal/statefulset/internal/metadata/generated_metrics.go index 161cc58eb74d..c4f652f30767 100644 --- a/receiver/k8sclusterreceiver/internal/statefulset/internal/metadata/generated_metrics.go +++ b/receiver/k8sclusterreceiver/internal/statefulset/internal/metadata/generated_metrics.go @@ -213,10 +213,8 @@ func newMetricK8sStatefulsetUpdatedPods(cfg MetricConfig) metricK8sStatefulsetUp type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricK8sStatefulsetCurrentPods metricK8sStatefulsetCurrentPods metricK8sStatefulsetDesiredPods metricK8sStatefulsetDesiredPods metricK8sStatefulsetReadyPods metricK8sStatefulsetReadyPods @@ -238,7 +236,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricK8sStatefulsetCurrentPods: newMetricK8sStatefulsetCurrentPods(mbc.Metrics.K8sStatefulsetCurrentPods), metricK8sStatefulsetDesiredPods: newMetricK8sStatefulsetDesiredPods(mbc.Metrics.K8sStatefulsetDesiredPods), metricK8sStatefulsetReadyPods: newMetricK8sStatefulsetReadyPods(mbc.Metrics.K8sStatefulsetReadyPods), @@ -255,54 +252,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithK8sNamespaceName sets provided value as "k8s.namespace.name" attribute for current resource. -func WithK8sNamespaceName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sNamespaceName.Enabled { - rm.Resource().Attributes().PutStr("k8s.namespace.name", val) - } - } -} - -// WithK8sStatefulsetName sets provided value as "k8s.statefulset.name" attribute for current resource. -func WithK8sStatefulsetName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sStatefulsetName.Enabled { - rm.Resource().Attributes().PutStr("k8s.statefulset.name", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithK8sStatefulsetUID sets provided value as "k8s.statefulset.uid" attribute for current resource. -func WithK8sStatefulsetUID(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sStatefulsetUID.Enabled { - rm.Resource().Attributes().PutStr("k8s.statefulset.uid", val) - } - } -} - -// WithOpencensusResourcetype sets provided value as "opencensus.resourcetype" attribute for current resource. -func WithOpencensusResourcetype(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.OpencensusResourcetype.Enabled { - rm.Resource().Attributes().PutStr("opencensus.resourcetype", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -327,7 +293,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() rm.SetSchemaUrl(conventions.SchemaURL) - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/k8sclusterreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -338,7 +303,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricK8sStatefulsetUpdatedPods.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/k8sclusterreceiver/internal/statefulset/internal/metadata/generated_metrics_test.go b/receiver/k8sclusterreceiver/internal/statefulset/internal/metadata/generated_metrics_test.go index 4cc0253217a0..3247eb8d3473 100644 --- a/receiver/k8sclusterreceiver/internal/statefulset/internal/metadata/generated_metrics_test.go +++ b/receiver/k8sclusterreceiver/internal/statefulset/internal/metadata/generated_metrics_test.go @@ -70,7 +70,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordK8sStatefulsetUpdatedPodsDataPoint(ts, 1) - metrics := mb.Emit(WithK8sNamespaceName("k8s.namespace.name-val"), WithK8sStatefulsetName("k8s.statefulset.name-val"), WithK8sStatefulsetUID("k8s.statefulset.uid-val"), WithOpencensusResourcetype("opencensus.resourcetype-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -79,39 +81,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("k8s.namespace.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sNamespaceName.Enabled, ok) - if mb.resourceAttributesConfig.K8sNamespaceName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.namespace.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.statefulset.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sStatefulsetName.Enabled, ok) - if mb.resourceAttributesConfig.K8sStatefulsetName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.statefulset.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.statefulset.uid") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sStatefulsetUID.Enabled, ok) - if mb.resourceAttributesConfig.K8sStatefulsetUID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.statefulset.uid-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("opencensus.resourcetype") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.OpencensusResourcetype.Enabled, ok) - if mb.resourceAttributesConfig.OpencensusResourcetype.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "opencensus.resourcetype-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 4) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/k8sclusterreceiver/internal/statefulset/internal/metadata/generated_resource.go b/receiver/k8sclusterreceiver/internal/statefulset/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..64f0a9180217 --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/statefulset/internal/metadata/generated_resource.go @@ -0,0 +1,57 @@ +// 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(), + } +} + +// SetK8sNamespaceName sets provided value as "k8s.namespace.name" attribute. +func (rb *ResourceBuilder) SetK8sNamespaceName(val string) { + if rb.config.K8sNamespaceName.Enabled { + rb.res.Attributes().PutStr("k8s.namespace.name", val) + } +} + +// SetK8sStatefulsetName sets provided value as "k8s.statefulset.name" attribute. +func (rb *ResourceBuilder) SetK8sStatefulsetName(val string) { + if rb.config.K8sStatefulsetName.Enabled { + rb.res.Attributes().PutStr("k8s.statefulset.name", val) + } +} + +// SetK8sStatefulsetUID sets provided value as "k8s.statefulset.uid" attribute. +func (rb *ResourceBuilder) SetK8sStatefulsetUID(val string) { + if rb.config.K8sStatefulsetUID.Enabled { + rb.res.Attributes().PutStr("k8s.statefulset.uid", val) + } +} + +// SetOpencensusResourcetype sets provided value as "opencensus.resourcetype" attribute. +func (rb *ResourceBuilder) SetOpencensusResourcetype(val string) { + if rb.config.OpencensusResourcetype.Enabled { + rb.res.Attributes().PutStr("opencensus.resourcetype", 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/receiver/k8sclusterreceiver/internal/statefulset/internal/metadata/generated_resource_test.go b/receiver/k8sclusterreceiver/internal/statefulset/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..26c1a28ca0d0 --- /dev/null +++ b/receiver/k8sclusterreceiver/internal/statefulset/internal/metadata/generated_resource_test.go @@ -0,0 +1,58 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetK8sNamespaceName("k8s.namespace.name-val") + rb.SetK8sStatefulsetName("k8s.statefulset.name-val") + rb.SetK8sStatefulsetUID("k8s.statefulset.uid-val") + rb.SetOpencensusResourcetype("opencensus.resourcetype-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 4, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 4, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("k8s.namespace.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.namespace.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.statefulset.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.statefulset.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.statefulset.uid") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.statefulset.uid-val", val.Str()) + } + val, ok = res.Attributes().Get("opencensus.resourcetype") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "opencensus.resourcetype-val", val.Str()) + } + }) + } +} diff --git a/receiver/k8sclusterreceiver/internal/statefulset/statefulsets.go b/receiver/k8sclusterreceiver/internal/statefulset/statefulsets.go index 84ed8b6c515a..54881271a5d5 100644 --- a/receiver/k8sclusterreceiver/internal/statefulset/statefulsets.go +++ b/receiver/k8sclusterreceiver/internal/statefulset/statefulsets.go @@ -49,7 +49,12 @@ func GetMetrics(set receiver.CreateSettings, ss *appsv1.StatefulSet) pmetric.Met mb.RecordK8sStatefulsetReadyPodsDataPoint(ts, int64(ss.Status.ReadyReplicas)) mb.RecordK8sStatefulsetCurrentPodsDataPoint(ts, int64(ss.Status.CurrentReplicas)) mb.RecordK8sStatefulsetUpdatedPodsDataPoint(ts, int64(ss.Status.UpdatedReplicas)) - return mb.Emit(imetadata.WithK8sStatefulsetUID(string(ss.UID)), imetadata.WithK8sStatefulsetName(ss.Name), imetadata.WithK8sNamespaceName(ss.Namespace), imetadata.WithOpencensusResourcetype("k8s")) + rb := imetadata.NewResourceBuilder(imetadata.DefaultResourceAttributesConfig()) + rb.SetK8sStatefulsetUID(string(ss.UID)) + rb.SetK8sStatefulsetName(ss.Name) + rb.SetK8sNamespaceName(ss.Namespace) + rb.SetOpencensusResourcetype("k8s") + return mb.Emit(imetadata.WithResource(rb.Emit())) } func GetMetadata(ss *appsv1.StatefulSet) map[experimentalmetricmetadata.ResourceID]*metadata.KubernetesMetadata { diff --git a/receiver/kafkametricsreceiver/internal/metadata/generated_metrics.go b/receiver/kafkametricsreceiver/internal/metadata/generated_metrics.go index 6f1e45c52efd..a171ea64521f 100644 --- a/receiver/kafkametricsreceiver/internal/metadata/generated_metrics.go +++ b/receiver/kafkametricsreceiver/internal/metadata/generated_metrics.go @@ -595,7 +595,6 @@ func newMetricKafkaTopicPartitions(cfg MetricConfig) metricKafkaTopicPartitions type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information metricKafkaBrokers metricKafkaBrokers @@ -649,14 +648,19 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. type ResourceMetricsOption func(pmetric.ResourceMetrics) +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) + } +} + // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { @@ -684,7 +688,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/kafkametricsreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) diff --git a/receiver/kafkametricsreceiver/internal/metadata/generated_metrics_test.go b/receiver/kafkametricsreceiver/internal/metadata/generated_metrics_test.go index 33d016025b01..1f8896dc80a0 100644 --- a/receiver/kafkametricsreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/kafkametricsreceiver/internal/metadata/generated_metrics_test.go @@ -98,7 +98,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordKafkaTopicPartitionsDataPoint(ts, 1, "topic-val") - metrics := mb.Emit() + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -107,11 +109,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 0) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/kubeletstatsreceiver/internal/kubelet/accumulator.go b/receiver/kubeletstatsreceiver/internal/kubelet/accumulator.go index 585ec0103b2f..9952740bffcc 100644 --- a/receiver/kubeletstatsreceiver/internal/kubelet/accumulator.go +++ b/receiver/kubeletstatsreceiver/internal/kubelet/accumulator.go @@ -38,6 +38,7 @@ type metricDataAccumulator struct { logger *zap.Logger metricGroupsToCollect map[MetricGroup]bool time time.Time + rb *metadata.ResourceBuilder mbs *metadata.MetricsBuilders } @@ -52,10 +53,10 @@ func (a *metricDataAccumulator) nodeStats(s stats.NodeStats) { addFilesystemMetrics(a.mbs.NodeMetricsBuilder, metadata.NodeFilesystemMetrics, s.Fs, currentTime) addNetworkMetrics(a.mbs.NodeMetricsBuilder, metadata.NodeNetworkMetrics, s.Network, currentTime) // todo s.Runtime.ImageFs - + a.rb.SetK8sNodeName(s.NodeName) a.m = append(a.m, a.mbs.NodeMetricsBuilder.Emit( metadata.WithStartTimeOverride(pcommon.NewTimestampFromTime(s.StartTime.Time)), - metadata.WithK8sNodeName(s.NodeName), + metadata.WithResource(a.rb.Emit()), )) } @@ -70,11 +71,12 @@ func (a *metricDataAccumulator) podStats(s stats.PodStats) { addFilesystemMetrics(a.mbs.PodMetricsBuilder, metadata.PodFilesystemMetrics, s.EphemeralStorage, currentTime) addNetworkMetrics(a.mbs.PodMetricsBuilder, metadata.PodNetworkMetrics, s.Network, currentTime) + a.rb.SetK8sPodUID(s.PodRef.UID) + a.rb.SetK8sPodName(s.PodRef.Name) + a.rb.SetK8sNamespaceName(s.PodRef.Namespace) a.m = append(a.m, a.mbs.PodMetricsBuilder.Emit( metadata.WithStartTimeOverride(pcommon.NewTimestampFromTime(s.StartTime.Time)), - metadata.WithK8sPodUID(s.PodRef.UID), - metadata.WithK8sPodName(s.PodRef.Name), - metadata.WithK8sNamespaceName(s.PodRef.Namespace), + metadata.WithResource(a.rb.Emit()), )) } @@ -83,7 +85,7 @@ func (a *metricDataAccumulator) containerStats(sPod stats.PodStats, s stats.Cont return } - ro, err := getContainerResourceOptions(sPod, s, a.metadata) + res, err := getContainerResource(a.rb, sPod, s, a.metadata) if err != nil { a.logger.Warn( "failed to fetch container metrics", @@ -98,7 +100,10 @@ func (a *metricDataAccumulator) containerStats(sPod stats.PodStats, s stats.Cont addMemoryMetrics(a.mbs.ContainerMetricsBuilder, metadata.ContainerMemoryMetrics, s.Memory, currentTime) addFilesystemMetrics(a.mbs.ContainerMetricsBuilder, metadata.ContainerFilesystemMetrics, s.Rootfs, currentTime) - a.m = append(a.m, a.mbs.ContainerMetricsBuilder.Emit(ro...)) + a.m = append(a.m, a.mbs.ContainerMetricsBuilder.Emit( + metadata.WithStartTimeOverride(pcommon.NewTimestampFromTime(s.StartTime.Time)), + metadata.WithResource(res), + )) } func (a *metricDataAccumulator) volumeStats(sPod stats.PodStats, s stats.VolumeStats) { @@ -106,7 +111,7 @@ func (a *metricDataAccumulator) volumeStats(sPod stats.PodStats, s stats.VolumeS return } - ro, err := getVolumeResourceOptions(sPod, s, a.metadata) + res, err := getVolumeResourceOptions(a.rb, sPod, s, a.metadata) if err != nil { a.logger.Warn( "Failed to gather additional volume metadata. Skipping metric collection.", @@ -119,5 +124,5 @@ func (a *metricDataAccumulator) volumeStats(sPod stats.PodStats, s stats.VolumeS currentTime := pcommon.NewTimestampFromTime(a.time) addVolumeMetrics(a.mbs.OtherMetricsBuilder, metadata.K8sVolumeMetrics, s, currentTime) - a.m = append(a.m, a.mbs.OtherMetricsBuilder.Emit(ro...)) + a.m = append(a.m, a.mbs.OtherMetricsBuilder.Emit(metadata.WithResource(res))) } diff --git a/receiver/kubeletstatsreceiver/internal/kubelet/accumulator_test.go b/receiver/kubeletstatsreceiver/internal/kubelet/accumulator_test.go index beb4edbaa423..b1a22106cc8a 100644 --- a/receiver/kubeletstatsreceiver/internal/kubelet/accumulator_test.go +++ b/receiver/kubeletstatsreceiver/internal/kubelet/accumulator_test.go @@ -31,7 +31,7 @@ func TestMetadataErrorCases(t *testing.T) { numMDs int numLogs int logMessages []string - detailedPVCLabelsSetterOverride func(volCacheID, volumeClaim, namespace string) ([]metadata.ResourceMetricsOption, error) + detailedPVCLabelsSetterOverride func(rb *metadata.ResourceBuilder, volCacheID, volumeClaim, namespace string) error }{ { name: "Fails to get container metadata", @@ -168,9 +168,9 @@ func TestMetadataErrorCases(t *testing.T) { }, }, }, nil), - detailedPVCLabelsSetterOverride: func(volCacheID, volumeClaim, namespace string) ([]metadata.ResourceMetricsOption, error) { + detailedPVCLabelsSetterOverride: func(rb *metadata.ResourceBuilder, volCacheID, volumeClaim, namespace string) error { // Mock failure cases. - return nil, errors.New("") + return errors.New("") }, testScenario: func(acc metricDataAccumulator) { podStats := stats.PodStats{ @@ -197,11 +197,12 @@ func TestMetadataErrorCases(t *testing.T) { observedLogger, logs := observer.New(zapcore.WarnLevel) logger := zap.New(observedLogger) - tt.metadata.DetailedPVCResourceGetter = tt.detailedPVCLabelsSetterOverride + tt.metadata.DetailedPVCResourceSetter = tt.detailedPVCLabelsSetterOverride acc := metricDataAccumulator{ metadata: tt.metadata, logger: logger, metricGroupsToCollect: tt.metricGroupsToCollect, + rb: metadata.NewResourceBuilder(metadata.DefaultResourceAttributesConfig()), mbs: &metadata.MetricsBuilders{ NodeMetricsBuilder: metadata.NewMetricsBuilder(metadata.DefaultMetricsBuilderConfig(), receivertest.NewNopCreateSettings()), PodMetricsBuilder: metadata.NewMetricsBuilder(metadata.DefaultMetricsBuilderConfig(), receivertest.NewNopCreateSettings()), @@ -228,6 +229,7 @@ func TestNilHandling(t *testing.T) { ContainerMetricGroup: true, VolumeMetricGroup: true, }, + rb: metadata.NewResourceBuilder(metadata.DefaultResourceAttributesConfig()), mbs: &metadata.MetricsBuilders{ NodeMetricsBuilder: metadata.NewMetricsBuilder(metadata.DefaultMetricsBuilderConfig(), receivertest.NewNopCreateSettings()), PodMetricsBuilder: metadata.NewMetricsBuilder(metadata.DefaultMetricsBuilderConfig(), receivertest.NewNopCreateSettings()), diff --git a/receiver/kubeletstatsreceiver/internal/kubelet/metadata.go b/receiver/kubeletstatsreceiver/internal/kubelet/metadata.go index e4056a6db178..ab22853b22bc 100644 --- a/receiver/kubeletstatsreceiver/internal/kubelet/metadata.go +++ b/receiver/kubeletstatsreceiver/internal/kubelet/metadata.go @@ -49,16 +49,15 @@ func ValidateMetadataLabelsConfig(labels []MetadataLabel) error { type Metadata struct { Labels map[MetadataLabel]bool PodsMetadata *v1.PodList - DetailedPVCResourceGetter func(volCacheID, volumeClaim, namespace string) ([]metadata.ResourceMetricsOption, error) + DetailedPVCResourceSetter func(rb *metadata.ResourceBuilder, volCacheID, volumeClaim, namespace string) error } -func NewMetadata( - labels []MetadataLabel, podsMetadata *v1.PodList, - detailedPVCResourceGetter func(volCacheID, volumeClaim, namespace string) ([]metadata.ResourceMetricsOption, error)) Metadata { +func NewMetadata(labels []MetadataLabel, podsMetadata *v1.PodList, + detailedPVCResourceSetter func(rb *metadata.ResourceBuilder, volCacheID, volumeClaim, namespace string) error) Metadata { return Metadata{ Labels: getLabelsMap(labels), PodsMetadata: podsMetadata, - DetailedPVCResourceGetter: detailedPVCResourceGetter, + DetailedPVCResourceSetter: detailedPVCResourceSetter, } } @@ -71,45 +70,43 @@ func getLabelsMap(metadataLabels []MetadataLabel) map[MetadataLabel]bool { } // getExtraResources gets extra resources based on provided metadata label. -func (m *Metadata) getExtraResources(podRef stats.PodReference, extraMetadataLabel MetadataLabel, - extraMetadataFrom string) ([]metadata.ResourceMetricsOption, error) { +func (m *Metadata) setExtraResources(rb *metadata.ResourceBuilder, podRef stats.PodReference, + extraMetadataLabel MetadataLabel, extraMetadataFrom string) error { // Ensure MetadataLabel exists before proceeding. if !m.Labels[extraMetadataLabel] || len(m.Labels) == 0 { - return nil, nil + return nil } // Cannot proceed, if metadata is unavailable. if m.PodsMetadata == nil { - return nil, errors.New("pods metadata were not fetched") + return errors.New("pods metadata were not fetched") } switch extraMetadataLabel { case MetadataLabelContainerID: containerID, err := m.getContainerID(podRef.UID, extraMetadataFrom) if err != nil { - return nil, err + return err } - return []metadata.ResourceMetricsOption{metadata.WithContainerID(containerID)}, nil + rb.SetContainerID(containerID) case MetadataLabelVolumeType: volume, err := m.getPodVolume(podRef.UID, extraMetadataFrom) if err != nil { - return nil, err + return err } - ro := getResourcesFromVolume(volume) + setResourcesFromVolume(rb, volume) // Get more labels from PersistentVolumeClaim volume type. if volume.PersistentVolumeClaim != nil { volCacheID := fmt.Sprintf("%s/%s", podRef.UID, extraMetadataFrom) - pvcResources, err := m.DetailedPVCResourceGetter(volCacheID, volume.PersistentVolumeClaim.ClaimName, podRef.Namespace) + err := m.DetailedPVCResourceSetter(rb, volCacheID, volume.PersistentVolumeClaim.ClaimName, podRef.Namespace) if err != nil { - return nil, fmt.Errorf("failed to set labels from volume claim: %w", err) + return fmt.Errorf("failed to set labels from volume claim: %w", err) } - ro = append(ro, pvcResources...) } - return ro, nil } - return nil, nil + return nil } // getContainerID retrieves container id from metadata for given pod UID and container name, diff --git a/receiver/kubeletstatsreceiver/internal/kubelet/metadata_test.go b/receiver/kubeletstatsreceiver/internal/kubelet/metadata_test.go index b053b0934d65..396c4a32c73e 100644 --- a/receiver/kubeletstatsreceiver/internal/kubelet/metadata_test.go +++ b/receiver/kubeletstatsreceiver/internal/kubelet/metadata_test.go @@ -8,7 +8,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "go.opentelemetry.io/collector/pdata/pmetric" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" stats "k8s.io/kubelet/pkg/apis/stats/v1alpha1" @@ -215,17 +214,13 @@ func TestSetExtraLabels(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - ro, err := tt.metadata.getExtraResources(stats.PodReference{UID: tt.args[0]}, MetadataLabel(tt.args[1]), tt.args[2]) - - r := pmetric.NewResourceMetrics() - rac := metadata.DefaultResourceAttributesConfig() - for _, op := range ro { - op(rac, r) - } + rb := metadata.NewResourceBuilder(metadata.DefaultResourceAttributesConfig()) + err := tt.metadata.setExtraResources(rb, stats.PodReference{UID: tt.args[0]}, MetadataLabel(tt.args[1]), tt.args[2]) + res := rb.Emit() if tt.wantError == "" { require.NoError(t, err) - temp := r.Resource().Attributes().AsRaw() + temp := res.Attributes().AsRaw() assert.EqualValues(t, tt.want, temp) } else { assert.Equal(t, tt.wantError, err.Error()) @@ -364,8 +359,7 @@ func TestSetExtraLabelsForVolumeTypes(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { volName := "volume0" - rac := metadata.DefaultResourceAttributesConfig() - metadata := NewMetadata([]MetadataLabel{MetadataLabelVolumeType}, &v1.PodList{ + md := NewMetadata([]MetadataLabel{MetadataLabelVolumeType}, &v1.PodList{ Items: []v1.Pod{ { ObjectMeta: metav1.ObjectMeta{ @@ -381,17 +375,14 @@ func TestSetExtraLabelsForVolumeTypes(t *testing.T) { }, }, }, - }, func(volCacheID, volumeClaim, namespace string) ([]metadata.ResourceMetricsOption, error) { - return nil, nil + }, func(rb *metadata.ResourceBuilder, volCacheID, volumeClaim, namespace string) error { + return nil }) - ro, _ := metadata.getExtraResources(stats.PodReference{UID: tt.args[0]}, MetadataLabel(tt.args[1]), volName) - - rm := pmetric.NewResourceMetrics() - for _, op := range ro { - op(rac, rm) - } + rb := metadata.NewResourceBuilder(metadata.DefaultResourceAttributesConfig()) + err := md.setExtraResources(rb, stats.PodReference{UID: tt.args[0]}, MetadataLabel(tt.args[1]), volName) + require.NoError(t, err) - assert.Equal(t, tt.want, rm.Resource().Attributes().AsRaw()) + assert.Equal(t, tt.want, rb.Emit().Attributes().AsRaw()) }) } } diff --git a/receiver/kubeletstatsreceiver/internal/kubelet/metrics.go b/receiver/kubeletstatsreceiver/internal/kubelet/metrics.go index afac93aa7953..eefab6eff7e1 100644 --- a/receiver/kubeletstatsreceiver/internal/kubelet/metrics.go +++ b/receiver/kubeletstatsreceiver/internal/kubelet/metrics.go @@ -17,12 +17,14 @@ func MetricsData( logger *zap.Logger, summary *stats.Summary, metadata Metadata, metricGroupsToCollect map[MetricGroup]bool, + rb *metadata.ResourceBuilder, mbs *metadata.MetricsBuilders) []pmetric.Metrics { acc := &metricDataAccumulator{ metadata: metadata, logger: logger, metricGroupsToCollect: metricGroupsToCollect, time: time.Now(), + rb: rb, mbs: mbs, } acc.nodeStats(summary.Node) diff --git a/receiver/kubeletstatsreceiver/internal/kubelet/metrics_test.go b/receiver/kubeletstatsreceiver/internal/kubelet/metrics_test.go index 11701eb08db6..c145692f3dcf 100644 --- a/receiver/kubeletstatsreceiver/internal/kubelet/metrics_test.go +++ b/receiver/kubeletstatsreceiver/internal/kubelet/metrics_test.go @@ -34,18 +34,19 @@ func TestMetricAccumulator(t *testing.T) { metadataProvider := NewMetadataProvider(rc) podsMetadata, _ := metadataProvider.Pods() k8sMetadata := NewMetadata([]MetadataLabel{MetadataLabelContainerID}, podsMetadata, nil) + rb := metadata.NewResourceBuilder(metadata.DefaultResourceAttributesConfig()) mbs := &metadata.MetricsBuilders{ NodeMetricsBuilder: metadata.NewMetricsBuilder(metadata.DefaultMetricsBuilderConfig(), receivertest.NewNopCreateSettings()), PodMetricsBuilder: metadata.NewMetricsBuilder(metadata.DefaultMetricsBuilderConfig(), receivertest.NewNopCreateSettings()), ContainerMetricsBuilder: metadata.NewMetricsBuilder(metadata.DefaultMetricsBuilderConfig(), receivertest.NewNopCreateSettings()), OtherMetricsBuilder: metadata.NewMetricsBuilder(metadata.DefaultMetricsBuilderConfig(), receivertest.NewNopCreateSettings()), } - requireMetricsOk(t, MetricsData(zap.NewNop(), summary, k8sMetadata, ValidMetricGroups, mbs)) + requireMetricsOk(t, MetricsData(zap.NewNop(), summary, k8sMetadata, ValidMetricGroups, rb, mbs)) // Disable all groups mbs.NodeMetricsBuilder.Reset() mbs.PodMetricsBuilder.Reset() mbs.OtherMetricsBuilder.Reset() - require.Equal(t, 0, len(MetricsData(zap.NewNop(), summary, k8sMetadata, map[MetricGroup]bool{}, mbs))) + require.Equal(t, 0, len(MetricsData(zap.NewNop(), summary, k8sMetadata, map[MetricGroup]bool{}, rb, mbs))) } func requireMetricsOk(t *testing.T, mds []pmetric.Metrics) { @@ -188,11 +189,12 @@ func fakeMetrics() []pmetric.Metrics { PodMetricGroup: true, NodeMetricGroup: true, } + rb := metadata.NewResourceBuilder(metadata.DefaultResourceAttributesConfig()) mbs := &metadata.MetricsBuilders{ NodeMetricsBuilder: metadata.NewMetricsBuilder(metadata.DefaultMetricsBuilderConfig(), receivertest.NewNopCreateSettings()), PodMetricsBuilder: metadata.NewMetricsBuilder(metadata.DefaultMetricsBuilderConfig(), receivertest.NewNopCreateSettings()), ContainerMetricsBuilder: metadata.NewMetricsBuilder(metadata.DefaultMetricsBuilderConfig(), receivertest.NewNopCreateSettings()), OtherMetricsBuilder: metadata.NewMetricsBuilder(metadata.DefaultMetricsBuilderConfig(), receivertest.NewNopCreateSettings()), } - return MetricsData(zap.NewNop(), summary, Metadata{}, mgs, mbs) + return MetricsData(zap.NewNop(), summary, Metadata{}, mgs, rb, mbs) } diff --git a/receiver/kubeletstatsreceiver/internal/kubelet/resource.go b/receiver/kubeletstatsreceiver/internal/kubelet/resource.go index db8e9bda0d2e..31c3a4164ca9 100644 --- a/receiver/kubeletstatsreceiver/internal/kubelet/resource.go +++ b/receiver/kubeletstatsreceiver/internal/kubelet/resource.go @@ -12,39 +12,32 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/kubeletstatsreceiver/internal/metadata" ) -func getContainerResourceOptions(sPod stats.PodStats, sContainer stats.ContainerStats, k8sMetadata Metadata) ([]metadata.ResourceMetricsOption, error) { - ro := []metadata.ResourceMetricsOption{ - metadata.WithStartTimeOverride(pcommon.NewTimestampFromTime(sContainer.StartTime.Time)), - metadata.WithK8sPodUID(sPod.PodRef.UID), - metadata.WithK8sPodName(sPod.PodRef.Name), - metadata.WithK8sNamespaceName(sPod.PodRef.Namespace), - metadata.WithK8sContainerName(sContainer.Name), - } - - extraResources, err := k8sMetadata.getExtraResources(sPod.PodRef, MetadataLabelContainerID, sContainer.Name) +func getContainerResource(rb *metadata.ResourceBuilder, sPod stats.PodStats, sContainer stats.ContainerStats, + k8sMetadata Metadata) (pcommon.Resource, error) { + rb.SetK8sPodUID(sPod.PodRef.UID) + rb.SetK8sPodName(sPod.PodRef.Name) + rb.SetK8sNamespaceName(sPod.PodRef.Namespace) + rb.SetK8sContainerName(sContainer.Name) + + err := k8sMetadata.setExtraResources(rb, sPod.PodRef, MetadataLabelContainerID, sContainer.Name) if err != nil { - return nil, fmt.Errorf("failed to set extra labels from metadata: %w", err) + return rb.Emit(), fmt.Errorf("failed to set extra labels from metadata: %w", err) } - ro = append(ro, extraResources...) - - return ro, nil + return rb.Emit(), nil } -func getVolumeResourceOptions(sPod stats.PodStats, vs stats.VolumeStats, k8sMetadata Metadata) ([]metadata.ResourceMetricsOption, error) { - ro := []metadata.ResourceMetricsOption{ - metadata.WithK8sPodUID(sPod.PodRef.UID), - metadata.WithK8sPodName(sPod.PodRef.Name), - metadata.WithK8sNamespaceName(sPod.PodRef.Namespace), - metadata.WithK8sVolumeName(vs.Name), - } +func getVolumeResourceOptions(rb *metadata.ResourceBuilder, sPod stats.PodStats, vs stats.VolumeStats, + k8sMetadata Metadata) (pcommon.Resource, error) { + rb.SetK8sPodUID(sPod.PodRef.UID) + rb.SetK8sPodName(sPod.PodRef.Name) + rb.SetK8sNamespaceName(sPod.PodRef.Namespace) + rb.SetK8sVolumeName(vs.Name) - extraResources, err := k8sMetadata.getExtraResources(sPod.PodRef, MetadataLabelVolumeType, vs.Name) + err := k8sMetadata.setExtraResources(rb, sPod.PodRef, MetadataLabelVolumeType, vs.Name) if err != nil { - return nil, fmt.Errorf("failed to set extra labels from metadata: %w", err) + return rb.Emit(), fmt.Errorf("failed to set extra labels from metadata: %w", err) } - ro = append(ro, extraResources...) - - return ro, nil + return rb.Emit(), nil } diff --git a/receiver/kubeletstatsreceiver/internal/kubelet/volume.go b/receiver/kubeletstatsreceiver/internal/kubelet/volume.go index acf1b03cb099..19c9c26fb980 100644 --- a/receiver/kubeletstatsreceiver/internal/kubelet/volume.go +++ b/receiver/kubeletstatsreceiver/internal/kubelet/volume.go @@ -21,80 +21,72 @@ func addVolumeMetrics(mb *metadata.MetricsBuilder, volumeMetrics metadata.Volume recordIntDataPoint(mb, volumeMetrics.InodesUsed, s.InodesUsed, currentTime) } -func getResourcesFromVolume(volume v1.Volume) []metadata.ResourceMetricsOption { +func setResourcesFromVolume(rb *metadata.ResourceBuilder, volume v1.Volume) { switch { // TODO: Support more types case volume.ConfigMap != nil: - return []metadata.ResourceMetricsOption{metadata.WithK8sVolumeType(labelValueConfigMapVolume)} + rb.SetK8sVolumeType(labelValueConfigMapVolume) case volume.DownwardAPI != nil: - return []metadata.ResourceMetricsOption{metadata.WithK8sVolumeType(labelValueDownwardAPIVolume)} + rb.SetK8sVolumeType(labelValueDownwardAPIVolume) case volume.EmptyDir != nil: - return []metadata.ResourceMetricsOption{metadata.WithK8sVolumeType(labelValueEmptyDirVolume)} + rb.SetK8sVolumeType(labelValueEmptyDirVolume) case volume.Secret != nil: - return []metadata.ResourceMetricsOption{metadata.WithK8sVolumeType(labelValueSecretVolume)} + rb.SetK8sVolumeType(labelValueSecretVolume) case volume.PersistentVolumeClaim != nil: - return []metadata.ResourceMetricsOption{metadata.WithK8sVolumeType(labelValuePersistentVolumeClaim), - metadata.WithK8sPersistentvolumeclaimName(volume.PersistentVolumeClaim.ClaimName)} + rb.SetK8sVolumeType(labelValuePersistentVolumeClaim) + rb.SetK8sPersistentvolumeclaimName(volume.PersistentVolumeClaim.ClaimName) case volume.HostPath != nil: - return []metadata.ResourceMetricsOption{metadata.WithK8sVolumeType(labelValueHostPathVolume)} + rb.SetK8sVolumeType(labelValueHostPathVolume) case volume.AWSElasticBlockStore != nil: - return awsElasticBlockStoreDims(*volume.AWSElasticBlockStore) + awsElasticBlockStoreDims(rb, *volume.AWSElasticBlockStore) case volume.GCEPersistentDisk != nil: - return gcePersistentDiskDims(*volume.GCEPersistentDisk) + gcePersistentDiskDims(rb, *volume.GCEPersistentDisk) case volume.Glusterfs != nil: - return glusterfsDims(*volume.Glusterfs) + glusterfsDims(rb, *volume.Glusterfs) } - return nil } -func GetPersistentVolumeLabels(pv v1.PersistentVolumeSource) []metadata.ResourceMetricsOption { +func SetPersistentVolumeLabels(rb *metadata.ResourceBuilder, pv v1.PersistentVolumeSource) { // TODO: Support more types switch { case pv.Local != nil: - return []metadata.ResourceMetricsOption{metadata.WithK8sVolumeType(labelValueLocalVolume)} + rb.SetK8sVolumeType(labelValueLocalVolume) case pv.AWSElasticBlockStore != nil: - return awsElasticBlockStoreDims(*pv.AWSElasticBlockStore) + awsElasticBlockStoreDims(rb, *pv.AWSElasticBlockStore) case pv.GCEPersistentDisk != nil: - return gcePersistentDiskDims(*pv.GCEPersistentDisk) + gcePersistentDiskDims(rb, *pv.GCEPersistentDisk) case pv.Glusterfs != nil: // pv.Glusterfs is a GlusterfsPersistentVolumeSource instead of GlusterfsVolumeSource, // convert to GlusterfsVolumeSource so a single method can handle both structs. This // can be broken out into separate methods if one is interested in different sets // of labels from the two structs in the future. - return glusterfsDims(v1.GlusterfsVolumeSource{ + glusterfsDims(rb, v1.GlusterfsVolumeSource{ EndpointsName: pv.Glusterfs.EndpointsName, Path: pv.Glusterfs.Path, ReadOnly: pv.Glusterfs.ReadOnly, }) } - return nil } -func awsElasticBlockStoreDims(vs v1.AWSElasticBlockStoreVolumeSource) []metadata.ResourceMetricsOption { - return []metadata.ResourceMetricsOption{ - metadata.WithK8sVolumeType(labelValueAWSEBSVolume), - // AWS specific labels. - metadata.WithAwsVolumeID(vs.VolumeID), - metadata.WithFsType(vs.FSType), - metadata.WithPartition(strconv.Itoa(int(vs.Partition))), - } +func awsElasticBlockStoreDims(rb *metadata.ResourceBuilder, vs v1.AWSElasticBlockStoreVolumeSource) { + rb.SetK8sVolumeType(labelValueAWSEBSVolume) + // AWS specific labels. + rb.SetAwsVolumeID(vs.VolumeID) + rb.SetFsType(vs.FSType) + rb.SetPartition(strconv.Itoa(int(vs.Partition))) } -func gcePersistentDiskDims(vs v1.GCEPersistentDiskVolumeSource) []metadata.ResourceMetricsOption { - return []metadata.ResourceMetricsOption{ - metadata.WithK8sVolumeType(labelValueGCEPDVolume), - // GCP specific labels. - metadata.WithGcePdName(vs.PDName), - metadata.WithFsType(vs.FSType), - metadata.WithPartition(strconv.Itoa(int(vs.Partition))), - } +func gcePersistentDiskDims(rb *metadata.ResourceBuilder, vs v1.GCEPersistentDiskVolumeSource) { + rb.SetK8sVolumeType(labelValueGCEPDVolume) + // GCP specific labels. + rb.SetGcePdName(vs.PDName) + rb.SetFsType(vs.FSType) + rb.SetPartition(strconv.Itoa(int(vs.Partition))) } -func glusterfsDims(vs v1.GlusterfsVolumeSource) []metadata.ResourceMetricsOption { - return []metadata.ResourceMetricsOption{ - metadata.WithK8sVolumeType(labelValueGlusterFSVolume), - // GlusterFS specific labels. - metadata.WithGlusterfsEndpointsName(vs.EndpointsName), - metadata.WithGlusterfsPath(vs.Path), - } +func glusterfsDims(rb *metadata.ResourceBuilder, vs v1.GlusterfsVolumeSource) { + rb.SetK8sVolumeType(labelValueGlusterFSVolume) + // GlusterFS specific labels. + rb.SetGlusterfsEndpointsName(vs.EndpointsName) + rb.SetGlusterfsPath(vs.Path) } diff --git a/receiver/kubeletstatsreceiver/internal/kubelet/volume_test.go b/receiver/kubeletstatsreceiver/internal/kubelet/volume_test.go index 466bb19420c9..bc0ef5dfc300 100644 --- a/receiver/kubeletstatsreceiver/internal/kubelet/volume_test.go +++ b/receiver/kubeletstatsreceiver/internal/kubelet/volume_test.go @@ -7,7 +7,6 @@ import ( "testing" "github.com/stretchr/testify/require" - "go.opentelemetry.io/collector/pdata/pmetric" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" @@ -29,7 +28,7 @@ func TestDetailedPVCLabels(t *testing.T) { volumeName string volumeSource v1.VolumeSource pod pod - detailedPVCLabelsSetterOverride func(volCacheID, volumeClaim, namespace string) ([]metadata.ResourceMetricsOption, error) + detailedPVCLabelsSetterOverride func(rb *metadata.ResourceBuilder, volCacheID, volumeClaim, namespace string) error want map[string]interface{} }{ { @@ -41,15 +40,15 @@ func TestDetailedPVCLabels(t *testing.T) { }, }, pod: pod{uid: "uid-1234", name: "pod-name", namespace: "pod-namespace"}, - detailedPVCLabelsSetterOverride: func(volCacheID, volumeClaim, namespace string) ([]metadata.ResourceMetricsOption, error) { - ro := GetPersistentVolumeLabels(v1.PersistentVolumeSource{ + detailedPVCLabelsSetterOverride: func(rb *metadata.ResourceBuilder, volCacheID, volumeClaim, namespace string) error { + SetPersistentVolumeLabels(rb, v1.PersistentVolumeSource{ AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{ VolumeID: "volume_id", FSType: "fs_type", Partition: 10, }, }) - return ro, nil + return nil }, want: map[string]interface{}{ "k8s.volume.name": "volume0", @@ -72,15 +71,15 @@ func TestDetailedPVCLabels(t *testing.T) { }, }, pod: pod{uid: "uid-1234", name: "pod-name", namespace: "pod-namespace"}, - detailedPVCLabelsSetterOverride: func(volCacheID, volumeClaim, namespace string) ([]metadata.ResourceMetricsOption, error) { - ro := GetPersistentVolumeLabels(v1.PersistentVolumeSource{ + detailedPVCLabelsSetterOverride: func(rb *metadata.ResourceBuilder, volCacheID, volumeClaim, namespace string) error { + SetPersistentVolumeLabels(rb, v1.PersistentVolumeSource{ GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{ PDName: "pd_name", FSType: "fs_type", Partition: 10, }, }) - return ro, nil + return nil }, want: map[string]interface{}{ "k8s.volume.name": "volume0", @@ -103,14 +102,14 @@ func TestDetailedPVCLabels(t *testing.T) { }, }, pod: pod{uid: "uid-1234", name: "pod-name", namespace: "pod-namespace"}, - detailedPVCLabelsSetterOverride: func(volCacheID, volumeClaim, namespace string) ([]metadata.ResourceMetricsOption, error) { - ro := GetPersistentVolumeLabels(v1.PersistentVolumeSource{ + detailedPVCLabelsSetterOverride: func(rb *metadata.ResourceBuilder, volCacheID, volumeClaim, namespace string) error { + SetPersistentVolumeLabels(rb, v1.PersistentVolumeSource{ Glusterfs: &v1.GlusterfsPersistentVolumeSource{ EndpointsName: "endpoints_name", Path: "path", }, }) - return ro, nil + return nil }, want: map[string]interface{}{ "k8s.volume.name": "volume0", @@ -132,13 +131,13 @@ func TestDetailedPVCLabels(t *testing.T) { }, }, pod: pod{uid: "uid-1234", name: "pod-name", namespace: "pod-namespace"}, - detailedPVCLabelsSetterOverride: func(volCacheID, volumeClaim, namespace string) ([]metadata.ResourceMetricsOption, error) { - ro := GetPersistentVolumeLabels(v1.PersistentVolumeSource{ + detailedPVCLabelsSetterOverride: func(rb *metadata.ResourceBuilder, volCacheID, volumeClaim, namespace string) error { + SetPersistentVolumeLabels(rb, v1.PersistentVolumeSource{ Local: &v1.LocalVolumeSource{ Path: "path", }, }) - return ro, nil + return nil }, want: map[string]interface{}{ "k8s.volume.name": "volume0", @@ -159,7 +158,7 @@ func TestDetailedPVCLabels(t *testing.T) { Namespace: tt.pod.namespace, }, } - rac := metadata.DefaultResourceAttributesConfig() + rb := metadata.NewResourceBuilder(metadata.DefaultResourceAttributesConfig()) metadata := NewMetadata([]MetadataLabel{MetadataLabelVolumeType}, &v1.PodList{ Items: []v1.Pod{ { @@ -179,17 +178,12 @@ func TestDetailedPVCLabels(t *testing.T) { }, }, }, nil) - metadata.DetailedPVCResourceGetter = tt.detailedPVCLabelsSetterOverride + metadata.DetailedPVCResourceSetter = tt.detailedPVCLabelsSetterOverride - ro, err := getVolumeResourceOptions(podStats, stats.VolumeStats{Name: tt.volumeName}, metadata) + res, err := getVolumeResourceOptions(rb, podStats, stats.VolumeStats{Name: tt.volumeName}, metadata) require.NoError(t, err) - volumeResourceMetrics := pmetric.NewResourceMetrics() - for _, op := range ro { - op(rac, volumeResourceMetrics) - } - - require.Equal(t, tt.want, volumeResourceMetrics.Resource().Attributes().AsRaw()) + require.Equal(t, tt.want, res.Attributes().AsRaw()) }) } } diff --git a/receiver/kubeletstatsreceiver/internal/metadata/generated_config_test.go b/receiver/kubeletstatsreceiver/internal/metadata/generated_config_test.go index bc619d6733de..3d2b0ff02228 100644 --- a/receiver/kubeletstatsreceiver/internal/metadata/generated_config_test.go +++ b/receiver/kubeletstatsreceiver/internal/metadata/generated_config_test.go @@ -174,3 +174,75 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + AwsVolumeID: ResourceAttributeConfig{Enabled: true}, + ContainerID: ResourceAttributeConfig{Enabled: true}, + FsType: ResourceAttributeConfig{Enabled: true}, + GcePdName: ResourceAttributeConfig{Enabled: true}, + GlusterfsEndpointsName: ResourceAttributeConfig{Enabled: true}, + GlusterfsPath: ResourceAttributeConfig{Enabled: true}, + K8sContainerName: ResourceAttributeConfig{Enabled: true}, + K8sNamespaceName: ResourceAttributeConfig{Enabled: true}, + K8sNodeName: ResourceAttributeConfig{Enabled: true}, + K8sPersistentvolumeclaimName: ResourceAttributeConfig{Enabled: true}, + K8sPodName: ResourceAttributeConfig{Enabled: true}, + K8sPodUID: ResourceAttributeConfig{Enabled: true}, + K8sVolumeName: ResourceAttributeConfig{Enabled: true}, + K8sVolumeType: ResourceAttributeConfig{Enabled: true}, + Partition: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + AwsVolumeID: ResourceAttributeConfig{Enabled: false}, + ContainerID: ResourceAttributeConfig{Enabled: false}, + FsType: ResourceAttributeConfig{Enabled: false}, + GcePdName: ResourceAttributeConfig{Enabled: false}, + GlusterfsEndpointsName: ResourceAttributeConfig{Enabled: false}, + GlusterfsPath: ResourceAttributeConfig{Enabled: false}, + K8sContainerName: ResourceAttributeConfig{Enabled: false}, + K8sNamespaceName: ResourceAttributeConfig{Enabled: false}, + K8sNodeName: ResourceAttributeConfig{Enabled: false}, + K8sPersistentvolumeclaimName: ResourceAttributeConfig{Enabled: false}, + K8sPodName: ResourceAttributeConfig{Enabled: false}, + K8sPodUID: ResourceAttributeConfig{Enabled: false}, + K8sVolumeName: ResourceAttributeConfig{Enabled: false}, + K8sVolumeType: ResourceAttributeConfig{Enabled: false}, + Partition: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/kubeletstatsreceiver/internal/metadata/generated_metrics.go b/receiver/kubeletstatsreceiver/internal/metadata/generated_metrics.go index dd123a5b2fc5..d3558f0d6cfd 100644 --- a/receiver/kubeletstatsreceiver/internal/metadata/generated_metrics.go +++ b/receiver/kubeletstatsreceiver/internal/metadata/generated_metrics.go @@ -2126,10 +2126,8 @@ func newMetricK8sVolumeInodesUsed(cfg MetricConfig) metricK8sVolumeInodesUsed { type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricContainerCPUTime metricContainerCPUTime metricContainerCPUUtilization metricContainerCPUUtilization metricContainerFilesystemAvailable metricContainerFilesystemAvailable @@ -2189,7 +2187,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricContainerCPUTime: newMetricContainerCPUTime(mbc.Metrics.ContainerCPUTime), metricContainerCPUUtilization: newMetricContainerCPUUtilization(mbc.Metrics.ContainerCPUUtilization), metricContainerFilesystemAvailable: newMetricContainerFilesystemAvailable(mbc.Metrics.ContainerFilesystemAvailable), @@ -2244,153 +2241,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithAwsVolumeID sets provided value as "aws.volume.id" attribute for current resource. -func WithAwsVolumeID(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.AwsVolumeID.Enabled { - rm.Resource().Attributes().PutStr("aws.volume.id", val) - } - } -} - -// WithContainerID sets provided value as "container.id" attribute for current resource. -func WithContainerID(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.ContainerID.Enabled { - rm.Resource().Attributes().PutStr("container.id", val) - } - } -} - -// WithFsType sets provided value as "fs.type" attribute for current resource. -func WithFsType(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.FsType.Enabled { - rm.Resource().Attributes().PutStr("fs.type", val) - } - } -} - -// WithGcePdName sets provided value as "gce.pd.name" attribute for current resource. -func WithGcePdName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.GcePdName.Enabled { - rm.Resource().Attributes().PutStr("gce.pd.name", val) - } - } -} - -// WithGlusterfsEndpointsName sets provided value as "glusterfs.endpoints.name" attribute for current resource. -func WithGlusterfsEndpointsName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.GlusterfsEndpointsName.Enabled { - rm.Resource().Attributes().PutStr("glusterfs.endpoints.name", val) - } - } -} - -// WithGlusterfsPath sets provided value as "glusterfs.path" attribute for current resource. -func WithGlusterfsPath(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.GlusterfsPath.Enabled { - rm.Resource().Attributes().PutStr("glusterfs.path", val) - } - } -} - -// WithK8sContainerName sets provided value as "k8s.container.name" attribute for current resource. -func WithK8sContainerName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sContainerName.Enabled { - rm.Resource().Attributes().PutStr("k8s.container.name", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithK8sNamespaceName sets provided value as "k8s.namespace.name" attribute for current resource. -func WithK8sNamespaceName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sNamespaceName.Enabled { - rm.Resource().Attributes().PutStr("k8s.namespace.name", val) - } - } -} - -// WithK8sNodeName sets provided value as "k8s.node.name" attribute for current resource. -func WithK8sNodeName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sNodeName.Enabled { - rm.Resource().Attributes().PutStr("k8s.node.name", val) - } - } -} - -// WithK8sPersistentvolumeclaimName sets provided value as "k8s.persistentvolumeclaim.name" attribute for current resource. -func WithK8sPersistentvolumeclaimName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sPersistentvolumeclaimName.Enabled { - rm.Resource().Attributes().PutStr("k8s.persistentvolumeclaim.name", val) - } - } -} - -// WithK8sPodName sets provided value as "k8s.pod.name" attribute for current resource. -func WithK8sPodName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sPodName.Enabled { - rm.Resource().Attributes().PutStr("k8s.pod.name", val) - } - } -} - -// WithK8sPodUID sets provided value as "k8s.pod.uid" attribute for current resource. -func WithK8sPodUID(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sPodUID.Enabled { - rm.Resource().Attributes().PutStr("k8s.pod.uid", val) - } - } -} - -// WithK8sVolumeName sets provided value as "k8s.volume.name" attribute for current resource. -func WithK8sVolumeName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sVolumeName.Enabled { - rm.Resource().Attributes().PutStr("k8s.volume.name", val) - } - } -} - -// WithK8sVolumeType sets provided value as "k8s.volume.type" attribute for current resource. -func WithK8sVolumeType(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.K8sVolumeType.Enabled { - rm.Resource().Attributes().PutStr("k8s.volume.type", val) - } - } -} - -// WithPartition sets provided value as "partition" attribute for current resource. -func WithPartition(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.Partition.Enabled { - rm.Resource().Attributes().PutStr("partition", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -2414,7 +2281,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/kubeletstatsreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -2463,7 +2329,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricK8sVolumeInodesUsed.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/kubeletstatsreceiver/internal/metadata/generated_metrics_test.go b/receiver/kubeletstatsreceiver/internal/metadata/generated_metrics_test.go index ab9fc302404d..f71918e04c63 100644 --- a/receiver/kubeletstatsreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/kubeletstatsreceiver/internal/metadata/generated_metrics_test.go @@ -222,7 +222,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordK8sVolumeInodesUsedDataPoint(ts, 1) - metrics := mb.Emit(WithAwsVolumeID("aws.volume.id-val"), WithContainerID("container.id-val"), WithFsType("fs.type-val"), WithGcePdName("gce.pd.name-val"), WithGlusterfsEndpointsName("glusterfs.endpoints.name-val"), WithGlusterfsPath("glusterfs.path-val"), WithK8sContainerName("k8s.container.name-val"), WithK8sNamespaceName("k8s.namespace.name-val"), WithK8sNodeName("k8s.node.name-val"), WithK8sPersistentvolumeclaimName("k8s.persistentvolumeclaim.name-val"), WithK8sPodName("k8s.pod.name-val"), WithK8sPodUID("k8s.pod.uid-val"), WithK8sVolumeName("k8s.volume.name-val"), WithK8sVolumeType("k8s.volume.type-val"), WithPartition("partition-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -231,116 +233,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("aws.volume.id") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.AwsVolumeID.Enabled, ok) - if mb.resourceAttributesConfig.AwsVolumeID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "aws.volume.id-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("container.id") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.ContainerID.Enabled, ok) - if mb.resourceAttributesConfig.ContainerID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "container.id-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("fs.type") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.FsType.Enabled, ok) - if mb.resourceAttributesConfig.FsType.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "fs.type-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("gce.pd.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.GcePdName.Enabled, ok) - if mb.resourceAttributesConfig.GcePdName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "gce.pd.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("glusterfs.endpoints.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.GlusterfsEndpointsName.Enabled, ok) - if mb.resourceAttributesConfig.GlusterfsEndpointsName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "glusterfs.endpoints.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("glusterfs.path") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.GlusterfsPath.Enabled, ok) - if mb.resourceAttributesConfig.GlusterfsPath.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "glusterfs.path-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.container.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sContainerName.Enabled, ok) - if mb.resourceAttributesConfig.K8sContainerName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.container.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.namespace.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sNamespaceName.Enabled, ok) - if mb.resourceAttributesConfig.K8sNamespaceName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.namespace.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.node.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sNodeName.Enabled, ok) - if mb.resourceAttributesConfig.K8sNodeName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.node.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.persistentvolumeclaim.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sPersistentvolumeclaimName.Enabled, ok) - if mb.resourceAttributesConfig.K8sPersistentvolumeclaimName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.persistentvolumeclaim.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.pod.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sPodName.Enabled, ok) - if mb.resourceAttributesConfig.K8sPodName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.pod.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.pod.uid") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sPodUID.Enabled, ok) - if mb.resourceAttributesConfig.K8sPodUID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.pod.uid-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.volume.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sVolumeName.Enabled, ok) - if mb.resourceAttributesConfig.K8sVolumeName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.volume.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("k8s.volume.type") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.K8sVolumeType.Enabled, ok) - if mb.resourceAttributesConfig.K8sVolumeType.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "k8s.volume.type-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("partition") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.Partition.Enabled, ok) - if mb.resourceAttributesConfig.Partition.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "partition-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 15) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/kubeletstatsreceiver/internal/metadata/generated_resource.go b/receiver/kubeletstatsreceiver/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..c30835b4af74 --- /dev/null +++ b/receiver/kubeletstatsreceiver/internal/metadata/generated_resource.go @@ -0,0 +1,134 @@ +// 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(), + } +} + +// SetAwsVolumeID sets provided value as "aws.volume.id" attribute. +func (rb *ResourceBuilder) SetAwsVolumeID(val string) { + if rb.config.AwsVolumeID.Enabled { + rb.res.Attributes().PutStr("aws.volume.id", val) + } +} + +// SetContainerID sets provided value as "container.id" attribute. +func (rb *ResourceBuilder) SetContainerID(val string) { + if rb.config.ContainerID.Enabled { + rb.res.Attributes().PutStr("container.id", val) + } +} + +// SetFsType sets provided value as "fs.type" attribute. +func (rb *ResourceBuilder) SetFsType(val string) { + if rb.config.FsType.Enabled { + rb.res.Attributes().PutStr("fs.type", val) + } +} + +// SetGcePdName sets provided value as "gce.pd.name" attribute. +func (rb *ResourceBuilder) SetGcePdName(val string) { + if rb.config.GcePdName.Enabled { + rb.res.Attributes().PutStr("gce.pd.name", val) + } +} + +// SetGlusterfsEndpointsName sets provided value as "glusterfs.endpoints.name" attribute. +func (rb *ResourceBuilder) SetGlusterfsEndpointsName(val string) { + if rb.config.GlusterfsEndpointsName.Enabled { + rb.res.Attributes().PutStr("glusterfs.endpoints.name", val) + } +} + +// SetGlusterfsPath sets provided value as "glusterfs.path" attribute. +func (rb *ResourceBuilder) SetGlusterfsPath(val string) { + if rb.config.GlusterfsPath.Enabled { + rb.res.Attributes().PutStr("glusterfs.path", val) + } +} + +// SetK8sContainerName sets provided value as "k8s.container.name" attribute. +func (rb *ResourceBuilder) SetK8sContainerName(val string) { + if rb.config.K8sContainerName.Enabled { + rb.res.Attributes().PutStr("k8s.container.name", val) + } +} + +// SetK8sNamespaceName sets provided value as "k8s.namespace.name" attribute. +func (rb *ResourceBuilder) SetK8sNamespaceName(val string) { + if rb.config.K8sNamespaceName.Enabled { + rb.res.Attributes().PutStr("k8s.namespace.name", val) + } +} + +// SetK8sNodeName sets provided value as "k8s.node.name" attribute. +func (rb *ResourceBuilder) SetK8sNodeName(val string) { + if rb.config.K8sNodeName.Enabled { + rb.res.Attributes().PutStr("k8s.node.name", val) + } +} + +// SetK8sPersistentvolumeclaimName sets provided value as "k8s.persistentvolumeclaim.name" attribute. +func (rb *ResourceBuilder) SetK8sPersistentvolumeclaimName(val string) { + if rb.config.K8sPersistentvolumeclaimName.Enabled { + rb.res.Attributes().PutStr("k8s.persistentvolumeclaim.name", val) + } +} + +// SetK8sPodName sets provided value as "k8s.pod.name" attribute. +func (rb *ResourceBuilder) SetK8sPodName(val string) { + if rb.config.K8sPodName.Enabled { + rb.res.Attributes().PutStr("k8s.pod.name", val) + } +} + +// SetK8sPodUID sets provided value as "k8s.pod.uid" attribute. +func (rb *ResourceBuilder) SetK8sPodUID(val string) { + if rb.config.K8sPodUID.Enabled { + rb.res.Attributes().PutStr("k8s.pod.uid", val) + } +} + +// SetK8sVolumeName sets provided value as "k8s.volume.name" attribute. +func (rb *ResourceBuilder) SetK8sVolumeName(val string) { + if rb.config.K8sVolumeName.Enabled { + rb.res.Attributes().PutStr("k8s.volume.name", val) + } +} + +// SetK8sVolumeType sets provided value as "k8s.volume.type" attribute. +func (rb *ResourceBuilder) SetK8sVolumeType(val string) { + if rb.config.K8sVolumeType.Enabled { + rb.res.Attributes().PutStr("k8s.volume.type", val) + } +} + +// SetPartition sets provided value as "partition" attribute. +func (rb *ResourceBuilder) SetPartition(val string) { + if rb.config.Partition.Enabled { + rb.res.Attributes().PutStr("partition", 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/receiver/kubeletstatsreceiver/internal/metadata/generated_resource_test.go b/receiver/kubeletstatsreceiver/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..8c6699ef0207 --- /dev/null +++ b/receiver/kubeletstatsreceiver/internal/metadata/generated_resource_test.go @@ -0,0 +1,124 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetAwsVolumeID("aws.volume.id-val") + rb.SetContainerID("container.id-val") + rb.SetFsType("fs.type-val") + rb.SetGcePdName("gce.pd.name-val") + rb.SetGlusterfsEndpointsName("glusterfs.endpoints.name-val") + rb.SetGlusterfsPath("glusterfs.path-val") + rb.SetK8sContainerName("k8s.container.name-val") + rb.SetK8sNamespaceName("k8s.namespace.name-val") + rb.SetK8sNodeName("k8s.node.name-val") + rb.SetK8sPersistentvolumeclaimName("k8s.persistentvolumeclaim.name-val") + rb.SetK8sPodName("k8s.pod.name-val") + rb.SetK8sPodUID("k8s.pod.uid-val") + rb.SetK8sVolumeName("k8s.volume.name-val") + rb.SetK8sVolumeType("k8s.volume.type-val") + rb.SetPartition("partition-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 15, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 15, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("aws.volume.id") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "aws.volume.id-val", val.Str()) + } + val, ok = res.Attributes().Get("container.id") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "container.id-val", val.Str()) + } + val, ok = res.Attributes().Get("fs.type") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "fs.type-val", val.Str()) + } + val, ok = res.Attributes().Get("gce.pd.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "gce.pd.name-val", val.Str()) + } + val, ok = res.Attributes().Get("glusterfs.endpoints.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "glusterfs.endpoints.name-val", val.Str()) + } + val, ok = res.Attributes().Get("glusterfs.path") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "glusterfs.path-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.container.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.container.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.namespace.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.namespace.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.node.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.node.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.persistentvolumeclaim.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.persistentvolumeclaim.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.pod.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.pod.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.pod.uid") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.pod.uid-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.volume.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.volume.name-val", val.Str()) + } + val, ok = res.Attributes().Get("k8s.volume.type") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "k8s.volume.type-val", val.Str()) + } + val, ok = res.Attributes().Get("partition") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "partition-val", val.Str()) + } + }) + } +} diff --git a/receiver/kubeletstatsreceiver/scraper.go b/receiver/kubeletstatsreceiver/scraper.go index 461389349c68..2d27ede54a07 100644 --- a/receiver/kubeletstatsreceiver/scraper.go +++ b/receiver/kubeletstatsreceiver/scraper.go @@ -34,7 +34,8 @@ type kubletScraper struct { extraMetadataLabels []kubelet.MetadataLabel metricGroupsToCollect map[kubelet.MetricGroup]bool k8sAPIClient kubernetes.Interface - cachedVolumeLabels map[string][]metadata.ResourceMetricsOption + cachedVolumeSource map[string]v1.PersistentVolumeSource + rb *metadata.ResourceBuilder mbs *metadata.MetricsBuilders } @@ -51,7 +52,8 @@ func newKubletScraper( extraMetadataLabels: rOptions.extraMetadataLabels, metricGroupsToCollect: rOptions.metricGroupsToCollect, k8sAPIClient: rOptions.k8sAPIClient, - cachedVolumeLabels: make(map[string][]metadata.ResourceMetricsOption), + cachedVolumeSource: make(map[string]v1.PersistentVolumeSource), + rb: metadata.NewResourceBuilder(metricsConfig.ResourceAttributes), mbs: &metadata.MetricsBuilders{ NodeMetricsBuilder: metadata.NewMetricsBuilder(metricsConfig, set), PodMetricsBuilder: metadata.NewMetricsBuilder(metricsConfig, set), @@ -80,7 +82,7 @@ func (r *kubletScraper) scrape(context.Context) (pmetric.Metrics, error) { } metadata := kubelet.NewMetadata(r.extraMetadataLabels, podsMetadata, r.detailedPVCLabelsSetter()) - mds := kubelet.MetricsData(r.logger, summary, metadata, r.metricGroupsToCollect, r.mbs) + mds := kubelet.MetricsData(r.logger, summary, metadata, r.metricGroupsToCollect, r.rb, r.mbs) md := pmetric.NewMetrics() for i := range mds { mds[i].ResourceMetrics().MoveAndAppendTo(md.ResourceMetrics()) @@ -88,34 +90,33 @@ func (r *kubletScraper) scrape(context.Context) (pmetric.Metrics, error) { return md, nil } -func (r *kubletScraper) detailedPVCLabelsSetter() func(volCacheID, volumeClaim, namespace string) ([]metadata.ResourceMetricsOption, error) { - return func(volCacheID, volumeClaim, namespace string) ([]metadata.ResourceMetricsOption, error) { +func (r *kubletScraper) detailedPVCLabelsSetter() func(rb *metadata.ResourceBuilder, volCacheID, volumeClaim, namespace string) error { + return func(rb *metadata.ResourceBuilder, volCacheID, volumeClaim, namespace string) error { if r.k8sAPIClient == nil { - return nil, nil + return nil } - if r.cachedVolumeLabels[volCacheID] == nil { + if _, ok := r.cachedVolumeSource[volCacheID]; !ok { ctx := context.Background() pvc, err := r.k8sAPIClient.CoreV1().PersistentVolumeClaims(namespace).Get(ctx, volumeClaim, metav1.GetOptions{}) if err != nil { - return nil, err + return err } volName := pvc.Spec.VolumeName if volName == "" { - return nil, fmt.Errorf("PersistentVolumeClaim %s does not have a volume name", pvc.Name) + return fmt.Errorf("PersistentVolumeClaim %s does not have a volume name", pvc.Name) } pv, err := r.k8sAPIClient.CoreV1().PersistentVolumes().Get(ctx, volName, metav1.GetOptions{}) if err != nil { - return nil, err + return err } - ro := kubelet.GetPersistentVolumeLabels(pv.Spec.PersistentVolumeSource) - - // Cache collected labels. - r.cachedVolumeLabels[volCacheID] = ro + // Cache collected source. + r.cachedVolumeSource[volCacheID] = pv.Spec.PersistentVolumeSource } - return r.cachedVolumeLabels[volCacheID], nil + kubelet.SetPersistentVolumeLabels(rb, r.cachedVolumeSource[volCacheID]) + return nil } } diff --git a/receiver/memcachedreceiver/internal/metadata/generated_metrics.go b/receiver/memcachedreceiver/internal/metadata/generated_metrics.go index a2195b1fa916..1d1eca2136a9 100644 --- a/receiver/memcachedreceiver/internal/metadata/generated_metrics.go +++ b/receiver/memcachedreceiver/internal/metadata/generated_metrics.go @@ -726,7 +726,6 @@ func newMetricMemcachedThreads(cfg MetricConfig) metricMemcachedThreads { type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information metricMemcachedBytes metricMemcachedBytes @@ -780,14 +779,19 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. type ResourceMetricsOption func(pmetric.ResourceMetrics) +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) + } +} + // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { @@ -815,7 +819,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/memcachedreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) diff --git a/receiver/memcachedreceiver/internal/metadata/generated_metrics_test.go b/receiver/memcachedreceiver/internal/metadata/generated_metrics_test.go index 2d4659cb79ab..4a0b5ef4e881 100644 --- a/receiver/memcachedreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/memcachedreceiver/internal/metadata/generated_metrics_test.go @@ -98,7 +98,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordMemcachedThreadsDataPoint(ts, 1) - metrics := mb.Emit() + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -107,11 +109,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 0) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/mongodbatlasreceiver/internal/metadata/generated_config_test.go b/receiver/mongodbatlasreceiver/internal/metadata/generated_config_test.go index aa29d310e123..1bbb93a8f7f8 100644 --- a/receiver/mongodbatlasreceiver/internal/metadata/generated_config_test.go +++ b/receiver/mongodbatlasreceiver/internal/metadata/generated_config_test.go @@ -206,3 +206,67 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + MongodbAtlasClusterName: ResourceAttributeConfig{Enabled: true}, + MongodbAtlasDbName: ResourceAttributeConfig{Enabled: true}, + MongodbAtlasDiskPartition: ResourceAttributeConfig{Enabled: true}, + MongodbAtlasHostName: ResourceAttributeConfig{Enabled: true}, + MongodbAtlasOrgName: ResourceAttributeConfig{Enabled: true}, + MongodbAtlasProcessID: ResourceAttributeConfig{Enabled: true}, + MongodbAtlasProcessPort: ResourceAttributeConfig{Enabled: true}, + MongodbAtlasProcessTypeName: ResourceAttributeConfig{Enabled: true}, + MongodbAtlasProjectID: ResourceAttributeConfig{Enabled: true}, + MongodbAtlasProjectName: ResourceAttributeConfig{Enabled: true}, + MongodbAtlasUserAlias: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + MongodbAtlasClusterName: ResourceAttributeConfig{Enabled: false}, + MongodbAtlasDbName: ResourceAttributeConfig{Enabled: false}, + MongodbAtlasDiskPartition: ResourceAttributeConfig{Enabled: false}, + MongodbAtlasHostName: ResourceAttributeConfig{Enabled: false}, + MongodbAtlasOrgName: ResourceAttributeConfig{Enabled: false}, + MongodbAtlasProcessID: ResourceAttributeConfig{Enabled: false}, + MongodbAtlasProcessPort: ResourceAttributeConfig{Enabled: false}, + MongodbAtlasProcessTypeName: ResourceAttributeConfig{Enabled: false}, + MongodbAtlasProjectID: ResourceAttributeConfig{Enabled: false}, + MongodbAtlasProjectName: ResourceAttributeConfig{Enabled: false}, + MongodbAtlasUserAlias: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/mongodbatlasreceiver/internal/metadata/generated_metrics.go b/receiver/mongodbatlasreceiver/internal/metadata/generated_metrics.go index 4a8080728e96..067de1a3503a 100644 --- a/receiver/mongodbatlasreceiver/internal/metadata/generated_metrics.go +++ b/receiver/mongodbatlasreceiver/internal/metadata/generated_metrics.go @@ -3885,10 +3885,8 @@ func newMetricMongodbatlasSystemPagingUsageMax(cfg MetricConfig) metricMongodbat type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricMongodbatlasDbCounts metricMongodbatlasDbCounts metricMongodbatlasDbSize metricMongodbatlasDbSize metricMongodbatlasDiskPartitionIopsAverage metricMongodbatlasDiskPartitionIopsAverage @@ -3968,7 +3966,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricMongodbatlasDbCounts: newMetricMongodbatlasDbCounts(mbc.Metrics.MongodbatlasDbCounts), metricMongodbatlasDbSize: newMetricMongodbatlasDbSize(mbc.Metrics.MongodbatlasDbSize), metricMongodbatlasDiskPartitionIopsAverage: newMetricMongodbatlasDiskPartitionIopsAverage(mbc.Metrics.MongodbatlasDiskPartitionIopsAverage), @@ -4043,117 +4040,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithMongodbAtlasClusterName sets provided value as "mongodb_atlas.cluster.name" attribute for current resource. -func WithMongodbAtlasClusterName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.MongodbAtlasClusterName.Enabled { - rm.Resource().Attributes().PutStr("mongodb_atlas.cluster.name", val) - } - } -} - -// WithMongodbAtlasDbName sets provided value as "mongodb_atlas.db.name" attribute for current resource. -func WithMongodbAtlasDbName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.MongodbAtlasDbName.Enabled { - rm.Resource().Attributes().PutStr("mongodb_atlas.db.name", val) - } - } -} - -// WithMongodbAtlasDiskPartition sets provided value as "mongodb_atlas.disk.partition" attribute for current resource. -func WithMongodbAtlasDiskPartition(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.MongodbAtlasDiskPartition.Enabled { - rm.Resource().Attributes().PutStr("mongodb_atlas.disk.partition", val) - } - } -} - -// WithMongodbAtlasHostName sets provided value as "mongodb_atlas.host.name" attribute for current resource. -func WithMongodbAtlasHostName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.MongodbAtlasHostName.Enabled { - rm.Resource().Attributes().PutStr("mongodb_atlas.host.name", val) - } - } -} - -// WithMongodbAtlasOrgName sets provided value as "mongodb_atlas.org_name" attribute for current resource. -func WithMongodbAtlasOrgName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.MongodbAtlasOrgName.Enabled { - rm.Resource().Attributes().PutStr("mongodb_atlas.org_name", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithMongodbAtlasProcessID sets provided value as "mongodb_atlas.process.id" attribute for current resource. -func WithMongodbAtlasProcessID(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.MongodbAtlasProcessID.Enabled { - rm.Resource().Attributes().PutStr("mongodb_atlas.process.id", val) - } - } -} - -// WithMongodbAtlasProcessPort sets provided value as "mongodb_atlas.process.port" attribute for current resource. -func WithMongodbAtlasProcessPort(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.MongodbAtlasProcessPort.Enabled { - rm.Resource().Attributes().PutStr("mongodb_atlas.process.port", val) - } - } -} - -// WithMongodbAtlasProcessTypeName sets provided value as "mongodb_atlas.process.type_name" attribute for current resource. -func WithMongodbAtlasProcessTypeName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.MongodbAtlasProcessTypeName.Enabled { - rm.Resource().Attributes().PutStr("mongodb_atlas.process.type_name", val) - } - } -} - -// WithMongodbAtlasProjectID sets provided value as "mongodb_atlas.project.id" attribute for current resource. -func WithMongodbAtlasProjectID(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.MongodbAtlasProjectID.Enabled { - rm.Resource().Attributes().PutStr("mongodb_atlas.project.id", val) - } - } -} - -// WithMongodbAtlasProjectName sets provided value as "mongodb_atlas.project.name" attribute for current resource. -func WithMongodbAtlasProjectName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.MongodbAtlasProjectName.Enabled { - rm.Resource().Attributes().PutStr("mongodb_atlas.project.name", val) - } - } -} - -// WithMongodbAtlasUserAlias sets provided value as "mongodb_atlas.user.alias" attribute for current resource. -func WithMongodbAtlasUserAlias(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.MongodbAtlasUserAlias.Enabled { - rm.Resource().Attributes().PutStr("mongodb_atlas.user.alias", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -4177,7 +4080,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/mongodbatlasreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -4246,7 +4148,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricMongodbatlasSystemPagingUsageMax.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/mongodbatlasreceiver/internal/metadata/generated_metrics_test.go b/receiver/mongodbatlasreceiver/internal/metadata/generated_metrics_test.go index e41ce088f803..19a2ae2084f0 100644 --- a/receiver/mongodbatlasreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/mongodbatlasreceiver/internal/metadata/generated_metrics_test.go @@ -302,7 +302,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordMongodbatlasSystemPagingUsageMaxDataPoint(ts, 1, AttributeMemoryStateResident) - metrics := mb.Emit(WithMongodbAtlasClusterName("mongodb_atlas.cluster.name-val"), WithMongodbAtlasDbName("mongodb_atlas.db.name-val"), WithMongodbAtlasDiskPartition("mongodb_atlas.disk.partition-val"), WithMongodbAtlasHostName("mongodb_atlas.host.name-val"), WithMongodbAtlasOrgName("mongodb_atlas.org_name-val"), WithMongodbAtlasProcessID("mongodb_atlas.process.id-val"), WithMongodbAtlasProcessPort("mongodb_atlas.process.port-val"), WithMongodbAtlasProcessTypeName("mongodb_atlas.process.type_name-val"), WithMongodbAtlasProjectID("mongodb_atlas.project.id-val"), WithMongodbAtlasProjectName("mongodb_atlas.project.name-val"), WithMongodbAtlasUserAlias("mongodb_atlas.user.alias-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -311,88 +313,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("mongodb_atlas.cluster.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.MongodbAtlasClusterName.Enabled, ok) - if mb.resourceAttributesConfig.MongodbAtlasClusterName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "mongodb_atlas.cluster.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("mongodb_atlas.db.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.MongodbAtlasDbName.Enabled, ok) - if mb.resourceAttributesConfig.MongodbAtlasDbName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "mongodb_atlas.db.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("mongodb_atlas.disk.partition") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.MongodbAtlasDiskPartition.Enabled, ok) - if mb.resourceAttributesConfig.MongodbAtlasDiskPartition.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "mongodb_atlas.disk.partition-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("mongodb_atlas.host.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.MongodbAtlasHostName.Enabled, ok) - if mb.resourceAttributesConfig.MongodbAtlasHostName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "mongodb_atlas.host.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("mongodb_atlas.org_name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.MongodbAtlasOrgName.Enabled, ok) - if mb.resourceAttributesConfig.MongodbAtlasOrgName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "mongodb_atlas.org_name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("mongodb_atlas.process.id") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.MongodbAtlasProcessID.Enabled, ok) - if mb.resourceAttributesConfig.MongodbAtlasProcessID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "mongodb_atlas.process.id-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("mongodb_atlas.process.port") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.MongodbAtlasProcessPort.Enabled, ok) - if mb.resourceAttributesConfig.MongodbAtlasProcessPort.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "mongodb_atlas.process.port-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("mongodb_atlas.process.type_name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.MongodbAtlasProcessTypeName.Enabled, ok) - if mb.resourceAttributesConfig.MongodbAtlasProcessTypeName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "mongodb_atlas.process.type_name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("mongodb_atlas.project.id") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.MongodbAtlasProjectID.Enabled, ok) - if mb.resourceAttributesConfig.MongodbAtlasProjectID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "mongodb_atlas.project.id-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("mongodb_atlas.project.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.MongodbAtlasProjectName.Enabled, ok) - if mb.resourceAttributesConfig.MongodbAtlasProjectName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "mongodb_atlas.project.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("mongodb_atlas.user.alias") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.MongodbAtlasUserAlias.Enabled, ok) - if mb.resourceAttributesConfig.MongodbAtlasUserAlias.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "mongodb_atlas.user.alias-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 11) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/mongodbatlasreceiver/internal/metadata/generated_resource.go b/receiver/mongodbatlasreceiver/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..41965211b057 --- /dev/null +++ b/receiver/mongodbatlasreceiver/internal/metadata/generated_resource.go @@ -0,0 +1,106 @@ +// 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(), + } +} + +// SetMongodbAtlasClusterName sets provided value as "mongodb_atlas.cluster.name" attribute. +func (rb *ResourceBuilder) SetMongodbAtlasClusterName(val string) { + if rb.config.MongodbAtlasClusterName.Enabled { + rb.res.Attributes().PutStr("mongodb_atlas.cluster.name", val) + } +} + +// SetMongodbAtlasDbName sets provided value as "mongodb_atlas.db.name" attribute. +func (rb *ResourceBuilder) SetMongodbAtlasDbName(val string) { + if rb.config.MongodbAtlasDbName.Enabled { + rb.res.Attributes().PutStr("mongodb_atlas.db.name", val) + } +} + +// SetMongodbAtlasDiskPartition sets provided value as "mongodb_atlas.disk.partition" attribute. +func (rb *ResourceBuilder) SetMongodbAtlasDiskPartition(val string) { + if rb.config.MongodbAtlasDiskPartition.Enabled { + rb.res.Attributes().PutStr("mongodb_atlas.disk.partition", val) + } +} + +// SetMongodbAtlasHostName sets provided value as "mongodb_atlas.host.name" attribute. +func (rb *ResourceBuilder) SetMongodbAtlasHostName(val string) { + if rb.config.MongodbAtlasHostName.Enabled { + rb.res.Attributes().PutStr("mongodb_atlas.host.name", val) + } +} + +// SetMongodbAtlasOrgName sets provided value as "mongodb_atlas.org_name" attribute. +func (rb *ResourceBuilder) SetMongodbAtlasOrgName(val string) { + if rb.config.MongodbAtlasOrgName.Enabled { + rb.res.Attributes().PutStr("mongodb_atlas.org_name", val) + } +} + +// SetMongodbAtlasProcessID sets provided value as "mongodb_atlas.process.id" attribute. +func (rb *ResourceBuilder) SetMongodbAtlasProcessID(val string) { + if rb.config.MongodbAtlasProcessID.Enabled { + rb.res.Attributes().PutStr("mongodb_atlas.process.id", val) + } +} + +// SetMongodbAtlasProcessPort sets provided value as "mongodb_atlas.process.port" attribute. +func (rb *ResourceBuilder) SetMongodbAtlasProcessPort(val string) { + if rb.config.MongodbAtlasProcessPort.Enabled { + rb.res.Attributes().PutStr("mongodb_atlas.process.port", val) + } +} + +// SetMongodbAtlasProcessTypeName sets provided value as "mongodb_atlas.process.type_name" attribute. +func (rb *ResourceBuilder) SetMongodbAtlasProcessTypeName(val string) { + if rb.config.MongodbAtlasProcessTypeName.Enabled { + rb.res.Attributes().PutStr("mongodb_atlas.process.type_name", val) + } +} + +// SetMongodbAtlasProjectID sets provided value as "mongodb_atlas.project.id" attribute. +func (rb *ResourceBuilder) SetMongodbAtlasProjectID(val string) { + if rb.config.MongodbAtlasProjectID.Enabled { + rb.res.Attributes().PutStr("mongodb_atlas.project.id", val) + } +} + +// SetMongodbAtlasProjectName sets provided value as "mongodb_atlas.project.name" attribute. +func (rb *ResourceBuilder) SetMongodbAtlasProjectName(val string) { + if rb.config.MongodbAtlasProjectName.Enabled { + rb.res.Attributes().PutStr("mongodb_atlas.project.name", val) + } +} + +// SetMongodbAtlasUserAlias sets provided value as "mongodb_atlas.user.alias" attribute. +func (rb *ResourceBuilder) SetMongodbAtlasUserAlias(val string) { + if rb.config.MongodbAtlasUserAlias.Enabled { + rb.res.Attributes().PutStr("mongodb_atlas.user.alias", 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/receiver/mongodbatlasreceiver/internal/metadata/generated_resource_test.go b/receiver/mongodbatlasreceiver/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..892610eaacb3 --- /dev/null +++ b/receiver/mongodbatlasreceiver/internal/metadata/generated_resource_test.go @@ -0,0 +1,100 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetMongodbAtlasClusterName("mongodb_atlas.cluster.name-val") + rb.SetMongodbAtlasDbName("mongodb_atlas.db.name-val") + rb.SetMongodbAtlasDiskPartition("mongodb_atlas.disk.partition-val") + rb.SetMongodbAtlasHostName("mongodb_atlas.host.name-val") + rb.SetMongodbAtlasOrgName("mongodb_atlas.org_name-val") + rb.SetMongodbAtlasProcessID("mongodb_atlas.process.id-val") + rb.SetMongodbAtlasProcessPort("mongodb_atlas.process.port-val") + rb.SetMongodbAtlasProcessTypeName("mongodb_atlas.process.type_name-val") + rb.SetMongodbAtlasProjectID("mongodb_atlas.project.id-val") + rb.SetMongodbAtlasProjectName("mongodb_atlas.project.name-val") + rb.SetMongodbAtlasUserAlias("mongodb_atlas.user.alias-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 9, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 11, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("mongodb_atlas.cluster.name") + assert.Equal(t, test == "all_set", ok) + if ok { + assert.EqualValues(t, "mongodb_atlas.cluster.name-val", val.Str()) + } + val, ok = res.Attributes().Get("mongodb_atlas.db.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "mongodb_atlas.db.name-val", val.Str()) + } + val, ok = res.Attributes().Get("mongodb_atlas.disk.partition") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "mongodb_atlas.disk.partition-val", val.Str()) + } + val, ok = res.Attributes().Get("mongodb_atlas.host.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "mongodb_atlas.host.name-val", val.Str()) + } + val, ok = res.Attributes().Get("mongodb_atlas.org_name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "mongodb_atlas.org_name-val", val.Str()) + } + val, ok = res.Attributes().Get("mongodb_atlas.process.id") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "mongodb_atlas.process.id-val", val.Str()) + } + val, ok = res.Attributes().Get("mongodb_atlas.process.port") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "mongodb_atlas.process.port-val", val.Str()) + } + val, ok = res.Attributes().Get("mongodb_atlas.process.type_name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "mongodb_atlas.process.type_name-val", val.Str()) + } + val, ok = res.Attributes().Get("mongodb_atlas.project.id") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "mongodb_atlas.project.id-val", val.Str()) + } + val, ok = res.Attributes().Get("mongodb_atlas.project.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "mongodb_atlas.project.name-val", val.Str()) + } + val, ok = res.Attributes().Get("mongodb_atlas.user.alias") + assert.Equal(t, test == "all_set", ok) + if ok { + assert.EqualValues(t, "mongodb_atlas.user.alias-val", val.Str()) + } + }) + } +} diff --git a/receiver/mongodbatlasreceiver/receiver.go b/receiver/mongodbatlasreceiver/receiver.go index 7f4dad0053d9..bb1a75e5debf 100644 --- a/receiver/mongodbatlasreceiver/receiver.go +++ b/receiver/mongodbatlasreceiver/receiver.go @@ -25,6 +25,7 @@ type receiver struct { cfg *Config client *internal.MongoDBAtlasClient lastRun time.Time + rb *metadata.ResourceBuilder mb *metadata.MetricsBuilder stopperChan chan struct{} } @@ -41,6 +42,7 @@ func newMongoDBAtlasReceiver(settings rcvr.CreateSettings, cfg *Config) *receive log: settings.Logger, cfg: cfg, client: client, + rb: metadata.NewResourceBuilder(cfg.MetricsBuilderConfig.ResourceAttributes), mb: metadata.NewMetricsBuilder(cfg.MetricsBuilderConfig, settings), stopperChan: make(chan struct{}), } @@ -161,17 +163,16 @@ func (s *receiver) extractProcessMetrics( return fmt.Errorf("error when polling process metrics from MongoDB Atlas: %w", err) } - s.mb.EmitForResource( - metadata.WithMongodbAtlasOrgName(orgName), - metadata.WithMongodbAtlasProjectName(project.Name), - metadata.WithMongodbAtlasProjectID(project.ID), - metadata.WithMongodbAtlasHostName(process.Hostname), - metadata.WithMongodbAtlasUserAlias(process.UserAlias), - metadata.WithMongodbAtlasClusterName(clusterName), - metadata.WithMongodbAtlasProcessPort(strconv.Itoa(process.Port)), - metadata.WithMongodbAtlasProcessTypeName(process.TypeName), - metadata.WithMongodbAtlasProcessID(process.ID), - ) + s.rb.SetMongodbAtlasOrgName(orgName) + s.rb.SetMongodbAtlasProjectName(project.Name) + s.rb.SetMongodbAtlasProjectID(project.ID) + s.rb.SetMongodbAtlasHostName(process.Hostname) + s.rb.SetMongodbAtlasUserAlias(process.UserAlias) + s.rb.SetMongodbAtlasClusterName(clusterName) + s.rb.SetMongodbAtlasProcessPort(strconv.Itoa(process.Port)) + s.rb.SetMongodbAtlasProcessTypeName(process.TypeName) + s.rb.SetMongodbAtlasProcessID(process.ID) + s.mb.EmitForResource(metadata.WithResource(s.rb.Emit())) return nil } @@ -208,18 +209,17 @@ func (s *receiver) extractProcessDatabaseMetrics( ); err != nil { return fmt.Errorf("error when polling database metrics from MongoDB Atlas: %w", err) } - s.mb.EmitForResource( - metadata.WithMongodbAtlasOrgName(orgName), - metadata.WithMongodbAtlasProjectName(project.Name), - metadata.WithMongodbAtlasProjectID(project.ID), - metadata.WithMongodbAtlasHostName(process.Hostname), - metadata.WithMongodbAtlasUserAlias(process.UserAlias), - metadata.WithMongodbAtlasClusterName(clusterName), - metadata.WithMongodbAtlasProcessPort(strconv.Itoa(process.Port)), - metadata.WithMongodbAtlasProcessTypeName(process.TypeName), - metadata.WithMongodbAtlasProcessID(process.ID), - metadata.WithMongodbAtlasDbName(db.DatabaseName), - ) + s.rb.SetMongodbAtlasOrgName(orgName) + s.rb.SetMongodbAtlasProjectName(project.Name) + s.rb.SetMongodbAtlasProjectID(project.ID) + s.rb.SetMongodbAtlasHostName(process.Hostname) + s.rb.SetMongodbAtlasUserAlias(process.UserAlias) + s.rb.SetMongodbAtlasClusterName(clusterName) + s.rb.SetMongodbAtlasProcessPort(strconv.Itoa(process.Port)) + s.rb.SetMongodbAtlasProcessTypeName(process.TypeName) + s.rb.SetMongodbAtlasProcessID(process.ID) + s.rb.SetMongodbAtlasDbName(db.DatabaseName) + s.mb.EmitForResource(metadata.WithResource(s.rb.Emit())) } return nil } @@ -246,18 +246,17 @@ func (s *receiver) extractProcessDiskMetrics( ); err != nil { return fmt.Errorf("error when polling disk metrics from MongoDB Atlas: %w", err) } - s.mb.EmitForResource( - metadata.WithMongodbAtlasOrgName(orgName), - metadata.WithMongodbAtlasProjectName(project.Name), - metadata.WithMongodbAtlasProjectID(project.ID), - metadata.WithMongodbAtlasHostName(process.Hostname), - metadata.WithMongodbAtlasUserAlias(process.UserAlias), - metadata.WithMongodbAtlasClusterName(clusterName), - metadata.WithMongodbAtlasProcessPort(strconv.Itoa(process.Port)), - metadata.WithMongodbAtlasProcessTypeName(process.TypeName), - metadata.WithMongodbAtlasProcessID(process.ID), - metadata.WithMongodbAtlasDiskPartition(disk.PartitionName), - ) + s.rb.SetMongodbAtlasOrgName(orgName) + s.rb.SetMongodbAtlasProjectName(project.Name) + s.rb.SetMongodbAtlasProjectID(project.ID) + s.rb.SetMongodbAtlasHostName(process.Hostname) + s.rb.SetMongodbAtlasUserAlias(process.UserAlias) + s.rb.SetMongodbAtlasClusterName(clusterName) + s.rb.SetMongodbAtlasProcessPort(strconv.Itoa(process.Port)) + s.rb.SetMongodbAtlasProcessTypeName(process.TypeName) + s.rb.SetMongodbAtlasProcessID(process.ID) + s.rb.SetMongodbAtlasDiskPartition(disk.PartitionName) + s.mb.EmitForResource(metadata.WithResource(s.rb.Emit())) } return nil } diff --git a/receiver/mongodbreceiver/internal/metadata/generated_config_test.go b/receiver/mongodbreceiver/internal/metadata/generated_config_test.go index 3192852782db..34192fe04db0 100644 --- a/receiver/mongodbreceiver/internal/metadata/generated_config_test.go +++ b/receiver/mongodbreceiver/internal/metadata/generated_config_test.go @@ -122,3 +122,47 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + Database: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + Database: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/mongodbreceiver/internal/metadata/generated_metrics.go b/receiver/mongodbreceiver/internal/metadata/generated_metrics.go index 64ade034d716..a006314483ca 100644 --- a/receiver/mongodbreceiver/internal/metadata/generated_metrics.go +++ b/receiver/mongodbreceiver/internal/metadata/generated_metrics.go @@ -1832,10 +1832,8 @@ func newMetricMongodbUptime(cfg MetricConfig) metricMongodbUptime { type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricMongodbCacheOperations metricMongodbCacheOperations metricMongodbCollectionCount metricMongodbCollectionCount metricMongodbConnectionCount metricMongodbConnectionCount @@ -1883,7 +1881,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricMongodbCacheOperations: newMetricMongodbCacheOperations(mbc.Metrics.MongodbCacheOperations), metricMongodbCollectionCount: newMetricMongodbCollectionCount(mbc.Metrics.MongodbCollectionCount), metricMongodbConnectionCount: newMetricMongodbConnectionCount(mbc.Metrics.MongodbConnectionCount), @@ -1926,27 +1923,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithDatabase sets provided value as "database" attribute for current resource. -func WithDatabase(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.Database.Enabled { - rm.Resource().Attributes().PutStr("database", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -1970,7 +1963,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/mongodbreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -2007,7 +1999,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricMongodbUptime.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/mongodbreceiver/internal/metadata/generated_metrics_test.go b/receiver/mongodbreceiver/internal/metadata/generated_metrics_test.go index 6f8e125f8e6a..fca537bf96f7 100644 --- a/receiver/mongodbreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/mongodbreceiver/internal/metadata/generated_metrics_test.go @@ -166,7 +166,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordMongodbUptimeDataPoint(ts, 1) - metrics := mb.Emit(WithDatabase("database-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -175,18 +177,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("database") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.Database.Enabled, ok) - if mb.resourceAttributesConfig.Database.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "database-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 1) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/mongodbreceiver/internal/metadata/generated_resource.go b/receiver/mongodbreceiver/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..7c72b171f2db --- /dev/null +++ b/receiver/mongodbreceiver/internal/metadata/generated_resource.go @@ -0,0 +1,36 @@ +// 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(), + } +} + +// SetDatabase sets provided value as "database" attribute. +func (rb *ResourceBuilder) SetDatabase(val string) { + if rb.config.Database.Enabled { + rb.res.Attributes().PutStr("database", 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/receiver/mongodbreceiver/internal/metadata/generated_resource_test.go b/receiver/mongodbreceiver/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..f5b0127facc2 --- /dev/null +++ b/receiver/mongodbreceiver/internal/metadata/generated_resource_test.go @@ -0,0 +1,40 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetDatabase("database-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 1, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 1, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("database") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "database-val", val.Str()) + } + }) + } +} diff --git a/receiver/mongodbreceiver/scraper.go b/receiver/mongodbreceiver/scraper.go index 873f7bfbb9c5..b7b6d15bf370 100644 --- a/receiver/mongodbreceiver/scraper.go +++ b/receiver/mongodbreceiver/scraper.go @@ -26,6 +26,7 @@ type mongodbScraper struct { config *Config client client mongoVersion *version.Version + rb *metadata.ResourceBuilder mb *metadata.MetricsBuilder } @@ -34,6 +35,7 @@ func newMongodbScraper(settings receiver.CreateSettings, config *Config) *mongod return &mongodbScraper{ logger: settings.Logger, config: config, + rb: metadata.NewResourceBuilder(config.ResourceAttributes), mb: metadata.NewMetricsBuilder(config.MetricsBuilderConfig, settings), mongoVersion: v, } @@ -116,7 +118,8 @@ func (s *mongodbScraper) collectDatabase(ctx context.Context, now pcommon.Timest } s.recordNormalServerStats(now, serverStatus, databaseName, errs) - s.mb.EmitForResource(metadata.WithDatabase(databaseName)) + s.rb.SetDatabase(databaseName) + s.mb.EmitForResource(metadata.WithResource(s.rb.Emit())) } func (s *mongodbScraper) collectAdminDatabase(ctx context.Context, now pcommon.Timestamp, errs *scrapererror.ScrapeErrors) { diff --git a/receiver/mysqlreceiver/internal/metadata/generated_config_test.go b/receiver/mysqlreceiver/internal/metadata/generated_config_test.go index 756e5076836d..72aa48318b82 100644 --- a/receiver/mysqlreceiver/internal/metadata/generated_config_test.go +++ b/receiver/mysqlreceiver/internal/metadata/generated_config_test.go @@ -148,3 +148,47 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + MysqlInstanceEndpoint: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + MysqlInstanceEndpoint: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/mysqlreceiver/internal/metadata/generated_metrics.go b/receiver/mysqlreceiver/internal/metadata/generated_metrics.go index 5b9eb05bbd93..83cd0585c1ae 100644 --- a/receiver/mysqlreceiver/internal/metadata/generated_metrics.go +++ b/receiver/mysqlreceiver/internal/metadata/generated_metrics.go @@ -3272,10 +3272,8 @@ func newMetricMysqlUptime(cfg MetricConfig) metricMysqlUptime { type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricMysqlBufferPoolDataPages metricMysqlBufferPoolDataPages metricMysqlBufferPoolLimit metricMysqlBufferPoolLimit metricMysqlBufferPoolOperations metricMysqlBufferPoolOperations @@ -3336,7 +3334,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricMysqlBufferPoolDataPages: newMetricMysqlBufferPoolDataPages(mbc.Metrics.MysqlBufferPoolDataPages), metricMysqlBufferPoolLimit: newMetricMysqlBufferPoolLimit(mbc.Metrics.MysqlBufferPoolLimit), metricMysqlBufferPoolOperations: newMetricMysqlBufferPoolOperations(mbc.Metrics.MysqlBufferPoolOperations), @@ -3392,27 +3389,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithMysqlInstanceEndpoint sets provided value as "mysql.instance.endpoint" attribute for current resource. -func WithMysqlInstanceEndpoint(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.MysqlInstanceEndpoint.Enabled { - rm.Resource().Attributes().PutStr("mysql.instance.endpoint", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -3436,7 +3429,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/mysqlreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -3486,7 +3478,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricMysqlUptime.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/mysqlreceiver/internal/metadata/generated_metrics_test.go b/receiver/mysqlreceiver/internal/metadata/generated_metrics_test.go index 3d6b0bc9e7da..ee8c92e3d3e5 100644 --- a/receiver/mysqlreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/mysqlreceiver/internal/metadata/generated_metrics_test.go @@ -208,7 +208,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordMysqlUptimeDataPoint(ts, "1") - metrics := mb.Emit(WithMysqlInstanceEndpoint("mysql.instance.endpoint-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -217,18 +219,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("mysql.instance.endpoint") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.MysqlInstanceEndpoint.Enabled, ok) - if mb.resourceAttributesConfig.MysqlInstanceEndpoint.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "mysql.instance.endpoint-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 1) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/mysqlreceiver/internal/metadata/generated_resource.go b/receiver/mysqlreceiver/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..9826df0c4769 --- /dev/null +++ b/receiver/mysqlreceiver/internal/metadata/generated_resource.go @@ -0,0 +1,36 @@ +// 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(), + } +} + +// SetMysqlInstanceEndpoint sets provided value as "mysql.instance.endpoint" attribute. +func (rb *ResourceBuilder) SetMysqlInstanceEndpoint(val string) { + if rb.config.MysqlInstanceEndpoint.Enabled { + rb.res.Attributes().PutStr("mysql.instance.endpoint", 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/receiver/mysqlreceiver/internal/metadata/generated_resource_test.go b/receiver/mysqlreceiver/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..8f087e747e63 --- /dev/null +++ b/receiver/mysqlreceiver/internal/metadata/generated_resource_test.go @@ -0,0 +1,40 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetMysqlInstanceEndpoint("mysql.instance.endpoint-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 1, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 1, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("mysql.instance.endpoint") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "mysql.instance.endpoint-val", val.Str()) + } + }) + } +} diff --git a/receiver/mysqlreceiver/scraper.go b/receiver/mysqlreceiver/scraper.go index 2b613684e147..3995b52af0fe 100644 --- a/receiver/mysqlreceiver/scraper.go +++ b/receiver/mysqlreceiver/scraper.go @@ -27,6 +27,7 @@ type mySQLScraper struct { sqlclient client logger *zap.Logger config *Config + rb *metadata.ResourceBuilder mb *metadata.MetricsBuilder // Feature gates regarding resource attributes @@ -40,6 +41,7 @@ func newMySQLScraper( ms := &mySQLScraper{ logger: settings.Logger, config: config, + rb: metadata.NewResourceBuilder(config.MetricsBuilderConfig.ResourceAttributes), mb: metadata.NewMetricsBuilder(config.MetricsBuilderConfig, settings), } @@ -104,7 +106,8 @@ func (m *mySQLScraper) scrape(context.Context) (pmetric.Metrics, error) { // colect replicas status metrics. m.scrapeReplicaStatusStats(now) - m.mb.EmitForResource(metadata.WithMysqlInstanceEndpoint(m.config.Endpoint)) + m.rb.SetMysqlInstanceEndpoint(m.config.Endpoint) + m.mb.EmitForResource(metadata.WithResource(m.rb.Emit())) return m.mb.Emit(), errs.Combine() } diff --git a/receiver/nginxreceiver/internal/metadata/generated_metrics.go b/receiver/nginxreceiver/internal/metadata/generated_metrics.go index f3d88852be96..724988b828ce 100644 --- a/receiver/nginxreceiver/internal/metadata/generated_metrics.go +++ b/receiver/nginxreceiver/internal/metadata/generated_metrics.go @@ -307,7 +307,6 @@ func newMetricTempConnectionsCurrent(cfg MetricConfig) metricTempConnectionsCurr type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information metricNginxConnectionsAccepted metricNginxConnectionsAccepted @@ -349,14 +348,19 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. type ResourceMetricsOption func(pmetric.ResourceMetrics) +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) + } +} + // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { @@ -384,7 +388,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/nginxreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) diff --git a/receiver/nginxreceiver/internal/metadata/generated_metrics_test.go b/receiver/nginxreceiver/internal/metadata/generated_metrics_test.go index b5ff882b7dff..cc10a1b85ce9 100644 --- a/receiver/nginxreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/nginxreceiver/internal/metadata/generated_metrics_test.go @@ -74,7 +74,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordTempConnectionsCurrentDataPoint(ts, 1, AttributeStateActive) - metrics := mb.Emit() + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -83,11 +85,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 0) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/nsxtreceiver/internal/metadata/generated_config_test.go b/receiver/nsxtreceiver/internal/metadata/generated_config_test.go index 8d1589e35018..d1c12f7b8f24 100644 --- a/receiver/nsxtreceiver/internal/metadata/generated_config_test.go +++ b/receiver/nsxtreceiver/internal/metadata/generated_config_test.go @@ -82,3 +82,53 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + DeviceID: ResourceAttributeConfig{Enabled: true}, + NsxtNodeID: ResourceAttributeConfig{Enabled: true}, + NsxtNodeName: ResourceAttributeConfig{Enabled: true}, + NsxtNodeType: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + DeviceID: ResourceAttributeConfig{Enabled: false}, + NsxtNodeID: ResourceAttributeConfig{Enabled: false}, + NsxtNodeName: ResourceAttributeConfig{Enabled: false}, + NsxtNodeType: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/nsxtreceiver/internal/metadata/generated_metrics.go b/receiver/nsxtreceiver/internal/metadata/generated_metrics.go index 4c613d38f637..bb8dcd798c2a 100644 --- a/receiver/nsxtreceiver/internal/metadata/generated_metrics.go +++ b/receiver/nsxtreceiver/internal/metadata/generated_metrics.go @@ -486,10 +486,8 @@ func newMetricNsxtNodeNetworkPacketCount(cfg MetricConfig) metricNsxtNodeNetwork type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricNsxtNodeCPUUtilization metricNsxtNodeCPUUtilization metricNsxtNodeFilesystemUsage metricNsxtNodeFilesystemUsage metricNsxtNodeFilesystemUtilization metricNsxtNodeFilesystemUtilization @@ -514,7 +512,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricNsxtNodeCPUUtilization: newMetricNsxtNodeCPUUtilization(mbc.Metrics.NsxtNodeCPUUtilization), metricNsxtNodeFilesystemUsage: newMetricNsxtNodeFilesystemUsage(mbc.Metrics.NsxtNodeFilesystemUsage), metricNsxtNodeFilesystemUtilization: newMetricNsxtNodeFilesystemUtilization(mbc.Metrics.NsxtNodeFilesystemUtilization), @@ -534,54 +531,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithDeviceID sets provided value as "device.id" attribute for current resource. -func WithDeviceID(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.DeviceID.Enabled { - rm.Resource().Attributes().PutStr("device.id", val) - } - } -} - -// WithNsxtNodeID sets provided value as "nsxt.node.id" attribute for current resource. -func WithNsxtNodeID(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.NsxtNodeID.Enabled { - rm.Resource().Attributes().PutStr("nsxt.node.id", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithNsxtNodeName sets provided value as "nsxt.node.name" attribute for current resource. -func WithNsxtNodeName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.NsxtNodeName.Enabled { - rm.Resource().Attributes().PutStr("nsxt.node.name", val) - } - } -} - -// WithNsxtNodeType sets provided value as "nsxt.node.type" attribute for current resource. -func WithNsxtNodeType(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.NsxtNodeType.Enabled { - rm.Resource().Attributes().PutStr("nsxt.node.type", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -605,7 +571,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/nsxtreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -619,7 +584,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricNsxtNodeNetworkPacketCount.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/nsxtreceiver/internal/metadata/generated_metrics_test.go b/receiver/nsxtreceiver/internal/metadata/generated_metrics_test.go index a108bdc01bf6..1a55d34adc97 100644 --- a/receiver/nsxtreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/nsxtreceiver/internal/metadata/generated_metrics_test.go @@ -82,7 +82,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordNsxtNodeNetworkPacketCountDataPoint(ts, 1, AttributeDirectionReceived, AttributePacketTypeDropped) - metrics := mb.Emit(WithDeviceID("device.id-val"), WithNsxtNodeID("nsxt.node.id-val"), WithNsxtNodeName("nsxt.node.name-val"), WithNsxtNodeType("nsxt.node.type-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -91,39 +93,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("device.id") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.DeviceID.Enabled, ok) - if mb.resourceAttributesConfig.DeviceID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "device.id-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("nsxt.node.id") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.NsxtNodeID.Enabled, ok) - if mb.resourceAttributesConfig.NsxtNodeID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "nsxt.node.id-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("nsxt.node.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.NsxtNodeName.Enabled, ok) - if mb.resourceAttributesConfig.NsxtNodeName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "nsxt.node.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("nsxt.node.type") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.NsxtNodeType.Enabled, ok) - if mb.resourceAttributesConfig.NsxtNodeType.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "nsxt.node.type-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 4) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/nsxtreceiver/internal/metadata/generated_resource.go b/receiver/nsxtreceiver/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..aefa3bb12008 --- /dev/null +++ b/receiver/nsxtreceiver/internal/metadata/generated_resource.go @@ -0,0 +1,57 @@ +// 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(), + } +} + +// SetDeviceID sets provided value as "device.id" attribute. +func (rb *ResourceBuilder) SetDeviceID(val string) { + if rb.config.DeviceID.Enabled { + rb.res.Attributes().PutStr("device.id", val) + } +} + +// SetNsxtNodeID sets provided value as "nsxt.node.id" attribute. +func (rb *ResourceBuilder) SetNsxtNodeID(val string) { + if rb.config.NsxtNodeID.Enabled { + rb.res.Attributes().PutStr("nsxt.node.id", val) + } +} + +// SetNsxtNodeName sets provided value as "nsxt.node.name" attribute. +func (rb *ResourceBuilder) SetNsxtNodeName(val string) { + if rb.config.NsxtNodeName.Enabled { + rb.res.Attributes().PutStr("nsxt.node.name", val) + } +} + +// SetNsxtNodeType sets provided value as "nsxt.node.type" attribute. +func (rb *ResourceBuilder) SetNsxtNodeType(val string) { + if rb.config.NsxtNodeType.Enabled { + rb.res.Attributes().PutStr("nsxt.node.type", 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/receiver/nsxtreceiver/internal/metadata/generated_resource_test.go b/receiver/nsxtreceiver/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..548a25f0b439 --- /dev/null +++ b/receiver/nsxtreceiver/internal/metadata/generated_resource_test.go @@ -0,0 +1,58 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetDeviceID("device.id-val") + rb.SetNsxtNodeID("nsxt.node.id-val") + rb.SetNsxtNodeName("nsxt.node.name-val") + rb.SetNsxtNodeType("nsxt.node.type-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 4, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 4, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("device.id") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "device.id-val", val.Str()) + } + val, ok = res.Attributes().Get("nsxt.node.id") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "nsxt.node.id-val", val.Str()) + } + val, ok = res.Attributes().Get("nsxt.node.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "nsxt.node.name-val", val.Str()) + } + val, ok = res.Attributes().Get("nsxt.node.type") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "nsxt.node.type-val", val.Str()) + } + }) + } +} diff --git a/receiver/nsxtreceiver/scraper.go b/receiver/nsxtreceiver/scraper.go index 2c2a2b9d2f34..6a8898b9745e 100644 --- a/receiver/nsxtreceiver/scraper.go +++ b/receiver/nsxtreceiver/scraper.go @@ -25,6 +25,7 @@ type scraper struct { settings component.TelemetrySettings host component.Host client Client + rb *metadata.ResourceBuilder mb *metadata.MetricsBuilder } @@ -32,6 +33,7 @@ func newScraper(cfg *Config, settings receiver.CreateSettings) *scraper { return &scraper{ config: cfg, settings: settings.TelemetrySettings, + rb: metadata.NewResourceBuilder(cfg.ResourceAttributes), mb: metadata.NewMetricsBuilder(cfg.MetricsBuilderConfig, settings), } } @@ -197,12 +199,11 @@ func (s *scraper) recordNodeInterface(colTime pcommon.Timestamp, nodeProps dm.No s.mb.RecordNsxtNodeNetworkIoDataPoint(colTime, i.stats.RxBytes, metadata.AttributeDirectionReceived) s.mb.RecordNsxtNodeNetworkIoDataPoint(colTime, i.stats.TxBytes, metadata.AttributeDirectionTransmitted) - s.mb.EmitForResource( - metadata.WithDeviceID(i.iFace.InterfaceId), - metadata.WithNsxtNodeName(nodeProps.Name), - metadata.WithNsxtNodeType(nodeProps.ResourceType), - metadata.WithNsxtNodeID(nodeProps.ID), - ) + s.rb.SetDeviceID(i.iFace.InterfaceId) + s.rb.SetNsxtNodeName(nodeProps.Name) + s.rb.SetNsxtNodeType(nodeProps.ResourceType) + s.rb.SetNsxtNodeID(nodeProps.ID) + s.mb.EmitForResource(metadata.WithResource(s.rb.Emit())) } func (s *scraper) recordNode( @@ -225,11 +226,10 @@ func (s *scraper) recordNode( // ensure division by zero is safeguarded s.mb.RecordNsxtNodeFilesystemUtilizationDataPoint(colTime, float64(ss.DiskSpaceUsed)/math.Max(float64(ss.DiskSpaceTotal), 1)) - s.mb.EmitForResource( - metadata.WithNsxtNodeName(info.nodeProps.Name), - metadata.WithNsxtNodeID(info.nodeProps.ID), - metadata.WithNsxtNodeType(info.nodeType), - ) + s.rb.SetNsxtNodeName(info.nodeProps.Name) + s.rb.SetNsxtNodeID(info.nodeProps.ID) + s.rb.SetNsxtNodeType(info.nodeType) + s.mb.EmitForResource(metadata.WithResource(s.rb.Emit())) } func clusterNodeType(node dm.ClusterNode) string { diff --git a/receiver/oracledbreceiver/internal/metadata/generated_config_test.go b/receiver/oracledbreceiver/internal/metadata/generated_config_test.go index b7d534953ec1..0ad19bb9eec1 100644 --- a/receiver/oracledbreceiver/internal/metadata/generated_config_test.go +++ b/receiver/oracledbreceiver/internal/metadata/generated_config_test.go @@ -116,3 +116,47 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + OracledbInstanceName: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + OracledbInstanceName: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/oracledbreceiver/internal/metadata/generated_metrics.go b/receiver/oracledbreceiver/internal/metadata/generated_metrics.go index 07c1bc969df1..8b35ebdb5986 100644 --- a/receiver/oracledbreceiver/internal/metadata/generated_metrics.go +++ b/receiver/oracledbreceiver/internal/metadata/generated_metrics.go @@ -1374,10 +1374,8 @@ func newMetricOracledbUserRollbacks(cfg MetricConfig) metricOracledbUserRollback type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricOracledbConsistentGets metricOracledbConsistentGets metricOracledbCPUTime metricOracledbCPUTime metricOracledbDbBlockGets metricOracledbDbBlockGets @@ -1422,7 +1420,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricOracledbConsistentGets: newMetricOracledbConsistentGets(mbc.Metrics.OracledbConsistentGets), metricOracledbCPUTime: newMetricOracledbCPUTime(mbc.Metrics.OracledbCPUTime), metricOracledbDbBlockGets: newMetricOracledbDbBlockGets(mbc.Metrics.OracledbDbBlockGets), @@ -1462,27 +1459,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithOracledbInstanceName sets provided value as "oracledb.instance.name" attribute for current resource. -func WithOracledbInstanceName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.OracledbInstanceName.Enabled { - rm.Resource().Attributes().PutStr("oracledb.instance.name", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -1506,7 +1499,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/oracledbreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -1540,7 +1532,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricOracledbUserRollbacks.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/oracledbreceiver/internal/metadata/generated_metrics_test.go b/receiver/oracledbreceiver/internal/metadata/generated_metrics_test.go index 4618022f15e0..b64a5dcb4881 100644 --- a/receiver/oracledbreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/oracledbreceiver/internal/metadata/generated_metrics_test.go @@ -160,7 +160,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordOracledbUserRollbacksDataPoint(ts, "1") - metrics := mb.Emit(WithOracledbInstanceName("oracledb.instance.name-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -169,18 +171,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("oracledb.instance.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.OracledbInstanceName.Enabled, ok) - if mb.resourceAttributesConfig.OracledbInstanceName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "oracledb.instance.name-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 1) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/oracledbreceiver/internal/metadata/generated_resource.go b/receiver/oracledbreceiver/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..77f4561fbb3f --- /dev/null +++ b/receiver/oracledbreceiver/internal/metadata/generated_resource.go @@ -0,0 +1,36 @@ +// 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(), + } +} + +// SetOracledbInstanceName sets provided value as "oracledb.instance.name" attribute. +func (rb *ResourceBuilder) SetOracledbInstanceName(val string) { + if rb.config.OracledbInstanceName.Enabled { + rb.res.Attributes().PutStr("oracledb.instance.name", 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/receiver/oracledbreceiver/internal/metadata/generated_resource_test.go b/receiver/oracledbreceiver/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..760e9c7b9b66 --- /dev/null +++ b/receiver/oracledbreceiver/internal/metadata/generated_resource_test.go @@ -0,0 +1,40 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetOracledbInstanceName("oracledb.instance.name-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 1, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 1, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("oracledb.instance.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "oracledb.instance.name-val", val.Str()) + } + }) + } +} diff --git a/receiver/oracledbreceiver/scraper.go b/receiver/oracledbreceiver/scraper.go index af759102c8a0..5e4b4e6a6ae1 100644 --- a/receiver/oracledbreceiver/scraper.go +++ b/receiver/oracledbreceiver/scraper.go @@ -54,7 +54,8 @@ type scraper struct { sessionCountClient dbClient db *sql.DB clientProviderFunc clientProviderFunc - metricsBuilder *metadata.MetricsBuilder + rb *metadata.ResourceBuilder + mb *metadata.MetricsBuilder dbProviderFunc dbProviderFunc logger *zap.Logger id component.ID @@ -66,7 +67,8 @@ type scraper struct { func newScraper(id component.ID, metricsBuilder *metadata.MetricsBuilder, metricsBuilderConfig metadata.MetricsBuilderConfig, scrapeCfg scraperhelper.ScraperControllerSettings, logger *zap.Logger, providerFunc dbProviderFunc, clientProviderFunc clientProviderFunc, instanceName string) (scraperhelper.Scraper, error) { s := &scraper{ - metricsBuilder: metricsBuilder, + rb: metadata.NewResourceBuilder(metricsBuilderConfig.ResourceAttributes), + mb: metricsBuilder, metricsBuilderConfig: metricsBuilderConfig, scrapeCfg: scrapeCfg, logger: logger, @@ -120,47 +122,47 @@ func (s *scraper) scrape(ctx context.Context) (pmetric.Metrics, error) { for _, row := range rows { switch row["NAME"] { case enqueueDeadlocks: - err := s.metricsBuilder.RecordOracledbEnqueueDeadlocksDataPoint(now, row["VALUE"]) + err := s.mb.RecordOracledbEnqueueDeadlocksDataPoint(now, row["VALUE"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } case exchangeDeadlocks: - err := s.metricsBuilder.RecordOracledbExchangeDeadlocksDataPoint(now, row["VALUE"]) + err := s.mb.RecordOracledbExchangeDeadlocksDataPoint(now, row["VALUE"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } case executeCount: - err := s.metricsBuilder.RecordOracledbExecutionsDataPoint(now, row["VALUE"]) + err := s.mb.RecordOracledbExecutionsDataPoint(now, row["VALUE"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } case parseCountTotal: - err := s.metricsBuilder.RecordOracledbParseCallsDataPoint(now, row["VALUE"]) + err := s.mb.RecordOracledbParseCallsDataPoint(now, row["VALUE"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } case parseCountHard: - err := s.metricsBuilder.RecordOracledbHardParsesDataPoint(now, row["VALUE"]) + err := s.mb.RecordOracledbHardParsesDataPoint(now, row["VALUE"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } case userCommits: - err := s.metricsBuilder.RecordOracledbUserCommitsDataPoint(now, row["VALUE"]) + err := s.mb.RecordOracledbUserCommitsDataPoint(now, row["VALUE"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } case userRollbacks: - err := s.metricsBuilder.RecordOracledbUserRollbacksDataPoint(now, row["VALUE"]) + err := s.mb.RecordOracledbUserRollbacksDataPoint(now, row["VALUE"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } case physicalReads: - err := s.metricsBuilder.RecordOracledbPhysicalReadsDataPoint(now, row["VALUE"]) + err := s.mb.RecordOracledbPhysicalReadsDataPoint(now, row["VALUE"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } case sessionLogicalReads: - err := s.metricsBuilder.RecordOracledbLogicalReadsDataPoint(now, row["VALUE"]) + err := s.mb.RecordOracledbLogicalReadsDataPoint(now, row["VALUE"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } @@ -171,20 +173,20 @@ func (s *scraper) scrape(ctx context.Context) (pmetric.Metrics, error) { } else { // divide by 100 as the value is expressed in tens of milliseconds value /= 100 - s.metricsBuilder.RecordOracledbCPUTimeDataPoint(now, value) + s.mb.RecordOracledbCPUTimeDataPoint(now, value) } case pgaMemory: - err := s.metricsBuilder.RecordOracledbPgaMemoryDataPoint(pcommon.NewTimestampFromTime(time.Now()), row["VALUE"]) + err := s.mb.RecordOracledbPgaMemoryDataPoint(pcommon.NewTimestampFromTime(time.Now()), row["VALUE"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } case dbBlockGets: - err := s.metricsBuilder.RecordOracledbDbBlockGetsDataPoint(now, row["VALUE"]) + err := s.mb.RecordOracledbDbBlockGetsDataPoint(now, row["VALUE"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } case consistentGets: - err := s.metricsBuilder.RecordOracledbConsistentGetsDataPoint(now, row["VALUE"]) + err := s.mb.RecordOracledbConsistentGetsDataPoint(now, row["VALUE"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } @@ -198,7 +200,8 @@ func (s *scraper) scrape(ctx context.Context) (pmetric.Metrics, error) { scrapeErrors = append(scrapeErrors, fmt.Errorf("error executing %s: %w", sessionCountSQL, err)) } for _, row := range rows { - err := s.metricsBuilder.RecordOracledbSessionsUsageDataPoint(pcommon.NewTimestampFromTime(time.Now()), row["VALUE"], row["TYPE"], row["STATUS"]) + err := s.mb.RecordOracledbSessionsUsageDataPoint(pcommon.NewTimestampFromTime(time.Now()), row["VALUE"], + row["TYPE"], row["STATUS"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } @@ -220,43 +223,54 @@ func (s *scraper) scrape(ctx context.Context) (pmetric.Metrics, error) { resourceName := row["RESOURCE_NAME"] switch resourceName { case "processes": - if err := s.metricsBuilder.RecordOracledbProcessesUsageDataPoint(pcommon.NewTimestampFromTime(time.Now()), row["CURRENT_UTILIZATION"]); err != nil { + if err := s.mb.RecordOracledbProcessesUsageDataPoint(pcommon.NewTimestampFromTime(time.Now()), + row["CURRENT_UTILIZATION"]); err != nil { scrapeErrors = append(scrapeErrors, err) } - if err := s.metricsBuilder.RecordOracledbProcessesLimitDataPoint(pcommon.NewTimestampFromTime(time.Now()), row["LIMIT_VALUE"]); err != nil { + if err := s.mb.RecordOracledbProcessesLimitDataPoint(pcommon.NewTimestampFromTime(time.Now()), + row["LIMIT_VALUE"]); err != nil { scrapeErrors = append(scrapeErrors, err) } case "sessions": - err := s.metricsBuilder.RecordOracledbSessionsLimitDataPoint(pcommon.NewTimestampFromTime(time.Now()), row["LIMIT_VALUE"]) + err := s.mb.RecordOracledbSessionsLimitDataPoint(pcommon.NewTimestampFromTime(time.Now()), + row["LIMIT_VALUE"]) if err != nil { scrapeErrors = append(scrapeErrors, err) } case "enqueue_locks": - if err := s.metricsBuilder.RecordOracledbEnqueueLocksUsageDataPoint(pcommon.NewTimestampFromTime(time.Now()), row["CURRENT_UTILIZATION"]); err != nil { + if err := s.mb.RecordOracledbEnqueueLocksUsageDataPoint(pcommon.NewTimestampFromTime(time.Now()), + row["CURRENT_UTILIZATION"]); err != nil { scrapeErrors = append(scrapeErrors, err) } - if err := s.metricsBuilder.RecordOracledbEnqueueLocksLimitDataPoint(pcommon.NewTimestampFromTime(time.Now()), row["LIMIT_VALUE"]); err != nil { + if err := s.mb.RecordOracledbEnqueueLocksLimitDataPoint(pcommon.NewTimestampFromTime(time.Now()), + row["LIMIT_VALUE"]); err != nil { scrapeErrors = append(scrapeErrors, err) } case "dml_locks": - if err := s.metricsBuilder.RecordOracledbDmlLocksUsageDataPoint(pcommon.NewTimestampFromTime(time.Now()), row["CURRENT_UTILIZATION"]); err != nil { + if err := s.mb.RecordOracledbDmlLocksUsageDataPoint(pcommon.NewTimestampFromTime(time.Now()), + row["CURRENT_UTILIZATION"]); err != nil { scrapeErrors = append(scrapeErrors, err) } - if err := s.metricsBuilder.RecordOracledbDmlLocksLimitDataPoint(pcommon.NewTimestampFromTime(time.Now()), row["LIMIT_VALUE"]); err != nil { + if err := s.mb.RecordOracledbDmlLocksLimitDataPoint(pcommon.NewTimestampFromTime(time.Now()), + row["LIMIT_VALUE"]); err != nil { scrapeErrors = append(scrapeErrors, err) } case "enqueue_resources": - if err := s.metricsBuilder.RecordOracledbEnqueueResourcesUsageDataPoint(pcommon.NewTimestampFromTime(time.Now()), row["CURRENT_UTILIZATION"]); err != nil { + if err := s.mb.RecordOracledbEnqueueResourcesUsageDataPoint(pcommon.NewTimestampFromTime(time.Now()), + row["CURRENT_UTILIZATION"]); err != nil { scrapeErrors = append(scrapeErrors, err) } - if err := s.metricsBuilder.RecordOracledbEnqueueResourcesLimitDataPoint(pcommon.NewTimestampFromTime(time.Now()), row["LIMIT_VALUE"]); err != nil { + if err := s.mb.RecordOracledbEnqueueResourcesLimitDataPoint(pcommon.NewTimestampFromTime(time.Now()), + row["LIMIT_VALUE"]); err != nil { scrapeErrors = append(scrapeErrors, err) } case "transactions": - if err := s.metricsBuilder.RecordOracledbTransactionsUsageDataPoint(pcommon.NewTimestampFromTime(time.Now()), row["CURRENT_UTILIZATION"]); err != nil { + if err := s.mb.RecordOracledbTransactionsUsageDataPoint(pcommon.NewTimestampFromTime(time.Now()), + row["CURRENT_UTILIZATION"]); err != nil { scrapeErrors = append(scrapeErrors, err) } - if err := s.metricsBuilder.RecordOracledbTransactionsLimitDataPoint(pcommon.NewTimestampFromTime(time.Now()), row["LIMIT_VALUE"]); err != nil { + if err := s.mb.RecordOracledbTransactionsLimitDataPoint(pcommon.NewTimestampFromTime(time.Now()), + row["LIMIT_VALUE"]); err != nil { scrapeErrors = append(scrapeErrors, err) } } @@ -270,7 +284,7 @@ func (s *scraper) scrape(ctx context.Context) (pmetric.Metrics, error) { now := pcommon.NewTimestampFromTime(time.Now()) for _, row := range rows { tablespaceName := row["TABLESPACE_NAME"] - err := s.metricsBuilder.RecordOracledbTablespaceSizeUsageDataPoint(now, row["BYTES"], tablespaceName) + err := s.mb.RecordOracledbTablespaceSizeUsageDataPoint(now, row["BYTES"], tablespaceName) if err != nil { scrapeErrors = append(scrapeErrors, err) } @@ -296,12 +310,13 @@ func (s *scraper) scrape(ctx context.Context) (pmetric.Metrics, error) { continue } } - s.metricsBuilder.RecordOracledbTablespaceSizeLimitDataPoint(now, val, tablespaceName) + s.mb.RecordOracledbTablespaceSizeLimitDataPoint(now, val, tablespaceName) } } } - out := s.metricsBuilder.Emit(metadata.WithOracledbInstanceName(s.instanceName)) + s.rb.SetOracledbInstanceName(s.instanceName) + out := s.mb.Emit(metadata.WithResource(s.rb.Emit())) s.logger.Debug("Done scraping") if len(scrapeErrors) > 0 { return out, scrapererror.NewPartialScrapeError(multierr.Combine(scrapeErrors...), len(scrapeErrors)) diff --git a/receiver/oracledbreceiver/scraper_test.go b/receiver/oracledbreceiver/scraper_test.go index 96711b8ca211..e43c094e3057 100644 --- a/receiver/oracledbreceiver/scraper_test.go +++ b/receiver/oracledbreceiver/scraper_test.go @@ -112,11 +112,11 @@ func TestScraper_Scrape(t *testing.T) { cfg := metadata.DefaultMetricsBuilderConfig() cfg.Metrics.OracledbConsistentGets.Enabled = true cfg.Metrics.OracledbDbBlockGets.Enabled = true - metricsBuilder := metadata.NewMetricsBuilder(cfg, receivertest.NewNopCreateSettings()) scrpr := scraper{ - logger: zap.NewNop(), - metricsBuilder: metricsBuilder, + logger: zap.NewNop(), + rb: metadata.NewResourceBuilder(cfg.ResourceAttributes), + mb: metadata.NewMetricsBuilder(cfg, receivertest.NewNopCreateSettings()), dbProviderFunc: func() (*sql.DB, error) { return nil, nil }, diff --git a/receiver/postgresqlreceiver/internal/metadata/generated_config_test.go b/receiver/postgresqlreceiver/internal/metadata/generated_config_test.go index 3a5627e0a6b6..2b350f921acc 100644 --- a/receiver/postgresqlreceiver/internal/metadata/generated_config_test.go +++ b/receiver/postgresqlreceiver/internal/metadata/generated_config_test.go @@ -110,3 +110,51 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + PostgresqlDatabaseName: ResourceAttributeConfig{Enabled: true}, + PostgresqlIndexName: ResourceAttributeConfig{Enabled: true}, + PostgresqlTableName: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + PostgresqlDatabaseName: ResourceAttributeConfig{Enabled: false}, + PostgresqlIndexName: ResourceAttributeConfig{Enabled: false}, + PostgresqlTableName: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/postgresqlreceiver/internal/metadata/generated_metrics.go b/receiver/postgresqlreceiver/internal/metadata/generated_metrics.go index 8f325fa33ec9..d4fdb0658001 100644 --- a/receiver/postgresqlreceiver/internal/metadata/generated_metrics.go +++ b/receiver/postgresqlreceiver/internal/metadata/generated_metrics.go @@ -1385,10 +1385,8 @@ func newMetricPostgresqlWalLag(cfg MetricConfig) metricPostgresqlWalLag { type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricPostgresqlBackends metricPostgresqlBackends metricPostgresqlBgwriterBuffersAllocated metricPostgresqlBgwriterBuffersAllocated metricPostgresqlBgwriterBuffersWrites metricPostgresqlBgwriterBuffersWrites @@ -1428,7 +1426,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricPostgresqlBackends: newMetricPostgresqlBackends(mbc.Metrics.PostgresqlBackends), metricPostgresqlBgwriterBuffersAllocated: newMetricPostgresqlBgwriterBuffersAllocated(mbc.Metrics.PostgresqlBgwriterBuffersAllocated), metricPostgresqlBgwriterBuffersWrites: newMetricPostgresqlBgwriterBuffersWrites(mbc.Metrics.PostgresqlBgwriterBuffersWrites), @@ -1463,45 +1460,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithPostgresqlDatabaseName sets provided value as "postgresql.database.name" attribute for current resource. -func WithPostgresqlDatabaseName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.PostgresqlDatabaseName.Enabled { - rm.Resource().Attributes().PutStr("postgresql.database.name", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithPostgresqlIndexName sets provided value as "postgresql.index.name" attribute for current resource. -func WithPostgresqlIndexName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.PostgresqlIndexName.Enabled { - rm.Resource().Attributes().PutStr("postgresql.index.name", val) - } - } -} - -// WithPostgresqlTableName sets provided value as "postgresql.table.name" attribute for current resource. -func WithPostgresqlTableName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.PostgresqlTableName.Enabled { - rm.Resource().Attributes().PutStr("postgresql.table.name", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -1525,7 +1500,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/postgresqlreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -1554,7 +1528,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricPostgresqlWalLag.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/postgresqlreceiver/internal/metadata/generated_metrics_test.go b/receiver/postgresqlreceiver/internal/metadata/generated_metrics_test.go index 936f19011702..daac04013696 100644 --- a/receiver/postgresqlreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/postgresqlreceiver/internal/metadata/generated_metrics_test.go @@ -142,7 +142,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordPostgresqlWalLagDataPoint(ts, 1, AttributeWalOperationLagFlush, "replication_client-val") - metrics := mb.Emit(WithPostgresqlDatabaseName("postgresql.database.name-val"), WithPostgresqlIndexName("postgresql.index.name-val"), WithPostgresqlTableName("postgresql.table.name-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -151,32 +153,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("postgresql.database.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.PostgresqlDatabaseName.Enabled, ok) - if mb.resourceAttributesConfig.PostgresqlDatabaseName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "postgresql.database.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("postgresql.index.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.PostgresqlIndexName.Enabled, ok) - if mb.resourceAttributesConfig.PostgresqlIndexName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "postgresql.index.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("postgresql.table.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.PostgresqlTableName.Enabled, ok) - if mb.resourceAttributesConfig.PostgresqlTableName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "postgresql.table.name-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 3) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/postgresqlreceiver/internal/metadata/generated_resource.go b/receiver/postgresqlreceiver/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..153aedca37fe --- /dev/null +++ b/receiver/postgresqlreceiver/internal/metadata/generated_resource.go @@ -0,0 +1,50 @@ +// 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(), + } +} + +// SetPostgresqlDatabaseName sets provided value as "postgresql.database.name" attribute. +func (rb *ResourceBuilder) SetPostgresqlDatabaseName(val string) { + if rb.config.PostgresqlDatabaseName.Enabled { + rb.res.Attributes().PutStr("postgresql.database.name", val) + } +} + +// SetPostgresqlIndexName sets provided value as "postgresql.index.name" attribute. +func (rb *ResourceBuilder) SetPostgresqlIndexName(val string) { + if rb.config.PostgresqlIndexName.Enabled { + rb.res.Attributes().PutStr("postgresql.index.name", val) + } +} + +// SetPostgresqlTableName sets provided value as "postgresql.table.name" attribute. +func (rb *ResourceBuilder) SetPostgresqlTableName(val string) { + if rb.config.PostgresqlTableName.Enabled { + rb.res.Attributes().PutStr("postgresql.table.name", 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/receiver/postgresqlreceiver/internal/metadata/generated_resource_test.go b/receiver/postgresqlreceiver/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..49c98311bab7 --- /dev/null +++ b/receiver/postgresqlreceiver/internal/metadata/generated_resource_test.go @@ -0,0 +1,52 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetPostgresqlDatabaseName("postgresql.database.name-val") + rb.SetPostgresqlIndexName("postgresql.index.name-val") + rb.SetPostgresqlTableName("postgresql.table.name-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 3, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 3, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("postgresql.database.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "postgresql.database.name-val", val.Str()) + } + val, ok = res.Attributes().Get("postgresql.index.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "postgresql.index.name-val", val.Str()) + } + val, ok = res.Attributes().Get("postgresql.table.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "postgresql.table.name-val", val.Str()) + } + }) + } +} diff --git a/receiver/postgresqlreceiver/scraper.go b/receiver/postgresqlreceiver/scraper.go index c6703648c03a..942837b9e989 100644 --- a/receiver/postgresqlreceiver/scraper.go +++ b/receiver/postgresqlreceiver/scraper.go @@ -23,6 +23,7 @@ type postgreSQLScraper struct { logger *zap.Logger config *Config clientFactory postgreSQLClientFactory + rb *metadata.ResourceBuilder mb *metadata.MetricsBuilder } type errsMux struct { @@ -73,6 +74,7 @@ func newPostgreSQLScraper( logger: settings.Logger, config: config, clientFactory: clientFactory, + rb: metadata.NewResourceBuilder(config.ResourceAttributes), mb: metadata.NewMetricsBuilder(config.MetricsBuilderConfig, settings), } } @@ -166,7 +168,8 @@ func (p *postgreSQLScraper) recordDatabase(now pcommon.Timestamp, db string, r * p.mb.RecordPostgresqlCommitsDataPointWithoutDatabase(now, stats.transactionCommitted) p.mb.RecordPostgresqlRollbacksDataPointWithoutDatabase(now, stats.transactionRollback) } - p.mb.EmitForResource(metadata.WithPostgresqlDatabaseName(db)) + p.rb.SetPostgresqlDatabaseName(db) + p.mb.EmitForResource(metadata.WithResource(p.rb.Emit())) } func (p *postgreSQLScraper) collectTables(ctx context.Context, now pcommon.Timestamp, dbClient client, db string, errs *errsMux) (numTables int64) { @@ -201,10 +204,9 @@ func (p *postgreSQLScraper) collectTables(ctx context.Context, now pcommon.Times p.mb.RecordPostgresqlBlocksReadDataPointWithoutDatabaseAndTable(now, br.tidxRead, metadata.AttributeSourceTidxRead) p.mb.RecordPostgresqlBlocksReadDataPointWithoutDatabaseAndTable(now, br.tidxHit, metadata.AttributeSourceTidxHit) } - p.mb.EmitForResource( - metadata.WithPostgresqlDatabaseName(db), - metadata.WithPostgresqlTableName(tm.table), - ) + p.rb.SetPostgresqlDatabaseName(db) + p.rb.SetPostgresqlTableName(tm.table) + p.mb.EmitForResource(metadata.WithResource(p.rb.Emit())) } return int64(len(tableMetrics)) } @@ -225,11 +227,10 @@ func (p *postgreSQLScraper) collectIndexes( for _, stat := range idxStats { p.mb.RecordPostgresqlIndexScansDataPoint(now, stat.scans) p.mb.RecordPostgresqlIndexSizeDataPoint(now, stat.size) - p.mb.EmitForResource( - metadata.WithPostgresqlDatabaseName(stat.database), - metadata.WithPostgresqlTableName(stat.table), - metadata.WithPostgresqlIndexName(stat.index), - ) + p.rb.SetPostgresqlDatabaseName(database) + p.rb.SetPostgresqlTableName(stat.table) + p.rb.SetPostgresqlIndexName(stat.index) + p.mb.EmitForResource(metadata.WithResource(p.rb.Emit())) } } diff --git a/receiver/rabbitmqreceiver/internal/metadata/generated_config_test.go b/receiver/rabbitmqreceiver/internal/metadata/generated_config_test.go index 5c5af11d9c36..2d858e935f3c 100644 --- a/receiver/rabbitmqreceiver/internal/metadata/generated_config_test.go +++ b/receiver/rabbitmqreceiver/internal/metadata/generated_config_test.go @@ -78,3 +78,51 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + RabbitmqNodeName: ResourceAttributeConfig{Enabled: true}, + RabbitmqQueueName: ResourceAttributeConfig{Enabled: true}, + RabbitmqVhostName: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + RabbitmqNodeName: ResourceAttributeConfig{Enabled: false}, + RabbitmqQueueName: ResourceAttributeConfig{Enabled: false}, + RabbitmqVhostName: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/rabbitmqreceiver/internal/metadata/generated_metrics.go b/receiver/rabbitmqreceiver/internal/metadata/generated_metrics.go index 1cfc033d95bf..bcf283e998a2 100644 --- a/receiver/rabbitmqreceiver/internal/metadata/generated_metrics.go +++ b/receiver/rabbitmqreceiver/internal/metadata/generated_metrics.go @@ -350,10 +350,8 @@ func newMetricRabbitmqMessagePublished(cfg MetricConfig) metricRabbitmqMessagePu type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricRabbitmqConsumerCount metricRabbitmqConsumerCount metricRabbitmqMessageAcknowledged metricRabbitmqMessageAcknowledged metricRabbitmqMessageCurrent metricRabbitmqMessageCurrent @@ -377,7 +375,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricRabbitmqConsumerCount: newMetricRabbitmqConsumerCount(mbc.Metrics.RabbitmqConsumerCount), metricRabbitmqMessageAcknowledged: newMetricRabbitmqMessageAcknowledged(mbc.Metrics.RabbitmqMessageAcknowledged), metricRabbitmqMessageCurrent: newMetricRabbitmqMessageCurrent(mbc.Metrics.RabbitmqMessageCurrent), @@ -396,45 +393,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithRabbitmqNodeName sets provided value as "rabbitmq.node.name" attribute for current resource. -func WithRabbitmqNodeName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.RabbitmqNodeName.Enabled { - rm.Resource().Attributes().PutStr("rabbitmq.node.name", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithRabbitmqQueueName sets provided value as "rabbitmq.queue.name" attribute for current resource. -func WithRabbitmqQueueName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.RabbitmqQueueName.Enabled { - rm.Resource().Attributes().PutStr("rabbitmq.queue.name", val) - } - } -} - -// WithRabbitmqVhostName sets provided value as "rabbitmq.vhost.name" attribute for current resource. -func WithRabbitmqVhostName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.RabbitmqVhostName.Enabled { - rm.Resource().Attributes().PutStr("rabbitmq.vhost.name", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -458,7 +433,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/rabbitmqreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -471,7 +445,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricRabbitmqMessagePublished.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/rabbitmqreceiver/internal/metadata/generated_metrics_test.go b/receiver/rabbitmqreceiver/internal/metadata/generated_metrics_test.go index 4a673b22eb69..31a0da1834a2 100644 --- a/receiver/rabbitmqreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/rabbitmqreceiver/internal/metadata/generated_metrics_test.go @@ -78,7 +78,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordRabbitmqMessagePublishedDataPoint(ts, 1) - metrics := mb.Emit(WithRabbitmqNodeName("rabbitmq.node.name-val"), WithRabbitmqQueueName("rabbitmq.queue.name-val"), WithRabbitmqVhostName("rabbitmq.vhost.name-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -87,32 +89,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("rabbitmq.node.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.RabbitmqNodeName.Enabled, ok) - if mb.resourceAttributesConfig.RabbitmqNodeName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "rabbitmq.node.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("rabbitmq.queue.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.RabbitmqQueueName.Enabled, ok) - if mb.resourceAttributesConfig.RabbitmqQueueName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "rabbitmq.queue.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("rabbitmq.vhost.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.RabbitmqVhostName.Enabled, ok) - if mb.resourceAttributesConfig.RabbitmqVhostName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "rabbitmq.vhost.name-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 3) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/rabbitmqreceiver/internal/metadata/generated_resource.go b/receiver/rabbitmqreceiver/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..3954ca4f7ea5 --- /dev/null +++ b/receiver/rabbitmqreceiver/internal/metadata/generated_resource.go @@ -0,0 +1,50 @@ +// 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(), + } +} + +// SetRabbitmqNodeName sets provided value as "rabbitmq.node.name" attribute. +func (rb *ResourceBuilder) SetRabbitmqNodeName(val string) { + if rb.config.RabbitmqNodeName.Enabled { + rb.res.Attributes().PutStr("rabbitmq.node.name", val) + } +} + +// SetRabbitmqQueueName sets provided value as "rabbitmq.queue.name" attribute. +func (rb *ResourceBuilder) SetRabbitmqQueueName(val string) { + if rb.config.RabbitmqQueueName.Enabled { + rb.res.Attributes().PutStr("rabbitmq.queue.name", val) + } +} + +// SetRabbitmqVhostName sets provided value as "rabbitmq.vhost.name" attribute. +func (rb *ResourceBuilder) SetRabbitmqVhostName(val string) { + if rb.config.RabbitmqVhostName.Enabled { + rb.res.Attributes().PutStr("rabbitmq.vhost.name", 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/receiver/rabbitmqreceiver/internal/metadata/generated_resource_test.go b/receiver/rabbitmqreceiver/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..4feb688858a8 --- /dev/null +++ b/receiver/rabbitmqreceiver/internal/metadata/generated_resource_test.go @@ -0,0 +1,52 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetRabbitmqNodeName("rabbitmq.node.name-val") + rb.SetRabbitmqQueueName("rabbitmq.queue.name-val") + rb.SetRabbitmqVhostName("rabbitmq.vhost.name-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 3, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 3, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("rabbitmq.node.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "rabbitmq.node.name-val", val.Str()) + } + val, ok = res.Attributes().Get("rabbitmq.queue.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "rabbitmq.queue.name-val", val.Str()) + } + val, ok = res.Attributes().Get("rabbitmq.vhost.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "rabbitmq.vhost.name-val", val.Str()) + } + }) + } +} diff --git a/receiver/rabbitmqreceiver/scraper.go b/receiver/rabbitmqreceiver/scraper.go index e0489092147f..cdab8bf638b1 100644 --- a/receiver/rabbitmqreceiver/scraper.go +++ b/receiver/rabbitmqreceiver/scraper.go @@ -42,6 +42,7 @@ type rabbitmqScraper struct { logger *zap.Logger cfg *Config settings component.TelemetrySettings + rb *metadata.ResourceBuilder mb *metadata.MetricsBuilder } @@ -51,6 +52,7 @@ func newScraper(logger *zap.Logger, cfg *Config, settings receiver.CreateSetting logger: logger, cfg: cfg, settings: settings.TelemetrySettings, + rb: metadata.NewResourceBuilder(cfg.ResourceAttributes), mb: metadata.NewMetricsBuilder(cfg.MetricsBuilderConfig, settings), } } @@ -119,11 +121,10 @@ func (r *rabbitmqScraper) collectQueue(queue *models.Queue, now pcommon.Timestam r.mb.RecordRabbitmqMessageDroppedDataPoint(now, val64) } } - r.mb.EmitForResource( - metadata.WithRabbitmqQueueName(queue.Name), - metadata.WithRabbitmqNodeName(queue.Node), - metadata.WithRabbitmqVhostName(queue.VHost), - ) + r.rb.SetRabbitmqQueueName(queue.Name) + r.rb.SetRabbitmqNodeName(queue.Node) + r.rb.SetRabbitmqVhostName(queue.VHost) + r.mb.EmitForResource(metadata.WithResource(r.rb.Emit())) } // convertValToInt64 values from message state unmarshal as float64s but should be int64. diff --git a/receiver/redisreceiver/internal/metadata/generated_config_test.go b/receiver/redisreceiver/internal/metadata/generated_config_test.go index 5d4ed45a04db..c3a9e64ff4f4 100644 --- a/receiver/redisreceiver/internal/metadata/generated_config_test.go +++ b/receiver/redisreceiver/internal/metadata/generated_config_test.go @@ -128,3 +128,47 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + RedisVersion: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + RedisVersion: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/redisreceiver/internal/metadata/generated_metrics.go b/receiver/redisreceiver/internal/metadata/generated_metrics.go index 528b139c6f5b..bb0d84a77459 100644 --- a/receiver/redisreceiver/internal/metadata/generated_metrics.go +++ b/receiver/redisreceiver/internal/metadata/generated_metrics.go @@ -1751,10 +1751,8 @@ func newMetricRedisUptime(cfg MetricConfig) metricRedisUptime { type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricRedisClientsBlocked metricRedisClientsBlocked metricRedisClientsConnected metricRedisClientsConnected metricRedisClientsMaxInputBuffer metricRedisClientsMaxInputBuffer @@ -1805,7 +1803,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricRedisClientsBlocked: newMetricRedisClientsBlocked(mbc.Metrics.RedisClientsBlocked), metricRedisClientsConnected: newMetricRedisClientsConnected(mbc.Metrics.RedisClientsConnected), metricRedisClientsMaxInputBuffer: newMetricRedisClientsMaxInputBuffer(mbc.Metrics.RedisClientsMaxInputBuffer), @@ -1851,27 +1848,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithRedisVersion sets provided value as "redis.version" attribute for current resource. -func WithRedisVersion(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.RedisVersion.Enabled { - rm.Resource().Attributes().PutStr("redis.version", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -1895,7 +1888,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/redisreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -1935,7 +1927,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricRedisUptime.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/redisreceiver/internal/metadata/generated_metrics_test.go b/receiver/redisreceiver/internal/metadata/generated_metrics_test.go index a5396a2ecfab..a6972efc2651 100644 --- a/receiver/redisreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/redisreceiver/internal/metadata/generated_metrics_test.go @@ -182,7 +182,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordRedisUptimeDataPoint(ts, 1) - metrics := mb.Emit(WithRedisVersion("redis.version-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -191,18 +193,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("redis.version") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.RedisVersion.Enabled, ok) - if mb.resourceAttributesConfig.RedisVersion.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "redis.version-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 1) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/redisreceiver/internal/metadata/generated_resource.go b/receiver/redisreceiver/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..24919b5b8310 --- /dev/null +++ b/receiver/redisreceiver/internal/metadata/generated_resource.go @@ -0,0 +1,36 @@ +// 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(), + } +} + +// SetRedisVersion sets provided value as "redis.version" attribute. +func (rb *ResourceBuilder) SetRedisVersion(val string) { + if rb.config.RedisVersion.Enabled { + rb.res.Attributes().PutStr("redis.version", 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/receiver/redisreceiver/internal/metadata/generated_resource_test.go b/receiver/redisreceiver/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..ff215d46cee3 --- /dev/null +++ b/receiver/redisreceiver/internal/metadata/generated_resource_test.go @@ -0,0 +1,40 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetRedisVersion("redis.version-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 1, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 1, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("redis.version") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "redis.version-val", val.Str()) + } + }) + } +} diff --git a/receiver/redisreceiver/redis_scraper.go b/receiver/redisreceiver/redis_scraper.go index f87112864cd9..fc24bdf105a6 100644 --- a/receiver/redisreceiver/redis_scraper.go +++ b/receiver/redisreceiver/redis_scraper.go @@ -26,6 +26,7 @@ type redisScraper struct { client client redisSvc *redisSvc settings component.TelemetrySettings + rb *metadata.ResourceBuilder mb *metadata.MetricsBuilder uptime time.Duration } @@ -51,6 +52,7 @@ func newRedisScraperWithClient(client client, settings receiver.CreateSettings, client: client, redisSvc: newRedisSvc(client), settings: settings.TelemetrySettings, + rb: metadata.NewResourceBuilder(cfg.MetricsBuilderConfig.ResourceAttributes), mb: metadata.NewMetricsBuilder(cfg.MetricsBuilderConfig, settings), } return scraperhelper.NewScraper( @@ -93,7 +95,8 @@ func (rs *redisScraper) Scrape(context.Context) (pmetric.Metrics, error) { rs.recordKeyspaceMetrics(now, inf) rs.recordRoleMetrics(now, inf) rs.recordCmdStatsMetrics(now, inf) - return rs.mb.Emit(metadata.WithRedisVersion(rs.getRedisVersion(inf))), nil + rs.rb.SetRedisVersion(rs.getRedisVersion(inf)) + return rs.mb.Emit(metadata.WithResource(rs.rb.Emit())), nil } // recordCommonMetrics records metrics from Redis info key-value pairs. diff --git a/receiver/riakreceiver/internal/metadata/generated_config_test.go b/receiver/riakreceiver/internal/metadata/generated_config_test.go index b74ef0deb06e..9c929fe7387d 100644 --- a/receiver/riakreceiver/internal/metadata/generated_config_test.go +++ b/receiver/riakreceiver/internal/metadata/generated_config_test.go @@ -74,3 +74,47 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + RiakNodeName: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + RiakNodeName: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/riakreceiver/internal/metadata/generated_metrics.go b/receiver/riakreceiver/internal/metadata/generated_metrics.go index 5dbff0aca990..0cc95fbd5638 100644 --- a/receiver/riakreceiver/internal/metadata/generated_metrics.go +++ b/receiver/riakreceiver/internal/metadata/generated_metrics.go @@ -384,10 +384,8 @@ func newMetricRiakVnodeOperationCount(cfg MetricConfig) metricRiakVnodeOperation type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricRiakMemoryLimit metricRiakMemoryLimit metricRiakNodeOperationCount metricRiakNodeOperationCount metricRiakNodeOperationTimeMean metricRiakNodeOperationTimeMean @@ -411,7 +409,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricRiakMemoryLimit: newMetricRiakMemoryLimit(mbc.Metrics.RiakMemoryLimit), metricRiakNodeOperationCount: newMetricRiakNodeOperationCount(mbc.Metrics.RiakNodeOperationCount), metricRiakNodeOperationTimeMean: newMetricRiakNodeOperationTimeMean(mbc.Metrics.RiakNodeOperationTimeMean), @@ -430,27 +427,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithRiakNodeName sets provided value as "riak.node.name" attribute for current resource. -func WithRiakNodeName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.RiakNodeName.Enabled { - rm.Resource().Attributes().PutStr("riak.node.name", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -474,7 +467,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/riakreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -487,7 +479,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricRiakVnodeOperationCount.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/riakreceiver/internal/metadata/generated_metrics_test.go b/receiver/riakreceiver/internal/metadata/generated_metrics_test.go index bf10d78b1c30..fe4e8e3cbf8a 100644 --- a/receiver/riakreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/riakreceiver/internal/metadata/generated_metrics_test.go @@ -78,7 +78,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordRiakVnodeOperationCountDataPoint(ts, 1, AttributeRequestPut) - metrics := mb.Emit(WithRiakNodeName("riak.node.name-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -87,18 +89,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("riak.node.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.RiakNodeName.Enabled, ok) - if mb.resourceAttributesConfig.RiakNodeName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "riak.node.name-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 1) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/riakreceiver/internal/metadata/generated_resource.go b/receiver/riakreceiver/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..cafbabfa9ec1 --- /dev/null +++ b/receiver/riakreceiver/internal/metadata/generated_resource.go @@ -0,0 +1,36 @@ +// 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(), + } +} + +// SetRiakNodeName sets provided value as "riak.node.name" attribute. +func (rb *ResourceBuilder) SetRiakNodeName(val string) { + if rb.config.RiakNodeName.Enabled { + rb.res.Attributes().PutStr("riak.node.name", 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/receiver/riakreceiver/internal/metadata/generated_resource_test.go b/receiver/riakreceiver/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..7058d6d354ad --- /dev/null +++ b/receiver/riakreceiver/internal/metadata/generated_resource_test.go @@ -0,0 +1,40 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetRiakNodeName("riak.node.name-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 1, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 1, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("riak.node.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "riak.node.name-val", val.Str()) + } + }) + } +} diff --git a/receiver/riakreceiver/scraper.go b/receiver/riakreceiver/scraper.go index 57ec1fc7228b..18cb54a58859 100644 --- a/receiver/riakreceiver/scraper.go +++ b/receiver/riakreceiver/scraper.go @@ -27,6 +27,7 @@ type riakScraper struct { cfg *Config settings component.TelemetrySettings client client + rb *metadata.ResourceBuilder mb *metadata.MetricsBuilder } @@ -36,6 +37,7 @@ func newScraper(logger *zap.Logger, cfg *Config, settings receiver.CreateSetting logger: logger, cfg: cfg, settings: settings.TelemetrySettings, + rb: metadata.NewResourceBuilder(cfg.MetricsBuilderConfig.ResourceAttributes), mb: metadata.NewMetricsBuilder(cfg.MetricsBuilderConfig, settings), } } @@ -89,5 +91,6 @@ func (r *riakScraper) collectStats(stat *model.Stats) (pmetric.Metrics, error) { r.mb.RecordRiakVnodeIndexOperationCountDataPoint(now, stat.VnodeIndexWrites, metadata.AttributeOperationWrite) r.mb.RecordRiakVnodeIndexOperationCountDataPoint(now, stat.VnodeIndexDeletes, metadata.AttributeOperationDelete) - return r.mb.Emit(metadata.WithRiakNodeName(stat.Node)), errors.Combine() + r.rb.SetRiakNodeName(stat.Node) + return r.mb.Emit(metadata.WithResource(r.rb.Emit())), errors.Combine() } diff --git a/receiver/saphanareceiver/internal/metadata/generated_config_test.go b/receiver/saphanareceiver/internal/metadata/generated_config_test.go index 51d988d8a248..f4109d60cdbc 100644 --- a/receiver/saphanareceiver/internal/metadata/generated_config_test.go +++ b/receiver/saphanareceiver/internal/metadata/generated_config_test.go @@ -154,3 +154,49 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + DbSystem: ResourceAttributeConfig{Enabled: true}, + SaphanaHost: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + DbSystem: ResourceAttributeConfig{Enabled: false}, + SaphanaHost: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/saphanareceiver/internal/metadata/generated_metrics.go b/receiver/saphanareceiver/internal/metadata/generated_metrics.go index eef6f0ca0f33..125cb84e9c67 100644 --- a/receiver/saphanareceiver/internal/metadata/generated_metrics.go +++ b/receiver/saphanareceiver/internal/metadata/generated_metrics.go @@ -2923,10 +2923,8 @@ func newMetricSaphanaVolumeOperationTime(cfg MetricConfig) metricSaphanaVolumeOp type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricSaphanaAlertCount metricSaphanaAlertCount metricSaphanaBackupLatest metricSaphanaBackupLatest metricSaphanaColumnMemoryUsed metricSaphanaColumnMemoryUsed @@ -2989,7 +2987,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricSaphanaAlertCount: newMetricSaphanaAlertCount(mbc.Metrics.SaphanaAlertCount), metricSaphanaBackupLatest: newMetricSaphanaBackupLatest(mbc.Metrics.SaphanaBackupLatest), metricSaphanaColumnMemoryUsed: newMetricSaphanaColumnMemoryUsed(mbc.Metrics.SaphanaColumnMemoryUsed), @@ -3047,36 +3044,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithDbSystem sets provided value as "db.system" attribute for current resource. -func WithDbSystem(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.DbSystem.Enabled { - rm.Resource().Attributes().PutStr("db.system", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithSaphanaHost sets provided value as "saphana.host" attribute for current resource. -func WithSaphanaHost(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.SaphanaHost.Enabled { - rm.Resource().Attributes().PutStr("saphana.host", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -3100,7 +3084,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/saphanareceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -3152,7 +3135,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricSaphanaVolumeOperationTime.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/saphanareceiver/internal/metadata/generated_metrics_test.go b/receiver/saphanareceiver/internal/metadata/generated_metrics_test.go index a247cc392ab1..7518331f767e 100644 --- a/receiver/saphanareceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/saphanareceiver/internal/metadata/generated_metrics_test.go @@ -234,7 +234,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordSaphanaVolumeOperationTimeDataPoint(ts, "1", "path-val", "disk_usage_type-val", AttributeVolumeOperationTypeRead) - metrics := mb.Emit(WithDbSystem("db.system-val"), WithSaphanaHost("saphana.host-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -243,25 +245,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("db.system") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.DbSystem.Enabled, ok) - if mb.resourceAttributesConfig.DbSystem.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "db.system-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("saphana.host") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.SaphanaHost.Enabled, ok) - if mb.resourceAttributesConfig.SaphanaHost.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "saphana.host-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 2) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/saphanareceiver/internal/metadata/generated_resource.go b/receiver/saphanareceiver/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..9af9988d1826 --- /dev/null +++ b/receiver/saphanareceiver/internal/metadata/generated_resource.go @@ -0,0 +1,43 @@ +// 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(), + } +} + +// SetDbSystem sets provided value as "db.system" attribute. +func (rb *ResourceBuilder) SetDbSystem(val string) { + if rb.config.DbSystem.Enabled { + rb.res.Attributes().PutStr("db.system", val) + } +} + +// SetSaphanaHost sets provided value as "saphana.host" attribute. +func (rb *ResourceBuilder) SetSaphanaHost(val string) { + if rb.config.SaphanaHost.Enabled { + rb.res.Attributes().PutStr("saphana.host", 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/receiver/saphanareceiver/internal/metadata/generated_resource_test.go b/receiver/saphanareceiver/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..c204c4eb6202 --- /dev/null +++ b/receiver/saphanareceiver/internal/metadata/generated_resource_test.go @@ -0,0 +1,46 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetDbSystem("db.system-val") + rb.SetSaphanaHost("saphana.host-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 2, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 2, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("db.system") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "db.system-val", val.Str()) + } + val, ok = res.Attributes().Get("saphana.host") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "saphana.host-val", val.Str()) + } + }) + } +} diff --git a/receiver/saphanareceiver/scraper.go b/receiver/saphanareceiver/scraper.go index d820e7da5c13..b174725bf9d2 100644 --- a/receiver/saphanareceiver/scraper.go +++ b/receiver/saphanareceiver/scraper.go @@ -23,6 +23,7 @@ import ( type sapHanaScraper struct { settings receiver.CreateSettings cfg *Config + rb *metadata.ResourceBuilder mbs map[string]*metadata.MetricsBuilder factory sapHanaConnectionFactory } @@ -31,6 +32,7 @@ func newSapHanaScraper(settings receiver.CreateSettings, cfg *Config, factory sa rs := &sapHanaScraper{ settings: settings, cfg: cfg, + rb: metadata.NewResourceBuilder(cfg.ResourceAttributes), mbs: make(map[string]*metadata.MetricsBuilder), factory: factory, } @@ -80,15 +82,15 @@ func (s *sapHanaScraper) scrape(ctx context.Context) (pmetric.Metrics, error) { errs.Add(fmt.Errorf("Error unmarshaling resource attributes for saphana scraper: %w", err)) continue } - resourceOptions := []metadata.ResourceMetricsOption{metadata.WithDbSystem("saphana")} + s.rb.SetDbSystem("saphana") for attribute, value := range resourceAttributes { if attribute == "host" { - resourceOptions = append(resourceOptions, metadata.WithSaphanaHost(value)) + s.rb.SetSaphanaHost(value) } else { errs.Add(fmt.Errorf("Unsupported resource attribute: %s", attribute)) } } - resourceMetrics := mb.Emit(resourceOptions...) + resourceMetrics := mb.Emit(metadata.WithResource(s.rb.Emit())) resourceMetrics.ResourceMetrics().At(0).MoveTo(metrics.ResourceMetrics().AppendEmpty()) } diff --git a/receiver/snowflakereceiver/internal/metadata/generated_config_test.go b/receiver/snowflakereceiver/internal/metadata/generated_config_test.go index bafbe5883baa..c794a5ea3240 100644 --- a/receiver/snowflakereceiver/internal/metadata/generated_config_test.go +++ b/receiver/snowflakereceiver/internal/metadata/generated_config_test.go @@ -132,3 +132,47 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + SnowflakeAccountName: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + SnowflakeAccountName: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/snowflakereceiver/internal/metadata/generated_metrics.go b/receiver/snowflakereceiver/internal/metadata/generated_metrics.go index 124e643a1edd..36300a7989b2 100644 --- a/receiver/snowflakereceiver/internal/metadata/generated_metrics.go +++ b/receiver/snowflakereceiver/internal/metadata/generated_metrics.go @@ -1911,10 +1911,8 @@ func newMetricSnowflakeTotalElapsedTimeAvg(cfg MetricConfig) metricSnowflakeTota type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricSnowflakeBillingCloudServiceTotal metricSnowflakeBillingCloudServiceTotal metricSnowflakeBillingTotalCreditTotal metricSnowflakeBillingTotalCreditTotal metricSnowflakeBillingVirtualWarehouseTotal metricSnowflakeBillingVirtualWarehouseTotal @@ -1967,7 +1965,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricSnowflakeBillingCloudServiceTotal: newMetricSnowflakeBillingCloudServiceTotal(mbc.Metrics.SnowflakeBillingCloudServiceTotal), metricSnowflakeBillingTotalCreditTotal: newMetricSnowflakeBillingTotalCreditTotal(mbc.Metrics.SnowflakeBillingTotalCreditTotal), metricSnowflakeBillingVirtualWarehouseTotal: newMetricSnowflakeBillingVirtualWarehouseTotal(mbc.Metrics.SnowflakeBillingVirtualWarehouseTotal), @@ -2015,27 +2012,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithSnowflakeAccountName sets provided value as "snowflake.account.name" attribute for current resource. -func WithSnowflakeAccountName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.SnowflakeAccountName.Enabled { - rm.Resource().Attributes().PutStr("snowflake.account.name", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -2059,7 +2052,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/snowflakereceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -2101,7 +2093,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricSnowflakeTotalElapsedTimeAvg.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/snowflakereceiver/internal/metadata/generated_metrics_test.go b/receiver/snowflakereceiver/internal/metadata/generated_metrics_test.go index a753f5363960..d418dee5b6b6 100644 --- a/receiver/snowflakereceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/snowflakereceiver/internal/metadata/generated_metrics_test.go @@ -175,7 +175,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordSnowflakeTotalElapsedTimeAvgDataPoint(ts, 1, "schema_name-val", "execution_status-val", "error_message-val", "query_type-val", "warehouse_name-val", "database_name-val", "warehouse_size-val") - metrics := mb.Emit(WithSnowflakeAccountName("snowflake.account.name-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -184,18 +186,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("snowflake.account.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.SnowflakeAccountName.Enabled, ok) - if mb.resourceAttributesConfig.SnowflakeAccountName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "snowflake.account.name-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 1) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/snowflakereceiver/internal/metadata/generated_resource.go b/receiver/snowflakereceiver/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..dafdbb6f4015 --- /dev/null +++ b/receiver/snowflakereceiver/internal/metadata/generated_resource.go @@ -0,0 +1,36 @@ +// 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(), + } +} + +// SetSnowflakeAccountName sets provided value as "snowflake.account.name" attribute. +func (rb *ResourceBuilder) SetSnowflakeAccountName(val string) { + if rb.config.SnowflakeAccountName.Enabled { + rb.res.Attributes().PutStr("snowflake.account.name", 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/receiver/snowflakereceiver/internal/metadata/generated_resource_test.go b/receiver/snowflakereceiver/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..f926f5c9d579 --- /dev/null +++ b/receiver/snowflakereceiver/internal/metadata/generated_resource_test.go @@ -0,0 +1,40 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetSnowflakeAccountName("snowflake.account.name-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 1, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 1, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("snowflake.account.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "snowflake.account.name-val", val.Str()) + } + }) + } +} diff --git a/receiver/snowflakereceiver/scraper.go b/receiver/snowflakereceiver/scraper.go index bef50581e62d..36952e19ef50 100644 --- a/receiver/snowflakereceiver/scraper.go +++ b/receiver/snowflakereceiver/scraper.go @@ -20,6 +20,7 @@ type snowflakeMetricsScraper struct { client *snowflakeClient settings component.TelemetrySettings conf *Config + rb *metadata.ResourceBuilder mb *metadata.MetricsBuilder } @@ -27,6 +28,7 @@ func newSnowflakeMetricsScraper(settings receiver.CreateSettings, conf *Config) return &snowflakeMetricsScraper{ settings: settings.TelemetrySettings, conf: conf, + rb: metadata.NewResourceBuilder(conf.ResourceAttributes), mb: metadata.NewMetricsBuilder(conf.MetricsBuilderConfig, settings), } } @@ -66,7 +68,8 @@ func (s *snowflakeMetricsScraper) scrape(ctx context.Context) (pmetric.Metrics, s.scrapeSnowpipeMetrics(ctx, now, *errs) s.scrapeStorageMetrics(ctx, now, *errs) - return s.mb.Emit(metadata.WithSnowflakeAccountName(s.conf.Account)), errs.Combine() + s.rb.SetSnowflakeAccountName(s.conf.Account) + return s.mb.Emit(metadata.WithResource(s.rb.Emit())), errs.Combine() } func (s *snowflakeMetricsScraper) scrapeBillingMetrics(ctx context.Context, t pcommon.Timestamp, errs scrapererror.ScrapeErrors) { diff --git a/receiver/sqlserverreceiver/internal/metadata/generated_config_test.go b/receiver/sqlserverreceiver/internal/metadata/generated_config_test.go index 77e95c4a3e84..4e8ad0069a83 100644 --- a/receiver/sqlserverreceiver/internal/metadata/generated_config_test.go +++ b/receiver/sqlserverreceiver/internal/metadata/generated_config_test.go @@ -106,3 +106,51 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + SqlserverComputerName: ResourceAttributeConfig{Enabled: true}, + SqlserverDatabaseName: ResourceAttributeConfig{Enabled: true}, + SqlserverInstanceName: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + SqlserverComputerName: ResourceAttributeConfig{Enabled: false}, + SqlserverDatabaseName: ResourceAttributeConfig{Enabled: false}, + SqlserverInstanceName: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/sqlserverreceiver/internal/metadata/generated_metrics.go b/receiver/sqlserverreceiver/internal/metadata/generated_metrics.go index 86cf860c978c..99887dfcc630 100644 --- a/receiver/sqlserverreceiver/internal/metadata/generated_metrics.go +++ b/receiver/sqlserverreceiver/internal/metadata/generated_metrics.go @@ -1028,10 +1028,8 @@ func newMetricSqlserverUserConnectionCount(cfg MetricConfig) metricSqlserverUser type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricSqlserverBatchRequestRate metricSqlserverBatchRequestRate metricSqlserverBatchSQLCompilationRate metricSqlserverBatchSQLCompilationRate metricSqlserverBatchSQLRecompilationRate metricSqlserverBatchSQLRecompilationRate @@ -1069,7 +1067,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricSqlserverBatchRequestRate: newMetricSqlserverBatchRequestRate(mbc.Metrics.SqlserverBatchRequestRate), metricSqlserverBatchSQLCompilationRate: newMetricSqlserverBatchSQLCompilationRate(mbc.Metrics.SqlserverBatchSQLCompilationRate), metricSqlserverBatchSQLRecompilationRate: newMetricSqlserverBatchSQLRecompilationRate(mbc.Metrics.SqlserverBatchSQLRecompilationRate), @@ -1102,45 +1099,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithSqlserverComputerName sets provided value as "sqlserver.computer.name" attribute for current resource. -func WithSqlserverComputerName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.SqlserverComputerName.Enabled { - rm.Resource().Attributes().PutStr("sqlserver.computer.name", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithSqlserverDatabaseName sets provided value as "sqlserver.database.name" attribute for current resource. -func WithSqlserverDatabaseName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.SqlserverDatabaseName.Enabled { - rm.Resource().Attributes().PutStr("sqlserver.database.name", val) - } - } -} - -// WithSqlserverInstanceName sets provided value as "sqlserver.instance.name" attribute for current resource. -func WithSqlserverInstanceName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.SqlserverInstanceName.Enabled { - rm.Resource().Attributes().PutStr("sqlserver.instance.name", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -1164,7 +1139,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/sqlserverreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -1191,7 +1165,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricSqlserverUserConnectionCount.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/sqlserverreceiver/internal/metadata/generated_metrics_test.go b/receiver/sqlserverreceiver/internal/metadata/generated_metrics_test.go index 0f23bc335b55..3738d7a2476b 100644 --- a/receiver/sqlserverreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/sqlserverreceiver/internal/metadata/generated_metrics_test.go @@ -134,7 +134,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordSqlserverUserConnectionCountDataPoint(ts, 1) - metrics := mb.Emit(WithSqlserverComputerName("sqlserver.computer.name-val"), WithSqlserverDatabaseName("sqlserver.database.name-val"), WithSqlserverInstanceName("sqlserver.instance.name-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -143,32 +145,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("sqlserver.computer.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.SqlserverComputerName.Enabled, ok) - if mb.resourceAttributesConfig.SqlserverComputerName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "sqlserver.computer.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("sqlserver.database.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.SqlserverDatabaseName.Enabled, ok) - if mb.resourceAttributesConfig.SqlserverDatabaseName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "sqlserver.database.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("sqlserver.instance.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.SqlserverInstanceName.Enabled, ok) - if mb.resourceAttributesConfig.SqlserverInstanceName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "sqlserver.instance.name-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 3) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/sqlserverreceiver/internal/metadata/generated_resource.go b/receiver/sqlserverreceiver/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..4a56be86bc64 --- /dev/null +++ b/receiver/sqlserverreceiver/internal/metadata/generated_resource.go @@ -0,0 +1,50 @@ +// 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(), + } +} + +// SetSqlserverComputerName sets provided value as "sqlserver.computer.name" attribute. +func (rb *ResourceBuilder) SetSqlserverComputerName(val string) { + if rb.config.SqlserverComputerName.Enabled { + rb.res.Attributes().PutStr("sqlserver.computer.name", val) + } +} + +// SetSqlserverDatabaseName sets provided value as "sqlserver.database.name" attribute. +func (rb *ResourceBuilder) SetSqlserverDatabaseName(val string) { + if rb.config.SqlserverDatabaseName.Enabled { + rb.res.Attributes().PutStr("sqlserver.database.name", val) + } +} + +// SetSqlserverInstanceName sets provided value as "sqlserver.instance.name" attribute. +func (rb *ResourceBuilder) SetSqlserverInstanceName(val string) { + if rb.config.SqlserverInstanceName.Enabled { + rb.res.Attributes().PutStr("sqlserver.instance.name", 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/receiver/sqlserverreceiver/internal/metadata/generated_resource_test.go b/receiver/sqlserverreceiver/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..be34090fe422 --- /dev/null +++ b/receiver/sqlserverreceiver/internal/metadata/generated_resource_test.go @@ -0,0 +1,52 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetSqlserverComputerName("sqlserver.computer.name-val") + rb.SetSqlserverDatabaseName("sqlserver.database.name-val") + rb.SetSqlserverInstanceName("sqlserver.instance.name-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 1, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 3, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("sqlserver.computer.name") + assert.Equal(t, test == "all_set", ok) + if ok { + assert.EqualValues(t, "sqlserver.computer.name-val", val.Str()) + } + val, ok = res.Attributes().Get("sqlserver.database.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "sqlserver.database.name-val", val.Str()) + } + val, ok = res.Attributes().Get("sqlserver.instance.name") + assert.Equal(t, test == "all_set", ok) + if ok { + assert.EqualValues(t, "sqlserver.instance.name-val", val.Str()) + } + }) + } +} diff --git a/receiver/sqlserverreceiver/scraper.go b/receiver/sqlserverreceiver/scraper.go index 8802679677a0..05098efcd9e9 100644 --- a/receiver/sqlserverreceiver/scraper.go +++ b/receiver/sqlserverreceiver/scraper.go @@ -25,7 +25,8 @@ type sqlServerScraper struct { logger *zap.Logger config *Config watcherRecorders []watcherRecorder - metricsBuilder *metadata.MetricsBuilder + rb *metadata.ResourceBuilder + mb *metadata.MetricsBuilder } // watcherRecorder is a struct containing perf counter watcher along with corresponding value recorder. @@ -40,8 +41,12 @@ type curriedRecorder func(*metadata.MetricsBuilder, pcommon.Timestamp) // newSqlServerScraper returns a new sqlServerScraper. func newSqlServerScraper(params receiver.CreateSettings, cfg *Config) *sqlServerScraper { - metricsBuilder := metadata.NewMetricsBuilder(cfg.MetricsBuilderConfig, params) - return &sqlServerScraper{logger: params.Logger, config: cfg, metricsBuilder: metricsBuilder} + return &sqlServerScraper{ + logger: params.Logger, + config: cfg, + rb: metadata.NewResourceBuilder(cfg.ResourceAttributes), + mb: metadata.NewMetricsBuilder(cfg.MetricsBuilderConfig, params), + } } // start creates and sets the watchers for the scraper. @@ -76,7 +81,7 @@ func (s *sqlServerScraper) scrape(ctx context.Context) (pmetric.Metrics, error) s.emitMetricGroup(recorders, dbName) } - return s.metricsBuilder.Emit(), errs + return s.mb.Emit(), errs } // recordersPerDatabase scrapes perf counter values using provided []watcherRecorder and returns @@ -115,18 +120,17 @@ func (s *sqlServerScraper) emitMetricGroup(recorders []curriedRecorder, database now := pcommon.NewTimestampFromTime(time.Now()) for _, recorder := range recorders { - recorder(s.metricsBuilder, now) + recorder(s.mb, now) } - attributes := []metadata.ResourceMetricsOption{} if databaseName != "" { - attributes = append(attributes, metadata.WithSqlserverDatabaseName(databaseName)) + s.rb.SetSqlserverDatabaseName(databaseName) } if s.config.InstanceName != "" { - attributes = append(attributes, metadata.WithSqlserverComputerName(s.config.ComputerName)) - attributes = append(attributes, metadata.WithSqlserverInstanceName(s.config.InstanceName)) + s.rb.SetSqlserverComputerName(s.config.ComputerName) + s.rb.SetSqlserverInstanceName(s.config.InstanceName) } - s.metricsBuilder.EmitForResource(attributes...) + s.mb.EmitForResource(metadata.WithResource(s.rb.Emit())) } // shutdown stops all of the watchers for the scraper. diff --git a/receiver/sshcheckreceiver/internal/metadata/generated_config_test.go b/receiver/sshcheckreceiver/internal/metadata/generated_config_test.go index 84c457868823..4488cd3137a8 100644 --- a/receiver/sshcheckreceiver/internal/metadata/generated_config_test.go +++ b/receiver/sshcheckreceiver/internal/metadata/generated_config_test.go @@ -74,3 +74,47 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + SSHEndpoint: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + SSHEndpoint: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/sshcheckreceiver/internal/metadata/generated_metrics.go b/receiver/sshcheckreceiver/internal/metadata/generated_metrics.go index 0df9d57bc653..004da145c5ee 100644 --- a/receiver/sshcheckreceiver/internal/metadata/generated_metrics.go +++ b/receiver/sshcheckreceiver/internal/metadata/generated_metrics.go @@ -322,10 +322,8 @@ func newMetricSshcheckStatus(cfg MetricConfig) metricSshcheckStatus { type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricSshcheckDuration metricSshcheckDuration metricSshcheckError metricSshcheckError metricSshcheckSftpDuration metricSshcheckSftpDuration @@ -349,7 +347,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricSshcheckDuration: newMetricSshcheckDuration(mbc.Metrics.SshcheckDuration), metricSshcheckError: newMetricSshcheckError(mbc.Metrics.SshcheckError), metricSshcheckSftpDuration: newMetricSshcheckSftpDuration(mbc.Metrics.SshcheckSftpDuration), @@ -368,27 +365,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithSSHEndpoint sets provided value as "ssh.endpoint" attribute for current resource. -func WithSSHEndpoint(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.SSHEndpoint.Enabled { - rm.Resource().Attributes().PutStr("ssh.endpoint", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -412,7 +405,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/sshcheckreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -425,7 +417,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricSshcheckStatus.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/sshcheckreceiver/internal/metadata/generated_metrics_test.go b/receiver/sshcheckreceiver/internal/metadata/generated_metrics_test.go index d7a25c8a67a9..3a35eb229dee 100644 --- a/receiver/sshcheckreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/sshcheckreceiver/internal/metadata/generated_metrics_test.go @@ -75,7 +75,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordSshcheckStatusDataPoint(ts, 1) - metrics := mb.Emit(WithSSHEndpoint("ssh.endpoint-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -84,18 +86,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("ssh.endpoint") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.SSHEndpoint.Enabled, ok) - if mb.resourceAttributesConfig.SSHEndpoint.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "ssh.endpoint-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 1) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/sshcheckreceiver/internal/metadata/generated_resource.go b/receiver/sshcheckreceiver/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..981a9a0f5781 --- /dev/null +++ b/receiver/sshcheckreceiver/internal/metadata/generated_resource.go @@ -0,0 +1,36 @@ +// 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(), + } +} + +// SetSSHEndpoint sets provided value as "ssh.endpoint" attribute. +func (rb *ResourceBuilder) SetSSHEndpoint(val string) { + if rb.config.SSHEndpoint.Enabled { + rb.res.Attributes().PutStr("ssh.endpoint", 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/receiver/sshcheckreceiver/internal/metadata/generated_resource_test.go b/receiver/sshcheckreceiver/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..cc4b76679d71 --- /dev/null +++ b/receiver/sshcheckreceiver/internal/metadata/generated_resource_test.go @@ -0,0 +1,40 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetSSHEndpoint("ssh.endpoint-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 0, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 1, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("ssh.endpoint") + assert.Equal(t, test == "all_set", ok) + if ok { + assert.EqualValues(t, "ssh.endpoint-val", val.Str()) + } + }) + } +} diff --git a/receiver/vcenterreceiver/internal/metadata/generated_config_test.go b/receiver/vcenterreceiver/internal/metadata/generated_config_test.go index 0a44f1953f7a..09931e3a61c0 100644 --- a/receiver/vcenterreceiver/internal/metadata/generated_config_test.go +++ b/receiver/vcenterreceiver/internal/metadata/generated_config_test.go @@ -150,3 +150,57 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + VcenterClusterName: ResourceAttributeConfig{Enabled: true}, + VcenterDatastoreName: ResourceAttributeConfig{Enabled: true}, + VcenterHostName: ResourceAttributeConfig{Enabled: true}, + VcenterResourcePoolName: ResourceAttributeConfig{Enabled: true}, + VcenterVMID: ResourceAttributeConfig{Enabled: true}, + VcenterVMName: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + VcenterClusterName: ResourceAttributeConfig{Enabled: false}, + VcenterDatastoreName: ResourceAttributeConfig{Enabled: false}, + VcenterHostName: ResourceAttributeConfig{Enabled: false}, + VcenterResourcePoolName: ResourceAttributeConfig{Enabled: false}, + VcenterVMID: ResourceAttributeConfig{Enabled: false}, + VcenterVMName: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/vcenterreceiver/internal/metadata/generated_metrics.go b/receiver/vcenterreceiver/internal/metadata/generated_metrics.go index 906407df6049..c4a2d396032c 100644 --- a/receiver/vcenterreceiver/internal/metadata/generated_metrics.go +++ b/receiver/vcenterreceiver/internal/metadata/generated_metrics.go @@ -2140,10 +2140,8 @@ func newMetricVcenterVMNetworkUsage(cfg MetricConfig) metricVcenterVMNetworkUsag type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricVcenterClusterCPUEffective metricVcenterClusterCPUEffective metricVcenterClusterCPULimit metricVcenterClusterCPULimit metricVcenterClusterHostCount metricVcenterClusterHostCount @@ -2200,7 +2198,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricVcenterClusterCPUEffective: newMetricVcenterClusterCPUEffective(mbc.Metrics.VcenterClusterCPUEffective), metricVcenterClusterCPULimit: newMetricVcenterClusterCPULimit(mbc.Metrics.VcenterClusterCPULimit), metricVcenterClusterHostCount: newMetricVcenterClusterHostCount(mbc.Metrics.VcenterClusterHostCount), @@ -2252,72 +2249,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithVcenterClusterName sets provided value as "vcenter.cluster.name" attribute for current resource. -func WithVcenterClusterName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.VcenterClusterName.Enabled { - rm.Resource().Attributes().PutStr("vcenter.cluster.name", val) - } - } -} - -// WithVcenterDatastoreName sets provided value as "vcenter.datastore.name" attribute for current resource. -func WithVcenterDatastoreName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.VcenterDatastoreName.Enabled { - rm.Resource().Attributes().PutStr("vcenter.datastore.name", val) - } - } -} - -// WithVcenterHostName sets provided value as "vcenter.host.name" attribute for current resource. -func WithVcenterHostName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.VcenterHostName.Enabled { - rm.Resource().Attributes().PutStr("vcenter.host.name", val) - } - } -} - -// WithVcenterResourcePoolName sets provided value as "vcenter.resource_pool.name" attribute for current resource. -func WithVcenterResourcePoolName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.VcenterResourcePoolName.Enabled { - rm.Resource().Attributes().PutStr("vcenter.resource_pool.name", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithVcenterVMID sets provided value as "vcenter.vm.id" attribute for current resource. -func WithVcenterVMID(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.VcenterVMID.Enabled { - rm.Resource().Attributes().PutStr("vcenter.vm.id", val) - } - } -} - -// WithVcenterVMName sets provided value as "vcenter.vm.name" attribute for current resource. -func WithVcenterVMName(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.VcenterVMName.Enabled { - rm.Resource().Attributes().PutStr("vcenter.vm.name", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -2341,7 +2289,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/vcenterreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -2387,7 +2334,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricVcenterVMNetworkUsage.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/vcenterreceiver/internal/metadata/generated_metrics_test.go b/receiver/vcenterreceiver/internal/metadata/generated_metrics_test.go index e9d211c82feb..779e2504dda3 100644 --- a/receiver/vcenterreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/vcenterreceiver/internal/metadata/generated_metrics_test.go @@ -209,7 +209,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordVcenterVMNetworkUsageDataPoint(ts, 1) - metrics := mb.Emit(WithVcenterClusterName("vcenter.cluster.name-val"), WithVcenterDatastoreName("vcenter.datastore.name-val"), WithVcenterHostName("vcenter.host.name-val"), WithVcenterResourcePoolName("vcenter.resource_pool.name-val"), WithVcenterVMID("vcenter.vm.id-val"), WithVcenterVMName("vcenter.vm.name-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -218,53 +220,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("vcenter.cluster.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.VcenterClusterName.Enabled, ok) - if mb.resourceAttributesConfig.VcenterClusterName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "vcenter.cluster.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("vcenter.datastore.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.VcenterDatastoreName.Enabled, ok) - if mb.resourceAttributesConfig.VcenterDatastoreName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "vcenter.datastore.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("vcenter.host.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.VcenterHostName.Enabled, ok) - if mb.resourceAttributesConfig.VcenterHostName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "vcenter.host.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("vcenter.resource_pool.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.VcenterResourcePoolName.Enabled, ok) - if mb.resourceAttributesConfig.VcenterResourcePoolName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "vcenter.resource_pool.name-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("vcenter.vm.id") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.VcenterVMID.Enabled, ok) - if mb.resourceAttributesConfig.VcenterVMID.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "vcenter.vm.id-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("vcenter.vm.name") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.VcenterVMName.Enabled, ok) - if mb.resourceAttributesConfig.VcenterVMName.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "vcenter.vm.name-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 6) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/vcenterreceiver/internal/metadata/generated_resource.go b/receiver/vcenterreceiver/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..efd0c67294b0 --- /dev/null +++ b/receiver/vcenterreceiver/internal/metadata/generated_resource.go @@ -0,0 +1,71 @@ +// 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(), + } +} + +// SetVcenterClusterName sets provided value as "vcenter.cluster.name" attribute. +func (rb *ResourceBuilder) SetVcenterClusterName(val string) { + if rb.config.VcenterClusterName.Enabled { + rb.res.Attributes().PutStr("vcenter.cluster.name", val) + } +} + +// SetVcenterDatastoreName sets provided value as "vcenter.datastore.name" attribute. +func (rb *ResourceBuilder) SetVcenterDatastoreName(val string) { + if rb.config.VcenterDatastoreName.Enabled { + rb.res.Attributes().PutStr("vcenter.datastore.name", val) + } +} + +// SetVcenterHostName sets provided value as "vcenter.host.name" attribute. +func (rb *ResourceBuilder) SetVcenterHostName(val string) { + if rb.config.VcenterHostName.Enabled { + rb.res.Attributes().PutStr("vcenter.host.name", val) + } +} + +// SetVcenterResourcePoolName sets provided value as "vcenter.resource_pool.name" attribute. +func (rb *ResourceBuilder) SetVcenterResourcePoolName(val string) { + if rb.config.VcenterResourcePoolName.Enabled { + rb.res.Attributes().PutStr("vcenter.resource_pool.name", val) + } +} + +// SetVcenterVMID sets provided value as "vcenter.vm.id" attribute. +func (rb *ResourceBuilder) SetVcenterVMID(val string) { + if rb.config.VcenterVMID.Enabled { + rb.res.Attributes().PutStr("vcenter.vm.id", val) + } +} + +// SetVcenterVMName sets provided value as "vcenter.vm.name" attribute. +func (rb *ResourceBuilder) SetVcenterVMName(val string) { + if rb.config.VcenterVMName.Enabled { + rb.res.Attributes().PutStr("vcenter.vm.name", 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/receiver/vcenterreceiver/internal/metadata/generated_resource_test.go b/receiver/vcenterreceiver/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..45a4efa8f741 --- /dev/null +++ b/receiver/vcenterreceiver/internal/metadata/generated_resource_test.go @@ -0,0 +1,70 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetVcenterClusterName("vcenter.cluster.name-val") + rb.SetVcenterDatastoreName("vcenter.datastore.name-val") + rb.SetVcenterHostName("vcenter.host.name-val") + rb.SetVcenterResourcePoolName("vcenter.resource_pool.name-val") + rb.SetVcenterVMID("vcenter.vm.id-val") + rb.SetVcenterVMName("vcenter.vm.name-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 6, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 6, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("vcenter.cluster.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "vcenter.cluster.name-val", val.Str()) + } + val, ok = res.Attributes().Get("vcenter.datastore.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "vcenter.datastore.name-val", val.Str()) + } + val, ok = res.Attributes().Get("vcenter.host.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "vcenter.host.name-val", val.Str()) + } + val, ok = res.Attributes().Get("vcenter.resource_pool.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "vcenter.resource_pool.name-val", val.Str()) + } + val, ok = res.Attributes().Get("vcenter.vm.id") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "vcenter.vm.id-val", val.Str()) + } + val, ok = res.Attributes().Get("vcenter.vm.name") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "vcenter.vm.name-val", val.Str()) + } + }) + } +} diff --git a/receiver/vcenterreceiver/scraper.go b/receiver/vcenterreceiver/scraper.go index 5024260a8737..a7a8f936ac0b 100644 --- a/receiver/vcenterreceiver/scraper.go +++ b/receiver/vcenterreceiver/scraper.go @@ -25,6 +25,7 @@ var _ receiver.Metrics = (*vcenterMetricScraper)(nil) type vcenterMetricScraper struct { client *vcenterClient config *Config + rb *metadata.ResourceBuilder mb *metadata.MetricsBuilder logger *zap.Logger } @@ -39,6 +40,7 @@ func newVmwareVcenterScraper( client: client, config: config, logger: logger, + rb: metadata.NewResourceBuilder(config.ResourceAttributes), mb: metadata.NewMetricsBuilder(config.MetricsBuilderConfig, settings), } } @@ -122,9 +124,8 @@ func (v *vcenterMetricScraper) collectCluster( v.mb.RecordVcenterClusterMemoryLimitDataPoint(now, s.TotalMemory) v.mb.RecordVcenterClusterHostCountDataPoint(now, int64(s.NumHosts-s.NumEffectiveHosts), false) v.mb.RecordVcenterClusterHostCountDataPoint(now, int64(s.NumEffectiveHosts), true) - v.mb.EmitForResource( - metadata.WithVcenterClusterName(c.Name()), - ) + v.rb.SetVcenterClusterName(c.Name()) + v.mb.EmitForResource(metadata.WithResource(v.rb.Emit())) } func (v *vcenterMetricScraper) collectDatastores( @@ -159,10 +160,9 @@ func (v *vcenterMetricScraper) collectDatastore( } v.recordDatastoreProperties(now, moDS) - v.mb.EmitForResource( - metadata.WithVcenterClusterName(cluster.Name()), - metadata.WithVcenterDatastoreName(moDS.Name), - ) + v.rb.SetVcenterClusterName(cluster.Name()) + v.rb.SetVcenterDatastoreName(moDS.Name) + v.mb.EmitForResource(metadata.WithResource(v.rb.Emit())) } func (v *vcenterMetricScraper) collectHosts( @@ -203,10 +203,9 @@ func (v *vcenterMetricScraper) collectHost( } v.recordHostSystemMemoryUsage(now, hwSum) v.recordHostPerformanceMetrics(ctx, hwSum, errs) - v.mb.EmitForResource( - metadata.WithVcenterHostName(host.Name()), - metadata.WithVcenterClusterName(cluster.Name()), - ) + v.rb.SetVcenterHostName(host.Name()) + v.rb.SetVcenterClusterName(cluster.Name()) + v.mb.EmitForResource(metadata.WithResource(v.rb.Emit())) } func (v *vcenterMetricScraper) collectResourcePools( @@ -231,7 +230,8 @@ func (v *vcenterMetricScraper) collectResourcePools( continue } v.recordResourcePool(ts, moRP) - v.mb.EmitForResource(metadata.WithVcenterResourcePoolName(rp.Name())) + v.rb.SetVcenterResourcePoolName(rp.Name()) + v.mb.EmitForResource(metadata.WithResource(v.rb.Emit())) } } @@ -294,12 +294,11 @@ func (v *vcenterMetricScraper) collectVMs( vmUUID := moVM.Config.InstanceUuid v.collectVM(ctx, colTime, moVM, hwSum, errs) - v.mb.EmitForResource( - metadata.WithVcenterVMName(vm.Name()), - metadata.WithVcenterVMID(vmUUID), - metadata.WithVcenterClusterName(cluster.Name()), - metadata.WithVcenterHostName(hostname), - ) + v.rb.SetVcenterVMName(vm.Name()) + v.rb.SetVcenterVMID(vmUUID) + v.rb.SetVcenterClusterName(cluster.Name()) + v.rb.SetVcenterHostName(hostname) + v.mb.EmitForResource(metadata.WithResource(v.rb.Emit())) } return poweredOnVMs, poweredOffVMs } diff --git a/receiver/zookeeperreceiver/internal/metadata/generated_config_test.go b/receiver/zookeeperreceiver/internal/metadata/generated_config_test.go index aa2feb6357b5..8a784145e62d 100644 --- a/receiver/zookeeperreceiver/internal/metadata/generated_config_test.go +++ b/receiver/zookeeperreceiver/internal/metadata/generated_config_test.go @@ -96,3 +96,49 @@ func loadMetricsBuilderConfig(t *testing.T, name string) MetricsBuilderConfig { require.NoError(t, component.UnmarshalConfig(sub, &cfg)) return cfg } + +func TestResourceAttributesConfig(t *testing.T) { + tests := []struct { + name string + want ResourceAttributesConfig + }{ + { + name: "default", + want: DefaultResourceAttributesConfig(), + }, + { + name: "all_set", + want: ResourceAttributesConfig{ + ServerState: ResourceAttributeConfig{Enabled: true}, + ZkVersion: ResourceAttributeConfig{Enabled: true}, + }, + }, + { + name: "none_set", + want: ResourceAttributesConfig{ + ServerState: ResourceAttributeConfig{Enabled: false}, + ZkVersion: 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, component.UnmarshalConfig(sub, &cfg)) + return cfg +} diff --git a/receiver/zookeeperreceiver/internal/metadata/generated_metrics.go b/receiver/zookeeperreceiver/internal/metadata/generated_metrics.go index 521e75f6e61a..1f36c03faaf2 100644 --- a/receiver/zookeeperreceiver/internal/metadata/generated_metrics.go +++ b/receiver/zookeeperreceiver/internal/metadata/generated_metrics.go @@ -878,10 +878,8 @@ func newMetricZookeeperZnodeCount(cfg MetricConfig) metricZookeeperZnodeCount { type MetricsBuilder struct { startTime pcommon.Timestamp // start time that will be applied to all recorded data points. metricsCapacity int // maximum observed number of metrics per resource. - resourceCapacity int // maximum observed number of resource attributes. metricsBuffer pmetric.Metrics // accumulates metrics data before emitting. buildInfo component.BuildInfo // contains version information - resourceAttributesConfig ResourceAttributesConfig metricZookeeperConnectionActive metricZookeeperConnectionActive metricZookeeperDataTreeEphemeralNodeCount metricZookeeperDataTreeEphemeralNodeCount metricZookeeperDataTreeSize metricZookeeperDataTreeSize @@ -915,7 +913,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSetting startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), buildInfo: settings.BuildInfo, - resourceAttributesConfig: mbc.ResourceAttributes, metricZookeeperConnectionActive: newMetricZookeeperConnectionActive(mbc.Metrics.ZookeeperConnectionActive), metricZookeeperDataTreeEphemeralNodeCount: newMetricZookeeperDataTreeEphemeralNodeCount(mbc.Metrics.ZookeeperDataTreeEphemeralNodeCount), metricZookeeperDataTreeSize: newMetricZookeeperDataTreeSize(mbc.Metrics.ZookeeperDataTreeSize), @@ -944,36 +941,23 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { if mb.metricsCapacity < rm.ScopeMetrics().At(0).Metrics().Len() { mb.metricsCapacity = rm.ScopeMetrics().At(0).Metrics().Len() } - if mb.resourceCapacity < rm.Resource().Attributes().Len() { - mb.resourceCapacity = rm.Resource().Attributes().Len() - } } // ResourceMetricsOption applies changes to provided resource metrics. -type ResourceMetricsOption func(ResourceAttributesConfig, pmetric.ResourceMetrics) - -// WithServerState sets provided value as "server.state" attribute for current resource. -func WithServerState(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.ServerState.Enabled { - rm.Resource().Attributes().PutStr("server.state", val) - } - } -} +type ResourceMetricsOption func(pmetric.ResourceMetrics) -// WithZkVersion sets provided value as "zk.version" attribute for current resource. -func WithZkVersion(val string) ResourceMetricsOption { - return func(rac ResourceAttributesConfig, rm pmetric.ResourceMetrics) { - if rac.ZkVersion.Enabled { - rm.Resource().Attributes().PutStr("zk.version", val) - } +// WithResource sets the provided resource on the emitted ResourceMetrics. +// It's recommended to use ResourceBuilder to create the resource. +func WithResource(res pcommon.Resource) ResourceMetricsOption { + return func(rm pmetric.ResourceMetrics) { + res.CopyTo(rm.Resource()) } } // WithStartTimeOverride overrides start time for all the resource metrics data points. // This option should be only used if different start time has to be set on metrics coming from different resources. func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { - return func(_ ResourceAttributesConfig, rm pmetric.ResourceMetrics) { + return func(rm pmetric.ResourceMetrics) { var dps pmetric.NumberDataPointSlice metrics := rm.ScopeMetrics().At(0).Metrics() for i := 0; i < metrics.Len(); i++ { @@ -997,7 +981,6 @@ func WithStartTimeOverride(start pcommon.Timestamp) ResourceMetricsOption { // Resource attributes should be provided as ResourceMetricsOption arguments. func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { rm := pmetric.NewResourceMetrics() - rm.Resource().Attributes().EnsureCapacity(mb.resourceCapacity) ils := rm.ScopeMetrics().AppendEmpty() ils.Scope().SetName("otelcol/zookeeperreceiver") ils.Scope().SetVersion(mb.buildInfo.Version) @@ -1020,7 +1003,7 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricZookeeperZnodeCount.emit(ils.Metrics()) for _, op := range rmo { - op(mb.resourceAttributesConfig, rm) + op(rm) } if ils.Metrics().Len() > 0 { mb.updateCapacity(rm) diff --git a/receiver/zookeeperreceiver/internal/metadata/generated_metrics_test.go b/receiver/zookeeperreceiver/internal/metadata/generated_metrics_test.go index fbf685f0cfd7..6b26362fb6d5 100644 --- a/receiver/zookeeperreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/zookeeperreceiver/internal/metadata/generated_metrics_test.go @@ -118,7 +118,9 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordZookeeperZnodeCountDataPoint(ts, 1) - metrics := mb.Emit(WithServerState("server.state-val"), WithZkVersion("zk.version-val")) + res := pcommon.NewResource() + res.Attributes().PutStr("k1", "v1") + metrics := mb.Emit(WithResource(res)) if test.configSet == testSetNone { assert.Equal(t, 0, metrics.ResourceMetrics().Len()) @@ -127,25 +129,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, 1, metrics.ResourceMetrics().Len()) rm := metrics.ResourceMetrics().At(0) - attrCount := 0 - enabledAttrCount := 0 - attrVal, ok := rm.Resource().Attributes().Get("server.state") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.ServerState.Enabled, ok) - if mb.resourceAttributesConfig.ServerState.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "server.state-val", attrVal.Str()) - } - attrVal, ok = rm.Resource().Attributes().Get("zk.version") - attrCount++ - assert.Equal(t, mb.resourceAttributesConfig.ZkVersion.Enabled, ok) - if mb.resourceAttributesConfig.ZkVersion.Enabled { - enabledAttrCount++ - assert.EqualValues(t, "zk.version-val", attrVal.Str()) - } - assert.Equal(t, enabledAttrCount, rm.Resource().Attributes().Len()) - assert.Equal(t, attrCount, 2) - + assert.Equal(t, res, rm.Resource()) assert.Equal(t, 1, rm.ScopeMetrics().Len()) ms := rm.ScopeMetrics().At(0).Metrics() if test.configSet == testSetDefault { diff --git a/receiver/zookeeperreceiver/internal/metadata/generated_resource.go b/receiver/zookeeperreceiver/internal/metadata/generated_resource.go new file mode 100644 index 000000000000..b3875b8c6080 --- /dev/null +++ b/receiver/zookeeperreceiver/internal/metadata/generated_resource.go @@ -0,0 +1,43 @@ +// 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(), + } +} + +// SetServerState sets provided value as "server.state" attribute. +func (rb *ResourceBuilder) SetServerState(val string) { + if rb.config.ServerState.Enabled { + rb.res.Attributes().PutStr("server.state", val) + } +} + +// SetZkVersion sets provided value as "zk.version" attribute. +func (rb *ResourceBuilder) SetZkVersion(val string) { + if rb.config.ZkVersion.Enabled { + rb.res.Attributes().PutStr("zk.version", 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/receiver/zookeeperreceiver/internal/metadata/generated_resource_test.go b/receiver/zookeeperreceiver/internal/metadata/generated_resource_test.go new file mode 100644 index 000000000000..c78e6c2a84fc --- /dev/null +++ b/receiver/zookeeperreceiver/internal/metadata/generated_resource_test.go @@ -0,0 +1,46 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResourceBuilder(t *testing.T) { + for _, test := range []string{"default", "all_set", "none_set"} { + t.Run(test, func(t *testing.T) { + cfg := loadResourceAttributesConfig(t, test) + rb := NewResourceBuilder(cfg) + rb.SetServerState("server.state-val") + rb.SetZkVersion("zk.version-val") + + res := rb.Emit() + assert.Equal(t, 0, rb.Emit().Attributes().Len()) // Second call should return 0 + + switch test { + case "default": + assert.Equal(t, 2, res.Attributes().Len()) + case "all_set": + assert.Equal(t, 2, res.Attributes().Len()) + case "none_set": + assert.Equal(t, 0, res.Attributes().Len()) + return + default: + assert.Failf(t, "unexpected test case: %s", test) + } + + val, ok := res.Attributes().Get("server.state") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "server.state-val", val.Str()) + } + val, ok = res.Attributes().Get("zk.version") + assert.True(t, ok) + if ok { + assert.EqualValues(t, "zk.version-val", val.Str()) + } + }) + } +} diff --git a/receiver/zookeeperreceiver/scraper.go b/receiver/zookeeperreceiver/scraper.go index 276d35b8448b..414e9cf83f8b 100644 --- a/receiver/zookeeperreceiver/scraper.go +++ b/receiver/zookeeperreceiver/scraper.go @@ -32,6 +32,7 @@ type zookeeperMetricsScraper struct { logger *zap.Logger config *Config cancel context.CancelFunc + rb *metadata.ResourceBuilder mb *metadata.MetricsBuilder // For mocking. @@ -57,6 +58,7 @@ func newZookeeperMetricsScraper(settings receiver.CreateSettings, config *Config z := &zookeeperMetricsScraper{ logger: settings.Logger, config: config, + rb: metadata.NewResourceBuilder(config.ResourceAttributes), mb: metadata.NewMetricsBuilder(config.MetricsBuilderConfig, settings), closeConnection: closeConnection, setConnectionDeadline: setConnectionDeadline, @@ -88,12 +90,10 @@ func (z *zookeeperMetricsScraper) scrape(ctx context.Context) (pmetric.Metrics, return pmetric.NewMetrics(), err } - resourceOpts := make([]metadata.ResourceMetricsOption, 0, 2) - - resourceOpts = z.processMntr(responseMntr, resourceOpts) + z.processMntr(responseMntr) z.processRuok(responseRuok) - return z.mb.Emit(resourceOpts...), nil + return z.mb.Emit(metadata.WithResource(z.rb.Emit())), nil } func (z *zookeeperMetricsScraper) runCommand(ctx context.Context, command string) ([]string, error) { @@ -135,7 +135,7 @@ func (z *zookeeperMetricsScraper) runCommand(ctx context.Context, command string return response, nil } -func (z *zookeeperMetricsScraper) processMntr(response []string, resourceOpts []metadata.ResourceMetricsOption) []metadata.ResourceMetricsOption { +func (z *zookeeperMetricsScraper) processMntr(response []string) { creator := newMetricCreator(z.mb) now := pcommon.NewTimestampFromTime(time.Now()) for _, line := range response { @@ -152,10 +152,10 @@ func (z *zookeeperMetricsScraper) processMntr(response []string, resourceOpts [] metricValue := parts[2] switch metricKey { case zkVersionKey: - resourceOpts = append(resourceOpts, metadata.WithZkVersion(metricValue)) + z.rb.SetZkVersion(metricValue) continue case serverStateKey: - resourceOpts = append(resourceOpts, metadata.WithServerState(metricValue)) + z.rb.SetServerState(metricValue) continue default: // Skip metric if there is no descriptor associated with it. @@ -178,7 +178,6 @@ func (z *zookeeperMetricsScraper) processMntr(response []string, resourceOpts [] // Generate computed metrics creator.generateComputedMetrics(z.logger, now) - return resourceOpts } func (z *zookeeperMetricsScraper) processRuok(response []string) { From 36fc4261cb5a0c1cd8c8a9a6bf3c5466fc81f5bd Mon Sep 17 00:00:00 2001 From: Antoine Toulme Date: Tue, 25 Jul 2023 15:36:57 -0700 Subject: [PATCH 35/42] [receiver/hostmetrics] Remove the need to set environment variables (#23861) --- .chloggen/hostmetricsreceiver-env.yaml | 20 ++++++++ receiver/hostmetricsreceiver/config.go | 4 +- receiver/hostmetricsreceiver/config_test.go | 46 ++++++++++++++++--- receiver/hostmetricsreceiver/factory.go | 4 -- .../hostmetricsreceiver/hostmetrics_linux.go | 31 +++++++------ .../hostmetrics_linux_test.go | 21 ++++++--- .../hostmetricsreceiver/hostmetrics_others.go | 12 +++-- .../hostmetrics_others_test.go | 4 +- .../hostmetrics_receiver_test.go | 3 ++ .../perfcounters/perfcounter_scraper_mock.go | 12 ++--- .../hostmetricsreceiver/internal/scraper.go | 9 +++- .../scraper/cpuscraper/cpu_scraper.go | 17 ++++--- .../scraper/cpuscraper/cpu_scraper_test.go | 16 +++---- .../diskscraper/disk_scraper_others.go | 18 +++++--- .../diskscraper/disk_scraper_others_test.go | 10 ++-- .../scraper/diskscraper/disk_scraper_test.go | 6 +-- .../diskscraper/disk_scraper_windows.go | 10 ++-- .../filesystemscraper/filesystem_scraper.go | 21 +++++---- .../filesystem_scraper_others.go | 2 +- .../filesystem_scraper_test.go | 30 ++++++------ .../scraper/loadscraper/load_scraper.go | 16 ++++--- .../loadscraper/load_scraper_others.go | 4 +- .../scraper/loadscraper/load_scraper_test.go | 10 ++-- .../loadscraper/load_scraper_windows.go | 2 +- .../loadscraper/load_scraper_windows_test.go | 10 ++-- .../scraper/memoryscraper/memory_scraper.go | 19 +++++--- .../memoryscraper/memory_scraper_test.go | 12 ++--- .../scraper/networkscraper/network_linux.go | 6 ++- .../scraper/networkscraper/network_scraper.go | 28 ++++++----- .../networkscraper/network_scraper_test.go | 18 ++++---- .../pagingscraper/paging_scraper_others.go | 17 ++++--- .../paging_scraper_others_test.go | 6 +-- .../pagingscraper/paging_scraper_test.go | 4 +- .../pagingscraper/paging_scraper_windows.go | 8 ++-- .../processesscraper/processes_scraper.go | 15 ++++-- .../processes_scraper_test.go | 6 +-- .../processes_scraper_unix.go | 5 +- .../handlecount/handles_windows_test.go | 3 +- .../scraper/processscraper/process.go | 5 +- .../scraper/processscraper/process_scraper.go | 7 ++- .../processscraper/process_scraper_test.go | 12 ++--- .../processscraper/process_scraper_windows.go | 2 +- 42 files changed, 313 insertions(+), 198 deletions(-) create mode 100644 .chloggen/hostmetricsreceiver-env.yaml diff --git a/.chloggen/hostmetricsreceiver-env.yaml b/.chloggen/hostmetricsreceiver-env.yaml new file mode 100644 index 000000000000..0ed3802d763d --- /dev/null +++ b/.chloggen/hostmetricsreceiver-env.yaml @@ -0,0 +1,20 @@ +# Use this changelog template to create an entry for release notes. +# If your change doesn't affect end users, such as a test fix or a tooling change, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. + +# 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. filelogreceiver) +component: hostmetricsreceiver + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Remove the need to set environment variables with hostmetricsreceiver + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [23861] + +# (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: diff --git a/receiver/hostmetricsreceiver/config.go b/receiver/hostmetricsreceiver/config.go index f99f73c7fe96..80343dd5ea15 100644 --- a/receiver/hostmetricsreceiver/config.go +++ b/receiver/hostmetricsreceiver/config.go @@ -36,7 +36,7 @@ func (cfg *Config) Validate() error { if len(cfg.Scrapers) == 0 { err = multierr.Append(err, errors.New("must specify at least one scraper when using hostmetrics receiver")) } - err = multierr.Append(err, validateRootPath(cfg.RootPath, &osEnv{})) + err = multierr.Append(err, validateRootPath(cfg.RootPath)) return err } @@ -78,6 +78,8 @@ func (cfg *Config) Unmarshal(componentParser *confmap.Conf) error { } collectorCfg.SetRootPath(cfg.RootPath) + envMap := setGoPsutilEnvVars(cfg.RootPath, &osEnv{}) + collectorCfg.SetEnvMap(envMap) cfg.Scrapers[key] = collectorCfg } diff --git a/receiver/hostmetricsreceiver/config_test.go b/receiver/hostmetricsreceiver/config_test.go index 7c5f77236aeb..c88fc7fd2262 100644 --- a/receiver/hostmetricsreceiver/config_test.go +++ b/receiver/hostmetricsreceiver/config_test.go @@ -8,6 +8,7 @@ import ( "testing" "time" + "github.com/shirou/gopsutil/v3/common" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/component" @@ -44,7 +45,11 @@ func TestLoadConfig(t *testing.T) { r0 := cfg.Receivers[component.NewID(metadata.Type)] defaultConfigCPUScraper := factory.CreateDefaultConfig() defaultConfigCPUScraper.(*Config).Scrapers = map[string]internal.Config{ - cpuscraper.TypeStr: (&cpuscraper.Factory{}).CreateDefaultConfig(), + cpuscraper.TypeStr: func() internal.Config { + cfg := (&cpuscraper.Factory{}).CreateDefaultConfig() + cfg.SetEnvMap(common.EnvMap{}) + return cfg + }(), } assert.Equal(t, defaultConfigCPUScraper, r0) @@ -56,31 +61,58 @@ func TestLoadConfig(t *testing.T) { InitialDelay: time.Second, }, Scrapers: map[string]internal.Config{ - cpuscraper.TypeStr: (&cpuscraper.Factory{}).CreateDefaultConfig(), - diskscraper.TypeStr: (&diskscraper.Factory{}).CreateDefaultConfig(), + cpuscraper.TypeStr: func() internal.Config { + cfg := (&cpuscraper.Factory{}).CreateDefaultConfig() + cfg.SetEnvMap(common.EnvMap{}) + return cfg + }(), + diskscraper.TypeStr: func() internal.Config { + cfg := (&diskscraper.Factory{}).CreateDefaultConfig() + cfg.SetEnvMap(common.EnvMap{}) + return cfg + }(), loadscraper.TypeStr: (func() internal.Config { cfg := (&loadscraper.Factory{}).CreateDefaultConfig() cfg.(*loadscraper.Config).CPUAverage = true + cfg.SetEnvMap(common.EnvMap{}) return cfg })(), - filesystemscraper.TypeStr: (&filesystemscraper.Factory{}).CreateDefaultConfig(), - memoryscraper.TypeStr: (&memoryscraper.Factory{}).CreateDefaultConfig(), + filesystemscraper.TypeStr: func() internal.Config { + cfg := (&filesystemscraper.Factory{}).CreateDefaultConfig() + cfg.SetEnvMap(common.EnvMap{}) + return cfg + }(), + memoryscraper.TypeStr: func() internal.Config { + cfg := (&memoryscraper.Factory{}).CreateDefaultConfig() + cfg.SetEnvMap(common.EnvMap{}) + return cfg + }(), networkscraper.TypeStr: (func() internal.Config { cfg := (&networkscraper.Factory{}).CreateDefaultConfig() cfg.(*networkscraper.Config).Include = networkscraper.MatchConfig{ Interfaces: []string{"test1"}, Config: filterset.Config{MatchType: "strict"}, } + cfg.SetEnvMap(common.EnvMap{}) return cfg })(), - processesscraper.TypeStr: (&processesscraper.Factory{}).CreateDefaultConfig(), - pagingscraper.TypeStr: (&pagingscraper.Factory{}).CreateDefaultConfig(), + processesscraper.TypeStr: func() internal.Config { + cfg := (&processesscraper.Factory{}).CreateDefaultConfig() + cfg.SetEnvMap(common.EnvMap{}) + return cfg + }(), + pagingscraper.TypeStr: func() internal.Config { + cfg := (&pagingscraper.Factory{}).CreateDefaultConfig() + cfg.SetEnvMap(common.EnvMap{}) + return cfg + }(), processscraper.TypeStr: (func() internal.Config { cfg := (&processscraper.Factory{}).CreateDefaultConfig() cfg.(*processscraper.Config).Include = processscraper.MatchConfig{ Names: []string{"test2", "test3"}, Config: filterset.Config{MatchType: "regexp"}, } + cfg.SetEnvMap(common.EnvMap{}) return cfg })(), }, diff --git a/receiver/hostmetricsreceiver/factory.go b/receiver/hostmetricsreceiver/factory.go index 50003adca822..5a22d2385144 100644 --- a/receiver/hostmetricsreceiver/factory.go +++ b/receiver/hostmetricsreceiver/factory.go @@ -76,10 +76,6 @@ func createMetricsReceiver( return nil, err } - if err = setGoPsutilEnvVars(oCfg.RootPath, &osEnv{}); err != nil { - return nil, err - } - return scraperhelper.NewScraperControllerReceiver( &oCfg.ScraperControllerSettings, set, diff --git a/receiver/hostmetricsreceiver/hostmetrics_linux.go b/receiver/hostmetricsreceiver/hostmetrics_linux.go index ea83cd1f3028..0408c3615480 100644 --- a/receiver/hostmetricsreceiver/hostmetrics_linux.go +++ b/receiver/hostmetricsreceiver/hostmetrics_linux.go @@ -9,15 +9,17 @@ import ( "fmt" "os" "path/filepath" + + "github.com/shirou/gopsutil/v3/common" ) -var gopsutilEnvVars = map[string]string{ - "HOST_PROC": "/proc", - "HOST_SYS": "/sys", - "HOST_ETC": "/etc", - "HOST_VAR": "/var", - "HOST_RUN": "/run", - "HOST_DEV": "/dev", +var gopsutilEnvVars = map[common.EnvKeyType]string{ + common.HostProcEnvKey: "/proc", + common.HostSysEnvKey: "/sys", + common.HostEtcEnvKey: "/etc", + common.HostVarEnvKey: "/var", + common.HostRunEnvKey: "/run", + common.HostDevEnvKey: "/dev", } // This exists to validate that different instances of the hostmetricsreceiver do not @@ -25,7 +27,7 @@ var gopsutilEnvVars = map[string]string{ // through env vars, so it must be consistent across the process. var globalRootPath string -func validateRootPath(rootPath string, _ environment) error { +func validateRootPath(rootPath string) error { if rootPath == "" || rootPath == "/" { return nil } @@ -42,19 +44,18 @@ func validateRootPath(rootPath string, _ environment) error { return nil } -func setGoPsutilEnvVars(rootPath string, env environment) error { +func setGoPsutilEnvVars(rootPath string, env environment) common.EnvMap { + m := common.EnvMap{} if rootPath == "" || rootPath == "/" { - return nil + return m } for envVarKey, defaultValue := range gopsutilEnvVars { - _, ok := env.Lookup(envVarKey) + _, ok := env.Lookup(string(envVarKey)) if ok { continue // don't override if existing env var is set } - if err := env.Set(envVarKey, filepath.Join(rootPath, defaultValue)); err != nil { - return err - } + m[envVarKey] = filepath.Join(rootPath, defaultValue) } - return nil + return m } diff --git a/receiver/hostmetricsreceiver/hostmetrics_linux_test.go b/receiver/hostmetricsreceiver/hostmetrics_linux_test.go index 56a96807d9b9..38d614a44c30 100644 --- a/receiver/hostmetricsreceiver/hostmetrics_linux_test.go +++ b/receiver/hostmetricsreceiver/hostmetrics_linux_test.go @@ -9,6 +9,7 @@ import ( "path/filepath" "testing" + "github.com/shirou/gopsutil/v3/common" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/component" @@ -20,16 +21,15 @@ import ( ) func TestConsistentRootPaths(t *testing.T) { - env := &testEnv{env: map[string]string{"HOST_PROC": "testdata"}} // use testdata because it's a directory that exists - don't actually use any files in it - assert.Nil(t, testValidate("testdata", env)) - assert.Nil(t, testValidate("", env)) - assert.Nil(t, testValidate("/", env)) + assert.Nil(t, testValidate("testdata")) + assert.Nil(t, testValidate("")) + assert.Nil(t, testValidate("/")) } func TestInconsistentRootPaths(t *testing.T) { globalRootPath = "foo" - err := testValidate("testdata", &testEnv{}) + err := testValidate("testdata") assert.EqualError(t, err, "inconsistent root_path configuration detected between hostmetricsreceivers: `foo` != `testdata`") } @@ -47,6 +47,13 @@ func TestLoadConfigRootPath(t *testing.T) { expectedConfig.RootPath = "testdata" cpuScraperCfg := (&cpuscraper.Factory{}).CreateDefaultConfig() cpuScraperCfg.SetRootPath("testdata") + cpuScraperCfg.SetEnvMap(common.EnvMap{ + common.HostDevEnvKey: "testdata/dev", + common.HostEtcEnvKey: "testdata/etc", + common.HostRunEnvKey: "testdata/run", + common.HostSysEnvKey: "testdata/sys", + common.HostVarEnvKey: "testdata/var", + }) expectedConfig.Scrapers = map[string]internal.Config{cpuscraper.TypeStr: cpuScraperCfg} assert.Equal(t, expectedConfig, r) @@ -61,8 +68,8 @@ func TestLoadInvalidConfig_RootPathNotExist(t *testing.T) { globalRootPath = "" } -func testValidate(rootPath string, env environment) error { - err := validateRootPath(rootPath, env) +func testValidate(rootPath string) error { + err := validateRootPath(rootPath) globalRootPath = "" return err } diff --git a/receiver/hostmetricsreceiver/hostmetrics_others.go b/receiver/hostmetricsreceiver/hostmetrics_others.go index f526dba76d2a..d2c8d11c6c55 100644 --- a/receiver/hostmetricsreceiver/hostmetrics_others.go +++ b/receiver/hostmetricsreceiver/hostmetrics_others.go @@ -5,15 +5,19 @@ package hostmetricsreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver" -import "fmt" +import ( + "fmt" -func validateRootPath(rootPath string, _ environment) error { + "github.com/shirou/gopsutil/v3/common" +) + +func validateRootPath(rootPath string) error { if rootPath == "" { return nil } return fmt.Errorf("root_path is supported on linux only") } -func setGoPsutilEnvVars(_ string, _ environment) error { - return nil +func setGoPsutilEnvVars(_ string, _ environment) common.EnvMap { + return common.EnvMap{} } diff --git a/receiver/hostmetricsreceiver/hostmetrics_others_test.go b/receiver/hostmetricsreceiver/hostmetrics_others_test.go index 2ce7f1a7822a..25ccd7b15513 100644 --- a/receiver/hostmetricsreceiver/hostmetrics_others_test.go +++ b/receiver/hostmetricsreceiver/hostmetrics_others_test.go @@ -12,9 +12,9 @@ import ( ) func TestRootPathNotAllowedOnOS(t *testing.T) { - assert.NotNil(t, validateRootPath("testdata", &testEnv{})) + assert.NotNil(t, validateRootPath("testdata")) } func TestRootPathUnset(t *testing.T) { - assert.Nil(t, validateRootPath("", &testEnv{})) + assert.Nil(t, validateRootPath("")) } diff --git a/receiver/hostmetricsreceiver/hostmetrics_receiver_test.go b/receiver/hostmetricsreceiver/hostmetrics_receiver_test.go index 475834495d62..fb51a59d95ca 100644 --- a/receiver/hostmetricsreceiver/hostmetrics_receiver_test.go +++ b/receiver/hostmetricsreceiver/hostmetrics_receiver_test.go @@ -10,6 +10,7 @@ import ( "testing" "time" + "github.com/shirou/gopsutil/v3/common" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -215,6 +216,8 @@ type mockConfig struct{} func (m *mockConfig) SetRootPath(_ string) {} +func (m *mockConfig) SetEnvMap(_ common.EnvMap) {} + type mockFactory struct{ mock.Mock } type mockScraper struct{ mock.Mock } diff --git a/receiver/hostmetricsreceiver/internal/perfcounters/perfcounter_scraper_mock.go b/receiver/hostmetricsreceiver/internal/perfcounters/perfcounter_scraper_mock.go index 7e3858901bba..2bef0009403a 100644 --- a/receiver/hostmetricsreceiver/internal/perfcounters/perfcounter_scraper_mock.go +++ b/receiver/hostmetricsreceiver/internal/perfcounters/perfcounter_scraper_mock.go @@ -28,7 +28,7 @@ func NewMockPerfCounterScraperError(scrapeErr, getObjectErr, getValuesErr, initE } // start is a no-op -func (p *MockPerfCounterScraperError) Initialize(objects ...string) error { +func (p *MockPerfCounterScraperError) Initialize(_ ...string) error { if p.initError != nil { return p.initError } @@ -52,7 +52,7 @@ type mockPerfDataCollectionError struct { // GetObject returns the specified getObjectErr or an object that will return a subsequent // error if getObjectErr is nil -func (p mockPerfDataCollectionError) GetObject(objectName string) (PerfDataObject, error) { +func (p mockPerfDataCollectionError) GetObject(_ string) (PerfDataObject, error) { if p.getObjectErr != nil { return nil, p.getObjectErr } @@ -65,11 +65,11 @@ type mockPerfDataObjectError struct { } // Filter is a no-op -func (obj mockPerfDataObjectError) Filter(includeFS, excludeFS filterset.FilterSet, includeTotal bool) { +func (obj mockPerfDataObjectError) Filter(_, _ filterset.FilterSet, _ bool) { } // GetValues returns the specified getValuesErr -func (obj mockPerfDataObjectError) GetValues(counterNames ...string) ([]*CounterValues, error) { +func (obj mockPerfDataObjectError) GetValues(_ ...string) ([]*CounterValues, error) { return nil, obj.getValuesErr } @@ -101,7 +101,7 @@ func NewMockPerfCounterScraper(objectsAndValuesToReturn map[string]map[string][] } // start is a no-op -func (p *MockPerfCounterScraper) Initialize(objects ...string) error { +func (p *MockPerfCounterScraper) Initialize(_ ...string) error { return nil } @@ -144,7 +144,7 @@ type mockPerfDataObject struct { } // Filter is a no-op -func (obj mockPerfDataObject) Filter(includeFS, excludeFS filterset.FilterSet, includeTotal bool) { +func (obj mockPerfDataObject) Filter(_, _ filterset.FilterSet, _ bool) { } // GetValues returns the specified counter values diff --git a/receiver/hostmetricsreceiver/internal/scraper.go b/receiver/hostmetricsreceiver/internal/scraper.go index 2e0074e5d892..c07c7d3c4c9d 100644 --- a/receiver/hostmetricsreceiver/internal/scraper.go +++ b/receiver/hostmetricsreceiver/internal/scraper.go @@ -6,6 +6,7 @@ package internal // import "github.com/open-telemetry/opentelemetry-collector-co import ( "context" + "github.com/shirou/gopsutil/v3/common" "go.opentelemetry.io/collector/receiver" "go.opentelemetry.io/collector/receiver/scraperhelper" ) @@ -23,12 +24,18 @@ type ScraperFactory interface { // Config is the configuration of a scraper. type Config interface { SetRootPath(rootPath string) + SetEnvMap(envMap common.EnvMap) } type ScraperConfig struct { - RootPath string `mapstructure:"-"` + RootPath string `mapstructure:"-"` + EnvMap common.EnvMap `mapstructure:"-"` } func (p *ScraperConfig) SetRootPath(rootPath string) { p.RootPath = rootPath } + +func (p *ScraperConfig) SetEnvMap(envMap common.EnvMap) { + p.EnvMap = envMap +} diff --git a/receiver/hostmetricsreceiver/internal/scraper/cpuscraper/cpu_scraper.go b/receiver/hostmetricsreceiver/internal/scraper/cpuscraper/cpu_scraper.go index be9a40183b42..64dc77a6f0d3 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/cpuscraper/cpu_scraper.go +++ b/receiver/hostmetricsreceiver/internal/scraper/cpuscraper/cpu_scraper.go @@ -7,6 +7,7 @@ import ( "context" "time" + "github.com/shirou/gopsutil/v3/common" "github.com/shirou/gopsutil/v3/cpu" "github.com/shirou/gopsutil/v3/host" "go.opentelemetry.io/collector/component" @@ -29,18 +30,19 @@ type scraper struct { ucal *ucal.CPUUtilizationCalculator // for mocking - bootTime func() (uint64, error) - times func(bool) ([]cpu.TimesStat, error) + bootTime func(context.Context) (uint64, error) + times func(context.Context, bool) ([]cpu.TimesStat, error) now func() time.Time } // newCPUScraper creates a set of CPU related metrics func newCPUScraper(_ context.Context, settings receiver.CreateSettings, cfg *Config) *scraper { - return &scraper{settings: settings, config: cfg, bootTime: host.BootTime, times: cpu.Times, ucal: &ucal.CPUUtilizationCalculator{}, now: time.Now} + return &scraper{settings: settings, config: cfg, bootTime: host.BootTimeWithContext, times: cpu.TimesWithContext, ucal: &ucal.CPUUtilizationCalculator{}, now: time.Now} } -func (s *scraper) start(context.Context, component.Host) error { - bootTime, err := s.bootTime() +func (s *scraper) start(ctx context.Context, _ component.Host) error { + ctx = context.WithValue(ctx, common.EnvKey, s.config.EnvMap) + bootTime, err := s.bootTime(ctx) if err != nil { return err } @@ -48,9 +50,10 @@ func (s *scraper) start(context.Context, component.Host) error { return nil } -func (s *scraper) scrape(_ context.Context) (pmetric.Metrics, error) { +func (s *scraper) scrape(ctx context.Context) (pmetric.Metrics, error) { + ctx = context.WithValue(ctx, common.EnvKey, s.config.EnvMap) now := pcommon.NewTimestampFromTime(s.now()) - cpuTimes, err := s.times( /*percpu=*/ true) + cpuTimes, err := s.times(ctx, true /*percpu=*/) if err != nil { return pmetric.NewMetrics(), scrapererror.NewPartialScrapeError(err, metricsLen) } diff --git a/receiver/hostmetricsreceiver/internal/scraper/cpuscraper/cpu_scraper_test.go b/receiver/hostmetricsreceiver/internal/scraper/cpuscraper/cpu_scraper_test.go index 68331ba4dcd5..5cf68f2f7f8e 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/cpuscraper/cpu_scraper_test.go +++ b/receiver/hostmetricsreceiver/internal/scraper/cpuscraper/cpu_scraper_test.go @@ -26,8 +26,8 @@ import ( func TestScrape(t *testing.T) { type testCase struct { name string - bootTimeFunc func() (uint64, error) - timesFunc func(bool) ([]cpu.TimesStat, error) + bootTimeFunc func(context.Context) (uint64, error) + timesFunc func(context.Context, bool) ([]cpu.TimesStat, error) metricsConfig metadata.MetricsBuilderConfig expectedMetricCount int expectedStartTime pcommon.Timestamp @@ -46,21 +46,21 @@ func TestScrape(t *testing.T) { }, { name: "Validate Start Time", - bootTimeFunc: func() (uint64, error) { return 100, nil }, + bootTimeFunc: func(context.Context) (uint64, error) { return 100, nil }, metricsConfig: metadata.DefaultMetricsBuilderConfig(), expectedMetricCount: 1, expectedStartTime: 100 * 1e9, }, { name: "Boot Time Error", - bootTimeFunc: func() (uint64, error) { return 0, errors.New("err1") }, + bootTimeFunc: func(context.Context) (uint64, error) { return 0, errors.New("err1") }, metricsConfig: metadata.DefaultMetricsBuilderConfig(), expectedMetricCount: 1, initializationErr: "err1", }, { name: "Times Error", - timesFunc: func(bool) ([]cpu.TimesStat, error) { return nil, errors.New("err2") }, + timesFunc: func(context.Context, bool) ([]cpu.TimesStat, error) { return nil, errors.New("err2") }, metricsConfig: metadata.DefaultMetricsBuilderConfig(), expectedMetricCount: 1, expectedErr: "err2", @@ -212,7 +212,7 @@ func TestScrape_CpuUtilization(t *testing.T) { func TestScrape_CpuUtilizationError(t *testing.T) { scraper := newCPUScraper(context.Background(), receivertest.NewNopCreateSettings(), &Config{MetricsBuilderConfig: metadata.DefaultMetricsBuilderConfig()}) // mock times function to force an error in next scrape - scraper.times = func(bool) ([]cpu.TimesStat, error) { + scraper.times = func(context.Context, bool) ([]cpu.TimesStat, error) { return []cpu.TimesStat{{CPU: "1", System: 1, User: 2}}, nil } err := scraper.start(context.Background(), componenttest.NewNopHost()) @@ -220,7 +220,7 @@ func TestScrape_CpuUtilizationError(t *testing.T) { _, err = scraper.scrape(context.Background()) // Force error not finding CPU info - scraper.times = func(bool) ([]cpu.TimesStat, error) { + scraper.times = func(context.Context, bool) ([]cpu.TimesStat, error) { return []cpu.TimesStat{}, nil } require.NoError(t, err, "Failed to scrape metrics: %v", err) @@ -281,7 +281,7 @@ func TestScrape_CpuUtilizationStandard(t *testing.T) { cpuScraper := newCPUScraper(context.Background(), receivertest.NewNopCreateSettings(), &Config{MetricsBuilderConfig: overriddenMetricsSettings}) for _, scrapeData := range scrapesData { // mock TimeStats and Now - cpuScraper.times = func(_ bool) ([]cpu.TimesStat, error) { + cpuScraper.times = func(context.Context, bool) ([]cpu.TimesStat, error) { return scrapeData.times, nil } cpuScraper.now = func() time.Time { diff --git a/receiver/hostmetricsreceiver/internal/scraper/diskscraper/disk_scraper_others.go b/receiver/hostmetricsreceiver/internal/scraper/diskscraper/disk_scraper_others.go index 64a8de56a520..de1ebeef66f8 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/diskscraper/disk_scraper_others.go +++ b/receiver/hostmetricsreceiver/internal/scraper/diskscraper/disk_scraper_others.go @@ -11,6 +11,7 @@ import ( "fmt" "time" + "github.com/shirou/gopsutil/v3/common" "github.com/shirou/gopsutil/v3/disk" "github.com/shirou/gopsutil/v3/host" "go.opentelemetry.io/collector/component" @@ -38,13 +39,13 @@ type scraper struct { excludeFS filterset.FilterSet // for mocking - bootTime func() (uint64, error) - ioCounters func(names ...string) (map[string]disk.IOCountersStat, error) + bootTime func(context.Context) (uint64, error) + ioCounters func(ctx context.Context, names ...string) (map[string]disk.IOCountersStat, error) } // newDiskScraper creates a Disk Scraper func newDiskScraper(_ context.Context, settings receiver.CreateSettings, cfg *Config) (*scraper, error) { - scraper := &scraper{settings: settings, config: cfg, bootTime: host.BootTime, ioCounters: disk.IOCounters} + scraper := &scraper{settings: settings, config: cfg, bootTime: host.BootTimeWithContext, ioCounters: disk.IOCountersWithContext} var err error @@ -65,8 +66,9 @@ func newDiskScraper(_ context.Context, settings receiver.CreateSettings, cfg *Co return scraper, nil } -func (s *scraper) start(context.Context, component.Host) error { - bootTime, err := s.bootTime() +func (s *scraper) start(ctx context.Context, _ component.Host) error { + ctx = context.WithValue(ctx, common.EnvKey, s.config.EnvMap) + bootTime, err := s.bootTime(ctx) if err != nil { return err } @@ -76,9 +78,11 @@ func (s *scraper) start(context.Context, component.Host) error { return nil } -func (s *scraper) scrape(_ context.Context) (pmetric.Metrics, error) { +func (s *scraper) scrape(ctx context.Context) (pmetric.Metrics, error) { + ctx = context.WithValue(ctx, common.EnvKey, s.config.EnvMap) + now := pcommon.NewTimestampFromTime(time.Now()) - ioCounters, err := s.ioCounters() + ioCounters, err := s.ioCounters(ctx) if err != nil { return pmetric.NewMetrics(), scrapererror.NewPartialScrapeError(err, metricsLen) } diff --git a/receiver/hostmetricsreceiver/internal/scraper/diskscraper/disk_scraper_others_test.go b/receiver/hostmetricsreceiver/internal/scraper/diskscraper/disk_scraper_others_test.go index 80ef23411d10..10080b6c70d6 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/diskscraper/disk_scraper_others_test.go +++ b/receiver/hostmetricsreceiver/internal/scraper/diskscraper/disk_scraper_others_test.go @@ -22,15 +22,17 @@ import ( func TestScrape_Others(t *testing.T) { type testCase struct { name string - ioCountersFunc func(names ...string) (map[string]disk.IOCountersStat, error) + ioCountersFunc func(ctx context.Context, names ...string) (map[string]disk.IOCountersStat, error) expectedErr string } testCases := []testCase{ { - name: "Error", - ioCountersFunc: func(names ...string) (map[string]disk.IOCountersStat, error) { return nil, errors.New("err1") }, - expectedErr: "err1", + name: "Error", + ioCountersFunc: func(_ context.Context, names ...string) (map[string]disk.IOCountersStat, error) { + return nil, errors.New("err1") + }, + expectedErr: "err1", }, } diff --git a/receiver/hostmetricsreceiver/internal/scraper/diskscraper/disk_scraper_test.go b/receiver/hostmetricsreceiver/internal/scraper/diskscraper/disk_scraper_test.go index 1f4b9b4409a5..fd48439952d8 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/diskscraper/disk_scraper_test.go +++ b/receiver/hostmetricsreceiver/internal/scraper/diskscraper/disk_scraper_test.go @@ -24,7 +24,7 @@ func TestScrape(t *testing.T) { type testCase struct { name string config Config - bootTimeFunc func() (uint64, error) + bootTimeFunc func(context.Context) (uint64, error) newErrRegex string initializationErr string expectMetrics int @@ -41,14 +41,14 @@ func TestScrape(t *testing.T) { { name: "Validate Start Time", config: Config{MetricsBuilderConfig: metadata.DefaultMetricsBuilderConfig()}, - bootTimeFunc: func() (uint64, error) { return 100, nil }, + bootTimeFunc: func(context.Context) (uint64, error) { return 100, nil }, expectMetrics: metricsLen, expectedStartTime: 100 * 1e9, }, { name: "Boot Time Error", config: Config{MetricsBuilderConfig: metadata.DefaultMetricsBuilderConfig()}, - bootTimeFunc: func() (uint64, error) { return 0, errors.New("err1") }, + bootTimeFunc: func(context.Context) (uint64, error) { return 0, errors.New("err1") }, initializationErr: "err1", expectMetrics: metricsLen, }, diff --git a/receiver/hostmetricsreceiver/internal/scraper/diskscraper/disk_scraper_windows.go b/receiver/hostmetricsreceiver/internal/scraper/diskscraper/disk_scraper_windows.go index 7b0fb71d2ead..4a351a22aa90 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/diskscraper/disk_scraper_windows.go +++ b/receiver/hostmetricsreceiver/internal/scraper/diskscraper/disk_scraper_windows.go @@ -53,12 +53,12 @@ type scraper struct { skipScrape bool // for mocking - bootTime func() (uint64, error) + bootTime func(ctx context.Context) (uint64, error) } // newDiskScraper creates a Disk Scraper func newDiskScraper(_ context.Context, settings receiver.CreateSettings, cfg *Config) (*scraper, error) { - scraper := &scraper{settings: settings, config: cfg, perfCounterScraper: &perfcounters.PerfLibScraper{}, bootTime: host.BootTime} + scraper := &scraper{settings: settings, config: cfg, perfCounterScraper: &perfcounters.PerfLibScraper{}, bootTime: host.BootTimeWithContext} var err error @@ -79,8 +79,8 @@ func newDiskScraper(_ context.Context, settings receiver.CreateSettings, cfg *Co return scraper, nil } -func (s *scraper) start(context.Context, component.Host) error { - bootTime, err := s.bootTime() +func (s *scraper) start(ctx context.Context, _ component.Host) error { + bootTime, err := s.bootTime(ctx) if err != nil { return err } @@ -96,7 +96,7 @@ func (s *scraper) start(context.Context, component.Host) error { return nil } -func (s *scraper) scrape(ctx context.Context) (pmetric.Metrics, error) { +func (s *scraper) scrape(_ context.Context) (pmetric.Metrics, error) { if s.skipScrape { return pmetric.NewMetrics(), nil } diff --git a/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper/filesystem_scraper.go b/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper/filesystem_scraper.go index 88b2a3ca33fd..db4f3aa36022 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper/filesystem_scraper.go +++ b/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper/filesystem_scraper.go @@ -10,6 +10,7 @@ import ( "strings" "time" + "github.com/shirou/gopsutil/v3/common" "github.com/shirou/gopsutil/v3/disk" "github.com/shirou/gopsutil/v3/host" "go.opentelemetry.io/collector/component" @@ -35,9 +36,9 @@ type scraper struct { fsFilter fsFilter // for mocking gopsutil disk.Partitions & disk.Usage - bootTime func() (uint64, error) - partitions func(bool) ([]disk.PartitionStat, error) - usage func(string) (*disk.UsageStat, error) + bootTime func(context.Context) (uint64, error) + partitions func(context.Context, bool) ([]disk.PartitionStat, error) + usage func(context.Context, string) (*disk.UsageStat, error) } type deviceUsage struct { @@ -52,12 +53,13 @@ func newFileSystemScraper(_ context.Context, settings receiver.CreateSettings, c return nil, err } - scraper := &scraper{settings: settings, config: cfg, bootTime: host.BootTime, partitions: disk.Partitions, usage: disk.Usage, fsFilter: *fsFilter} + scraper := &scraper{settings: settings, config: cfg, bootTime: host.BootTimeWithContext, partitions: disk.PartitionsWithContext, usage: disk.UsageWithContext, fsFilter: *fsFilter} return scraper, nil } -func (s *scraper) start(context.Context, component.Host) error { - bootTime, err := s.bootTime() +func (s *scraper) start(ctx context.Context, _ component.Host) error { + ctx = context.WithValue(ctx, common.EnvKey, s.config.EnvMap) + bootTime, err := s.bootTime(ctx) if err != nil { return err } @@ -66,11 +68,12 @@ func (s *scraper) start(context.Context, component.Host) error { return nil } -func (s *scraper) scrape(_ context.Context) (pmetric.Metrics, error) { +func (s *scraper) scrape(ctx context.Context) (pmetric.Metrics, error) { + ctx = context.WithValue(ctx, common.EnvKey, s.config.EnvMap) now := pcommon.NewTimestampFromTime(time.Now()) var errors scrapererror.ScrapeErrors - partitions, err := s.partitions(s.config.IncludeVirtualFS) + partitions, err := s.partitions(ctx, s.config.IncludeVirtualFS) if err != nil { if len(partitions) == 0 { return pmetric.NewMetrics(), scrapererror.NewPartialScrapeError(err, metricsLen) @@ -92,7 +95,7 @@ func (s *scraper) scrape(_ context.Context) (pmetric.Metrics, error) { continue } translatedMountpoint := translateMountpoint(s.config.RootPath, partition.Mountpoint) - usage, usageErr := s.usage(translatedMountpoint) + usage, usageErr := s.usage(ctx, translatedMountpoint) if usageErr != nil { errors.AddPartial(0, fmt.Errorf("failed to read usage at %s: %w", translatedMountpoint, usageErr)) continue diff --git a/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper/filesystem_scraper_others.go b/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper/filesystem_scraper_others.go index 38fe8e10cfc0..24f35db0f628 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper/filesystem_scraper_others.go +++ b/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper/filesystem_scraper_others.go @@ -35,5 +35,5 @@ func (s *scraper) recordFileSystemUsageMetric(now pcommon.Timestamp, deviceUsage const systemSpecificMetricsLen = 0 -func (s *scraper) recordSystemSpecificMetrics(now pcommon.Timestamp, deviceUsages []*deviceUsage) { +func (s *scraper) recordSystemSpecificMetrics(_ pcommon.Timestamp, _ []*deviceUsage) { } diff --git a/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper/filesystem_scraper_test.go b/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper/filesystem_scraper_test.go index bc619c970576..247cc083d372 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper/filesystem_scraper_test.go +++ b/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper/filesystem_scraper_test.go @@ -30,9 +30,9 @@ func TestScrape(t *testing.T) { name string config Config rootPath string - bootTimeFunc func() (uint64, error) - partitionsFunc func(bool) ([]disk.PartitionStat, error) - usageFunc func(string) (*disk.UsageStat, error) + bootTimeFunc func(context.Context) (uint64, error) + partitionsFunc func(context.Context, bool) ([]disk.PartitionStat, error) + usageFunc func(context.Context, string) (*disk.UsageStat, error) expectMetrics bool expectedDeviceDataPoints int expectedDeviceAttributes []map[string]pcommon.Value @@ -55,10 +55,10 @@ func TestScrape(t *testing.T) { MetricsBuilderConfig: metadata.DefaultMetricsBuilderConfig(), IncludeDevices: DeviceMatchConfig{filterset.Config{MatchType: "strict"}, []string{"a"}}, }, - partitionsFunc: func(bool) ([]disk.PartitionStat, error) { + partitionsFunc: func(context.Context, bool) ([]disk.PartitionStat, error) { return []disk.PartitionStat{{Device: "a"}, {Device: "b"}}, nil }, - usageFunc: func(string) (*disk.UsageStat, error) { + usageFunc: func(context.Context, string) (*disk.UsageStat, error) { return &disk.UsageStat{}, nil }, expectMetrics: true, @@ -79,14 +79,14 @@ func TestScrape(t *testing.T) { IncludeVirtualFS: true, IncludeFSTypes: FSTypeMatchConfig{Config: filterset.Config{MatchType: filterset.Strict}, FSTypes: []string{"tmpfs"}}, }, - partitionsFunc: func(includeVirtual bool) (paritions []disk.PartitionStat, err error) { + partitionsFunc: func(_ context.Context, includeVirtual bool) (paritions []disk.PartitionStat, err error) { paritions = append(paritions, disk.PartitionStat{Device: "root-device", Fstype: "ext4"}) if includeVirtual { paritions = append(paritions, disk.PartitionStat{Device: "shm", Fstype: "tmpfs"}) } return paritions, err }, - usageFunc: func(s string) (*disk.UsageStat, error) { + usageFunc: func(_ context.Context, s string) (*disk.UsageStat, error) { return &disk.UsageStat{}, nil }, expectMetrics: true, @@ -115,12 +115,12 @@ func TestScrape(t *testing.T) { MountPoints: []string{"mount_point_b", "mount_point_c"}, }, }, - usageFunc: func(s string) (*disk.UsageStat, error) { + usageFunc: func(_ context.Context, s string) (*disk.UsageStat, error) { return &disk.UsageStat{ Fstype: "fs_type_a", }, nil }, - partitionsFunc: func(b bool) ([]disk.PartitionStat, error) { + partitionsFunc: func(_ context.Context, b bool) ([]disk.PartitionStat, error) { return []disk.PartitionStat{ { Device: "device_a", @@ -167,7 +167,7 @@ func TestScrape(t *testing.T) { MetricsBuilderConfig: metadata.DefaultMetricsBuilderConfig(), }, rootPath: filepath.Join("/", "hostfs"), - usageFunc: func(s string) (*disk.UsageStat, error) { + usageFunc: func(_ context.Context, s string) (*disk.UsageStat, error) { if s != filepath.Join("/hostfs", "mount_point_a") { return nil, errors.New("mountpoint not translated according to RootPath") } @@ -175,7 +175,7 @@ func TestScrape(t *testing.T) { Fstype: "fs_type_a", }, nil }, - partitionsFunc: func(b bool) ([]disk.PartitionStat, error) { + partitionsFunc: func(_ context.Context, b bool) ([]disk.PartitionStat, error) { return []disk.PartitionStat{ { Device: "device_a", @@ -245,7 +245,7 @@ func TestScrape(t *testing.T) { }, { name: "Partitions Error", - partitionsFunc: func(bool) ([]disk.PartitionStat, error) { return nil, errors.New("err1") }, + partitionsFunc: func(context.Context, bool) ([]disk.PartitionStat, error) { return nil, errors.New("err1") }, expectedErr: "err1", }, { @@ -265,12 +265,12 @@ func TestScrape(t *testing.T) { FSTypes: []string{"fs_type_b"}, }, }, - usageFunc: func(s string) (*disk.UsageStat, error) { + usageFunc: func(_ context.Context, s string) (*disk.UsageStat, error) { return &disk.UsageStat{ Fstype: "fs_type_a", }, nil }, - partitionsFunc: func(b bool) ([]disk.PartitionStat, error) { + partitionsFunc: func(_ context.Context, b bool) ([]disk.PartitionStat, error) { return []disk.PartitionStat{ { Device: "device_a", @@ -306,7 +306,7 @@ func TestScrape(t *testing.T) { }, { name: "Usage Error", - usageFunc: func(string) (*disk.UsageStat, error) { return nil, errors.New("err2") }, + usageFunc: func(context.Context, string) (*disk.UsageStat, error) { return nil, errors.New("err2") }, expectedErr: "err2", }, } diff --git a/receiver/hostmetricsreceiver/internal/scraper/loadscraper/load_scraper.go b/receiver/hostmetricsreceiver/internal/scraper/loadscraper/load_scraper.go index bb5ab0b0b253..1a9ee477c734 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/loadscraper/load_scraper.go +++ b/receiver/hostmetricsreceiver/internal/scraper/loadscraper/load_scraper.go @@ -9,6 +9,7 @@ import ( "runtime" "time" + "github.com/shirou/gopsutil/v3/common" "github.com/shirou/gopsutil/v3/host" "github.com/shirou/gopsutil/v3/load" "go.opentelemetry.io/collector/component" @@ -32,18 +33,19 @@ type scraper struct { skipScrape bool // for mocking - bootTime func() (uint64, error) - load func() (*load.AvgStat, error) + bootTime func(context.Context) (uint64, error) + load func(context.Context) (*load.AvgStat, error) } // newLoadScraper creates a set of Load related metrics func newLoadScraper(_ context.Context, settings receiver.CreateSettings, cfg *Config) *scraper { - return &scraper{settings: settings, config: cfg, bootTime: host.BootTime, load: getSampledLoadAverages} + return &scraper{settings: settings, config: cfg, bootTime: host.BootTimeWithContext, load: getSampledLoadAverages} } // start func (s *scraper) start(ctx context.Context, _ component.Host) error { - bootTime, err := s.bootTime() + ctx = context.WithValue(ctx, common.EnvKey, s.config.EnvMap) + bootTime, err := s.bootTime(ctx) if err != nil { return err } @@ -77,13 +79,15 @@ func (s *scraper) shutdown(ctx context.Context) error { } // scrape -func (s *scraper) scrape(_ context.Context) (pmetric.Metrics, error) { +func (s *scraper) scrape(ctx context.Context) (pmetric.Metrics, error) { if s.skipScrape { return pmetric.NewMetrics(), nil } now := pcommon.NewTimestampFromTime(time.Now()) - avgLoadValues, err := s.load() + ctx = context.WithValue(ctx, common.EnvKey, s.config.EnvMap) + + avgLoadValues, err := s.load(ctx) if err != nil { return pmetric.NewMetrics(), scrapererror.NewPartialScrapeError(err, metricsLen) } diff --git a/receiver/hostmetricsreceiver/internal/scraper/loadscraper/load_scraper_others.go b/receiver/hostmetricsreceiver/internal/scraper/loadscraper/load_scraper_others.go index bd4b1a54089e..8f48ffe9028e 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/loadscraper/load_scraper_others.go +++ b/receiver/hostmetricsreceiver/internal/scraper/loadscraper/load_scraper_others.go @@ -22,6 +22,6 @@ func stopSampling(_ context.Context) error { return nil } -func getSampledLoadAverages() (*load.AvgStat, error) { - return load.Avg() +func getSampledLoadAverages(ctx context.Context) (*load.AvgStat, error) { + return load.AvgWithContext(ctx) } diff --git a/receiver/hostmetricsreceiver/internal/scraper/loadscraper/load_scraper_test.go b/receiver/hostmetricsreceiver/internal/scraper/loadscraper/load_scraper_test.go index 00bcdc274b62..00c41da24b7f 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/loadscraper/load_scraper_test.go +++ b/receiver/hostmetricsreceiver/internal/scraper/loadscraper/load_scraper_test.go @@ -36,8 +36,8 @@ func TestScrape(t *testing.T) { skip(t, "Flaky test. See https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/10030") type testCase struct { name string - bootTimeFunc func() (uint64, error) - loadFunc func() (*load.AvgStat, error) + bootTimeFunc func(context.Context) (uint64, error) + loadFunc func(context.Context) (*load.AvgStat, error) expectedErr string saveMetrics bool config *Config @@ -58,11 +58,11 @@ func TestScrape(t *testing.T) { MetricsBuilderConfig: metadata.DefaultMetricsBuilderConfig(), CPUAverage: true, }, - bootTimeFunc: func() (uint64, error) { return bootTime, nil }, + bootTimeFunc: func(context.Context) (uint64, error) { return bootTime, nil }, }, { name: "Load Error", - loadFunc: func() (*load.AvgStat, error) { return nil, errors.New("err1") }, + loadFunc: func(context.Context) (*load.AvgStat, error) { return nil, errors.New("err1") }, config: &Config{ MetricsBuilderConfig: metadata.DefaultMetricsBuilderConfig(), }, @@ -102,7 +102,7 @@ func TestScrape(t *testing.T) { require.NoError(t, err, "Failed to scrape metrics: %v", err) if test.bootTimeFunc != nil { - actualBootTime, err := scraper.bootTime() + actualBootTime, err := scraper.bootTime(context.Background()) assert.Nil(t, err) assert.Equal(t, uint64(bootTime), actualBootTime) } diff --git a/receiver/hostmetricsreceiver/internal/scraper/loadscraper/load_scraper_windows.go b/receiver/hostmetricsreceiver/internal/scraper/loadscraper/load_scraper_windows.go index f6fc40e51ce2..c7f972f78672 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/loadscraper/load_scraper_windows.go +++ b/receiver/hostmetricsreceiver/internal/scraper/loadscraper/load_scraper_windows.go @@ -146,7 +146,7 @@ func stopSampling(_ context.Context) error { return nil } -func getSampledLoadAverages() (*load.AvgStat, error) { +func getSampledLoadAverages(_ context.Context) (*load.AvgStat, error) { samplerInstance.lock.RLock() defer samplerInstance.lock.RUnlock() diff --git a/receiver/hostmetricsreceiver/internal/scraper/loadscraper/load_scraper_windows_test.go b/receiver/hostmetricsreceiver/internal/scraper/loadscraper/load_scraper_windows_test.go index b46654eaa99e..577690df8a17 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/loadscraper/load_scraper_windows_test.go +++ b/receiver/hostmetricsreceiver/internal/scraper/loadscraper/load_scraper_windows_test.go @@ -24,7 +24,7 @@ func TestStartSampling(t *testing.T) { samplingFrequency = 2 * time.Millisecond // startSampling should set up perf counter and start sampling - startSampling(context.Background(), zap.NewNop()) + require.NoError(t, startSampling(context.Background(), zap.NewNop())) assertSamplingUnderway(t) // override the processor queue length perf counter with a mock @@ -35,7 +35,7 @@ func TestStartSampling(t *testing.T) { }) // second call to startSampling should succeed, but not do anything - startSampling(context.Background(), zap.NewNop()) + require.NoError(t, startSampling(context.Background(), zap.NewNop())) assertSamplingUnderway(t) assert.IsType(t, &perfcounters.MockPerfCounterScraper{}, samplerInstance.perfCounterScraper) @@ -43,19 +43,19 @@ func TestStartSampling(t *testing.T) { // "getSampledLoadAverages" which validates the value from the // mock perf counter was used require.Eventually(t, func() bool { - avgLoadValues, err := getSampledLoadAverages() + avgLoadValues, err := getSampledLoadAverages(context.Background()) assert.NoError(t, err) return avgLoadValues.Load1 > 0 && avgLoadValues.Load5 > 0 && avgLoadValues.Load15 > 0 }, time.Second, time.Millisecond, "Load Avg was not set after 1s") // sampling should continue after first call to stopSampling since // startSampling was called twice - stopSampling(context.Background()) + require.NoError(t, stopSampling(context.Background())) assertSamplingUnderway(t) // second call to stopSampling should close perf counter, stop // sampling, and clean up the sampler - stopSampling(context.Background()) + require.NoError(t, stopSampling(context.Background())) assertSamplingStopped(t) } diff --git a/receiver/hostmetricsreceiver/internal/scraper/memoryscraper/memory_scraper.go b/receiver/hostmetricsreceiver/internal/scraper/memoryscraper/memory_scraper.go index 4256194712be..2bd874f02b88 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/memoryscraper/memory_scraper.go +++ b/receiver/hostmetricsreceiver/internal/scraper/memoryscraper/memory_scraper.go @@ -9,6 +9,7 @@ import ( "fmt" "time" + "github.com/shirou/gopsutil/v3/common" "github.com/shirou/gopsutil/v3/host" "github.com/shirou/gopsutil/v3/mem" "go.opentelemetry.io/collector/component" @@ -29,19 +30,21 @@ type scraper struct { settings receiver.CreateSettings config *Config mb *metadata.MetricsBuilder + envMap common.EnvMap // for mocking gopsutil mem.VirtualMemory - bootTime func() (uint64, error) - virtualMemory func() (*mem.VirtualMemoryStat, error) + bootTime func(context.Context) (uint64, error) + virtualMemory func(context.Context) (*mem.VirtualMemoryStat, error) } // newMemoryScraper creates a Memory Scraper func newMemoryScraper(_ context.Context, settings receiver.CreateSettings, cfg *Config) *scraper { - return &scraper{settings: settings, config: cfg, bootTime: host.BootTime, virtualMemory: mem.VirtualMemory} + return &scraper{settings: settings, config: cfg, bootTime: host.BootTimeWithContext, virtualMemory: mem.VirtualMemoryWithContext} } -func (s *scraper) start(context.Context, component.Host) error { - bootTime, err := s.bootTime() +func (s *scraper) start(ctx context.Context, _ component.Host) error { + ctx = context.WithValue(ctx, common.EnvKey, s.envMap) + bootTime, err := s.bootTime(ctx) if err != nil { return err } @@ -50,9 +53,11 @@ func (s *scraper) start(context.Context, component.Host) error { return nil } -func (s *scraper) scrape(_ context.Context) (pmetric.Metrics, error) { +func (s *scraper) scrape(ctx context.Context) (pmetric.Metrics, error) { + ctx = context.WithValue(ctx, common.EnvKey, s.envMap) + now := pcommon.NewTimestampFromTime(time.Now()) - memInfo, err := s.virtualMemory() + memInfo, err := s.virtualMemory(ctx) if err != nil { return pmetric.NewMetrics(), scrapererror.NewPartialScrapeError(err, metricsLen) } diff --git a/receiver/hostmetricsreceiver/internal/scraper/memoryscraper/memory_scraper_test.go b/receiver/hostmetricsreceiver/internal/scraper/memoryscraper/memory_scraper_test.go index 9b8166c35500..03fcf3d54f24 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/memoryscraper/memory_scraper_test.go +++ b/receiver/hostmetricsreceiver/internal/scraper/memoryscraper/memory_scraper_test.go @@ -25,12 +25,12 @@ import ( func TestScrape(t *testing.T) { type testCase struct { name string - virtualMemoryFunc func() (*mem.VirtualMemoryStat, error) + virtualMemoryFunc func(context.Context) (*mem.VirtualMemoryStat, error) expectedErr string initializationErr string config *Config expectedMetricCount int - bootTimeFunc func() (uint64, error) + bootTimeFunc func(context.Context) (uint64, error) } testCases := []testCase{ @@ -59,7 +59,7 @@ func TestScrape(t *testing.T) { }, { name: "Error", - virtualMemoryFunc: func() (*mem.VirtualMemoryStat, error) { return nil, errors.New("err1") }, + virtualMemoryFunc: func(context.Context) (*mem.VirtualMemoryStat, error) { return nil, errors.New("err1") }, expectedErr: "err1", config: &Config{ MetricsBuilderConfig: metadata.DefaultMetricsBuilderConfig(), @@ -68,7 +68,7 @@ func TestScrape(t *testing.T) { }, { name: "Error", - bootTimeFunc: func() (uint64, error) { return 100, errors.New("err1") }, + bootTimeFunc: func(context.Context) (uint64, error) { return 100, errors.New("err1") }, initializationErr: "err1", config: &Config{ MetricsBuilderConfig: metadata.DefaultMetricsBuilderConfig(), @@ -129,7 +129,7 @@ func TestScrape(t *testing.T) { func TestScrape_MemoryUtilization(t *testing.T) { type testCase struct { name string - virtualMemoryFunc func() (*mem.VirtualMemoryStat, error) + virtualMemoryFunc func(context.Context) (*mem.VirtualMemoryStat, error) expectedErr error } testCases := []testCase{ @@ -138,7 +138,7 @@ func TestScrape_MemoryUtilization(t *testing.T) { }, { name: "Invalid total memory", - virtualMemoryFunc: func() (*mem.VirtualMemoryStat, error) { return &mem.VirtualMemoryStat{Total: 0}, nil }, + virtualMemoryFunc: func(context.Context) (*mem.VirtualMemoryStat, error) { return &mem.VirtualMemoryStat{Total: 0}, nil }, expectedErr: ErrInvalidTotalMem, }, } diff --git a/receiver/hostmetricsreceiver/internal/scraper/networkscraper/network_linux.go b/receiver/hostmetricsreceiver/internal/scraper/networkscraper/network_linux.go index e7c7de9a388d..456f343cb9ee 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/networkscraper/network_linux.go +++ b/receiver/hostmetricsreceiver/internal/scraper/networkscraper/network_linux.go @@ -7,9 +7,11 @@ package networkscraper // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/scraper/networkscraper" import ( + "context" "fmt" "time" + "github.com/shirou/gopsutil/v3/common" "go.opentelemetry.io/collector/pdata/pcommon" ) @@ -32,9 +34,9 @@ func (s *scraper) recordNetworkConntrackMetrics() error { if !s.config.MetricsBuilderConfig.Metrics.SystemNetworkConntrackCount.Enabled && !s.config.MetricsBuilderConfig.Metrics.SystemNetworkConntrackMax.Enabled { return nil } - + ctx := context.WithValue(context.Background(), common.EnvKey, s.config.EnvMap) now := pcommon.NewTimestampFromTime(time.Now()) - conntrack, err := s.conntrack() + conntrack, err := s.conntrack(ctx) if err != nil { return fmt.Errorf("failed to read conntrack info: %w", err) } diff --git a/receiver/hostmetricsreceiver/internal/scraper/networkscraper/network_scraper.go b/receiver/hostmetricsreceiver/internal/scraper/networkscraper/network_scraper.go index 5f1059485a1a..c014c4278aac 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/networkscraper/network_scraper.go +++ b/receiver/hostmetricsreceiver/internal/scraper/networkscraper/network_scraper.go @@ -8,6 +8,7 @@ import ( "fmt" "time" + "github.com/shirou/gopsutil/v3/common" "github.com/shirou/gopsutil/v3/host" "github.com/shirou/gopsutil/v3/net" "go.opentelemetry.io/collector/component" @@ -35,10 +36,10 @@ type scraper struct { excludeFS filterset.FilterSet // for mocking - bootTime func() (uint64, error) - ioCounters func(bool) ([]net.IOCountersStat, error) - connections func(string) ([]net.ConnectionStat, error) - conntrack func() ([]net.FilterStat, error) + bootTime func(context.Context) (uint64, error) + ioCounters func(context.Context, bool) ([]net.IOCountersStat, error) + connections func(context.Context, string) ([]net.ConnectionStat, error) + conntrack func(context.Context) ([]net.FilterStat, error) } // newNetworkScraper creates a set of Network related metrics @@ -46,10 +47,10 @@ func newNetworkScraper(_ context.Context, settings receiver.CreateSettings, cfg scraper := &scraper{ settings: settings, config: cfg, - bootTime: host.BootTime, - ioCounters: net.IOCounters, - connections: net.Connections, - conntrack: net.FilterCounters, + bootTime: host.BootTimeWithContext, + ioCounters: net.IOCountersWithContext, + connections: net.ConnectionsWithContext, + conntrack: net.FilterCountersWithContext, } var err error @@ -71,8 +72,9 @@ func newNetworkScraper(_ context.Context, settings receiver.CreateSettings, cfg return scraper, nil } -func (s *scraper) start(context.Context, component.Host) error { - bootTime, err := s.bootTime() +func (s *scraper) start(ctx context.Context, _ component.Host) error { + ctx = context.WithValue(ctx, common.EnvKey, s.config.EnvMap) + bootTime, err := s.bootTime(ctx) if err != nil { return err } @@ -104,10 +106,11 @@ func (s *scraper) scrape(_ context.Context) (pmetric.Metrics, error) { } func (s *scraper) recordNetworkCounterMetrics() error { + ctx := context.WithValue(context.Background(), common.EnvKey, s.config.EnvMap) now := pcommon.NewTimestampFromTime(time.Now()) // get total stats only - ioCounters, err := s.ioCounters( /*perNetworkInterfaceController=*/ true) + ioCounters, err := s.ioCounters(ctx, true /*perNetworkInterfaceController=*/) if err != nil { return fmt.Errorf("failed to read network IO stats: %w", err) } @@ -154,9 +157,10 @@ func (s *scraper) recordNetworkIOMetric(now pcommon.Timestamp, ioCountersSlice [ } func (s *scraper) recordNetworkConnectionsMetrics() error { + ctx := context.WithValue(context.Background(), common.EnvKey, s.config.EnvMap) now := pcommon.NewTimestampFromTime(time.Now()) - connections, err := s.connections("tcp") + connections, err := s.connections(ctx, "tcp") if err != nil { return fmt.Errorf("failed to read TCP connections: %w", err) } diff --git a/receiver/hostmetricsreceiver/internal/scraper/networkscraper/network_scraper_test.go b/receiver/hostmetricsreceiver/internal/scraper/networkscraper/network_scraper_test.go index cf06a43643bc..12ddcc75f90d 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/networkscraper/network_scraper_test.go +++ b/receiver/hostmetricsreceiver/internal/scraper/networkscraper/network_scraper_test.go @@ -26,10 +26,10 @@ func TestScrape(t *testing.T) { type testCase struct { name string config Config - bootTimeFunc func() (uint64, error) - ioCountersFunc func(bool) ([]net.IOCountersStat, error) - connectionsFunc func(string) ([]net.ConnectionStat, error) - conntrackFunc func() ([]net.FilterStat, error) + bootTimeFunc func(context.Context) (uint64, error) + ioCountersFunc func(context.Context, bool) ([]net.IOCountersStat, error) + connectionsFunc func(context.Context, string) ([]net.ConnectionStat, error) + conntrackFunc func(context.Context) ([]net.FilterStat, error) expectNetworkMetrics bool expectedStartTime pcommon.Timestamp newErrRegex string @@ -59,7 +59,7 @@ func TestScrape(t *testing.T) { config: Config{ MetricsBuilderConfig: metadata.DefaultMetricsBuilderConfig(), }, - bootTimeFunc: func() (uint64, error) { return 100, nil }, + bootTimeFunc: func(context.Context) (uint64, error) { return 100, nil }, expectNetworkMetrics: true, expectedStartTime: 100 * 1e9, }, @@ -89,18 +89,18 @@ func TestScrape(t *testing.T) { }, { name: "Boot Time Error", - bootTimeFunc: func() (uint64, error) { return 0, errors.New("err1") }, + bootTimeFunc: func(context.Context) (uint64, error) { return 0, errors.New("err1") }, initializationErr: "err1", }, { name: "IOCounters Error", - ioCountersFunc: func(bool) ([]net.IOCountersStat, error) { return nil, errors.New("err2") }, + ioCountersFunc: func(context.Context, bool) ([]net.IOCountersStat, error) { return nil, errors.New("err2") }, expectedErr: "failed to read network IO stats: err2", expectedErrCount: networkMetricsLen, }, { name: "Connections Error", - connectionsFunc: func(string) ([]net.ConnectionStat, error) { return nil, errors.New("err3") }, + connectionsFunc: func(context.Context, string) ([]net.ConnectionStat, error) { return nil, errors.New("err3") }, expectedErr: "failed to read TCP connections: err3", expectedErrCount: connectionsMetricsLen, }, @@ -109,7 +109,7 @@ func TestScrape(t *testing.T) { config: Config{ MetricsBuilderConfig: metadata.DefaultMetricsBuilderConfig(), // conntrack metrics are disabled by default }, - conntrackFunc: func() ([]net.FilterStat, error) { return nil, errors.New("conntrack failed") }, + conntrackFunc: func(ctx context.Context) ([]net.FilterStat, error) { return nil, errors.New("conntrack failed") }, expectNetworkMetrics: true, }, } diff --git a/receiver/hostmetricsreceiver/internal/scraper/pagingscraper/paging_scraper_others.go b/receiver/hostmetricsreceiver/internal/scraper/pagingscraper/paging_scraper_others.go index d7ddadfd9391..09973bd8a025 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/pagingscraper/paging_scraper_others.go +++ b/receiver/hostmetricsreceiver/internal/scraper/pagingscraper/paging_scraper_others.go @@ -11,6 +11,7 @@ import ( "fmt" "time" + "github.com/shirou/gopsutil/v3/common" "github.com/shirou/gopsutil/v3/host" "github.com/shirou/gopsutil/v3/mem" "go.opentelemetry.io/collector/component" @@ -34,9 +35,9 @@ type scraper struct { mb *metadata.MetricsBuilder // for mocking - bootTime func() (uint64, error) + bootTime func(context.Context) (uint64, error) getPageFileStats func() ([]*pageFileStats, error) - swapMemory func() (*mem.SwapMemoryStat, error) + swapMemory func(context.Context) (*mem.SwapMemoryStat, error) } // newPagingScraper creates a Paging Scraper @@ -44,14 +45,15 @@ func newPagingScraper(_ context.Context, settings receiver.CreateSettings, cfg * return &scraper{ settings: settings, config: cfg, - bootTime: host.BootTime, + bootTime: host.BootTimeWithContext, getPageFileStats: getPageFileStats, - swapMemory: mem.SwapMemory, + swapMemory: mem.SwapMemoryWithContext, } } -func (s *scraper) start(context.Context, component.Host) error { - bootTime, err := s.bootTime() +func (s *scraper) start(ctx context.Context, _ component.Host) error { + ctx = context.WithValue(ctx, common.EnvKey, s.config.EnvMap) + bootTime, err := s.bootTime(ctx) if err != nil { return err } @@ -109,8 +111,9 @@ func (s *scraper) recordPagingUtilizationDataPoints(now pcommon.Timestamp, pageF } func (s *scraper) scrapePagingMetrics() error { + ctx := context.WithValue(context.Background(), common.EnvKey, s.config.EnvMap) now := pcommon.NewTimestampFromTime(time.Now()) - swap, err := s.swapMemory() + swap, err := s.swapMemory(ctx) if err != nil { return fmt.Errorf("failed to read swap info: %w", err) } diff --git a/receiver/hostmetricsreceiver/internal/scraper/pagingscraper/paging_scraper_others_test.go b/receiver/hostmetricsreceiver/internal/scraper/pagingscraper/paging_scraper_others_test.go index be67f999efbb..fa46ca8652f5 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/pagingscraper/paging_scraper_others_test.go +++ b/receiver/hostmetricsreceiver/internal/scraper/pagingscraper/paging_scraper_others_test.go @@ -23,7 +23,7 @@ func TestScrape_Errors(t *testing.T) { type testCase struct { name string virtualMemoryFunc func() ([]*pageFileStats, error) - swapMemoryFunc func() (*mem.SwapMemoryStat, error) + swapMemoryFunc func(context.Context) (*mem.SwapMemoryStat, error) expectedError string expectedErrCount int } @@ -37,14 +37,14 @@ func TestScrape_Errors(t *testing.T) { }, { name: "swapMemoryError", - swapMemoryFunc: func() (*mem.SwapMemoryStat, error) { return nil, errors.New("err2") }, + swapMemoryFunc: func(context.Context) (*mem.SwapMemoryStat, error) { return nil, errors.New("err2") }, expectedError: "failed to read swap info: err2", expectedErrCount: pagingMetricsLen, }, { name: "multipleErrors", virtualMemoryFunc: func() ([]*pageFileStats, error) { return nil, errors.New("err1") }, - swapMemoryFunc: func() (*mem.SwapMemoryStat, error) { return nil, errors.New("err2") }, + swapMemoryFunc: func(context.Context) (*mem.SwapMemoryStat, error) { return nil, errors.New("err2") }, expectedError: "failed to read page file stats: err1; failed to read swap info: err2", expectedErrCount: pagingUsageMetricsLen + pagingMetricsLen, }, diff --git a/receiver/hostmetricsreceiver/internal/scraper/pagingscraper/paging_scraper_test.go b/receiver/hostmetricsreceiver/internal/scraper/pagingscraper/paging_scraper_test.go index 0539015f64bd..d30431f0874e 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/pagingscraper/paging_scraper_test.go +++ b/receiver/hostmetricsreceiver/internal/scraper/pagingscraper/paging_scraper_test.go @@ -45,7 +45,7 @@ func TestScrape(t *testing.T) { name: "Validate Start Time", config: Config{MetricsBuilderConfig: config}, mutateScraper: func(s *scraper) { - s.bootTime = func() (uint64, error) { return 100, nil } + s.bootTime = func(context.Context) (uint64, error) { return 100, nil } }, expectedStartTime: 100 * 1e9, }, @@ -53,7 +53,7 @@ func TestScrape(t *testing.T) { name: "Boot Time Error", config: Config{MetricsBuilderConfig: config}, mutateScraper: func(s *scraper) { - s.bootTime = func() (uint64, error) { return 0, errors.New("err1") } + s.bootTime = func(context.Context) (uint64, error) { return 0, errors.New("err1") } }, initializationErr: "err1", }, diff --git a/receiver/hostmetricsreceiver/internal/scraper/pagingscraper/paging_scraper_windows.go b/receiver/hostmetricsreceiver/internal/scraper/pagingscraper/paging_scraper_windows.go index caabe304f63b..c01686ed3c84 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/pagingscraper/paging_scraper_windows.go +++ b/receiver/hostmetricsreceiver/internal/scraper/pagingscraper/paging_scraper_windows.go @@ -43,7 +43,7 @@ type scraper struct { skipScrape bool // for mocking - bootTime func() (uint64, error) + bootTime func(context.Context) (uint64, error) pageFileStats func() ([]*pageFileStats, error) } @@ -53,13 +53,13 @@ func newPagingScraper(_ context.Context, settings receiver.CreateSettings, cfg * settings: settings, config: cfg, perfCounterScraper: &perfcounters.PerfLibScraper{}, - bootTime: host.BootTime, + bootTime: host.BootTimeWithContext, pageFileStats: getPageFileStats, } } -func (s *scraper) start(context.Context, component.Host) error { - bootTime, err := s.bootTime() +func (s *scraper) start(ctx context.Context, _ component.Host) error { + bootTime, err := s.bootTime(ctx) if err != nil { return err } diff --git a/receiver/hostmetricsreceiver/internal/scraper/processesscraper/processes_scraper.go b/receiver/hostmetricsreceiver/internal/scraper/processesscraper/processes_scraper.go index 9e60532c5953..5fa450273da2 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/processesscraper/processes_scraper.go +++ b/receiver/hostmetricsreceiver/internal/scraper/processesscraper/processes_scraper.go @@ -7,6 +7,7 @@ import ( "context" "time" + "github.com/shirou/gopsutil/v3/common" "github.com/shirou/gopsutil/v3/host" "github.com/shirou/gopsutil/v3/load" "github.com/shirou/gopsutil/v3/process" @@ -37,8 +38,9 @@ type scraper struct { mb *metadata.MetricsBuilder // for mocking gopsutil - getMiscStats func() (*load.MiscStat, error) + getMiscStats func(context.Context) (*load.MiscStat, error) getProcesses func() ([]proc, error) + bootTime func(context.Context) (uint64, error) } // for mocking out gopsutil process.Process @@ -56,20 +58,23 @@ func newProcessesScraper(_ context.Context, settings receiver.CreateSettings, cf return &scraper{ settings: settings, config: cfg, - getMiscStats: load.Misc, + getMiscStats: load.MiscWithContext, getProcesses: func() ([]proc, error) { - ps, err := process.Processes() + ctx := context.WithValue(context.Background(), common.EnvKey, cfg.EnvMap) + ps, err := process.ProcessesWithContext(ctx) ret := make([]proc, len(ps)) for i := range ps { ret[i] = ps[i] } return ret, err }, + bootTime: host.BootTimeWithContext, } } -func (s *scraper) start(context.Context, component.Host) error { - bootTime, err := host.BootTime() +func (s *scraper) start(ctx context.Context, _ component.Host) error { + ctx = context.WithValue(ctx, common.EnvKey, s.config.EnvMap) + bootTime, err := s.bootTime(ctx) if err != nil { return err } diff --git a/receiver/hostmetricsreceiver/internal/scraper/processesscraper/processes_scraper_test.go b/receiver/hostmetricsreceiver/internal/scraper/processesscraper/processes_scraper_test.go index 05baef941498..cf37e89b147f 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/processesscraper/processes_scraper_test.go +++ b/receiver/hostmetricsreceiver/internal/scraper/processesscraper/processes_scraper_test.go @@ -32,7 +32,7 @@ var ( func TestScrape(t *testing.T) { type testCase struct { name string - getMiscStats func() (*load.MiscStat, error) + getMiscStats func(context.Context) (*load.MiscStat, error) getProcesses func() ([]proc, error) expectedErr string validate func(*testing.T, pmetric.MetricSlice) @@ -43,12 +43,12 @@ func TestScrape(t *testing.T) { validate: validateRealData, }, { name: "FakeData", - getMiscStats: func() (*load.MiscStat, error) { return &fakeData, nil }, + getMiscStats: func(ctx context.Context) (*load.MiscStat, error) { return &fakeData, nil }, getProcesses: func() ([]proc, error) { return fakeProcessesData, nil }, validate: validateFakeData, }, { name: "ErrorFromMiscStat", - getMiscStats: func() (*load.MiscStat, error) { return &load.MiscStat{}, errors.New("err1") }, + getMiscStats: func(context.Context) (*load.MiscStat, error) { return &load.MiscStat{}, errors.New("err1") }, expectedErr: "err1", }, { name: "ErrorFromProcesses", diff --git a/receiver/hostmetricsreceiver/internal/scraper/processesscraper/processes_scraper_unix.go b/receiver/hostmetricsreceiver/internal/scraper/processesscraper/processes_scraper_unix.go index 349c6ce1c7c3..f257fc8408c9 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/processesscraper/processes_scraper_unix.go +++ b/receiver/hostmetricsreceiver/internal/scraper/processesscraper/processes_scraper_unix.go @@ -7,8 +7,10 @@ package processesscraper // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/scraper/processesscraper" import ( + "context" "runtime" + "github.com/shirou/gopsutil/v3/common" "github.com/shirou/gopsutil/v3/process" "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/scraper/processesscraper/internal/metadata" @@ -18,6 +20,7 @@ const enableProcessesCount = true const enableProcessesCreated = runtime.GOOS == "openbsd" || runtime.GOOS == "linux" func (s *scraper) getProcessesMetadata() (processesMetadata, error) { + ctx := context.WithValue(context.Background(), common.EnvKey, s.config.EnvMap) processes, err := s.getProcesses() if err != nil { return processesMetadata{}, err @@ -43,7 +46,7 @@ func (s *scraper) getProcessesMetadata() (processesMetadata, error) { // Processes are actively changing as we run this code, so this reason // the above loop will tend to underestimate process counts. // getMiscStats is a single read/syscall so it should be more accurate. - miscStat, err := s.getMiscStats() + miscStat, err := s.getMiscStats(ctx) if err != nil { return processesMetadata{}, err } diff --git a/receiver/hostmetricsreceiver/internal/scraper/processscraper/internal/handlecount/handles_windows_test.go b/receiver/hostmetricsreceiver/internal/scraper/processscraper/internal/handlecount/handles_windows_test.go index 00f3f37a4758..55459e2ea1fb 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/processscraper/internal/handlecount/handles_windows_test.go +++ b/receiver/hostmetricsreceiver/internal/scraper/processscraper/internal/handlecount/handles_windows_test.go @@ -12,6 +12,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestHandleCountManager(t *testing.T) { @@ -21,7 +22,7 @@ func TestHandleCountManager(t *testing.T) { } m := deterministicManagerWithInfo(testInfos) - m.Refresh() + require.NoError(t, m.Refresh()) count, err := m.GetProcessHandleCount(1) assert.NoError(t, err) diff --git a/receiver/hostmetricsreceiver/internal/scraper/processscraper/process.go b/receiver/hostmetricsreceiver/internal/scraper/processscraper/process.go index 8746fabb1ffc..261abcfa966c 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/processscraper/process.go +++ b/receiver/hostmetricsreceiver/internal/scraper/processscraper/process.go @@ -4,6 +4,7 @@ package processscraper // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/scraper/processscraper" import ( + "context" "runtime" "strings" "time" @@ -108,8 +109,8 @@ func (p *gopsProcessHandles) Len() int { return len(p.handles) } -func getProcessHandlesInternal() (processHandles, error) { - processes, err := process.Processes() +func getProcessHandlesInternal(ctx context.Context) (processHandles, error) { + processes, err := process.ProcessesWithContext(ctx) if err != nil { return nil, err } diff --git a/receiver/hostmetricsreceiver/internal/scraper/processscraper/process_scraper.go b/receiver/hostmetricsreceiver/internal/scraper/processscraper/process_scraper.go index c62f51f1b36e..c8ba6ba724a9 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/processscraper/process_scraper.go +++ b/receiver/hostmetricsreceiver/internal/scraper/processscraper/process_scraper.go @@ -10,6 +10,7 @@ import ( "runtime" "time" + "github.com/shirou/gopsutil/v3/common" "github.com/shirou/gopsutil/v3/process" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/pdata/pcommon" @@ -48,9 +49,10 @@ type scraper struct { excludeFS filterset.FilterSet scrapeProcessDelay time.Duration ucals map[int32]*ucal.CPUUtilizationCalculator + // for mocking getProcessCreateTime func(p processHandle) (int64, error) - getProcessHandles func() (processHandles, error) + getProcessHandles func(context.Context) (processHandles, error) handleCountManager handlecount.Manager } @@ -171,7 +173,8 @@ func (s *scraper) scrape(_ context.Context) (pmetric.Metrics, error) { // for some processes, an error will be returned, but any processes that were // successfully obtained will still be returned. func (s *scraper) getProcessMetadata() ([]*processMetadata, error) { - handles, err := s.getProcessHandles() + ctx := context.WithValue(context.Background(), common.EnvKey, s.config.EnvMap) + handles, err := s.getProcessHandles(ctx) if err != nil { return nil, err } diff --git a/receiver/hostmetricsreceiver/internal/scraper/processscraper/process_scraper_test.go b/receiver/hostmetricsreceiver/internal/scraper/processscraper/process_scraper_test.go index 27097fdf689a..32034120be9f 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/processscraper/process_scraper_test.go +++ b/receiver/hostmetricsreceiver/internal/scraper/processscraper/process_scraper_test.go @@ -354,7 +354,7 @@ func TestScrapeMetrics_GetProcessesError(t *testing.T) { scraper, err := newProcessScraper(receivertest.NewNopCreateSettings(), &Config{MetricsBuilderConfig: metadata.DefaultMetricsBuilderConfig()}) require.NoError(t, err, "Failed to create process scraper: %v", err) - scraper.getProcessHandles = func() (processHandles, error) { return nil, errors.New("err1") } + scraper.getProcessHandles = func(context.Context) (processHandles, error) { return nil, errors.New("err1") } err = scraper.start(context.Background(), componenttest.NewNopHost()) require.NoError(t, err, "Failed to initialize process scraper: %v", err) @@ -605,7 +605,7 @@ func TestScrapeMetrics_Filtered(t *testing.T) { handles = append(handles, handleMock) } - scraper.getProcessHandles = func() (processHandles, error) { + scraper.getProcessHandles = func(context.Context) (processHandles, error) { return &processHandlesMock{handles: handles}, nil } @@ -835,7 +835,7 @@ func TestScrapeMetrics_ProcessErrors(t *testing.T) { }, }, test.rlimitError) - scraper.getProcessHandles = func() (processHandles, error) { + scraper.getProcessHandles = func(context.Context) (processHandles, error) { return &processHandlesMock{handles: []*processHandleMock{handleMock}}, nil } @@ -1018,7 +1018,7 @@ func TestScrapeMetrics_MuteErrorFlags(t *testing.T) { handleMock.On("IOCounters").Return("test", errors.New("permission denied")) } - scraper.getProcessHandles = func() (processHandles, error) { + scraper.getProcessHandles = func(context.Context) (processHandles, error) { return &processHandlesMock{handles: []*processHandleMock{handleMock}}, nil } md, err := scraper.scrape(context.Background()) @@ -1080,7 +1080,7 @@ func TestScrapeMetrics_DontCheckDisabledMetrics(t *testing.T) { handleMock.On("CreateTime").Return(time.Now().UnixMilli(), nil) handleMock.On("Ppid").Return(int32(2), nil) - scraper.getProcessHandles = func() (processHandles, error) { + scraper.getProcessHandles = func(context.Context) (processHandles, error) { return &processHandlesMock{handles: []*processHandleMock{handleMock}}, nil } md, err := scraper.scrape(context.Background()) @@ -1148,7 +1148,7 @@ func TestScrapeMetrics_CpuUtilizationWhenCpuTimesIsDisabled(t *testing.T) { handleMock.On("Exe").Return("test", nil) handleMock.On("CreateTime").Return(time.Now().UnixMilli(), nil) - scraper.getProcessHandles = func() (processHandles, error) { + scraper.getProcessHandles = func(context.Context) (processHandles, error) { return &processHandlesMock{handles: []*processHandleMock{handleMock}}, nil } diff --git a/receiver/hostmetricsreceiver/internal/scraper/processscraper/process_scraper_windows.go b/receiver/hostmetricsreceiver/internal/scraper/processscraper/process_scraper_windows.go index 3698fc8520f6..ad9ef8c061e3 100644 --- a/receiver/hostmetricsreceiver/internal/scraper/processscraper/process_scraper_windows.go +++ b/receiver/hostmetricsreceiver/internal/scraper/processscraper/process_scraper_windows.go @@ -28,7 +28,7 @@ func (s *scraper) recordCPUUtilization(now pcommon.Timestamp, cpuUtilization uca s.mb.RecordProcessCPUUtilizationDataPoint(now, cpuUtilization.System, metadata.AttributeStateSystem) } -func getProcessName(proc processHandle, exePath string) (string, error) { +func getProcessName(_ processHandle, exePath string) (string, error) { if exePath == "" { return "", fmt.Errorf("executable path is empty") } From 42bda2a400330c31df4caed29ad72ce6ecc7a1d5 Mon Sep 17 00:00:00 2001 From: Pablo Baeyens Date: Wed, 26 Jul 2023 00:51:34 +0200 Subject: [PATCH 36/42] [exporter/datadog] Add support for metrics::sums::initial_cumulative_monotonic_value (#24544) **Description:** Add support for `metrics::sums::initial_cumulative_monotonic_value` setting. This is similar to #21905 but for the Datadog exporter legacy cumulative to delta logic. Keeping as draft until its counterpart on the Datadog Agent (DataDog/datadog-agent/pull/18371) is approved Relates to DataDog/opentelemetry-mapping-go/issues/100 --- .chloggen/mx-psi_cumulative-opts.yaml | 21 +++++++++ exporter/datadogexporter/config.go | 44 +++++++++++++++++++ exporter/datadogexporter/config_test.go | 23 ++++++++++ .../datadogexporter/examples/collector.yaml | 9 ++++ exporter/datadogexporter/factory.go | 3 +- exporter/datadogexporter/factory_test.go | 12 +++-- exporter/datadogexporter/metrics_exporter.go | 3 +- 7 files changed, 109 insertions(+), 6 deletions(-) create mode 100755 .chloggen/mx-psi_cumulative-opts.yaml diff --git a/.chloggen/mx-psi_cumulative-opts.yaml b/.chloggen/mx-psi_cumulative-opts.yaml new file mode 100755 index 000000000000..e2dc6e313381 --- /dev/null +++ b/.chloggen/mx-psi_cumulative-opts.yaml @@ -0,0 +1,21 @@ +# Use this changelog template to create an entry for release notes. +# If your change doesn't affect end users, such as a test fix or a tooling change, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. + +# 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. filelogreceiver) +component: datadogexporter + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: "Add support for the `metrics::sums::initial_cumulative_monotonic_value` setting" + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [24544] + +# (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: | + The setting has the same values and semantics as the `initial_value` setting from the `cumulativetodelta` processor diff --git a/exporter/datadogexporter/config.go b/exporter/datadogexporter/config.go index 1b29a9fb7963..d491c3b59701 100644 --- a/exporter/datadogexporter/config.go +++ b/exporter/datadogexporter/config.go @@ -149,6 +149,37 @@ func (sm *CumulativeMonotonicSumMode) UnmarshalText(in []byte) error { } } +// InitialValueMode defines what the exporter should do with the initial value +// of a time series when transforming from cumulative to delta. +type InitialValueMode string + +const ( + // InitialValueModeAuto reports the initial value if its start timestamp + // is set and it happens after the process was started. + InitialValueModeAuto InitialValueMode = "auto" + + // InitialValueModeDrop always drops the initial value. + InitialValueModeDrop InitialValueMode = "drop" + + // InitialValueModeKeep always reports the initial value. + InitialValueModeKeep InitialValueMode = "keep" +) + +var _ encoding.TextUnmarshaler = (*InitialValueMode)(nil) + +// UnmarshalText implements the encoding.TextUnmarshaler interface. +func (iv *InitialValueMode) UnmarshalText(in []byte) error { + switch mode := InitialValueMode(in); mode { + case InitialValueModeAuto, + InitialValueModeDrop, + InitialValueModeKeep: + *iv = mode + return nil + default: + return fmt.Errorf("invalid initial value mode %q", mode) + } +} + // SumConfig customizes export of OTLP Sums. type SumConfig struct { // CumulativeMonotonicMode is the mode for exporting OTLP Cumulative Monotonic Sums. @@ -159,6 +190,10 @@ type SumConfig struct { // The default is 'to_delta'. // See https://docs.datadoghq.com/metrics/otlp/?tab=sum#mapping for details and examples. CumulativeMonotonicMode CumulativeMonotonicSumMode `mapstructure:"cumulative_monotonic_mode"` + + // InitialCumulativeMonotonicMode defines the behavior of the exporter when receiving the first value + // of a cumulative monotonic sum. + InitialCumulativeMonotonicMode InitialValueMode `mapstructure:"initial_cumulative_monotonic_value"` } // SummaryMode is the export mode for OTLP Summary metrics. @@ -529,5 +564,14 @@ func (c *Config) Unmarshal(configMap *confmap.Conf) error { return errEmptyEndpoint } + const ( + initialValueSetting = "metrics::sums::initial_cumulative_monotonic_value" + cumulMonoMode = "metrics::sums::cumulative_monotonic_mode" + ) + if configMap.IsSet(initialValueSetting) && c.Metrics.SumConfig.CumulativeMonotonicMode != CumulativeMonotonicSumModeToDelta { + return fmt.Errorf("%q can only be configured when %q is set to %q", + initialValueSetting, cumulMonoMode, CumulativeMonotonicSumModeToDelta) + } + return nil } diff --git a/exporter/datadogexporter/config_test.go b/exporter/datadogexporter/config_test.go index 6f748a930526..e0f8575c90e0 100644 --- a/exporter/datadogexporter/config_test.go +++ b/exporter/datadogexporter/config_test.go @@ -227,6 +227,29 @@ func TestUnmarshal(t *testing.T) { }), err: errEmptyEndpoint.Error(), }, + { + name: "invalid initial cumulative monotonic value mode", + configMap: confmap.NewFromStringMap(map[string]interface{}{ + "metrics": map[string]interface{}{ + "sums": map[string]interface{}{ + "initial_cumulative_monotonic_value": "invalid_mode", + }, + }, + }), + err: "1 error(s) decoding:\n\n* error decoding 'metrics.sums.initial_cumulative_monotonic_value': invalid initial value mode \"invalid_mode\"", + }, + { + name: "initial cumulative monotonic value mode set with raw_value", + configMap: confmap.NewFromStringMap(map[string]interface{}{ + "metrics": map[string]interface{}{ + "sums": map[string]interface{}{ + "cumulative_monotonic_mode": "raw_value", + "initial_cumulative_monotonic_value": "drop", + }, + }, + }), + err: "\"metrics::sums::initial_cumulative_monotonic_value\" can only be configured when \"metrics::sums::cumulative_monotonic_mode\" is set to \"to_delta\"", + }, } f := NewFactory() diff --git a/exporter/datadogexporter/examples/collector.yaml b/exporter/datadogexporter/examples/collector.yaml index 7d66419fa85d..fcc3ca4effc4 100644 --- a/exporter/datadogexporter/examples/collector.yaml +++ b/exporter/datadogexporter/examples/collector.yaml @@ -272,6 +272,15 @@ exporters: # # cumulative_monotonic_mode: to_delta + ## @param initial_cumulative_monotonic_value - string - optional - default: auto + ## How to report the initial value for cumulative monotonic sums. Valid values are: + ## + ## - `auto` reports the initial value if its start timestamp is set and it happens after the process was started. + ## - `drop` always drops the initial value. + ## - `keep` always reports the initial value. + # + # initial_cumulative_monotonic_value: auto + ## @param summaries - custom object - optional ## Summaries specific configuration. ## @param mode - string - optional - default: gauges diff --git a/exporter/datadogexporter/factory.go b/exporter/datadogexporter/factory.go index 38558362c4dc..df0423b2688d 100644 --- a/exporter/datadogexporter/factory.go +++ b/exporter/datadogexporter/factory.go @@ -170,7 +170,8 @@ func (f *factory) createDefaultConfig() component.Config { SendAggregations: false, }, SumConfig: SumConfig{ - CumulativeMonotonicMode: CumulativeMonotonicSumModeToDelta, + CumulativeMonotonicMode: CumulativeMonotonicSumModeToDelta, + InitialCumulativeMonotonicMode: InitialValueModeAuto, }, SummaryConfig: SummaryConfig{ Mode: SummaryModeGauges, diff --git a/exporter/datadogexporter/factory_test.go b/exporter/datadogexporter/factory_test.go index 90176a31f045..2bfa0a6d96b7 100644 --- a/exporter/datadogexporter/factory_test.go +++ b/exporter/datadogexporter/factory_test.go @@ -88,7 +88,8 @@ func TestCreateDefaultConfig(t *testing.T) { SendAggregations: false, }, SumConfig: SumConfig{ - CumulativeMonotonicMode: CumulativeMonotonicSumModeToDelta, + CumulativeMonotonicMode: CumulativeMonotonicSumModeToDelta, + InitialCumulativeMonotonicMode: InitialValueModeAuto, }, SummaryConfig: SummaryConfig{ Mode: SummaryModeGauges, @@ -149,7 +150,8 @@ func TestLoadConfig(t *testing.T) { SendAggregations: false, }, SumConfig: SumConfig{ - CumulativeMonotonicMode: CumulativeMonotonicSumModeToDelta, + CumulativeMonotonicMode: CumulativeMonotonicSumModeToDelta, + InitialCumulativeMonotonicMode: InitialValueModeAuto, }, SummaryConfig: SummaryConfig{ Mode: SummaryModeGauges, @@ -198,7 +200,8 @@ func TestLoadConfig(t *testing.T) { SendAggregations: false, }, SumConfig: SumConfig{ - CumulativeMonotonicMode: CumulativeMonotonicSumModeToDelta, + CumulativeMonotonicMode: CumulativeMonotonicSumModeToDelta, + InitialCumulativeMonotonicMode: InitialValueModeAuto, }, SummaryConfig: SummaryConfig{ Mode: SummaryModeGauges, @@ -251,7 +254,8 @@ func TestLoadConfig(t *testing.T) { SendAggregations: false, }, SumConfig: SumConfig{ - CumulativeMonotonicMode: CumulativeMonotonicSumModeToDelta, + CumulativeMonotonicMode: CumulativeMonotonicSumModeToDelta, + InitialCumulativeMonotonicMode: InitialValueModeAuto, }, SummaryConfig: SummaryConfig{ Mode: SummaryModeGauges, diff --git a/exporter/datadogexporter/metrics_exporter.go b/exporter/datadogexporter/metrics_exporter.go index 9907ce212586..67a2c1dde470 100644 --- a/exporter/datadogexporter/metrics_exporter.go +++ b/exporter/datadogexporter/metrics_exporter.go @@ -82,8 +82,9 @@ func translatorFromConfig(logger *zap.Logger, cfg *Config, sourceProvider source case CumulativeMonotonicSumModeToDelta: numberMode = otlpmetrics.NumberModeCumulativeToDelta } - options = append(options, otlpmetrics.WithNumberMode(numberMode)) + options = append(options, otlpmetrics.WithInitialCumulMonoValueMode( + otlpmetrics.InitialCumulMonoValueMode(cfg.Metrics.SumConfig.InitialCumulativeMonotonicMode))) return otlpmetrics.NewTranslator(logger, options...) } From 996a8a6ea7b79530929228415dad2a893f59a317 Mon Sep 17 00:00:00 2001 From: Dmitrii Anoshin Date: Tue, 25 Jul 2023 18:10:25 -0700 Subject: [PATCH 37/42] [chore] [receiver/k8scluster] Remove OpenCensus dependency from a test (#24554) This is the last OpenCensus dependency in this component --- receiver/k8sclusterreceiver/go.mod | 10 +- receiver/k8sclusterreceiver/go.sum | 1177 ++++++++++++++--- .../internal/collection/collector.go | 10 - .../internal/collection/metricsstore_test.go | 29 +- 4 files changed, 990 insertions(+), 236 deletions(-) diff --git a/receiver/k8sclusterreceiver/go.mod b/receiver/k8sclusterreceiver/go.mod index 6a9fd3b9c257..305bfa90254e 100644 --- a/receiver/k8sclusterreceiver/go.mod +++ b/receiver/k8sclusterreceiver/go.mod @@ -3,7 +3,6 @@ module github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclu go 1.19 require ( - github.com/census-instrumentation/opencensus-proto v0.4.1 github.com/google/go-cmp v0.5.9 github.com/google/uuid v1.3.0 github.com/iancoleman/strcase v0.3.0 @@ -14,7 +13,6 @@ require ( github.com/open-telemetry/opentelemetry-collector-contrib/internal/sharedcomponent v0.81.0 github.com/open-telemetry/opentelemetry-collector-contrib/pkg/experimentalmetricmetadata v0.81.0 github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest v0.81.0 - github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/opencensus v0.81.0 github.com/openshift/api v3.9.0+incompatible github.com/openshift/client-go v0.0.0-20210521082421-73d9475a9142 github.com/stretchr/testify v1.8.4 @@ -59,7 +57,6 @@ require ( github.com/golang/snappy v0.0.4 // indirect github.com/google/gnostic v0.5.7-v3refs // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect github.com/imdario/mergo v0.3.15 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect @@ -121,8 +118,6 @@ require ( golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.11.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect google.golang.org/grpc v1.56.2 // indirect google.golang.org/protobuf v1.31.0 // indirect @@ -143,8 +138,6 @@ replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/k8sco replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/experimentalmetricmetadata => ../../pkg/experimentalmetricmetadata -replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/opencensus => ../../pkg/translator/opencensus - replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal => ../../internal/coreinternal retract ( @@ -163,3 +156,6 @@ replace github.com/openshift/api v3.9.0+incompatible => github.com/openshift/api replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/k8stest => ../../internal/k8stest replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/sharedcomponent => ../../internal/sharedcomponent + +// ambiguous import: found package cloud.google.com/go/compute/metadata in multiple modules +replace cloud.google.com/go => cloud.google.com/go v0.110.2 diff --git a/receiver/k8sclusterreceiver/go.sum b/receiver/k8sclusterreceiver/go.sum index cad04ea71c55..658eb0a3ae75 100644 --- a/receiver/k8sclusterreceiver/go.sum +++ b/receiver/k8sclusterreceiver/go.sum @@ -1,41 +1,551 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys= +cloud.google.com/go v0.110.2 h1:sdFPBr6xG9/wkBbfhmUz/JmZC7X6LavQgcrVINrKiVA= +cloud.google.com/go v0.110.2/go.mod h1:k04UEeEtb6ZBRTv3dZz4CeJC3jKGxyhl0sAiVVquxiw= +cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4= +cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw= +cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E= +cloud.google.com/go/accesscontextmanager v1.3.0/go.mod h1:TgCBehyr5gNMz7ZaH9xubp+CE8dkrszb4oK9CWyvD4o= +cloud.google.com/go/accesscontextmanager v1.4.0/go.mod h1:/Kjh7BBu/Gh83sv+K60vN9QE5NJcd80sU33vIe2IFPE= +cloud.google.com/go/accesscontextmanager v1.6.0/go.mod h1:8XCvZWfYw3K/ji0iVnp+6pu7huxoQTLmxAbVjbloTtM= +cloud.google.com/go/accesscontextmanager v1.7.0/go.mod h1:CEGLewx8dwa33aDAZQujl7Dx+uYhS0eay198wB/VumQ= +cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= +cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= +cloud.google.com/go/aiplatform v1.27.0/go.mod h1:Bvxqtl40l0WImSb04d0hXFU7gDOiq9jQmorivIiWcKg= +cloud.google.com/go/aiplatform v1.35.0/go.mod h1:7MFT/vCaOyZT/4IIFfxH4ErVg/4ku6lKv3w0+tFTgXQ= +cloud.google.com/go/aiplatform v1.36.1/go.mod h1:WTm12vJRPARNvJ+v6P52RDHCNe4AhvjcIZ/9/RRHy/k= +cloud.google.com/go/aiplatform v1.37.0/go.mod h1:IU2Cv29Lv9oCn/9LkFiiuKfwrRTq+QQMbW+hPCxJGZw= +cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= +cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= +cloud.google.com/go/analytics v0.17.0/go.mod h1:WXFa3WSym4IZ+JiKmavYdJwGG/CvpqiqczmL59bTD9M= +cloud.google.com/go/analytics v0.18.0/go.mod h1:ZkeHGQlcIPkw0R/GW+boWHhCOR43xz9RN/jn7WcqfIE= +cloud.google.com/go/analytics v0.19.0/go.mod h1:k8liqf5/HCnOUkbawNtrWWc+UAzyDlW89doe8TtoDsE= +cloud.google.com/go/apigateway v1.3.0/go.mod h1:89Z8Bhpmxu6AmUxuVRg/ECRGReEdiP3vQtk4Z1J9rJk= +cloud.google.com/go/apigateway v1.4.0/go.mod h1:pHVY9MKGaH9PQ3pJ4YLzoj6U5FUDeDFBllIz7WmzJoc= +cloud.google.com/go/apigateway v1.5.0/go.mod h1:GpnZR3Q4rR7LVu5951qfXPJCHquZt02jf7xQx7kpqN8= +cloud.google.com/go/apigeeconnect v1.3.0/go.mod h1:G/AwXFAKo0gIXkPTVfZDd2qA1TxBXJ3MgMRBQkIi9jc= +cloud.google.com/go/apigeeconnect v1.4.0/go.mod h1:kV4NwOKqjvt2JYR0AoIWo2QGfoRtn/pkS3QlHp0Ni04= +cloud.google.com/go/apigeeconnect v1.5.0/go.mod h1:KFaCqvBRU6idyhSNyn3vlHXc8VMDJdRmwDF6JyFRqZ8= +cloud.google.com/go/apigeeregistry v0.4.0/go.mod h1:EUG4PGcsZvxOXAdyEghIdXwAEi/4MEaoqLMLDMIwKXY= +cloud.google.com/go/apigeeregistry v0.5.0/go.mod h1:YR5+s0BVNZfVOUkMa5pAR2xGd0A473vA5M7j247o1wM= +cloud.google.com/go/apigeeregistry v0.6.0/go.mod h1:BFNzW7yQVLZ3yj0TKcwzb8n25CFBri51GVGOEUcgQsc= +cloud.google.com/go/apikeys v0.4.0/go.mod h1:XATS/yqZbaBK0HOssf+ALHp8jAlNHUgyfprvNcBIszU= +cloud.google.com/go/apikeys v0.5.0/go.mod h1:5aQfwY4D+ewMMWScd3hm2en3hCj+BROlyrt3ytS7KLI= +cloud.google.com/go/apikeys v0.6.0/go.mod h1:kbpXu5upyiAlGkKrJgQl8A0rKNNJ7dQ377pdroRSSi8= +cloud.google.com/go/appengine v1.4.0/go.mod h1:CS2NhuBuDXM9f+qscZ6V86m1MIIqPj3WC/UoEuR1Sno= +cloud.google.com/go/appengine v1.5.0/go.mod h1:TfasSozdkFI0zeoxW3PTBLiNqRmzraodCWatWI9Dmak= +cloud.google.com/go/appengine v1.6.0/go.mod h1:hg6i0J/BD2cKmDJbaFSYHFyZkgBEfQrDg/X0V5fJn84= +cloud.google.com/go/appengine v1.7.0/go.mod h1:eZqpbHFCqRGa2aCdope7eC0SWLV1j0neb/QnMJVWx6A= +cloud.google.com/go/appengine v1.7.1/go.mod h1:IHLToyb/3fKutRysUlFO0BPt5j7RiQ45nrzEJmKTo6E= +cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= +cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= +cloud.google.com/go/area120 v0.7.0/go.mod h1:a3+8EUD1SX5RUcCs3MY5YasiO1z6yLiNLRiFrykbynY= +cloud.google.com/go/area120 v0.7.1/go.mod h1:j84i4E1RboTWjKtZVWXPqvK5VHQFJRF2c1Nm69pWm9k= +cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= +cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= +cloud.google.com/go/artifactregistry v1.8.0/go.mod h1:w3GQXkJX8hiKN0v+at4b0qotwijQbYUqF2GWkZzAhC0= +cloud.google.com/go/artifactregistry v1.9.0/go.mod h1:2K2RqvA2CYvAeARHRkLDhMDJ3OXy26h3XW+3/Jh2uYc= +cloud.google.com/go/artifactregistry v1.11.1/go.mod h1:lLYghw+Itq9SONbCa1YWBoWs1nOucMH0pwXN1rOBZFI= +cloud.google.com/go/artifactregistry v1.11.2/go.mod h1:nLZns771ZGAwVLzTX/7Al6R9ehma4WUEhZGWV6CeQNQ= +cloud.google.com/go/artifactregistry v1.12.0/go.mod h1:o6P3MIvtzTOnmvGagO9v/rOjjA0HmhJ+/6KAXrmYDCI= +cloud.google.com/go/artifactregistry v1.13.0/go.mod h1:uy/LNfoOIivepGhooAUpL1i30Hgee3Cu0l4VTWHUC08= +cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= +cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= +cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= +cloud.google.com/go/asset v1.9.0/go.mod h1:83MOE6jEJBMqFKadM9NLRcs80Gdw76qGuHn8m3h8oHQ= +cloud.google.com/go/asset v1.10.0/go.mod h1:pLz7uokL80qKhzKr4xXGvBQXnzHn5evJAEAtZiIb0wY= +cloud.google.com/go/asset v1.11.1/go.mod h1:fSwLhbRvC9p9CXQHJ3BgFeQNM4c9x10lqlrdEUYXlJo= +cloud.google.com/go/asset v1.12.0/go.mod h1:h9/sFOa4eDIyKmH6QMpm4eUK3pDojWnUhTgJlk762Hg= +cloud.google.com/go/asset v1.13.0/go.mod h1:WQAMyYek/b7NBpYq/K4KJWcRqzoalEsxz/t/dTk4THw= +cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= +cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= +cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= +cloud.google.com/go/assuredworkloads v1.8.0/go.mod h1:AsX2cqyNCOvEQC8RMPnoc0yEarXQk6WEKkxYfL6kGIo= +cloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0= +cloud.google.com/go/assuredworkloads v1.10.0/go.mod h1:kwdUQuXcedVdsIaKgKTp9t0UJkE5+PAVNhdQm4ZVq2E= +cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= +cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= +cloud.google.com/go/automl v1.7.0/go.mod h1:RL9MYCCsJEOmt0Wf3z9uzG0a7adTT1fe+aObgSpkCt8= +cloud.google.com/go/automl v1.8.0/go.mod h1:xWx7G/aPEe/NP+qzYXktoBSDfjO+vnKMGgsApGJJquM= +cloud.google.com/go/automl v1.12.0/go.mod h1:tWDcHDp86aMIuHmyvjuKeeHEGq76lD7ZqfGLN6B0NuU= +cloud.google.com/go/baremetalsolution v0.3.0/go.mod h1:XOrocE+pvK1xFfleEnShBlNAXf+j5blPPxrhjKgnIFc= +cloud.google.com/go/baremetalsolution v0.4.0/go.mod h1:BymplhAadOO/eBa7KewQ0Ppg4A4Wplbn+PsFKRLo0uI= +cloud.google.com/go/baremetalsolution v0.5.0/go.mod h1:dXGxEkmR9BMwxhzBhV0AioD0ULBmuLZI8CdwalUxuss= +cloud.google.com/go/batch v0.3.0/go.mod h1:TR18ZoAekj1GuirsUsR1ZTKN3FC/4UDnScjT8NXImFE= +cloud.google.com/go/batch v0.4.0/go.mod h1:WZkHnP43R/QCGQsZ+0JyG4i79ranE2u8xvjq/9+STPE= +cloud.google.com/go/batch v0.7.0/go.mod h1:vLZN95s6teRUqRQ4s3RLDsH8PvboqBK+rn1oevL159g= +cloud.google.com/go/beyondcorp v0.2.0/go.mod h1:TB7Bd+EEtcw9PCPQhCJtJGjk/7TC6ckmnSFS+xwTfm4= +cloud.google.com/go/beyondcorp v0.3.0/go.mod h1:E5U5lcrcXMsCuoDNyGrpyTm/hn7ne941Jz2vmksAxW8= +cloud.google.com/go/beyondcorp v0.4.0/go.mod h1:3ApA0mbhHx6YImmuubf5pyW8srKnCEPON32/5hj+RmM= +cloud.google.com/go/beyondcorp v0.5.0/go.mod h1:uFqj9X+dSfrheVp7ssLTaRHd2EHqSL4QZmH4e8WXGGU= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= +cloud.google.com/go/bigquery v1.43.0/go.mod h1:ZMQcXHsl+xmU1z36G2jNGZmKp9zNY5BUua5wDgmNCfw= +cloud.google.com/go/bigquery v1.44.0/go.mod h1:0Y33VqXTEsbamHJvJHdFmtqHvMIY28aK1+dFsvaChGc= +cloud.google.com/go/bigquery v1.47.0/go.mod h1:sA9XOgy0A8vQK9+MWhEQTY6Tix87M/ZurWFIxmF9I/E= +cloud.google.com/go/bigquery v1.48.0/go.mod h1:QAwSz+ipNgfL5jxiaK7weyOhzdoAy1zFm0Nf1fysJac= +cloud.google.com/go/bigquery v1.49.0/go.mod h1:Sv8hMmTFFYBlt/ftw2uN6dFdQPzBlREY9yBh7Oy7/4Q= +cloud.google.com/go/bigquery v1.50.0/go.mod h1:YrleYEh2pSEbgTBZYMJ5SuSr0ML3ypjRB1zgf7pvQLU= +cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= +cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= +cloud.google.com/go/billing v1.6.0/go.mod h1:WoXzguj+BeHXPbKfNWkqVtDdzORazmCjraY+vrxcyvI= +cloud.google.com/go/billing v1.7.0/go.mod h1:q457N3Hbj9lYwwRbnlD7vUpyjq6u5U1RAOArInEiD5Y= +cloud.google.com/go/billing v1.12.0/go.mod h1:yKrZio/eu+okO/2McZEbch17O5CB5NpZhhXG6Z766ss= +cloud.google.com/go/billing v1.13.0/go.mod h1:7kB2W9Xf98hP9Sr12KfECgfGclsH3CQR0R08tnRlRbc= +cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= +cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= +cloud.google.com/go/binaryauthorization v1.3.0/go.mod h1:lRZbKgjDIIQvzYQS1p99A7/U1JqvqeZg0wiI5tp6tg0= +cloud.google.com/go/binaryauthorization v1.4.0/go.mod h1:tsSPQrBd77VLplV70GUhBf/Zm3FsKmgSqgm4UmiDItk= +cloud.google.com/go/binaryauthorization v1.5.0/go.mod h1:OSe4OU1nN/VswXKRBmciKpo9LulY41gch5c68htf3/Q= +cloud.google.com/go/certificatemanager v1.3.0/go.mod h1:n6twGDvcUBFu9uBgt4eYvvf3sQ6My8jADcOVwHmzadg= +cloud.google.com/go/certificatemanager v1.4.0/go.mod h1:vowpercVFyqs8ABSmrdV+GiFf2H/ch3KyudYQEMM590= +cloud.google.com/go/certificatemanager v1.6.0/go.mod h1:3Hh64rCKjRAX8dXgRAyOcY5vQ/fE1sh8o+Mdd6KPgY8= +cloud.google.com/go/channel v1.8.0/go.mod h1:W5SwCXDJsq/rg3tn3oG0LOxpAo6IMxNa09ngphpSlnk= +cloud.google.com/go/channel v1.9.0/go.mod h1:jcu05W0my9Vx4mt3/rEHpfxc9eKi9XwsdDL8yBMbKUk= +cloud.google.com/go/channel v1.11.0/go.mod h1:IdtI0uWGqhEeatSB62VOoJ8FSUhJ9/+iGkJVqp74CGE= +cloud.google.com/go/channel v1.12.0/go.mod h1:VkxCGKASi4Cq7TbXxlaBezonAYpp1GCnKMY6tnMQnLU= +cloud.google.com/go/cloudbuild v1.3.0/go.mod h1:WequR4ULxlqvMsjDEEEFnOG5ZSRSgWOywXYDb1vPE6U= +cloud.google.com/go/cloudbuild v1.4.0/go.mod h1:5Qwa40LHiOXmz3386FrjrYM93rM/hdRr7b53sySrTqA= +cloud.google.com/go/cloudbuild v1.6.0/go.mod h1:UIbc/w9QCbH12xX+ezUsgblrWv+Cv4Tw83GiSMHOn9M= +cloud.google.com/go/cloudbuild v1.7.0/go.mod h1:zb5tWh2XI6lR9zQmsm1VRA+7OCuve5d8S+zJUul8KTg= +cloud.google.com/go/cloudbuild v1.9.0/go.mod h1:qK1d7s4QlO0VwfYn5YuClDGg2hfmLZEb4wQGAbIgL1s= +cloud.google.com/go/clouddms v1.3.0/go.mod h1:oK6XsCDdW4Ib3jCCBugx+gVjevp2TMXFtgxvPSee3OM= +cloud.google.com/go/clouddms v1.4.0/go.mod h1:Eh7sUGCC+aKry14O1NRljhjyrr0NFC0G2cjwX0cByRk= +cloud.google.com/go/clouddms v1.5.0/go.mod h1:QSxQnhikCLUw13iAbffF2CZxAER3xDGNHjsTAkQJcQA= +cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= +cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= +cloud.google.com/go/cloudtasks v1.7.0/go.mod h1:ImsfdYWwlWNJbdgPIIGJWC+gemEGTBK/SunNQQNCAb4= +cloud.google.com/go/cloudtasks v1.8.0/go.mod h1:gQXUIwCSOI4yPVK7DgTVFiiP0ZW/eQkydWzwVMdHxrI= +cloud.google.com/go/cloudtasks v1.9.0/go.mod h1:w+EyLsVkLWHcOaqNEyvcKAsWp9p29dL6uL9Nst1cI7Y= +cloud.google.com/go/cloudtasks v1.10.0/go.mod h1:NDSoTLkZ3+vExFEWu2UJV1arUyzVDAiZtdWcsUyNwBs= +cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= +cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= +cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= +cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= +cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= +cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= +cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= +cloud.google.com/go/compute v1.12.0/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= +cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= +cloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARyZtRXDJ8GE= +cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo= +cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA= +cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= +cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU= cloud.google.com/go/compute v1.20.1 h1:6aKEtlUiwEpJzM001l0yFkpXmUVXaN8W+fbkb2AZNbg= +cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= +cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/compute/metadata v0.2.4-0.20230617002413-005d2dfb6b68 h1:aRVqY1p2IJaBGStWMsQMpkAa83cPkCDLl80eOj0Rbz4= +cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY= +cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck= +cloud.google.com/go/contactcenterinsights v1.6.0/go.mod h1:IIDlT6CLcDoyv79kDv8iWxMSTZhLxSCofVV5W6YFM/w= +cloud.google.com/go/container v1.6.0/go.mod h1:Xazp7GjJSeUYo688S+6J5V+n/t+G5sKBTFkKNudGRxg= +cloud.google.com/go/container v1.7.0/go.mod h1:Dp5AHtmothHGX3DwwIHPgq45Y8KmNsgN3amoYfxVkLo= +cloud.google.com/go/container v1.13.1/go.mod h1:6wgbMPeQRw9rSnKBCAJXnds3Pzj03C4JHamr8asWKy4= +cloud.google.com/go/container v1.14.0/go.mod h1:3AoJMPhHfLDxLvrlVWaK57IXzaPnLaZq63WX59aQBfM= +cloud.google.com/go/container v1.15.0/go.mod h1:ft+9S0WGjAyjDggg5S06DXj+fHJICWg8L7isCQe9pQA= +cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= +cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= +cloud.google.com/go/containeranalysis v0.7.0/go.mod h1:9aUL+/vZ55P2CXfuZjS4UjQ9AgXoSw8Ts6lemfmxBxI= +cloud.google.com/go/containeranalysis v0.9.0/go.mod h1:orbOANbwk5Ejoom+s+DUCTTJ7IBdBQJDcSylAx/on9s= +cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= +cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= +cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= +cloud.google.com/go/datacatalog v1.7.0/go.mod h1:9mEl4AuDYWw81UGc41HonIHH7/sn52H0/tc8f8ZbZIE= +cloud.google.com/go/datacatalog v1.8.0/go.mod h1:KYuoVOv9BM8EYz/4eMFxrr4DUKhGIOXxZoKYF5wdISM= +cloud.google.com/go/datacatalog v1.8.1/go.mod h1:RJ58z4rMp3gvETA465Vg+ag8BGgBdnRPEMMSTr5Uv+M= +cloud.google.com/go/datacatalog v1.12.0/go.mod h1:CWae8rFkfp6LzLumKOnmVh4+Zle4A3NXLzVJ1d1mRm0= +cloud.google.com/go/datacatalog v1.13.0/go.mod h1:E4Rj9a5ZtAxcQJlEBTLgMTphfP11/lNaAshpoBgemX8= +cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= +cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= +cloud.google.com/go/dataflow v0.8.0/go.mod h1:Rcf5YgTKPtQyYz8bLYhFoIV/vP39eL7fWNcSOyFfLJE= +cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= +cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= +cloud.google.com/go/dataform v0.5.0/go.mod h1:GFUYRe8IBa2hcomWplodVmUx/iTL0FrsauObOM3Ipr0= +cloud.google.com/go/dataform v0.6.0/go.mod h1:QPflImQy33e29VuapFdf19oPbE4aYTJxr31OAPV+ulA= +cloud.google.com/go/dataform v0.7.0/go.mod h1:7NulqnVozfHvWUBpMDfKMUESr+85aJsC/2O0o3jWPDE= +cloud.google.com/go/datafusion v1.4.0/go.mod h1:1Zb6VN+W6ALo85cXnM1IKiPw+yQMKMhB9TsTSRDo/38= +cloud.google.com/go/datafusion v1.5.0/go.mod h1:Kz+l1FGHB0J+4XF2fud96WMmRiq/wj8N9u007vyXZ2w= +cloud.google.com/go/datafusion v1.6.0/go.mod h1:WBsMF8F1RhSXvVM8rCV3AeyWVxcC2xY6vith3iw3S+8= +cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= +cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= +cloud.google.com/go/datalabeling v0.7.0/go.mod h1:WPQb1y08RJbmpM3ww0CSUAGweL0SxByuW2E+FU+wXcM= +cloud.google.com/go/dataplex v1.3.0/go.mod h1:hQuRtDg+fCiFgC8j0zV222HvzFQdRd+SVX8gdmFcZzA= +cloud.google.com/go/dataplex v1.4.0/go.mod h1:X51GfLXEMVJ6UN47ESVqvlsRplbLhcsAt0kZCCKsU0A= +cloud.google.com/go/dataplex v1.5.2/go.mod h1:cVMgQHsmfRoI5KFYq4JtIBEUbYwc3c7tXmIDhRmNNVQ= +cloud.google.com/go/dataplex v1.6.0/go.mod h1:bMsomC/aEJOSpHXdFKFGQ1b0TDPIeL28nJObeO1ppRs= +cloud.google.com/go/dataproc v1.7.0/go.mod h1:CKAlMjII9H90RXaMpSxQ8EU6dQx6iAYNPcYPOkSbi8s= +cloud.google.com/go/dataproc v1.8.0/go.mod h1:5OW+zNAH0pMpw14JVrPONsxMQYMBqJuzORhIBfBn9uI= +cloud.google.com/go/dataproc v1.12.0/go.mod h1:zrF3aX0uV3ikkMz6z4uBbIKyhRITnxvr4i3IjKsKrw4= +cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= +cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= +cloud.google.com/go/dataqna v0.7.0/go.mod h1:Lx9OcIIeqCrw1a6KdO3/5KMP1wAmTc0slZWwP12Qq3c= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/datastore v1.10.0/go.mod h1:PC5UzAmDEkAmkfaknstTYbNpgE49HAgW2J1gcgUfmdM= +cloud.google.com/go/datastore v1.11.0/go.mod h1:TvGxBIHCS50u8jzG+AW/ppf87v1of8nwzFNgEZU1D3c= +cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= +cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= +cloud.google.com/go/datastream v1.4.0/go.mod h1:h9dpzScPhDTs5noEMQVWP8Wx8AFBRyS0s8KWPx/9r0g= +cloud.google.com/go/datastream v1.5.0/go.mod h1:6TZMMNPwjUqZHBKPQ1wwXpb0d5VDVPl2/XoS5yi88q4= +cloud.google.com/go/datastream v1.6.0/go.mod h1:6LQSuswqLa7S4rPAOZFVjHIG3wJIjZcZrw8JDEDJuIs= +cloud.google.com/go/datastream v1.7.0/go.mod h1:uxVRMm2elUSPuh65IbZpzJNMbuzkcvu5CjMqVIUHrww= +cloud.google.com/go/deploy v1.4.0/go.mod h1:5Xghikd4VrmMLNaF6FiRFDlHb59VM59YoDQnOUdsH/c= +cloud.google.com/go/deploy v1.5.0/go.mod h1:ffgdD0B89tToyW/U/D2eL0jN2+IEV/3EMuXHA0l4r+s= +cloud.google.com/go/deploy v1.6.0/go.mod h1:f9PTHehG/DjCom3QH0cntOVRm93uGBDt2vKzAPwpXQI= +cloud.google.com/go/deploy v1.8.0/go.mod h1:z3myEJnA/2wnB4sgjqdMfgxCA0EqC3RBTNcVPs93mtQ= +cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= +cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= +cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= +cloud.google.com/go/dialogflow v1.18.0/go.mod h1:trO7Zu5YdyEuR+BhSNOqJezyFQ3aUzz0njv7sMx/iek= +cloud.google.com/go/dialogflow v1.19.0/go.mod h1:JVmlG1TwykZDtxtTXujec4tQ+D8SBFMoosgy+6Gn0s0= +cloud.google.com/go/dialogflow v1.29.0/go.mod h1:b+2bzMe+k1s9V+F2jbJwpHPzrnIyHihAdRFMtn2WXuM= +cloud.google.com/go/dialogflow v1.31.0/go.mod h1:cuoUccuL1Z+HADhyIA7dci3N5zUssgpBJmCzI6fNRB4= +cloud.google.com/go/dialogflow v1.32.0/go.mod h1:jG9TRJl8CKrDhMEcvfcfFkkpp8ZhgPz3sBGmAUYJ2qE= +cloud.google.com/go/dlp v1.6.0/go.mod h1:9eyB2xIhpU0sVwUixfBubDoRwP+GjeUoxxeueZmqvmM= +cloud.google.com/go/dlp v1.7.0/go.mod h1:68ak9vCiMBjbasxeVD17hVPxDEck+ExiHavX8kiHG+Q= +cloud.google.com/go/dlp v1.9.0/go.mod h1:qdgmqgTyReTz5/YNSSuueR8pl7hO0o9bQ39ZhtgkWp4= +cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= +cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= +cloud.google.com/go/documentai v1.9.0/go.mod h1:FS5485S8R00U10GhgBC0aNGrJxBP8ZVpEeJ7PQDZd6k= +cloud.google.com/go/documentai v1.10.0/go.mod h1:vod47hKQIPeCfN2QS/jULIvQTugbmdc0ZvxxfQY1bg4= +cloud.google.com/go/documentai v1.16.0/go.mod h1:o0o0DLTEZ+YnJZ+J4wNfTxmDVyrkzFvttBXXtYRMHkM= +cloud.google.com/go/documentai v1.18.0/go.mod h1:F6CK6iUH8J81FehpskRmhLq/3VlwQvb7TvwOceQ2tbs= +cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= +cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= +cloud.google.com/go/domains v0.8.0/go.mod h1:M9i3MMDzGFXsydri9/vW+EWz9sWb4I6WyHqdlAk0idE= +cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= +cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= +cloud.google.com/go/edgecontainer v0.3.0/go.mod h1:FLDpP4nykgwwIfcLt6zInhprzw0lEi2P1fjO6Ie0qbc= +cloud.google.com/go/edgecontainer v1.0.0/go.mod h1:cttArqZpBB2q58W/upSG++ooo6EsblxDIolxa3jSjbY= +cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= +cloud.google.com/go/essentialcontacts v1.3.0/go.mod h1:r+OnHa5jfj90qIfZDO/VztSFqbQan7HV75p8sA+mdGI= +cloud.google.com/go/essentialcontacts v1.4.0/go.mod h1:8tRldvHYsmnBCHdFpvU+GL75oWiBKl80BiqlFh9tp+8= +cloud.google.com/go/essentialcontacts v1.5.0/go.mod h1:ay29Z4zODTuwliK7SnX8E86aUF2CTzdNtvv42niCX0M= +cloud.google.com/go/eventarc v1.7.0/go.mod h1:6ctpF3zTnaQCxUjHUdcfgcA1A2T309+omHZth7gDfmc= +cloud.google.com/go/eventarc v1.8.0/go.mod h1:imbzxkyAU4ubfsaKYdQg04WS1NvncblHEup4kvF+4gw= +cloud.google.com/go/eventarc v1.10.0/go.mod h1:u3R35tmZ9HvswGRBnF48IlYgYeBcPUCjkr4BTdem2Kw= +cloud.google.com/go/eventarc v1.11.0/go.mod h1:PyUjsUKPWoRBCHeOxZd/lbOOjahV41icXyUY5kSTvVY= +cloud.google.com/go/filestore v1.3.0/go.mod h1:+qbvHGvXU1HaKX2nD0WEPo92TP/8AQuCVEBXNY9z0+w= +cloud.google.com/go/filestore v1.4.0/go.mod h1:PaG5oDfo9r224f8OYXURtAsY+Fbyq/bLYoINEK8XQAI= +cloud.google.com/go/filestore v1.5.0/go.mod h1:FqBXDWBp4YLHqRnVGveOkHDf8svj9r5+mUDLupOWEDs= +cloud.google.com/go/filestore v1.6.0/go.mod h1:di5unNuss/qfZTw2U9nhFqo8/ZDSc466dre85Kydllg= +cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE= +cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= +cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= +cloud.google.com/go/functions v1.8.0/go.mod h1:RTZ4/HsQjIqIYP9a9YPbU+QFoQsAlYgrwOXJWHn1POY= +cloud.google.com/go/functions v1.9.0/go.mod h1:Y+Dz8yGguzO3PpIjhLTbnqV1CWmgQ5UwtlpzoyquQ08= +cloud.google.com/go/functions v1.10.0/go.mod h1:0D3hEOe3DbEvCXtYOZHQZmD+SzYsi1YbI7dGvHfldXw= +cloud.google.com/go/functions v1.12.0/go.mod h1:AXWGrF3e2C/5ehvwYo/GH6O5s09tOPksiKhz+hH8WkA= +cloud.google.com/go/functions v1.13.0/go.mod h1:EU4O007sQm6Ef/PwRsI8N2umygGqPBS/IZQKBQBcJ3c= +cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= +cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= +cloud.google.com/go/gaming v1.7.0/go.mod h1:LrB8U7MHdGgFG851iHAfqUdLcKBdQ55hzXy9xBJz0+w= +cloud.google.com/go/gaming v1.8.0/go.mod h1:xAqjS8b7jAVW0KFYeRUxngo9My3f33kFmua++Pi+ggM= +cloud.google.com/go/gaming v1.9.0/go.mod h1:Fc7kEmCObylSWLO334NcO+O9QMDyz+TKC4v1D7X+Bc0= +cloud.google.com/go/gkebackup v0.2.0/go.mod h1:XKvv/4LfG829/B8B7xRkk8zRrOEbKtEam6yNfuQNH60= +cloud.google.com/go/gkebackup v0.3.0/go.mod h1:n/E671i1aOQvUxT541aTkCwExO/bTer2HDlj4TsBRAo= +cloud.google.com/go/gkebackup v0.4.0/go.mod h1:byAyBGUwYGEEww7xsbnUTBHIYcOPy/PgUWUtOeRm9Vg= +cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= +cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= +cloud.google.com/go/gkeconnect v0.7.0/go.mod h1:SNfmVqPkaEi3bF/B3CNZOAYPYdg7sU+obZ+QTky2Myw= +cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= +cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= +cloud.google.com/go/gkehub v0.11.0/go.mod h1:JOWHlmN+GHyIbuWQPl47/C2RFhnFKH38jH9Ascu3n0E= +cloud.google.com/go/gkehub v0.12.0/go.mod h1:djiIwwzTTBrF5NaXCGv3mf7klpEMcST17VBTVVDcuaw= +cloud.google.com/go/gkemulticloud v0.3.0/go.mod h1:7orzy7O0S+5kq95e4Hpn7RysVA7dPs8W/GgfUtsPbrA= +cloud.google.com/go/gkemulticloud v0.4.0/go.mod h1:E9gxVBnseLWCk24ch+P9+B2CoDFJZTyIgLKSalC7tuI= +cloud.google.com/go/gkemulticloud v0.5.0/go.mod h1:W0JDkiyi3Tqh0TJr//y19wyb1yf8llHVto2Htf2Ja3Y= +cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= +cloud.google.com/go/gsuiteaddons v1.3.0/go.mod h1:EUNK/J1lZEZO8yPtykKxLXI6JSVN2rg9bN8SXOa0bgM= +cloud.google.com/go/gsuiteaddons v1.4.0/go.mod h1:rZK5I8hht7u7HxFQcFei0+AtfS9uSushomRlg+3ua1o= +cloud.google.com/go/gsuiteaddons v1.5.0/go.mod h1:TFCClYLd64Eaa12sFVmUyG62tk4mdIsI7pAnSXRkcFo= +cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= +cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= +cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= +cloud.google.com/go/iam v0.6.0/go.mod h1:+1AH33ueBne5MzYccyMHtEKqLE4/kJOibtffMHDMFMc= +cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg= +cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE= +cloud.google.com/go/iam v0.11.0/go.mod h1:9PiLDanza5D+oWFZiH1uG+RnRCfEGKoyl6yo4cgWZGY= +cloud.google.com/go/iam v0.12.0/go.mod h1:knyHGviacl11zrtZUoDuYpDgLjvr28sLQaG0YB2GYAY= +cloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0= +cloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc= +cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A= +cloud.google.com/go/iap v1.6.0/go.mod h1:NSuvI9C/j7UdjGjIde7t7HBz+QTwBcapPE07+sSRcLk= +cloud.google.com/go/iap v1.7.0/go.mod h1:beqQx56T9O1G1yNPph+spKpNibDlYIiIixiqsQXxLIo= +cloud.google.com/go/iap v1.7.1/go.mod h1:WapEwPc7ZxGt2jFGB/C/bm+hP0Y6NXzOYGjpPnmMS74= +cloud.google.com/go/ids v1.1.0/go.mod h1:WIuwCaYVOzHIj2OhN9HAwvW+DBdmUAdcWlFxRl+KubM= +cloud.google.com/go/ids v1.2.0/go.mod h1:5WXvp4n25S0rA/mQWAg1YEEBBq6/s+7ml1RDCW1IrcY= +cloud.google.com/go/ids v1.3.0/go.mod h1:JBdTYwANikFKaDP6LtW5JAi4gubs57SVNQjemdt6xV4= +cloud.google.com/go/iot v1.3.0/go.mod h1:r7RGh2B61+B8oz0AGE+J72AhA0G7tdXItODWsaA2oLs= +cloud.google.com/go/iot v1.4.0/go.mod h1:dIDxPOn0UvNDUMD8Ger7FIaTuvMkj+aGk94RPP0iV+g= +cloud.google.com/go/iot v1.5.0/go.mod h1:mpz5259PDl3XJthEmh9+ap0affn/MqNSP4My77Qql9o= +cloud.google.com/go/iot v1.6.0/go.mod h1:IqdAsmE2cTYYNO1Fvjfzo9po179rAtJeVGUvkLN3rLE= +cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA= +cloud.google.com/go/kms v1.5.0/go.mod h1:QJS2YY0eJGBg3mnDfuaCyLauWwBJiHRboYxJ++1xJNg= +cloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0= +cloud.google.com/go/kms v1.8.0/go.mod h1:4xFEhYFqvW+4VMELtZyxomGSYtSQKzM178ylFW4jMAg= +cloud.google.com/go/kms v1.9.0/go.mod h1:qb1tPTgfF9RQP8e1wq4cLFErVuTJv7UsSC915J8dh3w= +cloud.google.com/go/kms v1.10.0/go.mod h1:ng3KTUtQQU9bPX3+QGLsflZIHlkbn8amFAMY63m8d24= +cloud.google.com/go/kms v1.10.1/go.mod h1:rIWk/TryCkR59GMC3YtHtXeLzd634lBbKenvyySAyYI= +cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= +cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= +cloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE= +cloud.google.com/go/language v1.8.0/go.mod h1:qYPVHf7SPoNNiCL2Dr0FfEFNil1qi3pQEyygwpgVKB8= +cloud.google.com/go/language v1.9.0/go.mod h1:Ns15WooPM5Ad/5no/0n81yUetis74g3zrbeJBE+ptUY= +cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= +cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= +cloud.google.com/go/lifesciences v0.8.0/go.mod h1:lFxiEOMqII6XggGbOnKiyZ7IBwoIqA84ClvoezaA/bo= +cloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw= +cloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeNqVNkzY8M= +cloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE= +cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= +cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo= +cloud.google.com/go/managedidentities v1.3.0/go.mod h1:UzlW3cBOiPrzucO5qWkNkh0w33KFtBJU281hacNvsdE= +cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM= +cloud.google.com/go/managedidentities v1.5.0/go.mod h1:+dWcZ0JlUmpuxpIDfyP5pP5y0bLdRwOS4Lp7gMni/LA= +cloud.google.com/go/maps v0.1.0/go.mod h1:BQM97WGyfw9FWEmQMpZ5T6cpovXXSd1cGmFma94eubI= +cloud.google.com/go/maps v0.6.0/go.mod h1:o6DAMMfb+aINHz/p/jbcY+mYeXBoZoxTfdSQ8VAJaCw= +cloud.google.com/go/maps v0.7.0/go.mod h1:3GnvVl3cqeSvgMcpRlQidXsPYuDGQ8naBis7MVzpXsY= +cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= +cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= +cloud.google.com/go/mediatranslation v0.7.0/go.mod h1:LCnB/gZr90ONOIQLgSXagp8XUW1ODs2UmUMvcgMfI2I= +cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= +cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= +cloud.google.com/go/memcache v1.6.0/go.mod h1:XS5xB0eQZdHtTuTF9Hf8eJkKtR3pVRCcvJwtm68T3rA= +cloud.google.com/go/memcache v1.7.0/go.mod h1:ywMKfjWhNtkQTxrWxCkCFkoPjLHPW6A7WOTVI8xy3LY= +cloud.google.com/go/memcache v1.9.0/go.mod h1:8oEyzXCu+zo9RzlEaEjHl4KkgjlNDaXbCQeQWlzNFJM= +cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= +cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= +cloud.google.com/go/metastore v1.7.0/go.mod h1:s45D0B4IlsINu87/AsWiEVYbLaIMeUSoxlKKDqBGFS8= +cloud.google.com/go/metastore v1.8.0/go.mod h1:zHiMc4ZUpBiM7twCIFQmJ9JMEkDSyZS9U12uf7wHqSI= +cloud.google.com/go/metastore v1.10.0/go.mod h1:fPEnH3g4JJAk+gMRnrAnoqyv2lpUCqJPWOodSaf45Eo= +cloud.google.com/go/monitoring v1.7.0/go.mod h1:HpYse6kkGo//7p6sT0wsIC6IBDET0RhIsnmlA53dvEk= +cloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4= +cloud.google.com/go/monitoring v1.12.0/go.mod h1:yx8Jj2fZNEkL/GYZyTLS4ZtZEZN8WtDEiEqG4kLK50w= +cloud.google.com/go/monitoring v1.13.0/go.mod h1:k2yMBAB1H9JT/QETjNkgdCGD9bPF712XiLTVr+cBrpw= +cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= +cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= +cloud.google.com/go/networkconnectivity v1.6.0/go.mod h1:OJOoEXW+0LAxHh89nXd64uGG+FbQoeH8DtxCHVOMlaM= +cloud.google.com/go/networkconnectivity v1.7.0/go.mod h1:RMuSbkdbPwNMQjB5HBWD5MpTBnNm39iAVpC3TmsExt8= +cloud.google.com/go/networkconnectivity v1.10.0/go.mod h1:UP4O4sWXJG13AqrTdQCD9TnLGEbtNRqjuaaA7bNjF5E= +cloud.google.com/go/networkconnectivity v1.11.0/go.mod h1:iWmDD4QF16VCDLXUqvyspJjIEtBR/4zq5hwnY2X3scM= +cloud.google.com/go/networkmanagement v1.4.0/go.mod h1:Q9mdLLRn60AsOrPc8rs8iNV6OHXaGcDdsIQe1ohekq8= +cloud.google.com/go/networkmanagement v1.5.0/go.mod h1:ZnOeZ/evzUdUsnvRt792H0uYEnHQEMaz+REhhzJRcf4= +cloud.google.com/go/networkmanagement v1.6.0/go.mod h1:5pKPqyXjB/sgtvB5xqOemumoQNB7y95Q7S+4rjSOPYY= +cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= +cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= +cloud.google.com/go/networksecurity v0.7.0/go.mod h1:mAnzoxx/8TBSyXEeESMy9OOYwo1v+gZ5eMRnsT5bC8k= +cloud.google.com/go/networksecurity v0.8.0/go.mod h1:B78DkqsxFG5zRSVuwYFRZ9Xz8IcQ5iECsNrPn74hKHU= +cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= +cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= +cloud.google.com/go/notebooks v1.4.0/go.mod h1:4QPMngcwmgb6uw7Po99B2xv5ufVoIQ7nOGDyL4P8AgA= +cloud.google.com/go/notebooks v1.5.0/go.mod h1:q8mwhnP9aR8Hpfnrc5iN5IBhrXUy8S2vuYs+kBJ/gu0= +cloud.google.com/go/notebooks v1.7.0/go.mod h1:PVlaDGfJgj1fl1S3dUwhFMXFgfYGhYQt2164xOMONmE= +cloud.google.com/go/notebooks v1.8.0/go.mod h1:Lq6dYKOYOWUCTvw5t2q1gp1lAp0zxAxRycayS0iJcqQ= +cloud.google.com/go/optimization v1.1.0/go.mod h1:5po+wfvX5AQlPznyVEZjGJTMr4+CAkJf2XSTQOOl9l4= +cloud.google.com/go/optimization v1.2.0/go.mod h1:Lr7SOHdRDENsh+WXVmQhQTrzdu9ybg0NecjHidBq6xs= +cloud.google.com/go/optimization v1.3.1/go.mod h1:IvUSefKiwd1a5p0RgHDbWCIbDFgKuEdB+fPPuP0IDLI= +cloud.google.com/go/orchestration v1.3.0/go.mod h1:Sj5tq/JpWiB//X/q3Ngwdl5K7B7Y0KZ7bfv0wL6fqVA= +cloud.google.com/go/orchestration v1.4.0/go.mod h1:6W5NLFWs2TlniBphAViZEVhrXRSMgUGDfW7vrWKvsBk= +cloud.google.com/go/orchestration v1.6.0/go.mod h1:M62Bevp7pkxStDfFfTuCOaXgaaqRAga1yKyoMtEoWPQ= +cloud.google.com/go/orgpolicy v1.4.0/go.mod h1:xrSLIV4RePWmP9P3tBl8S93lTmlAxjm06NSm2UTmKvE= +cloud.google.com/go/orgpolicy v1.5.0/go.mod h1:hZEc5q3wzwXJaKrsx5+Ewg0u1LxJ51nNFlext7Tanwc= +cloud.google.com/go/orgpolicy v1.10.0/go.mod h1:w1fo8b7rRqlXlIJbVhOMPrwVljyuW5mqssvBtU18ONc= +cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= +cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= +cloud.google.com/go/osconfig v1.9.0/go.mod h1:Yx+IeIZJ3bdWmzbQU4fxNl8xsZ4amB+dygAwFPlvnNo= +cloud.google.com/go/osconfig v1.10.0/go.mod h1:uMhCzqC5I8zfD9zDEAfvgVhDS8oIjySWh+l4WK6GnWw= +cloud.google.com/go/osconfig v1.11.0/go.mod h1:aDICxrur2ogRd9zY5ytBLV89KEgT2MKB2L/n6x1ooPw= +cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= +cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= +cloud.google.com/go/oslogin v1.6.0/go.mod h1:zOJ1O3+dTU8WPlGEkFSh7qeHPPSoxrcMbbK1Nm2iX70= +cloud.google.com/go/oslogin v1.7.0/go.mod h1:e04SN0xO1UNJ1M5GP0vzVBFicIe4O53FOfcixIqTyXo= +cloud.google.com/go/oslogin v1.9.0/go.mod h1:HNavntnH8nzrn8JCTT5fj18FuJLFJc4NaZJtBnQtKFs= +cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= +cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= +cloud.google.com/go/phishingprotection v0.7.0/go.mod h1:8qJI4QKHoda/sb/7/YmMQ2omRLSLYSu9bU0EKCNI+Lk= +cloud.google.com/go/policytroubleshooter v1.3.0/go.mod h1:qy0+VwANja+kKrjlQuOzmlvscn4RNsAc0e15GGqfMxg= +cloud.google.com/go/policytroubleshooter v1.4.0/go.mod h1:DZT4BcRw3QoO8ota9xw/LKtPa8lKeCByYeKTIf/vxdE= +cloud.google.com/go/policytroubleshooter v1.5.0/go.mod h1:Rz1WfV+1oIpPdN2VvvuboLVRsB1Hclg3CKQ53j9l8vw= +cloud.google.com/go/policytroubleshooter v1.6.0/go.mod h1:zYqaPTsmfvpjm5ULxAyD/lINQxJ0DDsnWOP/GZ7xzBc= +cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= +cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= +cloud.google.com/go/privatecatalog v0.7.0/go.mod h1:2s5ssIFO69F5csTXcwBP7NPFTZvps26xGzvQ2PQaBYg= +cloud.google.com/go/privatecatalog v0.8.0/go.mod h1:nQ6pfaegeDAq/Q5lrfCQzQLhubPiZhSaNhIgfJlnIXs= +cloud.google.com/go/pubsub v1.26.0/go.mod h1:QgBH3U/jdJy/ftjPhTkyXNj543Tin1pRYcdcPRnFIRI= +cloud.google.com/go/pubsub v1.27.1/go.mod h1:hQN39ymbV9geqBnfQq6Xf63yNhUAhv9CZhzp5O6qsW0= +cloud.google.com/go/pubsub v1.28.0/go.mod h1:vuXFpwaVoIPQMGXqRyUQigu/AX1S3IWugR9xznmcXX8= +cloud.google.com/go/pubsub v1.30.0/go.mod h1:qWi1OPS0B+b5L+Sg6Gmc9zD1Y+HaM0MdUr7LsupY1P4= +cloud.google.com/go/pubsublite v1.5.0/go.mod h1:xapqNQ1CuLfGi23Yda/9l4bBCKz/wC3KIJ5gKcxveZg= +cloud.google.com/go/pubsublite v1.6.0/go.mod h1:1eFCS0U11xlOuMFV/0iBqw3zP12kddMeCbj/F3FSj9k= +cloud.google.com/go/pubsublite v1.7.0/go.mod h1:8hVMwRXfDfvGm3fahVbtDbiLePT3gpoiJYJY+vxWxVM= +cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= +cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= +cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= +cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= +cloud.google.com/go/recaptchaenterprise/v2 v2.4.0/go.mod h1:Am3LHfOuBstrLrNCBrlI5sbwx9LBg3te2N6hGvHn2mE= +cloud.google.com/go/recaptchaenterprise/v2 v2.5.0/go.mod h1:O8LzcHXN3rz0j+LBC91jrwI3R+1ZSZEWrfL7XHgNo9U= +cloud.google.com/go/recaptchaenterprise/v2 v2.6.0/go.mod h1:RPauz9jeLtB3JVzg6nCbe12qNoaa8pXc4d/YukAmcnA= +cloud.google.com/go/recaptchaenterprise/v2 v2.7.0/go.mod h1:19wVj/fs5RtYtynAPJdDTb69oW0vNHYDBTbB4NvMD9c= +cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= +cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= +cloud.google.com/go/recommendationengine v0.7.0/go.mod h1:1reUcE3GIu6MeBz/h5xZJqNLuuVjNg1lmWMPyjatzac= +cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= +cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= +cloud.google.com/go/recommender v1.7.0/go.mod h1:XLHs/W+T8olwlGOgfQenXBTbIseGclClff6lhFVe9Bs= +cloud.google.com/go/recommender v1.8.0/go.mod h1:PkjXrTT05BFKwxaUxQmtIlrtj0kph108r02ZZQ5FE70= +cloud.google.com/go/recommender v1.9.0/go.mod h1:PnSsnZY7q+VL1uax2JWkt/UegHssxjUVVCrX52CuEmQ= +cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= +cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= +cloud.google.com/go/redis v1.9.0/go.mod h1:HMYQuajvb2D0LvMgZmLDZW8V5aOC/WxstZHiy4g8OiA= +cloud.google.com/go/redis v1.10.0/go.mod h1:ThJf3mMBQtW18JzGgh41/Wld6vnDDc/F/F35UolRZPM= +cloud.google.com/go/redis v1.11.0/go.mod h1:/X6eicana+BWcUda5PpwZC48o37SiFVTFSs0fWAJ7uQ= +cloud.google.com/go/resourcemanager v1.3.0/go.mod h1:bAtrTjZQFJkiWTPDb1WBjzvc6/kifjj4QBYuKCCoqKA= +cloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7LIXwrShilPh3P1tR0= +cloud.google.com/go/resourcemanager v1.5.0/go.mod h1:eQoXNAiAvCf5PXxWxXjhKQoTMaUSNrEfg+6qdf/wots= +cloud.google.com/go/resourcemanager v1.6.0/go.mod h1:YcpXGRs8fDzcUl1Xw8uOVmI8JEadvhRIkoXXUNVYcVo= +cloud.google.com/go/resourcemanager v1.7.0/go.mod h1:HlD3m6+bwhzj9XCouqmeiGuni95NTrExfhoSrkC/3EI= +cloud.google.com/go/resourcesettings v1.3.0/go.mod h1:lzew8VfESA5DQ8gdlHwMrqZs1S9V87v3oCnKCWoOuQU= +cloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg= +cloud.google.com/go/resourcesettings v1.5.0/go.mod h1:+xJF7QSG6undsQDfsCJyqWXyBwUoJLhetkRMDRnIoXA= +cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= +cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= +cloud.google.com/go/retail v1.10.0/go.mod h1:2gDk9HsL4HMS4oZwz6daui2/jmKvqShXKQuB2RZ+cCc= +cloud.google.com/go/retail v1.11.0/go.mod h1:MBLk1NaWPmh6iVFSz9MeKG/Psyd7TAgm6y/9L2B4x9Y= +cloud.google.com/go/retail v1.12.0/go.mod h1:UMkelN/0Z8XvKymXFbD4EhFJlYKRx1FGhQkVPU5kF14= +cloud.google.com/go/run v0.2.0/go.mod h1:CNtKsTA1sDcnqqIFR3Pb5Tq0usWxJJvsWOCPldRU3Do= +cloud.google.com/go/run v0.3.0/go.mod h1:TuyY1+taHxTjrD0ZFk2iAR+xyOXEA0ztb7U3UNA0zBo= +cloud.google.com/go/run v0.8.0/go.mod h1:VniEnuBwqjigv0A7ONfQUaEItaiCRVujlMqerPPiktM= +cloud.google.com/go/run v0.9.0/go.mod h1:Wwu+/vvg8Y+JUApMwEDfVfhetv30hCG4ZwDR/IXl2Qg= +cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= +cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= +cloud.google.com/go/scheduler v1.6.0/go.mod h1:SgeKVM7MIwPn3BqtcBntpLyrIJftQISRrYB5ZtT+KOk= +cloud.google.com/go/scheduler v1.7.0/go.mod h1:jyCiBqWW956uBjjPMMuX09n3x37mtyPJegEWKxRsn44= +cloud.google.com/go/scheduler v1.8.0/go.mod h1:TCET+Y5Gp1YgHT8py4nlg2Sew8nUHMqcpousDgXJVQc= +cloud.google.com/go/scheduler v1.9.0/go.mod h1:yexg5t+KSmqu+njTIh3b7oYPheFtBWGcbVUYF1GGMIc= +cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= +cloud.google.com/go/secretmanager v1.8.0/go.mod h1:hnVgi/bN5MYHd3Gt0SPuTPPp5ENina1/LxM+2W9U9J4= +cloud.google.com/go/secretmanager v1.9.0/go.mod h1:b71qH2l1yHmWQHt9LC80akm86mX8AL6X1MA01dW8ht4= +cloud.google.com/go/secretmanager v1.10.0/go.mod h1:MfnrdvKMPNra9aZtQFvBcvRU54hbPD8/HayQdlUgJpU= +cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= +cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= +cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= +cloud.google.com/go/security v1.9.0/go.mod h1:6Ta1bO8LXI89nZnmnsZGp9lVoVWXqsVbIq/t9dzI+2Q= +cloud.google.com/go/security v1.10.0/go.mod h1:QtOMZByJVlibUT2h9afNDWRZ1G96gVywH8T5GUSb9IA= +cloud.google.com/go/security v1.12.0/go.mod h1:rV6EhrpbNHrrxqlvW0BWAIawFWq3X90SduMJdFwtLB8= +cloud.google.com/go/security v1.13.0/go.mod h1:Q1Nvxl1PAgmeW0y3HTt54JYIvUdtcpYKVfIB8AOMZ+0= +cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= +cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= +cloud.google.com/go/securitycenter v1.15.0/go.mod h1:PeKJ0t8MoFmmXLXWm41JidyzI3PJjd8sXWaVqg43WWk= +cloud.google.com/go/securitycenter v1.16.0/go.mod h1:Q9GMaLQFUD+5ZTabrbujNWLtSLZIZF7SAR0wWECrjdk= +cloud.google.com/go/securitycenter v1.18.1/go.mod h1:0/25gAzCM/9OL9vVx4ChPeM/+DlfGQJDwBy/UC8AKK0= +cloud.google.com/go/securitycenter v1.19.0/go.mod h1:LVLmSg8ZkkyaNy4u7HCIshAngSQ8EcIRREP3xBnyfag= +cloud.google.com/go/servicecontrol v1.4.0/go.mod h1:o0hUSJ1TXJAmi/7fLJAedOovnujSEvjKCAFNXPQ1RaU= +cloud.google.com/go/servicecontrol v1.5.0/go.mod h1:qM0CnXHhyqKVuiZnGKrIurvVImCs8gmqWsDoqe9sU1s= +cloud.google.com/go/servicecontrol v1.10.0/go.mod h1:pQvyvSRh7YzUF2efw7H87V92mxU8FnFDawMClGCNuAA= +cloud.google.com/go/servicecontrol v1.11.0/go.mod h1:kFmTzYzTUIuZs0ycVqRHNaNhgR+UMUpw9n02l/pY+mc= +cloud.google.com/go/servicecontrol v1.11.1/go.mod h1:aSnNNlwEFBY+PWGQ2DoM0JJ/QUXqV5/ZD9DOLB7SnUk= +cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs= +cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= +cloud.google.com/go/servicedirectory v1.6.0/go.mod h1:pUlbnWsLH9c13yGkxCmfumWEPjsRs1RlmJ4pqiNjVL4= +cloud.google.com/go/servicedirectory v1.7.0/go.mod h1:5p/U5oyvgYGYejufvxhgwjL8UVXjkuw7q5XcG10wx1U= +cloud.google.com/go/servicedirectory v1.8.0/go.mod h1:srXodfhY1GFIPvltunswqXpVxFPpZjf8nkKQT7XcXaY= +cloud.google.com/go/servicedirectory v1.9.0/go.mod h1:29je5JjiygNYlmsGz8k6o+OZ8vd4f//bQLtvzkPPT/s= +cloud.google.com/go/servicemanagement v1.4.0/go.mod h1:d8t8MDbezI7Z2R1O/wu8oTggo3BI2GKYbdG4y/SJTco= +cloud.google.com/go/servicemanagement v1.5.0/go.mod h1:XGaCRe57kfqu4+lRxaFEAuqmjzF0r+gWHjWqKqBvKFo= +cloud.google.com/go/servicemanagement v1.6.0/go.mod h1:aWns7EeeCOtGEX4OvZUWCCJONRZeFKiptqKf1D0l/Jc= +cloud.google.com/go/servicemanagement v1.8.0/go.mod h1:MSS2TDlIEQD/fzsSGfCdJItQveu9NXnUniTrq/L8LK4= +cloud.google.com/go/serviceusage v1.3.0/go.mod h1:Hya1cozXM4SeSKTAgGXgj97GlqUvF5JaoXacR1JTP/E= +cloud.google.com/go/serviceusage v1.4.0/go.mod h1:SB4yxXSaYVuUBYUml6qklyONXNLt83U0Rb+CXyhjEeU= +cloud.google.com/go/serviceusage v1.5.0/go.mod h1:w8U1JvqUqwJNPEOTQjrMHkw3IaIFLoLsPLvsE3xueec= +cloud.google.com/go/serviceusage v1.6.0/go.mod h1:R5wwQcbOWsyuOfbP9tGdAnCAc6B9DRwPG1xtWMDeuPA= +cloud.google.com/go/shell v1.3.0/go.mod h1:VZ9HmRjZBsjLGXusm7K5Q5lzzByZmJHf1d0IWHEN5X4= +cloud.google.com/go/shell v1.4.0/go.mod h1:HDxPzZf3GkDdhExzD/gs8Grqk+dmYcEjGShZgYa9URw= +cloud.google.com/go/shell v1.6.0/go.mod h1:oHO8QACS90luWgxP3N9iZVuEiSF84zNyLytb+qE2f9A= +cloud.google.com/go/spanner v1.41.0/go.mod h1:MLYDBJR/dY4Wt7ZaMIQ7rXOTLjYrmxLE/5ve9vFfWos= +cloud.google.com/go/spanner v1.44.0/go.mod h1:G8XIgYdOK+Fbcpbs7p2fiprDw4CaZX63whnSMLVBxjk= +cloud.google.com/go/spanner v1.45.0/go.mod h1:FIws5LowYz8YAE1J8fOS7DJup8ff7xJeetWEo5REA2M= +cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= +cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= +cloud.google.com/go/speech v1.8.0/go.mod h1:9bYIl1/tjsAnMgKGHKmBZzXKEkGgtU+MpdDPTE9f7y0= +cloud.google.com/go/speech v1.9.0/go.mod h1:xQ0jTcmnRFFM2RfX/U+rk6FQNUF6DQlydUSyoooSpco= +cloud.google.com/go/speech v1.14.1/go.mod h1:gEosVRPJ9waG7zqqnsHpYTOoAS4KouMRLDFMekpJ0J0= +cloud.google.com/go/speech v1.15.0/go.mod h1:y6oH7GhqCaZANH7+Oe0BhgIogsNInLlz542tg3VqeYI= +cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= +cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= +cloud.google.com/go/storage v1.28.1/go.mod h1:Qnisd4CqDdo6BGs2AD5LLnEsmSQ80wQ5ogcBBKhU86Y= +cloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4= +cloud.google.com/go/storagetransfer v1.5.0/go.mod h1:dxNzUopWy7RQevYFHewchb29POFv3/AaBgnhqzqiK0w= +cloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I= +cloud.google.com/go/storagetransfer v1.7.0/go.mod h1:8Giuj1QNb1kfLAiWM1bN6dHzfdlDAVC9rv9abHot2W4= +cloud.google.com/go/storagetransfer v1.8.0/go.mod h1:JpegsHHU1eXg7lMHkvf+KE5XDJ7EQu0GwNJbbVGanEw= +cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= +cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= +cloud.google.com/go/talent v1.3.0/go.mod h1:CmcxwJ/PKfRgd1pBjQgU6W3YBwiewmUzQYH5HHmSCmM= +cloud.google.com/go/talent v1.4.0/go.mod h1:ezFtAgVuRf8jRsvyE6EwmbTK5LKciD4KVnHuDEFmOOA= +cloud.google.com/go/talent v1.5.0/go.mod h1:G+ODMj9bsasAEJkQSzO2uHQWXHHXUomArjWQQYkqK6c= +cloud.google.com/go/texttospeech v1.4.0/go.mod h1:FX8HQHA6sEpJ7rCMSfXuzBcysDAuWusNNNvN9FELDd8= +cloud.google.com/go/texttospeech v1.5.0/go.mod h1:oKPLhR4n4ZdQqWKURdwxMy0uiTS1xU161C8W57Wkea4= +cloud.google.com/go/texttospeech v1.6.0/go.mod h1:YmwmFT8pj1aBblQOI3TfKmwibnsfvhIBzPXcW4EBovc= +cloud.google.com/go/tpu v1.3.0/go.mod h1:aJIManG0o20tfDQlRIej44FcwGGl/cD0oiRyMKG19IQ= +cloud.google.com/go/tpu v1.4.0/go.mod h1:mjZaX8p0VBgllCzF6wcU2ovUXN9TONFLd7iz227X2Xg= +cloud.google.com/go/tpu v1.5.0/go.mod h1:8zVo1rYDFuW2l4yZVY0R0fb/v44xLh3llq7RuV61fPM= +cloud.google.com/go/trace v1.3.0/go.mod h1:FFUE83d9Ca57C+K8rDl/Ih8LwOzWIV1krKgxg6N0G28= +cloud.google.com/go/trace v1.4.0/go.mod h1:UG0v8UBqzusp+z63o7FK74SdFE+AXpCLdFb1rshXG+Y= +cloud.google.com/go/trace v1.8.0/go.mod h1:zH7vcsbAhklH8hWFig58HvxcxyQbaIqMarMg9hn5ECA= +cloud.google.com/go/trace v1.9.0/go.mod h1:lOQqpE5IaWY0Ixg7/r2SjixMuc6lfTFeO4QGM4dQWOk= +cloud.google.com/go/translate v1.3.0/go.mod h1:gzMUwRjvOqj5i69y/LYLd8RrNQk+hOmIXTi9+nb3Djs= +cloud.google.com/go/translate v1.4.0/go.mod h1:06Dn/ppvLD6WvA5Rhdp029IX2Mi3Mn7fpMRLPvXT5Wg= +cloud.google.com/go/translate v1.5.0/go.mod h1:29YDSYveqqpA1CQFD7NQuP49xymq17RXNaUDdc0mNu0= +cloud.google.com/go/translate v1.6.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= +cloud.google.com/go/translate v1.7.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= +cloud.google.com/go/video v1.8.0/go.mod h1:sTzKFc0bUSByE8Yoh8X0mn8bMymItVGPfTuUBUyRgxk= +cloud.google.com/go/video v1.9.0/go.mod h1:0RhNKFRF5v92f8dQt0yhaHrEuH95m068JYOvLZYnJSw= +cloud.google.com/go/video v1.12.0/go.mod h1:MLQew95eTuaNDEGriQdcYn0dTwf9oWiA4uYebxM5kdg= +cloud.google.com/go/video v1.13.0/go.mod h1:ulzkYlYgCp15N2AokzKjy7MQ9ejuynOJdf1tR5lGthk= +cloud.google.com/go/video v1.14.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= +cloud.google.com/go/video v1.15.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= +cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= +cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= +cloud.google.com/go/videointelligence v1.8.0/go.mod h1:dIcCn4gVDdS7yte/w+koiXn5dWVplOZkE+xwG9FgK+M= +cloud.google.com/go/videointelligence v1.9.0/go.mod h1:29lVRMPDYHikk3v8EdPSaL8Ku+eMzDljjuvRs105XoU= +cloud.google.com/go/videointelligence v1.10.0/go.mod h1:LHZngX1liVtUhZvi2uNS0VQuOzNi2TkY1OakiuoUOjU= +cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= +cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= +cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= +cloud.google.com/go/vision/v2 v2.4.0/go.mod h1:VtI579ll9RpVTrdKdkMzckdnwMyX2JILb+MhPqRbPsY= +cloud.google.com/go/vision/v2 v2.5.0/go.mod h1:MmaezXOOE+IWa+cS7OhRRLK2cNv1ZL98zhqFFZaaH2E= +cloud.google.com/go/vision/v2 v2.6.0/go.mod h1:158Hes0MvOS9Z/bDMSFpjwsUrZ5fPrdwuyyvKSGAGMY= +cloud.google.com/go/vision/v2 v2.7.0/go.mod h1:H89VysHy21avemp6xcf9b9JvZHVehWbET0uT/bcuY/0= +cloud.google.com/go/vmmigration v1.2.0/go.mod h1:IRf0o7myyWFSmVR1ItrBSFLFD/rJkfDCUTO4vLlJvsE= +cloud.google.com/go/vmmigration v1.3.0/go.mod h1:oGJ6ZgGPQOFdjHuocGcLqX4lc98YQ7Ygq8YQwHh9A7g= +cloud.google.com/go/vmmigration v1.5.0/go.mod h1:E4YQ8q7/4W9gobHjQg4JJSgXXSgY21nA5r8swQV+Xxc= +cloud.google.com/go/vmmigration v1.6.0/go.mod h1:bopQ/g4z+8qXzichC7GW1w2MjbErL54rk3/C843CjfY= +cloud.google.com/go/vmwareengine v0.1.0/go.mod h1:RsdNEf/8UDvKllXhMz5J40XxDrNJNN4sagiox+OI208= +cloud.google.com/go/vmwareengine v0.2.2/go.mod h1:sKdctNJxb3KLZkE/6Oui94iw/xs9PRNC2wnNLXsHvH8= +cloud.google.com/go/vmwareengine v0.3.0/go.mod h1:wvoyMvNWdIzxMYSpH/R7y2h5h3WFkx6d+1TIsP39WGY= +cloud.google.com/go/vpcaccess v1.4.0/go.mod h1:aQHVbTWDYUR1EbTApSVvMq1EnT57ppDmQzZ3imqIk4w= +cloud.google.com/go/vpcaccess v1.5.0/go.mod h1:drmg4HLk9NkZpGfCmZ3Tz0Bwnm2+DKqViEpeEpOq0m8= +cloud.google.com/go/vpcaccess v1.6.0/go.mod h1:wX2ILaNhe7TlVa4vC5xce1bCnqE3AeH27RV31lnmZes= +cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= +cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= +cloud.google.com/go/webrisk v1.6.0/go.mod h1:65sW9V9rOosnc9ZY7A7jsy1zoHS5W9IAXv6dGqhMQMc= +cloud.google.com/go/webrisk v1.7.0/go.mod h1:mVMHgEYH0r337nmt1JyLthzMr6YxwN1aAIEc2fTcq7A= +cloud.google.com/go/webrisk v1.8.0/go.mod h1:oJPDuamzHXgUc+b8SiHRcVInZQuybnvEW72PqTc7sSg= +cloud.google.com/go/websecurityscanner v1.3.0/go.mod h1:uImdKm2wyeXQevQJXeh8Uun/Ym1VqworNDlBXQevGMo= +cloud.google.com/go/websecurityscanner v1.4.0/go.mod h1:ebit/Fp0a+FWu5j4JOmJEV8S8CzdTkAS77oDsiSqYWQ= +cloud.google.com/go/websecurityscanner v1.5.0/go.mod h1:Y6xdCPy81yi0SQnDY1xdNTNpfY1oAgXUlcfN3B3eSng= +cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= +cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= +cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M= +cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= +cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw= contrib.go.opencensus.io/exporter/prometheus v0.4.2 h1:sqfsYl5GIY/L570iT+l93ehxaWJs2/OwXtiWwew3oAg= contrib.go.opencensus.io/exporter/prometheus v0.4.2/go.mod h1:dvEHbiKmgvbr5pjaF9fpw1KeYcjrnC1J8B+JKjsZyRQ= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= +git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= @@ -46,18 +556,28 @@ github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZ github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= +github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= +github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= +github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0= +github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI= +github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= @@ -79,19 +599,30 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= +github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= @@ -117,8 +648,18 @@ github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= +github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34= +github.com/envoyproxy/go-control-plane v0.11.0/go.mod h1:VnHyVMpzcLvCFt9yUz1UnCwHLhwx1WguiVDV7pTG/tI= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= +github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= +github.com/envoyproxy/protoc-gen-validate v0.10.0/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= github.com/envoyproxy/protoc-gen-validate v0.10.1 h1:c0g45+xCJhdgFGw7a5QAfdS4byAbud7miNWJ1WwEVf8= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= @@ -128,21 +669,28 @@ github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= +github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= +github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= +github.com/go-fonts/liberation v0.2.0/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= +github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U= +github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpxhq9o2S/CELCSUxEWWAuoCUcVCQWv7G2OCk= github.com/go-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= @@ -172,32 +720,30 @@ github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= +github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -208,23 +754,23 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -238,30 +784,39 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/s2a-go v0.1.0/go.mod h1:OJpEgntRZo8ugHpF9hkoLJbS5dSI20XZeXJ9JVywLlM= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= +github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= +github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= +github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= +github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= +github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= +github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= +github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= +github.com/googleapis/gax-go/v2 v2.8.0/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= +github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= +github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= github.com/hashicorp/consul/api v1.13.0/go.mod h1:ZlVrynguJKcYr54zGaDbaL3fOvKC9m72FhPvA8T35KQ= github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -297,9 +852,9 @@ github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKe github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hjson/hjson-go/v4 v4.0.0/go.mod h1:KaYt3bTw3zhBjYqnXkYywcYctk0A2nxeEFTse3rH13E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= @@ -314,30 +869,39 @@ github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/ github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= +github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/knadh/koanf v1.5.0 h1:q2TSd/3Pyc/5yP9ldIrSdIz26MCcyNQzW0pEAugLPNs= github.com/knadh/koanf v1.5.0/go.mod h1:Hgyjp4y8v44hpZtPzs7JZfRAW5AhN7KfZcwv1RYggDs= github.com/knadh/koanf/v2 v2.0.1 h1:1dYGITt1I23x8cfx8ZnldtezdyaZtfAuRtIFOiRzK7g= github.com/knadh/koanf/v2 v2.0.1/go.mod h1:ZeiIlIDXTE7w1lMT6UVcNiRAS2/rCeLn/GdLNvY1Dus= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= +github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= +github.com/lyft/protoc-gen-star/v2 v2.0.1/go.mod h1:RcCdONR2ScXaYnQC5tUzxzlpA3WVYF7/opLeUgcQs/o= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= @@ -351,11 +915,15 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= +github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= +github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= @@ -416,11 +984,18 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY= +github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= +github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= @@ -439,6 +1014,7 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1: github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= @@ -459,12 +1035,16 @@ github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+Pymzi github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT1pX2CziuyQR0= github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= +github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rhnvrm/simples3 v0.6.1/go.mod h1:Y+3vYm2V7Y4VijFoJHHTrja6OgPrJ2cBti8dPGkC3sA= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE= github.com/rs/cors v1.9.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= +github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= @@ -472,7 +1052,11 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -494,19 +1078,18 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= +github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= @@ -570,6 +1153,9 @@ go.opentelemetry.io/otel/sdk/metric v0.39.0 h1:Kun8i1eYf48kHH83RucG93ffz0zGV1sh4 go.opentelemetry.io/otel/sdk/metric v0.39.0/go.mod h1:piDIRgjcK7u0HCL5pCA4e74qpK/jk3NiUoAHATVAmiI= go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= +go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= @@ -585,44 +1171,57 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE= +golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= +golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20210607152325-775e3b0c77b9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20220302094943-723b81ca9867/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +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.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -633,47 +1232,73 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 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-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +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.7.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.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= +golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= +golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= +golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -682,12 +1307,14 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -706,61 +1333,82 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +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.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +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.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 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= @@ -768,128 +1416,195 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8= golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= +gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0= +gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA= +gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= +gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY= +gonum.org/v1/plot v0.10.1/go.mod h1:VZW5OlhkL1mysU9vaqNHnsy86inf6Ot+jB3r+BczCEo= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= +google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= +google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= +google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= +google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= +google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= +google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g= +google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI= +google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.99.0/go.mod h1:1YOf74vkVndF7pG6hIHuINsM7eWwpVTAfNMNiL91A08= +google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= +google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo= +google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0= +google.golang.org/api v0.106.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= +google.golang.org/api v0.107.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= +google.golang.org/api v0.108.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= +google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI= +google.golang.org/api v0.111.0/go.mod h1:qtFHvU9mhgTJegR31csQ+rwxyUTHOKFqCKWp1J0fdw0= +google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg= +google.golang.org/api v0.118.0/go.mod h1:76TtD3vkgmZ66zZzp72bUUklpmQmKlhh6sYtIjYK+5E= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc h1:8DyZCyvI8mE1IdLy/60bS+52xfymkE72wv1asokgtao= -google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64= -google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc h1:kVKPf/IiYSBWEWtkIn6wZXwWGCnLKcC8oWfZvXjsGnM= -google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220329172620-7be39ac1afc7/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= +google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= +google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw= +google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U= +google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221024153911-1573dae28c9c/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo= +google.golang.org/genproto v0.0.0-20221109142239-94d6d90a7d66/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221117204609-8f9c96812029/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221201204527-e3fa12d562f3/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE= +google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230112194545-e10362b5ecf9/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230113154510-dbe35b8444a5/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230123190316-2c411cf9d197/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230127162408-596548ed4efa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA= +google.golang.org/genproto v0.0.0-20230222225845-10f96fb3dbec/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= +google.golang.org/genproto v0.0.0-20230223222841-637eb2293923/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= +google.golang.org/genproto v0.0.0-20230303212802-e74f57abe488/go.mod h1:TvhZT5f700eVlTNwND1xoEZQeWTB2RY/65kplwl/bFA= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= +google.golang.org/genproto v0.0.0-20230320184635-7606e756e683/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= +google.golang.org/genproto v0.0.0-20230323212658-478b75c54725/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230330154414-c0448cd141ea/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230403163135-c38d8f061ccd/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc h1:XSJ8Vk1SWuNr8S18z1NZSziL0CPIXLCCMDOEFtHBOFc= google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= @@ -899,18 +1614,36 @@ google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ij google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= +google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= +google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= +google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= +google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= google.golang.org/grpc v1.56.2 h1:fVRFRnXvU+x6C4IlHZewvJOVHoOv1TUuQyoRsYnB4bI= google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -923,8 +1656,11 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -957,12 +1693,9 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= k8s.io/api v0.21.1/go.mod h1:FstGROTmsSHBarKc8bylzXih8BLNYTiS3TZcsoEDg2s= k8s.io/api v0.27.3 h1:yR6oQXXnUEBWEWcvPWS0jQL575KoAboQPfJAuKNrw5Y= k8s.io/api v0.27.3/go.mod h1:C4BNvZnQOF7JA/0Xed2S+aUyJSfTGkGFxLXz9MnpIpg= @@ -986,9 +1719,41 @@ k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3 k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20230209194617-a36077c30491 h1:r0BAOLElQnnFhE/ApUsg3iHdVYYPBjNSSOMowRZxxsY= k8s.io/utils v0.0.0-20230209194617-a36077c30491/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= +lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= +modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= +modernc.org/cc/v3 v3.36.2/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= +modernc.org/cc/v3 v3.36.3/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= +modernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc= +modernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw= +modernc.org/ccgo/v3 v3.16.4/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= +modernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= +modernc.org/ccgo/v3 v3.16.8/go.mod h1:zNjwkizS+fIFDrDjIAgBSCLkWbJuHF+ar3QRn+Z9aws= +modernc.org/ccgo/v3 v3.16.9/go.mod h1:zNMzC9A9xeNUepy6KuZBbugn3c0Mc9TeiJO4lgvkJDo= +modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= +modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= +modernc.org/libc v0.0.0-20220428101251-2d5f3daf273b/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= +modernc.org/libc v1.16.0/go.mod h1:N4LD6DBE9cf+Dzf9buBlzVJndKr/iJHG97vGLHYnb5A= +modernc.org/libc v1.16.1/go.mod h1:JjJE0eu4yeK7tab2n4S1w8tlWd9MxXLRzheaRnAKymU= +modernc.org/libc v1.16.17/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU= +modernc.org/libc v1.16.19/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= +modernc.org/libc v1.17.0/go.mod h1:XsgLldpP4aWlPlsjqKRdHPqCxCjISdHfM/yeWC5GyW0= +modernc.org/libc v1.17.1/go.mod h1:FZ23b+8LjxZs7XtFMbSzL/EhPxNbfZbErxEHc7cbD9s= +modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= +modernc.org/memory v1.2.0/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= +modernc.org/memory v1.2.1/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= +modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/sqlite v1.18.1/go.mod h1:6ho+Gow7oX5V+OiOQ6Tr4xeqbx13UZ6t+Fw9IRUG4d4= +modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= +modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= +modernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw= +modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= diff --git a/receiver/k8sclusterreceiver/internal/collection/collector.go b/receiver/k8sclusterreceiver/internal/collection/collector.go index 41b50edc24b8..813238df606b 100644 --- a/receiver/k8sclusterreceiver/internal/collection/collector.go +++ b/receiver/k8sclusterreceiver/internal/collection/collector.go @@ -7,7 +7,6 @@ import ( "reflect" "time" - agentmetricspb "github.com/census-instrumentation/opencensus-proto/gen-go/agent/metrics/v1" quotav1 "github.com/openshift/api/quota/v1" "go.opentelemetry.io/collector/pdata/pmetric" "go.opentelemetry.io/collector/receiver" @@ -24,7 +23,6 @@ import ( "k8s.io/client-go/tools/cache" "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/experimentalmetricmetadata" - internaldata "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/opencensus" "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/clusterresourcequota" "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/cronjob" "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/k8sclusterreceiver/internal/demonset" @@ -176,11 +174,3 @@ func (dc *DataCollector) SyncMetadata(obj interface{}) map[experimentalmetricmet return km } - -func ocsToMetrics(ocs []*agentmetricspb.ExportMetricsServiceRequest) pmetric.Metrics { - md := pmetric.NewMetrics() - for _, ocm := range ocs { - internaldata.OCToMetrics(ocm.Node, ocm.Resource, ocm.Metrics).ResourceMetrics().MoveAndAppendTo(md.ResourceMetrics()) - } - return md -} diff --git a/receiver/k8sclusterreceiver/internal/collection/metricsstore_test.go b/receiver/k8sclusterreceiver/internal/collection/metricsstore_test.go index 055e26050672..9d969084db95 100644 --- a/receiver/k8sclusterreceiver/internal/collection/metricsstore_test.go +++ b/receiver/k8sclusterreceiver/internal/collection/metricsstore_test.go @@ -7,8 +7,6 @@ import ( "testing" "time" - agentmetricspb "github.com/census-instrumentation/opencensus-proto/gen-go/agent/metrics/v1" - resourcepb "github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1" "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/pdata/pmetric" corev1 "k8s.io/api/core/v1" @@ -23,33 +21,38 @@ func TestMetricsStoreOperations(t *testing.T) { updates := []struct { id types.UID - rm []*agentmetricspb.ExportMetricsServiceRequest + rm pmetric.Metrics }{ { id: types.UID("test-uid-1"), - rm: []*agentmetricspb.ExportMetricsServiceRequest{ - {Resource: &resourcepb.Resource{Labels: map[string]string{"k1": "v1"}}}, - {Resource: &resourcepb.Resource{Labels: map[string]string{"k2": "v2"}}}}, + rm: func() pmetric.Metrics { + m := pmetric.NewMetrics() + m.ResourceMetrics().AppendEmpty().Resource().Attributes().PutStr("k1", "v1") + m.ResourceMetrics().AppendEmpty().Resource().Attributes().PutStr("k2", "v2") + return m + }(), }, { id: types.UID("test-uid-2"), - rm: []*agentmetricspb.ExportMetricsServiceRequest{{Resource: &resourcepb.Resource{Labels: map[string]string{"k3": "v3"}}}}, + rm: func() pmetric.Metrics { + m := pmetric.NewMetrics() + m.ResourceMetrics().AppendEmpty().Resource().Attributes().PutStr("k3", "v3") + return m + }(), }, } // Update metric store with metrics for _, u := range updates { - require.NoError(t, ms.update( - &corev1.Pod{ObjectMeta: v1.ObjectMeta{UID: u.id}}, - ocsToMetrics(u.rm))) + require.NoError(t, ms.update(&corev1.Pod{ObjectMeta: v1.ObjectMeta{UID: u.id}}, u.rm)) } // Asset values form updates expectedMetricData := 0 for _, u := range updates { require.Contains(t, ms.metricsCache, u.id) - require.Equal(t, len(u.rm), ms.metricsCache[u.id].ResourceMetrics().Len()) - expectedMetricData += len(u.rm) + require.Equal(t, u.rm.ResourceMetrics().Len(), ms.metricsCache[u.id].ResourceMetrics().Len()) + expectedMetricData += u.rm.ResourceMetrics().Len() } require.Equal(t, expectedMetricData, ms.getMetricData(time.Now()).ResourceMetrics().Len()) @@ -67,7 +70,7 @@ func TestMetricsStoreOperations(t *testing.T) { UID: updates[1].id, }, })) - expectedMetricData -= len(updates[1].rm) + expectedMetricData -= updates[1].rm.ResourceMetrics().Len() require.Equal(t, len(updates)-1, len(ms.metricsCache)) require.Equal(t, expectedMetricData, ms.getMetricData(time.Now()).ResourceMetrics().Len()) } From ba90c67433b293eaa8adf45fbd509a90d864db9e Mon Sep 17 00:00:00 2001 From: Antoine Toulme Date: Tue, 25 Jul 2023 20:53:59 -0700 Subject: [PATCH 38/42] [chore] [cmd/githubgen] Add codeowner (#24555) Adds the codeowner for githubgen, updating the metadata.yaml and CODEOWNERS file simultaneously. --- .github/CODEOWNERS | 1 + .github/ISSUE_TEMPLATE/bug_report.yaml | 1 + .github/ISSUE_TEMPLATE/feature_request.yaml | 1 + .github/ISSUE_TEMPLATE/other.yaml | 1 + cmd/githubgen/metadata.yaml | 6 ++++++ 5 files changed, 10 insertions(+) create mode 100644 cmd/githubgen/metadata.yaml diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 10fb0e6ba7ab..e08bbb8b6eae 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -22,6 +22,7 @@ * @open-telemetry/collector-contrib-approvers cmd/configschema/ @open-telemetry/collector-contrib-approvers @mx-psi @dmitryax @pmcollins +cmd/githubgen/ @open-telemetry/collector-contrib-approvers @atoulme cmd/mdatagen/ @open-telemetry/collector-contrib-approvers @dmitryax cmd/opampsupervisor/ @open-telemetry/collector-contrib-approvers @evan-bradley @atoulme @tigrannajaryan cmd/otelcontribcol/ @open-telemetry/collector-contrib-approvers diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 16abddfa66df..d1db0a7c7065 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -19,6 +19,7 @@ body: # Do not manually edit it. # Start Collector components list - cmd/configschema + - cmd/githubgen - cmd/mdatagen - cmd/opampsupervisor - cmd/otelcontribcol diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml index cf1b929682e1..ae75253e8611 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yaml +++ b/.github/ISSUE_TEMPLATE/feature_request.yaml @@ -13,6 +13,7 @@ body: # Do not manually edit it. # Start Collector components list - cmd/configschema + - cmd/githubgen - cmd/mdatagen - cmd/opampsupervisor - cmd/otelcontribcol diff --git a/.github/ISSUE_TEMPLATE/other.yaml b/.github/ISSUE_TEMPLATE/other.yaml index 87e43369e987..c7d681ad06a2 100644 --- a/.github/ISSUE_TEMPLATE/other.yaml +++ b/.github/ISSUE_TEMPLATE/other.yaml @@ -13,6 +13,7 @@ body: # Do not manually edit it. # Start Collector components list - cmd/configschema + - cmd/githubgen - cmd/mdatagen - cmd/opampsupervisor - cmd/otelcontribcol diff --git a/cmd/githubgen/metadata.yaml b/cmd/githubgen/metadata.yaml new file mode 100644 index 000000000000..a0d01e83f024 --- /dev/null +++ b/cmd/githubgen/metadata.yaml @@ -0,0 +1,6 @@ +type: githubgen + +status: + class: cmd + codeowners: + active: [atoulme] \ No newline at end of file From 368c836f3eb4bf72fdcd9f6380d0a6aa48db9fa4 Mon Sep 17 00:00:00 2001 From: Ziqi Zhao Date: Wed, 26 Jul 2023 14:06:21 +0800 Subject: [PATCH 39/42] [chore] [processor/metricstransform] Enable exhaustive linter (#24559) related to #23266 Signed-off-by: Ziqi Zhao --- .../metrics_transform_processor_otlp.go | 4 ++++ .../metricstransformprocessor/operation_delete_label_value.go | 1 + 2 files changed, 5 insertions(+) diff --git a/processor/metricstransformprocessor/metrics_transform_processor_otlp.go b/processor/metricstransformprocessor/metrics_transform_processor_otlp.go index d27e862e22f7..cf93a5263f49 100644 --- a/processor/metricstransformprocessor/metrics_transform_processor_otlp.go +++ b/processor/metricstransformprocessor/metrics_transform_processor_otlp.go @@ -163,6 +163,7 @@ func extractMetricWithMatchingAttrs(metric pmetric.Metric, f internalFilter) pme newMetric.SetUnit(metric.Unit()) switch metric.Type() { + //exhaustive:enforce case pmetric.MetricTypeGauge: newMetric.SetEmptyGauge().DataPoints().EnsureCapacity(matchedDpsCount) for i := 0; i < metric.Gauge().DataPoints().Len(); i++ { @@ -443,6 +444,7 @@ func copyMetricDetails(from, to pmetric.Metric) { to.SetName(from.Name()) to.SetUnit(from.Unit()) to.SetDescription(from.Description()) + //exhaustive:enforce switch from.Type() { case pmetric.MetricTypeGauge: to.SetEmptyGauge() @@ -461,6 +463,7 @@ func copyMetricDetails(from, to pmetric.Metric) { // rangeDataPointAttributes calls f sequentially on attributes of every metric data point. // The iteration terminates if f returns false. func rangeDataPointAttributes(metric pmetric.Metric, f func(pcommon.Map) bool) { + //exhaustive:enforce switch metric.Type() { case pmetric.MetricTypeGauge: for i := 0; i < metric.Gauge().DataPoints().Len(); i++ { @@ -501,6 +504,7 @@ func rangeDataPointAttributes(metric pmetric.Metric, f func(pcommon.Map) bool) { } func countDataPoints(metric pmetric.Metric) int { + //exhaustive:enforce switch metric.Type() { case pmetric.MetricTypeGauge: return metric.Gauge().DataPoints().Len() diff --git a/processor/metricstransformprocessor/operation_delete_label_value.go b/processor/metricstransformprocessor/operation_delete_label_value.go index b6b68446d94b..c34ffa40c3ad 100644 --- a/processor/metricstransformprocessor/operation_delete_label_value.go +++ b/processor/metricstransformprocessor/operation_delete_label_value.go @@ -11,6 +11,7 @@ import ( // deleteLabelValueOp deletes a label value and all data associated with it func deleteLabelValueOp(metric pmetric.Metric, mtpOp internalOperation) { op := mtpOp.configOperation + //exhaustive:enforce switch metric.Type() { case pmetric.MetricTypeGauge: metric.Gauge().DataPoints().RemoveIf(func(dp pmetric.NumberDataPoint) bool { From f83c2e3e59a75004ab7bc9781451a23f40bb8568 Mon Sep 17 00:00:00 2001 From: Yang Song Date: Wed, 26 Jul 2023 04:18:11 -0400 Subject: [PATCH 40/42] [exporter/datadog] Add new configs to example yaml (#24553) **Description:** Add new configs `compute_stats_by_span_kind` and `peer_service_aggregation` to examples/collector.yaml. **Link to tracking Issue:** **Testing:** **Documentation:** --- exporter/datadogexporter/examples/collector.yaml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/exporter/datadogexporter/examples/collector.yaml b/exporter/datadogexporter/examples/collector.yaml index fcc3ca4effc4..0bf6d4248063 100644 --- a/exporter/datadogexporter/examples/collector.yaml +++ b/exporter/datadogexporter/examples/collector.yaml @@ -325,6 +325,21 @@ exporters: # # span_name_as_resource_name: true + ## @param compute_stats_by_span_kind - enables APM stats computation based on `span.kind` + ## If set to true, enables an additional stats computation check on spans to see they have an eligible `span.kind` (server, consumer, client, producer). + ## If enabled, a span with an eligible `span.kind` will have stats computed. If disabled, only top-level and measured spans will have stats computed. + ## NOTE: For stats computed from OTel traces, only top-level spans are considered when this option is off. + # + # compute_stats_by_span_kind: true + + ## @param peer_service_aggregation - enables `peer.service` aggregation on trace stats in Datadog exporter + ## If set to true, enables `peer.service` aggregation in the exporter. If disabled, aggregated trace stats will not include `peer.service` as a dimension. + ## For the best experience with `peer.service`, it is recommended to also enable `compute_stats_by_span_kind`. + ## If enabling both causes the datadog exporter to consume too many resources, try disabling `compute_stats_by_span_kind` first. + ## If the overhead remains high, it will be due to a high cardinality of `peer.service` values from the traces. You may need to check your instrumentation. + # + # peer_service_aggregation: true + ## @param host_metadata - custom object - optional ## Host metadata specific configuration. ## Host metadata is the information used for populating the infrastructure list, the host map and providing host tags functionality within the Datadog app. From 62c7b5363db1c0df545222d66fb931edc4a49263 Mon Sep 17 00:00:00 2001 From: Ruslan Kovalov Date: Wed, 26 Jul 2023 16:54:32 +0400 Subject: [PATCH 41/42] Remove @kovrus from code owners and approvers. (#24565) Hey everyone! I haven't been contributing to the project recently and won't be able to do it in the future, so I am removing myself from the components' code owners and approvers. Thank you all for your collaboration! --- .github/CODEOWNERS | 18 +++++++++--------- .github/auto_assign.yml | 1 - README.md | 2 +- connector/routingconnector/README.md | 2 +- connector/routingconnector/metadata.yaml | 2 +- connector/spanmetricsconnector/README.md | 2 +- connector/spanmetricsconnector/metadata.yaml | 2 +- exporter/lokiexporter/README.md | 2 +- exporter/lokiexporter/metadata.yaml | 2 +- extension/headerssetterextension/README.md | 2 +- extension/headerssetterextension/metadata.yaml | 2 +- pkg/translator/loki/metadata.yaml | 2 +- .../prometheusremotewrite/metadata.yaml | 2 +- processor/routingprocessor/README.md | 2 +- processor/routingprocessor/metadata.yaml | 2 +- .../awscloudwatchmetricsreceiver/README.md | 2 +- .../awscloudwatchmetricsreceiver/metadata.yaml | 2 +- receiver/lokireceiver/README.md | 2 +- receiver/lokireceiver/metadata.yaml | 2 +- 19 files changed, 26 insertions(+), 27 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index e08bbb8b6eae..07c256d58240 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -33,9 +33,9 @@ confmap/provider/s3provider/ @open-telemetry/collect connector/countconnector/ @open-telemetry/collector-contrib-approvers @djaglowski @jpkrohling connector/exceptionsconnector/ @open-telemetry/collector-contrib-approvers @jpkrohling -connector/routingconnector/ @open-telemetry/collector-contrib-approvers @jpkrohling @kovrus @mwear +connector/routingconnector/ @open-telemetry/collector-contrib-approvers @jpkrohling @mwear connector/servicegraphconnector/ @open-telemetry/collector-contrib-approvers @jpkrohling @mapno -connector/spanmetricsconnector/ @open-telemetry/collector-contrib-approvers @albertteoh @kovrus +connector/spanmetricsconnector/ @open-telemetry/collector-contrib-approvers @albertteoh examples/demo/ @open-telemetry/collector-contrib-approvers @open-telemetry/collector-approvers @@ -68,7 +68,7 @@ exporter/kafkaexporter/ @open-telemetry/collect exporter/loadbalancingexporter/ @open-telemetry/collector-contrib-approvers @jpkrohling exporter/logicmonitorexporter/ @open-telemetry/collector-contrib-approvers @bogdandrutu @khyatigandhi6 @avadhut123pisal exporter/logzioexporter/ @open-telemetry/collector-contrib-approvers @Doron-Bargo @yotamloe -exporter/lokiexporter/ @open-telemetry/collector-contrib-approvers @gramidt @gouthamve @jpkrohling @kovrus @mar4uk +exporter/lokiexporter/ @open-telemetry/collector-contrib-approvers @gramidt @gouthamve @jpkrohling @mar4uk exporter/mezmoexporter/ @open-telemetry/collector-contrib-approvers @dashpole @billmeyer @gjanco exporter/opencensusexporter/ @open-telemetry/collector-contrib-approvers @open-telemetry/collector-approvers exporter/opensearchexporter/ @open-telemetry/collector-contrib-approvers @Aneurysm9 @MitchellGale @MaxKsyunz @YANG-DB @@ -92,7 +92,7 @@ extension/awsproxy/ @open-telemetry/collect extension/basicauthextension/ @open-telemetry/collector-contrib-approvers @jpkrohling @svrakitin extension/bearertokenauthextension/ @open-telemetry/collector-contrib-approvers @jpkrohling @pavankrish123 @frzifus extension/encodingextension/ @open-telemetry/collector-contrib-approvers @MovieStoreGuy -extension/headerssetterextension/ @open-telemetry/collector-contrib-approvers @jpkrohling @kovrus +extension/headerssetterextension/ @open-telemetry/collector-contrib-approvers @jpkrohling extension/healthcheckextension/ @open-telemetry/collector-contrib-approvers @jpkrohling extension/httpforwarder/ @open-telemetry/collector-contrib-approvers @atoulme @rmfitzpatrick extension/jaegerremotesampling/ @open-telemetry/collector-contrib-approvers @jpkrohling @frzifus @@ -131,10 +131,10 @@ pkg/pdatautil/ @open-telemetry/collect pkg/resourcetotelemetry/ @open-telemetry/collector-contrib-approvers @mx-psi pkg/stanza/ @open-telemetry/collector-contrib-approvers @djaglowski pkg/translator/jaeger/ @open-telemetry/collector-contrib-approvers @open-telemetry/collector-approvers -pkg/translator/loki/ @open-telemetry/collector-contrib-approvers @gouthamve @jpkrohling @kovrus @mar4uk +pkg/translator/loki/ @open-telemetry/collector-contrib-approvers @gouthamve @jpkrohling @mar4uk pkg/translator/opencensus/ @open-telemetry/collector-contrib-approvers @open-telemetry/collector-approvers pkg/translator/prometheus/ @open-telemetry/collector-contrib-approvers @dashpole @bertysentry -pkg/translator/prometheusremotewrite/ @open-telemetry/collector-contrib-approvers @Aneurysm9 @kovrus +pkg/translator/prometheusremotewrite/ @open-telemetry/collector-contrib-approvers @Aneurysm9 pkg/translator/signalfx/ @open-telemetry/collector-contrib-approvers @dmitryax pkg/translator/zipkin/ @open-telemetry/collector-contrib-approvers @MovieStoreGuy @astencel-sumo @crobert-1 pkg/winperfcounters/ @open-telemetry/collector-contrib-approvers @dashpole @mrod1598 @binaryfissiongames @@ -158,7 +158,7 @@ processor/resourcedetectionprocessor/internal/azure/ @open-telemetry/collect processor/resourcedetectionprocessor/internal/heroku/ @open-telemetry/collector-contrib-approvers @atoulme processor/resourcedetectionprocessor/internal/openshift/ @open-telemetry/collector-contrib-approvers @frzifus processor/resourceprocessor/ @open-telemetry/collector-contrib-approvers @dmitryax -processor/routingprocessor/ @open-telemetry/collector-contrib-approvers @jpkrohling @kovrus +processor/routingprocessor/ @open-telemetry/collector-contrib-approvers @jpkrohling processor/schemaprocessor/ @open-telemetry/collector-contrib-approvers @MovieStoreGuy processor/servicegraphprocessor/ @open-telemetry/collector-contrib-approvers @jpkrohling @mapno processor/spanmetricsprocessor/ @open-telemetry/collector-contrib-approvers @albertteoh @@ -170,7 +170,7 @@ receiver/activedirectorydsreceiver/ @open-telemetry/collect receiver/aerospikereceiver/ @open-telemetry/collector-contrib-approvers @djaglowski @antonblock receiver/apachereceiver/ @open-telemetry/collector-contrib-approvers @djaglowski receiver/apachesparkreceiver/ @open-telemetry/collector-contrib-approvers @djaglowski @Caleb-Hurshman @mrsillydog -receiver/awscloudwatchmetricsreceiver/ @open-telemetry/collector-contrib-approvers @jpkrohling @kovrus +receiver/awscloudwatchmetricsreceiver/ @open-telemetry/collector-contrib-approvers @jpkrohling receiver/awscloudwatchreceiver/ @open-telemetry/collector-contrib-approvers @djaglowski @schmikei receiver/awscontainerinsightreceiver/ @open-telemetry/collector-contrib-approvers @Aneurysm9 @pxaws receiver/awsecscontainermetricsreceiver/ @open-telemetry/collector-contrib-approvers @Aneurysm9 @@ -211,7 +211,7 @@ receiver/k8sobjectsreceiver/ @open-telemetry/collect receiver/kafkametricsreceiver/ @open-telemetry/collector-contrib-approvers @dmitryax receiver/kafkareceiver/ @open-telemetry/collector-contrib-approvers @pavolloffay @MovieStoreGuy receiver/kubeletstatsreceiver/ @open-telemetry/collector-contrib-approvers @dmitryax -receiver/lokireceiver/ @open-telemetry/collector-contrib-approvers @mar4uk @kovrus @jpkrohling +receiver/lokireceiver/ @open-telemetry/collector-contrib-approvers @mar4uk @jpkrohling receiver/memcachedreceiver/ @open-telemetry/collector-contrib-approvers @djaglowski receiver/mongodbatlasreceiver/ @open-telemetry/collector-contrib-approvers @djaglowski @schmikei receiver/mongodbreceiver/ @open-telemetry/collector-contrib-approvers @djaglowski @schmikei diff --git a/.github/auto_assign.yml b/.github/auto_assign.yml index 4fbf22a1ee9e..79cf1af3d7e1 100644 --- a/.github/auto_assign.yml +++ b/.github/auto_assign.yml @@ -15,7 +15,6 @@ assigneeGroups: - atoulme - dashpole - fatsheep9146 - - kovrus # Maintainers - bogdandrutu - codeboten diff --git a/README.md b/README.md index cd97728f12d2..746b152cc954 100644 --- a/README.md +++ b/README.md @@ -94,13 +94,13 @@ Approvers ([@open-telemetry/collector-contrib-approvers](https://github.com/orgs - [Anthony Mirabella](https://github.com/Aneurysm9), AWS - [Antoine Toulme](https://github.com/atoulme), Splunk - [David Ashpole](https://github.com/dashpole), Google -- [Ruslan Kovalov](https://github.com/kovrus), Grafana Labs - [Yang Song](https://github.com/songy23), DataDog - [Ziqi Zhao](https://github.com/fatsheep9146), Alibaba Emeritus Approvers: - [Przemek Maciolek](https://github.com/pmm-sumo) +- [Ruslan Kovalov](https://github.com/kovrus) Maintainers ([@open-telemetry/collector-contrib-maintainer](https://github.com/orgs/open-telemetry/teams/collector-contrib-maintainer)): diff --git a/connector/routingconnector/README.md b/connector/routingconnector/README.md index 79c55a3549f3..d3a55a258378 100644 --- a/connector/routingconnector/README.md +++ b/connector/routingconnector/README.md @@ -5,7 +5,7 @@ | ------------- |-----------| | Distributions | [contrib] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aconnector%2Frouting%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aconnector%2Frouting%20&label=closed&color=blue&logo=opentelemetry) | -| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jpkrohling](https://www.github.com/jpkrohling), [@kovrus](https://www.github.com/kovrus), [@mwear](https://www.github.com/mwear) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jpkrohling](https://www.github.com/jpkrohling), [@mwear](https://www.github.com/mwear) | [development]: https://github.com/open-telemetry/opentelemetry-collector#development [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/connector/routingconnector/metadata.yaml b/connector/routingconnector/metadata.yaml index cae3b0280c05..5ad00df77959 100644 --- a/connector/routingconnector/metadata.yaml +++ b/connector/routingconnector/metadata.yaml @@ -6,4 +6,4 @@ status: development: [traces_to_traces, metrics_to_metrics, logs_to_logs] distributions: [contrib] codeowners: - active: [jpkrohling, kovrus, mwear] + active: [jpkrohling, mwear] diff --git a/connector/spanmetricsconnector/README.md b/connector/spanmetricsconnector/README.md index d81e7354c9b5..74f4d1f35ab7 100644 --- a/connector/spanmetricsconnector/README.md +++ b/connector/spanmetricsconnector/README.md @@ -5,7 +5,7 @@ | ------------- |-----------| | Distributions | [contrib], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aconnector%2Fspanmetrics%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aconnector%2Fspanmetrics%20&label=closed&color=blue&logo=opentelemetry) | -| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@albertteoh](https://www.github.com/albertteoh), [@kovrus](https://www.github.com/kovrus) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@albertteoh](https://www.github.com/albertteoh) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/connector/spanmetricsconnector/metadata.yaml b/connector/spanmetricsconnector/metadata.yaml index e01dba7cbd30..6c3fea8c4b93 100644 --- a/connector/spanmetricsconnector/metadata.yaml +++ b/connector/spanmetricsconnector/metadata.yaml @@ -6,4 +6,4 @@ status: alpha: [traces_to_metrics] distributions: [contrib, sumo] codeowners: - active: [albertteoh, kovrus] + active: [albertteoh] diff --git a/exporter/lokiexporter/README.md b/exporter/lokiexporter/README.md index cb43d1c0c5a9..4647842b843d 100644 --- a/exporter/lokiexporter/README.md +++ b/exporter/lokiexporter/README.md @@ -6,7 +6,7 @@ | Stability | [beta]: logs | | Distributions | [contrib], [observiq] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aexporter%2Floki%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aexporter%2Floki%20&label=closed&color=blue&logo=opentelemetry) | -| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@gramidt](https://www.github.com/gramidt), [@gouthamve](https://www.github.com/gouthamve), [@jpkrohling](https://www.github.com/jpkrohling), [@kovrus](https://www.github.com/kovrus), [@mar4uk](https://www.github.com/mar4uk) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@gramidt](https://www.github.com/gramidt), [@gouthamve](https://www.github.com/gouthamve), [@jpkrohling](https://www.github.com/jpkrohling), [@mar4uk](https://www.github.com/mar4uk) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/exporter/lokiexporter/metadata.yaml b/exporter/lokiexporter/metadata.yaml index ba9cbdf72813..b5b1c2c7cab2 100644 --- a/exporter/lokiexporter/metadata.yaml +++ b/exporter/lokiexporter/metadata.yaml @@ -8,4 +8,4 @@ status: - contrib - observiq codeowners: - active: [gramidt, gouthamve, jpkrohling, kovrus, mar4uk] + active: [gramidt, gouthamve, jpkrohling, mar4uk] diff --git a/extension/headerssetterextension/README.md b/extension/headerssetterextension/README.md index 73c42bd73b94..4487890a9b1e 100644 --- a/extension/headerssetterextension/README.md +++ b/extension/headerssetterextension/README.md @@ -5,7 +5,7 @@ | Stability | [alpha] | | Distributions | [contrib], [grafana], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aextension%2Fheaderssetter%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aextension%2Fheaderssetter%20&label=closed&color=blue&logo=opentelemetry) | -| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jpkrohling](https://www.github.com/jpkrohling), [@kovrus](https://www.github.com/kovrus) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jpkrohling](https://www.github.com/jpkrohling) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/extension/headerssetterextension/metadata.yaml b/extension/headerssetterextension/metadata.yaml index b21ca5e2af7f..9382e6c68779 100644 --- a/extension/headerssetterextension/metadata.yaml +++ b/extension/headerssetterextension/metadata.yaml @@ -9,4 +9,4 @@ status: - grafana - sumo codeowners: - active: [jpkrohling, kovrus] + active: [jpkrohling] diff --git a/pkg/translator/loki/metadata.yaml b/pkg/translator/loki/metadata.yaml index 2b9d4919864e..94d94e815591 100644 --- a/pkg/translator/loki/metadata.yaml +++ b/pkg/translator/loki/metadata.yaml @@ -1,3 +1,3 @@ status: codeowners: - active: [gouthamve, jpkrohling, kovrus, mar4uk] \ No newline at end of file + active: [gouthamve, jpkrohling, mar4uk] \ No newline at end of file diff --git a/pkg/translator/prometheusremotewrite/metadata.yaml b/pkg/translator/prometheusremotewrite/metadata.yaml index 1f5c7161da0e..79f2d095d572 100644 --- a/pkg/translator/prometheusremotewrite/metadata.yaml +++ b/pkg/translator/prometheusremotewrite/metadata.yaml @@ -1,3 +1,3 @@ status: codeowners: - active: [Aneurysm9, kovrus] \ No newline at end of file + active: [Aneurysm9] \ No newline at end of file diff --git a/processor/routingprocessor/README.md b/processor/routingprocessor/README.md index 590757be314a..e577397b305e 100644 --- a/processor/routingprocessor/README.md +++ b/processor/routingprocessor/README.md @@ -6,7 +6,7 @@ | Stability | [beta]: traces, metrics, logs | | Distributions | [contrib], [observiq], [redhat], [splunk], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Aprocessor%2Frouting%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Aprocessor%2Frouting%20&label=closed&color=blue&logo=opentelemetry) | -| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jpkrohling](https://www.github.com/jpkrohling), [@kovrus](https://www.github.com/kovrus) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jpkrohling](https://www.github.com/jpkrohling) | [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/processor/routingprocessor/metadata.yaml b/processor/routingprocessor/metadata.yaml index d9b9c0b18d9f..1022640b3c38 100644 --- a/processor/routingprocessor/metadata.yaml +++ b/processor/routingprocessor/metadata.yaml @@ -6,4 +6,4 @@ status: beta: [traces, metrics, logs] distributions: [contrib, observiq, splunk, sumo, redhat] codeowners: - active: [jpkrohling, kovrus] \ No newline at end of file + active: [jpkrohling] \ No newline at end of file diff --git a/receiver/awscloudwatchmetricsreceiver/README.md b/receiver/awscloudwatchmetricsreceiver/README.md index 518ec0ba9adc..9f61597937be 100644 --- a/receiver/awscloudwatchmetricsreceiver/README.md +++ b/receiver/awscloudwatchmetricsreceiver/README.md @@ -6,7 +6,7 @@ | Stability | [development]: metrics | | Distributions | [contrib] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Fawscloudwatchmetrics%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Fawscloudwatchmetrics%20&label=closed&color=blue&logo=opentelemetry) | -| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jpkrohling](https://www.github.com/jpkrohling), [@kovrus](https://www.github.com/kovrus) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@jpkrohling](https://www.github.com/jpkrohling) | [development]: https://github.com/open-telemetry/opentelemetry-collector#development [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/awscloudwatchmetricsreceiver/metadata.yaml b/receiver/awscloudwatchmetricsreceiver/metadata.yaml index a10c59f43335..9dae2cb53b24 100644 --- a/receiver/awscloudwatchmetricsreceiver/metadata.yaml +++ b/receiver/awscloudwatchmetricsreceiver/metadata.yaml @@ -6,4 +6,4 @@ status: development: [metrics] distributions: [contrib] codeowners: - active: [jpkrohling, kovrus] \ No newline at end of file + active: [jpkrohling] \ No newline at end of file diff --git a/receiver/lokireceiver/README.md b/receiver/lokireceiver/README.md index a788af4a8f09..15b08da4d855 100644 --- a/receiver/lokireceiver/README.md +++ b/receiver/lokireceiver/README.md @@ -6,7 +6,7 @@ | Stability | [alpha]: logs | | Distributions | [contrib], [sumo] | | Issues | ![Open issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aopen%20label%3Areceiver%2Floki%20&label=open&color=orange&logo=opentelemetry) ![Closed issues](https://img.shields.io/github/issues-search/open-telemetry/opentelemetry-collector-contrib?query=is%3Aissue%20is%3Aclosed%20label%3Areceiver%2Floki%20&label=closed&color=blue&logo=opentelemetry) | -| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@mar4uk](https://www.github.com/mar4uk), [@kovrus](https://www.github.com/kovrus), [@jpkrohling](https://www.github.com/jpkrohling) | +| [Code Owners](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#becoming-a-code-owner) | [@mar4uk](https://www.github.com/mar4uk), [@jpkrohling](https://www.github.com/jpkrohling) | [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib diff --git a/receiver/lokireceiver/metadata.yaml b/receiver/lokireceiver/metadata.yaml index 08a702fd9194..edad5b935124 100644 --- a/receiver/lokireceiver/metadata.yaml +++ b/receiver/lokireceiver/metadata.yaml @@ -8,4 +8,4 @@ status: - contrib - sumo codeowners: - active: [mar4uk, kovrus, jpkrohling] + active: [mar4uk, jpkrohling] From 635ec0bb1ab82d73394023a0e565bc73c9177da8 Mon Sep 17 00:00:00 2001 From: Daniel Jaglowski Date: Wed, 26 Jul 2023 10:25:40 -0400 Subject: [PATCH 42/42] [chore] Add "Code Owners" field to new component template (#23780) #20868 represents a push to ensure that all component code owners are members of the OpenTelemetry organization. This has direct implications for our notion of "vendor-specific components", which are those that interact specifically with a particular vendor, and are contributed and maintained by a representative of a vendor. We require that the vendor representative must maintain the component, which essentially means they must be a code owner. Therefore, I am proposing that the representative must be a member of the org before the component may be accepted. --- .github/ISSUE_TEMPLATE/new_component.yaml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/new_component.yaml b/.github/ISSUE_TEMPLATE/new_component.yaml index 25ab550ce21d..982218d463c3 100644 --- a/.github/ISSUE_TEMPLATE/new_component.yaml +++ b/.github/ISSUE_TEMPLATE/new_component.yaml @@ -27,11 +27,21 @@ body: description: A vendor-specific component directly interfaces with a vendor-specific API and is expected to be maintained by a representative of the same vendor. options: - label: This is a vendor-specific component - - label: If this is a vendor-specific component, I am proposing to contribute this as a representative of the vendor. + - label: If this is a vendor-specific component, I am proposing to contribute and support it as a representative of the vendor. + - type: input + attributes: + label: Code Owner(s) + description: A code owner is responsible for supporting the component, including triaging issues, reviewing PRs, and submitting bug fixes. + Please list one or more members or aspiring members of the OpenTelemetry project who will serve as code owners. + For vendor-specific components, the code owner is required and must be a representative of the vendor. + For non-vendor components, having a code owner is strongly recommended. However, you may use the issue to try to find a code owner for your component. - type: input attributes: label: Sponsor (optional) - description: "A sponsor is an approver who will be in charge of being the official reviewer of the code. For vendor-specific components, it's good to have a volunteer sponsor. If you can't find one, we'll assign one in a round-robin fashion. For non-vendor components, having a sponsor means that your use-case has been validated. If there are no sponsors yet for the component, it's fine: use the issue as a means to try to find a sponsor for your component." + description: "A sponsor is an approver who will be in charge of being the official reviewer of the code. + For vendor-specific components, it's good to have a volunteer sponsor. If you can't find one, we'll assign one in a round-robin fashion. + For non-vendor components, having a sponsor means that your use-case has been validated. + If there are no sponsors yet for the component, it's fine: use the issue as a means to try to find a sponsor for your component." - type: textarea attributes: label: Additional context