From a2e2c157124a20e8e4dac9f9f9be2decb263c425 Mon Sep 17 00:00:00 2001 From: Hardik Choksi Date: Thu, 11 Apr 2024 12:43:27 +0530 Subject: [PATCH] Added 4 Metrics with Unit tests --- receiver/apachereceiver/documentation.md | 32 ++ .../internal/metadata/generated_config.go | 40 ++- .../metadata/generated_config_test.go | 56 ++-- .../internal/metadata/generated_metrics.go | 316 ++++++++++++++++-- .../metadata/generated_metrics_test.go | 66 ++++ .../internal/metadata/testdata/config.yaml | 16 + receiver/apachereceiver/metadata.yaml | 34 ++ receiver/apachereceiver/scraper.go | 8 + receiver/apachereceiver/scraper_test.go | 9 +- .../testdata/integration/expected.yaml | 31 ++ .../testdata/scraper/expected.yaml | 30 ++ 11 files changed, 567 insertions(+), 71 deletions(-) diff --git a/receiver/apachereceiver/documentation.md b/receiver/apachereceiver/documentation.md index a0514c8405d2..0a4181e6b4d3 100644 --- a/receiver/apachereceiver/documentation.md +++ b/receiver/apachereceiver/documentation.md @@ -12,6 +12,38 @@ metrics: enabled: false ``` +### apache.bytes_served + +The total number of bytes served. + +| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic | +| ---- | ----------- | ---------- | ----------------------- | --------- | +| {byte} | Sum | Int | Cumulative | true | + +### apache.conns_async_closing + +The number of asynchronous closing connections. + +| Unit | Metric Type | Value Type | +| ---- | ----------- | ---------- | +| {connections} | Gauge | Int | + +### apache.conns_async_keep_alive + +The number of asynchronous keep alive connections. + +| Unit | Metric Type | Value Type | +| ---- | ----------- | ---------- | +| {connections} | Gauge | Int | + +### apache.conns_async_writing + +The number of asynchronous writes connections. + +| Unit | Metric Type | Value Type | +| ---- | ----------- | ---------- | +| {connections} | Gauge | Int | + ### apache.cpu.load Current load of the CPU. diff --git a/receiver/apachereceiver/internal/metadata/generated_config.go b/receiver/apachereceiver/internal/metadata/generated_config.go index 74c9818683f8..0520d2e8a8a2 100644 --- a/receiver/apachereceiver/internal/metadata/generated_config.go +++ b/receiver/apachereceiver/internal/metadata/generated_config.go @@ -25,22 +25,38 @@ func (ms *MetricConfig) Unmarshal(parser *confmap.Conf) error { // MetricsConfig provides config for apache metrics. type MetricsConfig struct { - ApacheCPULoad MetricConfig `mapstructure:"apache.cpu.load"` - ApacheCPUTime MetricConfig `mapstructure:"apache.cpu.time"` - ApacheCurrentConnections MetricConfig `mapstructure:"apache.current_connections"` - ApacheLoad1 MetricConfig `mapstructure:"apache.load.1"` - ApacheLoad15 MetricConfig `mapstructure:"apache.load.15"` - ApacheLoad5 MetricConfig `mapstructure:"apache.load.5"` - ApacheRequestTime MetricConfig `mapstructure:"apache.request.time"` - ApacheRequests MetricConfig `mapstructure:"apache.requests"` - ApacheScoreboard MetricConfig `mapstructure:"apache.scoreboard"` - ApacheTraffic MetricConfig `mapstructure:"apache.traffic"` - ApacheUptime MetricConfig `mapstructure:"apache.uptime"` - ApacheWorkers MetricConfig `mapstructure:"apache.workers"` + ApacheBytesServed MetricConfig `mapstructure:"apache.bytes_served"` + ApacheConnsAsyncClosing MetricConfig `mapstructure:"apache.conns_async_closing"` + ApacheConnsAsyncKeepAlive MetricConfig `mapstructure:"apache.conns_async_keep_alive"` + ApacheConnsAsyncWriting MetricConfig `mapstructure:"apache.conns_async_writing"` + ApacheCPULoad MetricConfig `mapstructure:"apache.cpu.load"` + ApacheCPUTime MetricConfig `mapstructure:"apache.cpu.time"` + ApacheCurrentConnections MetricConfig `mapstructure:"apache.current_connections"` + ApacheLoad1 MetricConfig `mapstructure:"apache.load.1"` + ApacheLoad15 MetricConfig `mapstructure:"apache.load.15"` + ApacheLoad5 MetricConfig `mapstructure:"apache.load.5"` + ApacheRequestTime MetricConfig `mapstructure:"apache.request.time"` + ApacheRequests MetricConfig `mapstructure:"apache.requests"` + ApacheScoreboard MetricConfig `mapstructure:"apache.scoreboard"` + ApacheTraffic MetricConfig `mapstructure:"apache.traffic"` + ApacheUptime MetricConfig `mapstructure:"apache.uptime"` + ApacheWorkers MetricConfig `mapstructure:"apache.workers"` } func DefaultMetricsConfig() MetricsConfig { return MetricsConfig{ + ApacheBytesServed: MetricConfig{ + Enabled: true, + }, + ApacheConnsAsyncClosing: MetricConfig{ + Enabled: true, + }, + ApacheConnsAsyncKeepAlive: MetricConfig{ + Enabled: true, + }, + ApacheConnsAsyncWriting: MetricConfig{ + Enabled: true, + }, ApacheCPULoad: MetricConfig{ Enabled: true, }, diff --git a/receiver/apachereceiver/internal/metadata/generated_config_test.go b/receiver/apachereceiver/internal/metadata/generated_config_test.go index 952442d94609..c7f08eb3abb9 100644 --- a/receiver/apachereceiver/internal/metadata/generated_config_test.go +++ b/receiver/apachereceiver/internal/metadata/generated_config_test.go @@ -26,18 +26,22 @@ func TestMetricsBuilderConfig(t *testing.T) { name: "all_set", want: MetricsBuilderConfig{ Metrics: MetricsConfig{ - ApacheCPULoad: MetricConfig{Enabled: true}, - ApacheCPUTime: MetricConfig{Enabled: true}, - ApacheCurrentConnections: MetricConfig{Enabled: true}, - ApacheLoad1: MetricConfig{Enabled: true}, - ApacheLoad15: MetricConfig{Enabled: true}, - ApacheLoad5: MetricConfig{Enabled: true}, - ApacheRequestTime: MetricConfig{Enabled: true}, - ApacheRequests: MetricConfig{Enabled: true}, - ApacheScoreboard: MetricConfig{Enabled: true}, - ApacheTraffic: MetricConfig{Enabled: true}, - ApacheUptime: MetricConfig{Enabled: true}, - ApacheWorkers: MetricConfig{Enabled: true}, + ApacheBytesServed: MetricConfig{Enabled: true}, + ApacheConnsAsyncClosing: MetricConfig{Enabled: true}, + ApacheConnsAsyncKeepAlive: MetricConfig{Enabled: true}, + ApacheConnsAsyncWriting: MetricConfig{Enabled: true}, + ApacheCPULoad: MetricConfig{Enabled: true}, + ApacheCPUTime: MetricConfig{Enabled: true}, + ApacheCurrentConnections: MetricConfig{Enabled: true}, + ApacheLoad1: MetricConfig{Enabled: true}, + ApacheLoad15: MetricConfig{Enabled: true}, + ApacheLoad5: MetricConfig{Enabled: true}, + ApacheRequestTime: MetricConfig{Enabled: true}, + ApacheRequests: MetricConfig{Enabled: true}, + ApacheScoreboard: MetricConfig{Enabled: true}, + ApacheTraffic: MetricConfig{Enabled: true}, + ApacheUptime: MetricConfig{Enabled: true}, + ApacheWorkers: MetricConfig{Enabled: true}, }, ResourceAttributes: ResourceAttributesConfig{ ApacheServerName: ResourceAttributeConfig{Enabled: true}, @@ -49,18 +53,22 @@ func TestMetricsBuilderConfig(t *testing.T) { name: "none_set", want: MetricsBuilderConfig{ Metrics: MetricsConfig{ - ApacheCPULoad: MetricConfig{Enabled: false}, - ApacheCPUTime: MetricConfig{Enabled: false}, - ApacheCurrentConnections: MetricConfig{Enabled: false}, - ApacheLoad1: MetricConfig{Enabled: false}, - ApacheLoad15: MetricConfig{Enabled: false}, - ApacheLoad5: MetricConfig{Enabled: false}, - ApacheRequestTime: MetricConfig{Enabled: false}, - ApacheRequests: MetricConfig{Enabled: false}, - ApacheScoreboard: MetricConfig{Enabled: false}, - ApacheTraffic: MetricConfig{Enabled: false}, - ApacheUptime: MetricConfig{Enabled: false}, - ApacheWorkers: MetricConfig{Enabled: false}, + ApacheBytesServed: MetricConfig{Enabled: false}, + ApacheConnsAsyncClosing: MetricConfig{Enabled: false}, + ApacheConnsAsyncKeepAlive: MetricConfig{Enabled: false}, + ApacheConnsAsyncWriting: MetricConfig{Enabled: false}, + ApacheCPULoad: MetricConfig{Enabled: false}, + ApacheCPUTime: MetricConfig{Enabled: false}, + ApacheCurrentConnections: MetricConfig{Enabled: false}, + ApacheLoad1: MetricConfig{Enabled: false}, + ApacheLoad15: MetricConfig{Enabled: false}, + ApacheLoad5: MetricConfig{Enabled: false}, + ApacheRequestTime: MetricConfig{Enabled: false}, + ApacheRequests: MetricConfig{Enabled: false}, + ApacheScoreboard: MetricConfig{Enabled: false}, + ApacheTraffic: MetricConfig{Enabled: false}, + ApacheUptime: MetricConfig{Enabled: false}, + ApacheWorkers: MetricConfig{Enabled: false}, }, ResourceAttributes: ResourceAttributesConfig{ ApacheServerName: ResourceAttributeConfig{Enabled: false}, diff --git a/receiver/apachereceiver/internal/metadata/generated_metrics.go b/receiver/apachereceiver/internal/metadata/generated_metrics.go index 06cd9722312a..4a8c06eddb8a 100644 --- a/receiver/apachereceiver/internal/metadata/generated_metrics.go +++ b/receiver/apachereceiver/internal/metadata/generated_metrics.go @@ -157,6 +157,204 @@ var MapAttributeWorkersState = map[string]AttributeWorkersState{ "idle": AttributeWorkersStateIdle, } +type metricApacheBytesServed 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 apache.bytes_served metric with initial data. +func (m *metricApacheBytesServed) init() { + m.data.SetName("apache.bytes_served") + m.data.SetDescription("The total number of bytes served.") + m.data.SetUnit("{byte}") + m.data.SetEmptySum() + m.data.Sum().SetIsMonotonic(true) + m.data.Sum().SetAggregationTemporality(pmetric.AggregationTemporalityCumulative) +} + +func (m *metricApacheBytesServed) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64) { + if !m.config.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntValue(val) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricApacheBytesServed) updateCapacity() { + if m.data.Sum().DataPoints().Len() > m.capacity { + m.capacity = m.data.Sum().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricApacheBytesServed) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricApacheBytesServed(cfg MetricConfig) metricApacheBytesServed { + m := metricApacheBytesServed{config: cfg} + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricApacheConnsAsyncClosing 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 apache.conns_async_closing metric with initial data. +func (m *metricApacheConnsAsyncClosing) init() { + m.data.SetName("apache.conns_async_closing") + m.data.SetDescription("The number of asynchronous closing connections.") + m.data.SetUnit("{connections}") + m.data.SetEmptyGauge() +} + +func (m *metricApacheConnsAsyncClosing) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64) { + if !m.config.Enabled { + return + } + dp := m.data.Gauge().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntValue(val) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricApacheConnsAsyncClosing) 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 *metricApacheConnsAsyncClosing) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricApacheConnsAsyncClosing(cfg MetricConfig) metricApacheConnsAsyncClosing { + m := metricApacheConnsAsyncClosing{config: cfg} + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricApacheConnsAsyncKeepAlive 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 apache.conns_async_keep_alive metric with initial data. +func (m *metricApacheConnsAsyncKeepAlive) init() { + m.data.SetName("apache.conns_async_keep_alive") + m.data.SetDescription("The number of asynchronous keep alive connections.") + m.data.SetUnit("{connections}") + m.data.SetEmptyGauge() +} + +func (m *metricApacheConnsAsyncKeepAlive) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64) { + if !m.config.Enabled { + return + } + dp := m.data.Gauge().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntValue(val) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricApacheConnsAsyncKeepAlive) 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 *metricApacheConnsAsyncKeepAlive) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricApacheConnsAsyncKeepAlive(cfg MetricConfig) metricApacheConnsAsyncKeepAlive { + m := metricApacheConnsAsyncKeepAlive{config: cfg} + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricApacheConnsAsyncWriting 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 apache.conns_async_writing metric with initial data. +func (m *metricApacheConnsAsyncWriting) init() { + m.data.SetName("apache.conns_async_writing") + m.data.SetDescription("The number of asynchronous writes connections.") + m.data.SetUnit("{connections}") + m.data.SetEmptyGauge() +} + +func (m *metricApacheConnsAsyncWriting) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64) { + if !m.config.Enabled { + return + } + dp := m.data.Gauge().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntValue(val) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricApacheConnsAsyncWriting) 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 *metricApacheConnsAsyncWriting) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricApacheConnsAsyncWriting(cfg MetricConfig) metricApacheConnsAsyncWriting { + m := metricApacheConnsAsyncWriting{config: cfg} + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + type metricApacheCPULoad struct { data pmetric.Metric // data buffer for generated metric. config MetricConfig // metric config provided by user. @@ -771,23 +969,27 @@ func newMetricApacheWorkers(cfg MetricConfig) metricApacheWorkers { // 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 { - config MetricsBuilderConfig // config of the metrics builder. - 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. - metricApacheCPULoad metricApacheCPULoad - metricApacheCPUTime metricApacheCPUTime - metricApacheCurrentConnections metricApacheCurrentConnections - metricApacheLoad1 metricApacheLoad1 - metricApacheLoad15 metricApacheLoad15 - metricApacheLoad5 metricApacheLoad5 - metricApacheRequestTime metricApacheRequestTime - metricApacheRequests metricApacheRequests - metricApacheScoreboard metricApacheScoreboard - metricApacheTraffic metricApacheTraffic - metricApacheUptime metricApacheUptime - metricApacheWorkers metricApacheWorkers + config MetricsBuilderConfig // config of the metrics builder. + 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. + metricApacheBytesServed metricApacheBytesServed + metricApacheConnsAsyncClosing metricApacheConnsAsyncClosing + metricApacheConnsAsyncKeepAlive metricApacheConnsAsyncKeepAlive + metricApacheConnsAsyncWriting metricApacheConnsAsyncWriting + metricApacheCPULoad metricApacheCPULoad + metricApacheCPUTime metricApacheCPUTime + metricApacheCurrentConnections metricApacheCurrentConnections + metricApacheLoad1 metricApacheLoad1 + metricApacheLoad15 metricApacheLoad15 + metricApacheLoad5 metricApacheLoad5 + metricApacheRequestTime metricApacheRequestTime + metricApacheRequests metricApacheRequests + metricApacheScoreboard metricApacheScoreboard + metricApacheTraffic metricApacheTraffic + metricApacheUptime metricApacheUptime + metricApacheWorkers metricApacheWorkers } // metricBuilderOption applies changes to default metrics builder. @@ -802,22 +1004,26 @@ func WithStartTime(startTime pcommon.Timestamp) metricBuilderOption { func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.CreateSettings, options ...metricBuilderOption) *MetricsBuilder { mb := &MetricsBuilder{ - config: mbc, - startTime: pcommon.NewTimestampFromTime(time.Now()), - metricsBuffer: pmetric.NewMetrics(), - buildInfo: settings.BuildInfo, - metricApacheCPULoad: newMetricApacheCPULoad(mbc.Metrics.ApacheCPULoad), - metricApacheCPUTime: newMetricApacheCPUTime(mbc.Metrics.ApacheCPUTime), - metricApacheCurrentConnections: newMetricApacheCurrentConnections(mbc.Metrics.ApacheCurrentConnections), - metricApacheLoad1: newMetricApacheLoad1(mbc.Metrics.ApacheLoad1), - metricApacheLoad15: newMetricApacheLoad15(mbc.Metrics.ApacheLoad15), - metricApacheLoad5: newMetricApacheLoad5(mbc.Metrics.ApacheLoad5), - metricApacheRequestTime: newMetricApacheRequestTime(mbc.Metrics.ApacheRequestTime), - metricApacheRequests: newMetricApacheRequests(mbc.Metrics.ApacheRequests), - metricApacheScoreboard: newMetricApacheScoreboard(mbc.Metrics.ApacheScoreboard), - metricApacheTraffic: newMetricApacheTraffic(mbc.Metrics.ApacheTraffic), - metricApacheUptime: newMetricApacheUptime(mbc.Metrics.ApacheUptime), - metricApacheWorkers: newMetricApacheWorkers(mbc.Metrics.ApacheWorkers), + config: mbc, + startTime: pcommon.NewTimestampFromTime(time.Now()), + metricsBuffer: pmetric.NewMetrics(), + buildInfo: settings.BuildInfo, + metricApacheBytesServed: newMetricApacheBytesServed(mbc.Metrics.ApacheBytesServed), + metricApacheConnsAsyncClosing: newMetricApacheConnsAsyncClosing(mbc.Metrics.ApacheConnsAsyncClosing), + metricApacheConnsAsyncKeepAlive: newMetricApacheConnsAsyncKeepAlive(mbc.Metrics.ApacheConnsAsyncKeepAlive), + metricApacheConnsAsyncWriting: newMetricApacheConnsAsyncWriting(mbc.Metrics.ApacheConnsAsyncWriting), + metricApacheCPULoad: newMetricApacheCPULoad(mbc.Metrics.ApacheCPULoad), + metricApacheCPUTime: newMetricApacheCPUTime(mbc.Metrics.ApacheCPUTime), + metricApacheCurrentConnections: newMetricApacheCurrentConnections(mbc.Metrics.ApacheCurrentConnections), + metricApacheLoad1: newMetricApacheLoad1(mbc.Metrics.ApacheLoad1), + metricApacheLoad15: newMetricApacheLoad15(mbc.Metrics.ApacheLoad15), + metricApacheLoad5: newMetricApacheLoad5(mbc.Metrics.ApacheLoad5), + metricApacheRequestTime: newMetricApacheRequestTime(mbc.Metrics.ApacheRequestTime), + metricApacheRequests: newMetricApacheRequests(mbc.Metrics.ApacheRequests), + metricApacheScoreboard: newMetricApacheScoreboard(mbc.Metrics.ApacheScoreboard), + metricApacheTraffic: newMetricApacheTraffic(mbc.Metrics.ApacheTraffic), + metricApacheUptime: newMetricApacheUptime(mbc.Metrics.ApacheUptime), + metricApacheWorkers: newMetricApacheWorkers(mbc.Metrics.ApacheWorkers), } for _, op := range options { op(mb) @@ -879,6 +1085,10 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { ils.Scope().SetName("otelcol/apachereceiver") ils.Scope().SetVersion(mb.buildInfo.Version) ils.Metrics().EnsureCapacity(mb.metricsCapacity) + mb.metricApacheBytesServed.emit(ils.Metrics()) + mb.metricApacheConnsAsyncClosing.emit(ils.Metrics()) + mb.metricApacheConnsAsyncKeepAlive.emit(ils.Metrics()) + mb.metricApacheConnsAsyncWriting.emit(ils.Metrics()) mb.metricApacheCPULoad.emit(ils.Metrics()) mb.metricApacheCPUTime.emit(ils.Metrics()) mb.metricApacheCurrentConnections.emit(ils.Metrics()) @@ -911,6 +1121,46 @@ func (mb *MetricsBuilder) Emit(rmo ...ResourceMetricsOption) pmetric.Metrics { return metrics } +// RecordApacheBytesServedDataPoint adds a data point to apache.bytes_served metric. +func (mb *MetricsBuilder) RecordApacheBytesServedDataPoint(ts pcommon.Timestamp, inputVal string) error { + val, err := strconv.ParseInt(inputVal, 10, 64) + if err != nil { + return fmt.Errorf("failed to parse int64 for ApacheBytesServed, value was %s: %w", inputVal, err) + } + mb.metricApacheBytesServed.recordDataPoint(mb.startTime, ts, val) + return nil +} + +// RecordApacheConnsAsyncClosingDataPoint adds a data point to apache.conns_async_closing metric. +func (mb *MetricsBuilder) RecordApacheConnsAsyncClosingDataPoint(ts pcommon.Timestamp, inputVal string) error { + val, err := strconv.ParseInt(inputVal, 10, 64) + if err != nil { + return fmt.Errorf("failed to parse int64 for ApacheConnsAsyncClosing, value was %s: %w", inputVal, err) + } + mb.metricApacheConnsAsyncClosing.recordDataPoint(mb.startTime, ts, val) + return nil +} + +// RecordApacheConnsAsyncKeepAliveDataPoint adds a data point to apache.conns_async_keep_alive metric. +func (mb *MetricsBuilder) RecordApacheConnsAsyncKeepAliveDataPoint(ts pcommon.Timestamp, inputVal string) error { + val, err := strconv.ParseInt(inputVal, 10, 64) + if err != nil { + return fmt.Errorf("failed to parse int64 for ApacheConnsAsyncKeepAlive, value was %s: %w", inputVal, err) + } + mb.metricApacheConnsAsyncKeepAlive.recordDataPoint(mb.startTime, ts, val) + return nil +} + +// RecordApacheConnsAsyncWritingDataPoint adds a data point to apache.conns_async_writing metric. +func (mb *MetricsBuilder) RecordApacheConnsAsyncWritingDataPoint(ts pcommon.Timestamp, inputVal string) error { + val, err := strconv.ParseInt(inputVal, 10, 64) + if err != nil { + return fmt.Errorf("failed to parse int64 for ApacheConnsAsyncWriting, value was %s: %w", inputVal, err) + } + mb.metricApacheConnsAsyncWriting.recordDataPoint(mb.startTime, ts, val) + return nil +} + // RecordApacheCPULoadDataPoint adds a data point to apache.cpu.load metric. func (mb *MetricsBuilder) RecordApacheCPULoadDataPoint(ts pcommon.Timestamp, inputVal string) error { val, err := strconv.ParseFloat(inputVal, 64) diff --git a/receiver/apachereceiver/internal/metadata/generated_metrics_test.go b/receiver/apachereceiver/internal/metadata/generated_metrics_test.go index 00ac5eaf7063..2fbf1b7dab25 100644 --- a/receiver/apachereceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/apachereceiver/internal/metadata/generated_metrics_test.go @@ -54,6 +54,22 @@ func TestMetricsBuilder(t *testing.T) { defaultMetricsCount := 0 allMetricsCount := 0 + defaultMetricsCount++ + allMetricsCount++ + mb.RecordApacheBytesServedDataPoint(ts, "1") + + defaultMetricsCount++ + allMetricsCount++ + mb.RecordApacheConnsAsyncClosingDataPoint(ts, "1") + + defaultMetricsCount++ + allMetricsCount++ + mb.RecordApacheConnsAsyncKeepAliveDataPoint(ts, "1") + + defaultMetricsCount++ + allMetricsCount++ + mb.RecordApacheConnsAsyncWritingDataPoint(ts, "1") + defaultMetricsCount++ allMetricsCount++ mb.RecordApacheCPULoadDataPoint(ts, "1") @@ -127,6 +143,56 @@ func TestMetricsBuilder(t *testing.T) { validatedMetrics := make(map[string]bool) for i := 0; i < ms.Len(); i++ { switch ms.At(i).Name() { + case "apache.bytes_served": + assert.False(t, validatedMetrics["apache.bytes_served"], "Found a duplicate in the metrics slice: apache.bytes_served") + validatedMetrics["apache.bytes_served"] = true + assert.Equal(t, pmetric.MetricTypeSum, ms.At(i).Type()) + assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) + assert.Equal(t, "The total number of bytes served.", ms.At(i).Description()) + assert.Equal(t, "{byte}", ms.At(i).Unit()) + assert.Equal(t, true, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) + dp := ms.At(i).Sum().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()) + case "apache.conns_async_closing": + assert.False(t, validatedMetrics["apache.conns_async_closing"], "Found a duplicate in the metrics slice: apache.conns_async_closing") + validatedMetrics["apache.conns_async_closing"] = true + assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) + assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) + assert.Equal(t, "The number of asynchronous closing connections.", ms.At(i).Description()) + assert.Equal(t, "{connections}", 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()) + case "apache.conns_async_keep_alive": + assert.False(t, validatedMetrics["apache.conns_async_keep_alive"], "Found a duplicate in the metrics slice: apache.conns_async_keep_alive") + validatedMetrics["apache.conns_async_keep_alive"] = true + assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) + assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) + assert.Equal(t, "The number of asynchronous keep alive connections.", ms.At(i).Description()) + assert.Equal(t, "{connections}", 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()) + case "apache.conns_async_writing": + assert.False(t, validatedMetrics["apache.conns_async_writing"], "Found a duplicate in the metrics slice: apache.conns_async_writing") + validatedMetrics["apache.conns_async_writing"] = true + assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) + assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) + assert.Equal(t, "The number of asynchronous writes connections.", ms.At(i).Description()) + assert.Equal(t, "{connections}", 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()) case "apache.cpu.load": assert.False(t, validatedMetrics["apache.cpu.load"], "Found a duplicate in the metrics slice: apache.cpu.load") validatedMetrics["apache.cpu.load"] = true diff --git a/receiver/apachereceiver/internal/metadata/testdata/config.yaml b/receiver/apachereceiver/internal/metadata/testdata/config.yaml index 0afbe1b42a6a..003940c87f4b 100644 --- a/receiver/apachereceiver/internal/metadata/testdata/config.yaml +++ b/receiver/apachereceiver/internal/metadata/testdata/config.yaml @@ -1,6 +1,14 @@ default: all_set: metrics: + apache.bytes_served: + enabled: true + apache.conns_async_closing: + enabled: true + apache.conns_async_keep_alive: + enabled: true + apache.conns_async_writing: + enabled: true apache.cpu.load: enabled: true apache.cpu.time: @@ -32,6 +40,14 @@ all_set: enabled: true none_set: metrics: + apache.bytes_served: + enabled: false + apache.conns_async_closing: + enabled: false + apache.conns_async_keep_alive: + enabled: false + apache.conns_async_writing: + enabled: false apache.cpu.load: enabled: false apache.cpu.time: diff --git a/receiver/apachereceiver/metadata.yaml b/receiver/apachereceiver/metadata.yaml index a5bec812ed4a..3f609e91b485 100644 --- a/receiver/apachereceiver/metadata.yaml +++ b/receiver/apachereceiver/metadata.yaml @@ -173,3 +173,37 @@ metrics: monotonic: false aggregation_temporality: cumulative attributes: [scoreboard_state] + apache.conns_async_closing: + enabled: true + description: The number of asynchronous closing connections. + unit: "{connections}" + gauge: + value_type: int + input_type: string + attributes: [] + apache.conns_async_keep_alive: + enabled: true + description: The number of asynchronous keep alive connections. + unit: "{connections}" + gauge: + value_type: int + input_type: string + attributes: [] + apache.conns_async_writing: + enabled: true + description: The number of asynchronous writes connections. + unit: "{connections}" + gauge: + value_type: int + input_type: string + attributes: [] + apache.bytes_served: + enabled: true + description: The total number of bytes served. + unit: "{byte}" + sum: + value_type: int + input_type: string + monotonic: true + aggregation_temporality: cumulative + attributes: [] diff --git a/receiver/apachereceiver/scraper.go b/receiver/apachereceiver/scraper.go index 409d701e756e..469f6a061350 100644 --- a/receiver/apachereceiver/scraper.go +++ b/receiver/apachereceiver/scraper.go @@ -124,6 +124,14 @@ func (r *apacheScraper) scrape(context.Context) (pmetric.Metrics, error) { for state, score := range scoreboardMap { r.mb.RecordApacheScoreboardDataPoint(now, score, state) } + case "ConnsAsyncClosing": + addPartialIfError(errs, r.mb.RecordApacheConnsAsyncClosingDataPoint(now, metricValue)) + case "ConnsAsyncKeepAlive": + addPartialIfError(errs, r.mb.RecordApacheConnsAsyncKeepAliveDataPoint(now, metricValue)) + case "ConnsAsyncWriting": + addPartialIfError(errs, r.mb.RecordApacheConnsAsyncWritingDataPoint(now, metricValue)) + case "BytesPerSec": + addPartialIfError(errs, r.mb.RecordApacheBytesServedDataPoint(now, metricValue)) } } diff --git a/receiver/apachereceiver/scraper_test.go b/receiver/apachereceiver/scraper_test.go index 51f7e66f9ece..34423ba94e59 100644 --- a/receiver/apachereceiver/scraper_test.go +++ b/receiver/apachereceiver/scraper_test.go @@ -50,8 +50,9 @@ func TestScraper(t *testing.T) { expectedMetrics.ResourceMetrics().At(0).Resource().Attributes().PutStr("apache.server.port", url.Port()) // The port is random, so we shouldn't check if this value matches. - require.NoError(t, pmetrictest.CompareMetrics(expectedMetrics, actualMetrics, - pmetrictest.IgnoreMetricDataPointsOrder(), pmetrictest.IgnoreStartTimestamp(), pmetrictest.IgnoreTimestamp())) + require.NoError(t, pmetrictest.CompareMetrics(actualMetrics, expectedMetrics, pmetrictest.IgnoreMetricsOrder(), pmetrictest.IgnoreMetricDataPointsOrder(), + pmetrictest.IgnoreStartTimestamp(), pmetrictest.IgnoreTimestamp(), + )) } func TestScraperFailedStart(t *testing.T) { @@ -185,6 +186,10 @@ Load1: 0.9 Load5: 0.4 Load15: 0.3 Total Duration: 1501 +ConnsAsyncClosing: 0 +ConnsAsyncKeepAlive: 1 +ConnsAsyncWriting: 1 +BytesPerSec: 222230 Scoreboard: S_DD_L_GGG_____W__IIII_C________________W__________________________________.........................____WR______W____W________________________C______________________________________W_W____W______________R_________R________C_________WK_W________K_____W__C__________W___R______............................................................................................................................. `)) require.NoError(t, err) diff --git a/receiver/apachereceiver/testdata/integration/expected.yaml b/receiver/apachereceiver/testdata/integration/expected.yaml index b658dedcb444..fc4e4f8fd719 100644 --- a/receiver/apachereceiver/testdata/integration/expected.yaml +++ b/receiver/apachereceiver/testdata/integration/expected.yaml @@ -214,6 +214,37 @@ resourceMetrics: stringValue: idle timeUnixNano: "1632495518500962000" unit: '{workers}' + - description: The number of asynchronous closing connections. + gauge: + dataPoints: + - asInt: 0 + timeUnixNano: "1632495518500962000" + name: apache.conns_async_closing + unit: '{connections}' + - description: The number of asynchronous keep alive connections. + gauge: + dataPoints: + - asInt: 1 + timeUnixNano: "1632495518500962000" + name: apache.conns_async_keep_alive + unit: '{connections}' + - description: The number of asynchronous writes connections. + gauge: + dataPoints: + - asInt: 1 + timeUnixNano: "1632495518500962000" + name: apache.conns_async_writing + unit: '{connections}' + - description: The total number of bytes served. + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: 222230 + timeUnixNano: "1632495518500962000" + isMonotonic: true + name: apache.bytes_served + unit: '{byte}' + scope: name: otelcol/apachereceiver version: latest diff --git a/receiver/apachereceiver/testdata/scraper/expected.yaml b/receiver/apachereceiver/testdata/scraper/expected.yaml index 83bf3862fb66..50aab6eca8ad 100644 --- a/receiver/apachereceiver/testdata/scraper/expected.yaml +++ b/receiver/apachereceiver/testdata/scraper/expected.yaml @@ -214,6 +214,36 @@ resourceMetrics: stringValue: idle timeUnixNano: "1000000" unit: '{workers}' + - description: The number of asynchronous closing connections. + name: apache.conns_async_closing + gauge: + dataPoints: + - asInt: 0 + timeUnixNano: "1000000" + unit: '{connections}' + - description: The number of asynchronous keep alive connections. + name: apache.conns_async_keep_alive + gauge: + dataPoints: + - asInt: 1 + timeUnixNano: "1000000" + unit: '{connections}' + - description: The number of asynchronous writes connections. + name: apache.conns_async_writing + gauge: + dataPoints: + - asInt: 1 + timeUnixNano: "1000000" + unit: '{connections}' + - description: The total number of bytes served. + name: apache.bytes_served + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: 222230 + timeUnixNano: "1000000" + isMonotonic: true + unit: '{byte}' scope: name: otelcol/apachereceiver version: latest