From fc0c4ea32c00ae5aa178a366ff86aa8f7d85a82d Mon Sep 17 00:00:00 2001 From: Dmitry Date: Thu, 5 May 2022 11:44:40 -0700 Subject: [PATCH] [receiver/elasticsearch] Use metrics builder for resource metrics This change refactors the receiver to rely more on generated code. The only functional change: Metrics scope name is changed from `otelcol/elasticsearch` to `otelcol/elasticsearchreceiver` --- CHANGELOG.md | 2 + .../elasticsearchreceiver/documentation.md | 9 +++- .../internal/metadata/emitters.go | 52 ------------------- .../internal/metadata/generated_metrics_v2.go | 20 ++++--- receiver/elasticsearchreceiver/metadata.yaml | 6 ++- receiver/elasticsearchreceiver/scraper.go | 35 +++---------- 6 files changed, 36 insertions(+), 88 deletions(-) delete mode 100644 receiver/elasticsearchreceiver/internal/metadata/emitters.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f2431f75b88..53aae42bb6c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ ### 💡 Enhancements 💡 - `cmd/mdatagen`: Replace enum attributes values with typed constants (#9683) +- `elasticsearchreceiver`: Update metrics scope name from `otelcol/elasticsearch` + to `otelcol/elasticsearchreceiver` (#9757) - `k8sclusterreceiver`: Validate that k8s API supports a resource before setting up a watcher for it (#9523) - `internal/stanza`: Add support for `remove` operator (#9524) - `k8sattributesprocessor`: Support regex capture groups in tag_name (#9525) diff --git a/receiver/elasticsearchreceiver/documentation.md b/receiver/elasticsearchreceiver/documentation.md index 84a5a3ec0580..74571aed717c 100644 --- a/receiver/elasticsearchreceiver/documentation.md +++ b/receiver/elasticsearchreceiver/documentation.md @@ -47,6 +47,13 @@ metrics: enabled: ``` +## Resource attributes + +| Name | Description | Type | +| ---- | ----------- | ---- | +| elasticsearch.cluster.name | The name of the elasticsearch cluster. | String | +| elasticsearch.node.name | The name of the elasticsearch node. | String | + ## Metric attributes | Name | Description | Values | @@ -56,8 +63,6 @@ metrics: | direction | The direction of network data. | received, sent | | disk_usage_state (state) | The state of a section of space on disk. | used, free | | document_state (state) | The state of the document. | active, deleted | -| elasticsearch.cluster.name | The name of the elasticsearch cluster. | | -| elasticsearch.node.name | The name of the elasticsearch node. | | | fs_direction (direction) | The direction of filesystem IO. | read, write | | health_status (status) | The health status of the cluster. | green, yellow, red | | memory_pool_name (name) | The name of the JVM memory pool. | | diff --git a/receiver/elasticsearchreceiver/internal/metadata/emitters.go b/receiver/elasticsearchreceiver/internal/metadata/emitters.go deleted file mode 100644 index 213b9f31c7f2..000000000000 --- a/receiver/elasticsearchreceiver/internal/metadata/emitters.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package metadata // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/elasticsearchreceiver/internal/metadata" - -import "go.opentelemetry.io/collector/pdata/pmetric" - -func (mb *MetricsBuilder) EmitNodeMetrics(metrics pmetric.MetricSlice) { - mb.metricElasticsearchNodeCacheEvictions.emit(metrics) - mb.metricElasticsearchNodeCacheMemoryUsage.emit(metrics) - mb.metricElasticsearchNodeClusterConnections.emit(metrics) - mb.metricElasticsearchNodeClusterIo.emit(metrics) - mb.metricElasticsearchNodeDocuments.emit(metrics) - mb.metricElasticsearchNodeFsDiskAvailable.emit(metrics) - mb.metricElasticsearchNodeHTTPConnections.emit(metrics) - mb.metricElasticsearchNodeOpenFiles.emit(metrics) - mb.metricElasticsearchNodeOperationsCompleted.emit(metrics) - mb.metricElasticsearchNodeOperationsTime.emit(metrics) - mb.metricElasticsearchNodeShardsSize.emit(metrics) - mb.metricElasticsearchNodeThreadPoolTasksFinished.emit(metrics) - mb.metricElasticsearchNodeThreadPoolTasksQueued.emit(metrics) - mb.metricElasticsearchNodeThreadPoolThreads.emit(metrics) - mb.metricJvmClassesLoaded.emit(metrics) - mb.metricJvmGcCollectionsCount.emit(metrics) - mb.metricJvmGcCollectionsElapsed.emit(metrics) - mb.metricJvmMemoryHeapCommitted.emit(metrics) - mb.metricJvmMemoryHeapMax.emit(metrics) - mb.metricJvmMemoryHeapUsed.emit(metrics) - mb.metricJvmMemoryNonheapCommitted.emit(metrics) - mb.metricJvmMemoryNonheapUsed.emit(metrics) - mb.metricJvmMemoryPoolMax.emit(metrics) - mb.metricJvmMemoryPoolUsed.emit(metrics) - mb.metricJvmThreadsCount.emit(metrics) -} - -func (mb *MetricsBuilder) EmitClusterMetrics(metrics pmetric.MetricSlice) { - mb.metricElasticsearchClusterDataNodes.emit(metrics) - mb.metricElasticsearchClusterNodes.emit(metrics) - mb.metricElasticsearchClusterShards.emit(metrics) - mb.metricElasticsearchClusterHealth.emit(metrics) -} diff --git a/receiver/elasticsearchreceiver/internal/metadata/generated_metrics_v2.go b/receiver/elasticsearchreceiver/internal/metadata/generated_metrics_v2.go index f839729ac40b..7bdd90762b72 100644 --- a/receiver/elasticsearchreceiver/internal/metadata/generated_metrics_v2.go +++ b/receiver/elasticsearchreceiver/internal/metadata/generated_metrics_v2.go @@ -2041,6 +2041,20 @@ func (mb *MetricsBuilder) updateCapacity(rm pmetric.ResourceMetrics) { // ResourceOption applies changes to provided resource. type ResourceOption func(pcommon.Resource) +// WithElasticsearchClusterName sets provided value as "elasticsearch.cluster.name" attribute for current resource. +func WithElasticsearchClusterName(val string) ResourceOption { + return func(r pcommon.Resource) { + r.Attributes().UpsertString("elasticsearch.cluster.name", val) + } +} + +// WithElasticsearchNodeName sets provided value as "elasticsearch.node.name" attribute for current resource. +func WithElasticsearchNodeName(val string) ResourceOption { + return func(r pcommon.Resource) { + r.Attributes().UpsertString("elasticsearch.node.name", val) + } +} + // 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, @@ -2265,10 +2279,6 @@ var Attributes = struct { DiskUsageState string // DocumentState (The state of the document.) DocumentState string - // ElasticsearchClusterName (The name of the elasticsearch cluster.) - ElasticsearchClusterName string - // ElasticsearchNodeName (The name of the elasticsearch node.) - ElasticsearchNodeName string // FsDirection (The direction of filesystem IO.) FsDirection string // HealthStatus (The health status of the cluster.) @@ -2291,8 +2301,6 @@ var Attributes = struct { "direction", "state", "state", - "elasticsearch.cluster.name", - "elasticsearch.node.name", "direction", "status", "name", diff --git a/receiver/elasticsearchreceiver/metadata.yaml b/receiver/elasticsearchreceiver/metadata.yaml index 6295b92ad61d..44abde74a8ab 100644 --- a/receiver/elasticsearchreceiver/metadata.yaml +++ b/receiver/elasticsearchreceiver/metadata.yaml @@ -1,10 +1,14 @@ name: elasticsearchreceiver -attributes: +resource_attributes: elasticsearch.cluster.name: description: The name of the elasticsearch cluster. + type: string elasticsearch.node.name: description: The name of the elasticsearch node. + type: string + +attributes: cache_name: description: The name of cache. enum: diff --git a/receiver/elasticsearchreceiver/scraper.go b/receiver/elasticsearchreceiver/scraper.go index 870c4a452028..ca1be7d7c46a 100644 --- a/receiver/elasticsearchreceiver/scraper.go +++ b/receiver/elasticsearchreceiver/scraper.go @@ -28,8 +28,6 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/elasticsearchreceiver/internal/metadata" ) -const instrumentationLibraryName = "otelcol/elasticsearch" - var errUnknownClusterStatus = errors.New("unknown cluster status") type elasticsearchScraper struct { @@ -56,21 +54,18 @@ func (r *elasticsearchScraper) start(_ context.Context, host component.Host) (er } func (r *elasticsearchScraper) scrape(ctx context.Context) (pmetric.Metrics, error) { - metrics := pmetric.NewMetrics() - rms := metrics.ResourceMetrics() - errs := &scrapererror.ScrapeErrors{} now := pcommon.NewTimestampFromTime(time.Now()) - r.scrapeNodeMetrics(ctx, now, rms, errs) - r.scrapeClusterMetrics(ctx, now, rms, errs) + r.scrapeNodeMetrics(ctx, now, errs) + r.scrapeClusterMetrics(ctx, now, errs) - return metrics, errs.Combine() + return r.mb.Emit(), errs.Combine() } // scrapeNodeMetrics scrapes adds node-level metrics to the given MetricSlice from the NodeStats endpoint -func (r *elasticsearchScraper) scrapeNodeMetrics(ctx context.Context, now pcommon.Timestamp, rms pmetric.ResourceMetricsSlice, errs *scrapererror.ScrapeErrors) { +func (r *elasticsearchScraper) scrapeNodeMetrics(ctx context.Context, now pcommon.Timestamp, errs *scrapererror.ScrapeErrors) { if len(r.cfg.Nodes) == 0 { return } @@ -82,14 +77,6 @@ func (r *elasticsearchScraper) scrapeNodeMetrics(ctx context.Context, now pcommo } for _, info := range nodeStats.Nodes { - rm := rms.AppendEmpty() - resourceAttrs := rm.Resource().Attributes() - resourceAttrs.InsertString(metadata.A.ElasticsearchClusterName, nodeStats.ClusterName) - resourceAttrs.InsertString(metadata.A.ElasticsearchNodeName, info.Name) - - ilms := rm.ScopeMetrics().AppendEmpty() - ilms.Scope().SetName(instrumentationLibraryName) - r.mb.RecordElasticsearchNodeCacheMemoryUsageDataPoint(now, info.Indices.FieldDataCache.MemorySizeInBy, metadata.AttributeCacheNameFielddata) r.mb.RecordElasticsearchNodeCacheMemoryUsageDataPoint(now, info.Indices.QueryCache.MemorySizeInBy, metadata.AttributeCacheNameQuery) @@ -171,11 +158,12 @@ func (r *elasticsearchScraper) scrapeNodeMetrics(ctx context.Context, now pcommo r.mb.RecordJvmThreadsCountDataPoint(now, info.JVMInfo.JVMThreadInfo.Count) - r.mb.EmitNodeMetrics(ilms.Metrics()) + r.mb.EmitForResource(metadata.WithElasticsearchClusterName(nodeStats.ClusterName), + metadata.WithElasticsearchNodeName(info.Name)) } } -func (r *elasticsearchScraper) scrapeClusterMetrics(ctx context.Context, now pcommon.Timestamp, rms pmetric.ResourceMetricsSlice, errs *scrapererror.ScrapeErrors) { +func (r *elasticsearchScraper) scrapeClusterMetrics(ctx context.Context, now pcommon.Timestamp, errs *scrapererror.ScrapeErrors) { if r.cfg.SkipClusterMetrics { return } @@ -186,13 +174,6 @@ func (r *elasticsearchScraper) scrapeClusterMetrics(ctx context.Context, now pco return } - rm := rms.AppendEmpty() - resourceAttrs := rm.Resource().Attributes() - resourceAttrs.InsertString(metadata.A.ElasticsearchClusterName, clusterHealth.ClusterName) - - ilms := rm.ScopeMetrics().AppendEmpty() - ilms.Scope().SetName(instrumentationLibraryName) - r.mb.RecordElasticsearchClusterNodesDataPoint(now, clusterHealth.NodeCount) r.mb.RecordElasticsearchClusterDataNodesDataPoint(now, clusterHealth.DataNodeCount) @@ -219,5 +200,5 @@ func (r *elasticsearchScraper) scrapeClusterMetrics(ctx context.Context, now pco errs.AddPartial(1, fmt.Errorf("health status %s: %w", clusterHealth.Status, errUnknownClusterStatus)) } - r.mb.EmitClusterMetrics(ilms.Metrics()) + r.mb.EmitForResource(metadata.WithElasticsearchClusterName(clusterHealth.ClusterName)) }