From 2567bd376a29793a5da0f807deb77e5daf5b6580 Mon Sep 17 00:00:00 2001 From: Paulo Dias Date: Mon, 1 Sep 2025 23:31:09 +0100 Subject: [PATCH 01/12] [receiver/redisreceiver] Add support for Redis sentinel information Signed-off-by: Paulo Dias --- .chloggen/feat_42365.yaml | 27 + receiver/redisreceiver/documentation.md | 70 +++ .../internal/metadata/generated_config.go | 32 ++ .../metadata/generated_config_test.go | 16 + .../internal/metadata/generated_metrics.go | 522 ++++++++++++++++++ .../metadata/generated_metrics_test.go | 133 +++++ .../internal/metadata/testdata/config.yaml | 32 ++ receiver/redisreceiver/latencystats.go | 4 +- receiver/redisreceiver/metadata.yaml | 69 ++- receiver/redisreceiver/redis_scraper.go | 83 ++- receiver/redisreceiver/redis_scraper_test.go | 6 +- 11 files changed, 986 insertions(+), 8 deletions(-) create mode 100644 .chloggen/feat_42365.yaml diff --git a/.chloggen/feat_42365.yaml b/.chloggen/feat_42365.yaml new file mode 100644 index 0000000000000..8ff293468e5c4 --- /dev/null +++ b/.chloggen/feat_42365.yaml @@ -0,0 +1,27 @@ +# Use this changelog template to create an entry for release notes. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: "enhancement" + +# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) +component: "redisreceiver" + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: "Add support for redis.mode and redis.sentinel.* metrics" + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [42365] + +# (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: + +# If your change doesn't affect end users or the exported elements of any package, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [user] diff --git a/receiver/redisreceiver/documentation.md b/receiver/redisreceiver/documentation.md index 48fbc78e9d02e..e5f801b52408e 100644 --- a/receiver/redisreceiver/documentation.md +++ b/receiver/redisreceiver/documentation.md @@ -212,6 +212,20 @@ Total number of bytes allocated by Redis using its allocator | ---- | ----------- | ---------- | | By | Gauge | Int | +### redis.mode + +Redis server mode + +| Unit | Metric Type | Value Type | +| ---- | ----------- | ---------- | +| {state} | Gauge | Int | + +#### Attributes + +| Name | Description | Values | Optional | +| ---- | ----------- | ------ | -------- | +| mode | Redis server mode | Str: ``cluster``, ``sentinel``, ``standalone`` | false | + ### redis.net.input The total number of bytes read from the network @@ -252,6 +266,62 @@ The server's current replication offset | ---- | ----------- | ---------- | | By | Gauge | Int | +### redis.sentinel.masters + +Number of masters monitored by Sentinel. + +| Unit | Metric Type | Value Type | +| ---- | ----------- | ---------- | +| {masters} | Gauge | Int | + +### redis.sentinel.running_scripts + +Number of running Sentinel scripts. + +| Unit | Metric Type | Value Type | +| ---- | ----------- | ---------- | +| {scripts} | Gauge | Int | + +### redis.sentinel.scripts_queue_length + +Length of Sentinel scripts queue. + +| Unit | Metric Type | Value Type | +| ---- | ----------- | ---------- | +| {scripts} | Gauge | Int | + +### redis.sentinel.simulate_failure_flags + +Simulated failure flags bitmask. + +| Unit | Metric Type | Value Type | +| ---- | ----------- | ---------- | +| {flags} | Gauge | Int | + +### redis.sentinel.tilt + +Whether Sentinel is in TILT mode (1 = tilt, 0 = normal). + +| Unit | Metric Type | Value Type | +| ---- | ----------- | ---------- | +| {state} | Gauge | Int | + +### redis.sentinel.tilt_since_seconds + +Duration in seconds of current TILT, or -1 if not in TILT mode. + +| Unit | Metric Type | Value Type | +| ---- | ----------- | ---------- | +| s | Gauge | Int | + +### redis.sentinel.total_tilt + +Total TILT occurrences since start. + +| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic | +| ---- | ----------- | ---------- | ----------------------- | --------- | +| {events} | Sum | Int | Cumulative | true | + ### redis.slaves.connected Number of connected replicas diff --git a/receiver/redisreceiver/internal/metadata/generated_config.go b/receiver/redisreceiver/internal/metadata/generated_config.go index 1eb628b7220da..df25306160182 100644 --- a/receiver/redisreceiver/internal/metadata/generated_config.go +++ b/receiver/redisreceiver/internal/metadata/generated_config.go @@ -54,6 +54,7 @@ type MetricsConfig struct { RedisMemoryPeak MetricConfig `mapstructure:"redis.memory.peak"` RedisMemoryRss MetricConfig `mapstructure:"redis.memory.rss"` RedisMemoryUsed MetricConfig `mapstructure:"redis.memory.used"` + RedisMode MetricConfig `mapstructure:"redis.mode"` RedisNetInput MetricConfig `mapstructure:"redis.net.input"` RedisNetOutput MetricConfig `mapstructure:"redis.net.output"` RedisRdbChangesSinceLastSave MetricConfig `mapstructure:"redis.rdb.changes_since_last_save"` @@ -61,6 +62,13 @@ type MetricsConfig struct { RedisReplicationOffset MetricConfig `mapstructure:"redis.replication.offset"` RedisReplicationReplicaOffset MetricConfig `mapstructure:"redis.replication.replica_offset"` RedisRole MetricConfig `mapstructure:"redis.role"` + RedisSentinelMasters MetricConfig `mapstructure:"redis.sentinel.masters"` + RedisSentinelRunningScripts MetricConfig `mapstructure:"redis.sentinel.running_scripts"` + RedisSentinelScriptsQueueLength MetricConfig `mapstructure:"redis.sentinel.scripts_queue_length"` + RedisSentinelSimulateFailureFlags MetricConfig `mapstructure:"redis.sentinel.simulate_failure_flags"` + RedisSentinelTilt MetricConfig `mapstructure:"redis.sentinel.tilt"` + RedisSentinelTiltSinceSeconds MetricConfig `mapstructure:"redis.sentinel.tilt_since_seconds"` + RedisSentinelTotalTilt MetricConfig `mapstructure:"redis.sentinel.total_tilt"` RedisSlavesConnected MetricConfig `mapstructure:"redis.slaves.connected"` RedisUptime MetricConfig `mapstructure:"redis.uptime"` } @@ -145,6 +153,9 @@ func DefaultMetricsConfig() MetricsConfig { RedisMemoryUsed: MetricConfig{ Enabled: true, }, + RedisMode: MetricConfig{ + Enabled: true, + }, RedisNetInput: MetricConfig{ Enabled: true, }, @@ -166,6 +177,27 @@ func DefaultMetricsConfig() MetricsConfig { RedisRole: MetricConfig{ Enabled: false, }, + RedisSentinelMasters: MetricConfig{ + Enabled: true, + }, + RedisSentinelRunningScripts: MetricConfig{ + Enabled: true, + }, + RedisSentinelScriptsQueueLength: MetricConfig{ + Enabled: true, + }, + RedisSentinelSimulateFailureFlags: MetricConfig{ + Enabled: true, + }, + RedisSentinelTilt: MetricConfig{ + Enabled: true, + }, + RedisSentinelTiltSinceSeconds: MetricConfig{ + Enabled: true, + }, + RedisSentinelTotalTilt: MetricConfig{ + Enabled: true, + }, RedisSlavesConnected: MetricConfig{ Enabled: true, }, diff --git a/receiver/redisreceiver/internal/metadata/generated_config_test.go b/receiver/redisreceiver/internal/metadata/generated_config_test.go index e1b310f67fa49..dfb17365e7654 100644 --- a/receiver/redisreceiver/internal/metadata/generated_config_test.go +++ b/receiver/redisreceiver/internal/metadata/generated_config_test.go @@ -53,6 +53,7 @@ func TestMetricsBuilderConfig(t *testing.T) { RedisMemoryPeak: MetricConfig{Enabled: true}, RedisMemoryRss: MetricConfig{Enabled: true}, RedisMemoryUsed: MetricConfig{Enabled: true}, + RedisMode: MetricConfig{Enabled: true}, RedisNetInput: MetricConfig{Enabled: true}, RedisNetOutput: MetricConfig{Enabled: true}, RedisRdbChangesSinceLastSave: MetricConfig{Enabled: true}, @@ -60,6 +61,13 @@ func TestMetricsBuilderConfig(t *testing.T) { RedisReplicationOffset: MetricConfig{Enabled: true}, RedisReplicationReplicaOffset: MetricConfig{Enabled: true}, RedisRole: MetricConfig{Enabled: true}, + RedisSentinelMasters: MetricConfig{Enabled: true}, + RedisSentinelRunningScripts: MetricConfig{Enabled: true}, + RedisSentinelScriptsQueueLength: MetricConfig{Enabled: true}, + RedisSentinelSimulateFailureFlags: MetricConfig{Enabled: true}, + RedisSentinelTilt: MetricConfig{Enabled: true}, + RedisSentinelTiltSinceSeconds: MetricConfig{Enabled: true}, + RedisSentinelTotalTilt: MetricConfig{Enabled: true}, RedisSlavesConnected: MetricConfig{Enabled: true}, RedisUptime: MetricConfig{Enabled: true}, }, @@ -100,6 +108,7 @@ func TestMetricsBuilderConfig(t *testing.T) { RedisMemoryPeak: MetricConfig{Enabled: false}, RedisMemoryRss: MetricConfig{Enabled: false}, RedisMemoryUsed: MetricConfig{Enabled: false}, + RedisMode: MetricConfig{Enabled: false}, RedisNetInput: MetricConfig{Enabled: false}, RedisNetOutput: MetricConfig{Enabled: false}, RedisRdbChangesSinceLastSave: MetricConfig{Enabled: false}, @@ -107,6 +116,13 @@ func TestMetricsBuilderConfig(t *testing.T) { RedisReplicationOffset: MetricConfig{Enabled: false}, RedisReplicationReplicaOffset: MetricConfig{Enabled: false}, RedisRole: MetricConfig{Enabled: false}, + RedisSentinelMasters: MetricConfig{Enabled: false}, + RedisSentinelRunningScripts: MetricConfig{Enabled: false}, + RedisSentinelScriptsQueueLength: MetricConfig{Enabled: false}, + RedisSentinelSimulateFailureFlags: MetricConfig{Enabled: false}, + RedisSentinelTilt: MetricConfig{Enabled: false}, + RedisSentinelTiltSinceSeconds: MetricConfig{Enabled: false}, + RedisSentinelTotalTilt: MetricConfig{Enabled: false}, RedisSlavesConnected: MetricConfig{Enabled: false}, RedisUptime: MetricConfig{Enabled: false}, }, diff --git a/receiver/redisreceiver/internal/metadata/generated_metrics.go b/receiver/redisreceiver/internal/metadata/generated_metrics.go index 715898e73c030..17de50220ef30 100644 --- a/receiver/redisreceiver/internal/metadata/generated_metrics.go +++ b/receiver/redisreceiver/internal/metadata/generated_metrics.go @@ -12,6 +12,36 @@ import ( "go.opentelemetry.io/collector/receiver" ) +// AttributeMode specifies the value mode attribute. +type AttributeMode int + +const ( + _ AttributeMode = iota + AttributeModeCluster + AttributeModeSentinel + AttributeModeStandalone +) + +// String returns the string representation of the AttributeMode. +func (av AttributeMode) String() string { + switch av { + case AttributeModeCluster: + return "cluster" + case AttributeModeSentinel: + return "sentinel" + case AttributeModeStandalone: + return "standalone" + } + return "" +} + +// MapAttributeMode is a helper map of string to AttributeMode attribute value. +var MapAttributeMode = map[string]AttributeMode{ + "cluster": AttributeModeCluster, + "sentinel": AttributeModeSentinel, + "standalone": AttributeModeStandalone, +} + // AttributePercentile specifies the value percentile attribute. type AttributePercentile int @@ -189,6 +219,9 @@ var MetricsInfo = metricsInfo{ RedisMemoryUsed: metricInfo{ Name: "redis.memory.used", }, + RedisMode: metricInfo{ + Name: "redis.mode", + }, RedisNetInput: metricInfo{ Name: "redis.net.input", }, @@ -210,6 +243,27 @@ var MetricsInfo = metricsInfo{ RedisRole: metricInfo{ Name: "redis.role", }, + RedisSentinelMasters: metricInfo{ + Name: "redis.sentinel.masters", + }, + RedisSentinelRunningScripts: metricInfo{ + Name: "redis.sentinel.running_scripts", + }, + RedisSentinelScriptsQueueLength: metricInfo{ + Name: "redis.sentinel.scripts_queue_length", + }, + RedisSentinelSimulateFailureFlags: metricInfo{ + Name: "redis.sentinel.simulate_failure_flags", + }, + RedisSentinelTilt: metricInfo{ + Name: "redis.sentinel.tilt", + }, + RedisSentinelTiltSinceSeconds: metricInfo{ + Name: "redis.sentinel.tilt_since_seconds", + }, + RedisSentinelTotalTilt: metricInfo{ + Name: "redis.sentinel.total_tilt", + }, RedisSlavesConnected: metricInfo{ Name: "redis.slaves.connected", }, @@ -245,6 +299,7 @@ type metricsInfo struct { RedisMemoryPeak metricInfo RedisMemoryRss metricInfo RedisMemoryUsed metricInfo + RedisMode metricInfo RedisNetInput metricInfo RedisNetOutput metricInfo RedisRdbChangesSinceLastSave metricInfo @@ -252,6 +307,13 @@ type metricsInfo struct { RedisReplicationOffset metricInfo RedisReplicationReplicaOffset metricInfo RedisRole metricInfo + RedisSentinelMasters metricInfo + RedisSentinelRunningScripts metricInfo + RedisSentinelScriptsQueueLength metricInfo + RedisSentinelSimulateFailureFlags metricInfo + RedisSentinelTilt metricInfo + RedisSentinelTiltSinceSeconds metricInfo + RedisSentinelTotalTilt metricInfo RedisSlavesConnected metricInfo RedisUptime metricInfo } @@ -1573,6 +1635,57 @@ func newMetricRedisMemoryUsed(cfg MetricConfig) metricRedisMemoryUsed { return m } +type metricRedisMode 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 redis.mode metric with initial data. +func (m *metricRedisMode) init() { + m.data.SetName("redis.mode") + m.data.SetDescription("Redis server mode") + m.data.SetUnit("{state}") + m.data.SetEmptyGauge() + m.data.Gauge().DataPoints().EnsureCapacity(m.capacity) +} + +func (m *metricRedisMode) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, modeAttributeValue string) { + if !m.config.Enabled { + return + } + dp := m.data.Gauge().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntValue(val) + dp.Attributes().PutStr("mode", modeAttributeValue) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricRedisMode) 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 *metricRedisMode) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricRedisMode(cfg MetricConfig) metricRedisMode { + m := metricRedisMode{config: cfg} + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + type metricRedisNetInput struct { data pmetric.Metric // data buffer for generated metric. config MetricConfig // metric config provided by user. @@ -1926,6 +2039,351 @@ func newMetricRedisRole(cfg MetricConfig) metricRedisRole { return m } +type metricRedisSentinelMasters 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 redis.sentinel.masters metric with initial data. +func (m *metricRedisSentinelMasters) init() { + m.data.SetName("redis.sentinel.masters") + m.data.SetDescription("Number of masters monitored by Sentinel.") + m.data.SetUnit("{masters}") + m.data.SetEmptyGauge() +} + +func (m *metricRedisSentinelMasters) 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 *metricRedisSentinelMasters) 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 *metricRedisSentinelMasters) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricRedisSentinelMasters(cfg MetricConfig) metricRedisSentinelMasters { + m := metricRedisSentinelMasters{config: cfg} + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricRedisSentinelRunningScripts 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 redis.sentinel.running_scripts metric with initial data. +func (m *metricRedisSentinelRunningScripts) init() { + m.data.SetName("redis.sentinel.running_scripts") + m.data.SetDescription("Number of running Sentinel scripts.") + m.data.SetUnit("{scripts}") + m.data.SetEmptyGauge() +} + +func (m *metricRedisSentinelRunningScripts) 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 *metricRedisSentinelRunningScripts) 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 *metricRedisSentinelRunningScripts) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricRedisSentinelRunningScripts(cfg MetricConfig) metricRedisSentinelRunningScripts { + m := metricRedisSentinelRunningScripts{config: cfg} + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricRedisSentinelScriptsQueueLength 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 redis.sentinel.scripts_queue_length metric with initial data. +func (m *metricRedisSentinelScriptsQueueLength) init() { + m.data.SetName("redis.sentinel.scripts_queue_length") + m.data.SetDescription("Length of Sentinel scripts queue.") + m.data.SetUnit("{scripts}") + m.data.SetEmptyGauge() +} + +func (m *metricRedisSentinelScriptsQueueLength) 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 *metricRedisSentinelScriptsQueueLength) 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 *metricRedisSentinelScriptsQueueLength) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricRedisSentinelScriptsQueueLength(cfg MetricConfig) metricRedisSentinelScriptsQueueLength { + m := metricRedisSentinelScriptsQueueLength{config: cfg} + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricRedisSentinelSimulateFailureFlags 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 redis.sentinel.simulate_failure_flags metric with initial data. +func (m *metricRedisSentinelSimulateFailureFlags) init() { + m.data.SetName("redis.sentinel.simulate_failure_flags") + m.data.SetDescription("Simulated failure flags bitmask.") + m.data.SetUnit("{flags}") + m.data.SetEmptyGauge() +} + +func (m *metricRedisSentinelSimulateFailureFlags) 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 *metricRedisSentinelSimulateFailureFlags) 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 *metricRedisSentinelSimulateFailureFlags) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricRedisSentinelSimulateFailureFlags(cfg MetricConfig) metricRedisSentinelSimulateFailureFlags { + m := metricRedisSentinelSimulateFailureFlags{config: cfg} + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricRedisSentinelTilt 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 redis.sentinel.tilt metric with initial data. +func (m *metricRedisSentinelTilt) init() { + m.data.SetName("redis.sentinel.tilt") + m.data.SetDescription("Whether Sentinel is in TILT mode (1 = tilt, 0 = normal).") + m.data.SetUnit("{state}") + m.data.SetEmptyGauge() +} + +func (m *metricRedisSentinelTilt) 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 *metricRedisSentinelTilt) 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 *metricRedisSentinelTilt) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricRedisSentinelTilt(cfg MetricConfig) metricRedisSentinelTilt { + m := metricRedisSentinelTilt{config: cfg} + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricRedisSentinelTiltSinceSeconds 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 redis.sentinel.tilt_since_seconds metric with initial data. +func (m *metricRedisSentinelTiltSinceSeconds) init() { + m.data.SetName("redis.sentinel.tilt_since_seconds") + m.data.SetDescription("Duration in seconds of current TILT, or -1 if not in TILT mode.") + m.data.SetUnit("s") + m.data.SetEmptyGauge() +} + +func (m *metricRedisSentinelTiltSinceSeconds) 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 *metricRedisSentinelTiltSinceSeconds) 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 *metricRedisSentinelTiltSinceSeconds) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricRedisSentinelTiltSinceSeconds(cfg MetricConfig) metricRedisSentinelTiltSinceSeconds { + m := metricRedisSentinelTiltSinceSeconds{config: cfg} + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricRedisSentinelTotalTilt 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 redis.sentinel.total_tilt metric with initial data. +func (m *metricRedisSentinelTotalTilt) init() { + m.data.SetName("redis.sentinel.total_tilt") + m.data.SetDescription("Total TILT occurrences since start.") + m.data.SetUnit("{events}") + m.data.SetEmptySum() + m.data.Sum().SetIsMonotonic(true) + m.data.Sum().SetAggregationTemporality(pmetric.AggregationTemporalityCumulative) +} + +func (m *metricRedisSentinelTotalTilt) 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 *metricRedisSentinelTotalTilt) 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 *metricRedisSentinelTotalTilt) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricRedisSentinelTotalTilt(cfg MetricConfig) metricRedisSentinelTotalTilt { + m := metricRedisSentinelTotalTilt{config: cfg} + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + type metricRedisSlavesConnected struct { data pmetric.Metric // data buffer for generated metric. config MetricConfig // metric config provided by user. @@ -2064,6 +2522,7 @@ type MetricsBuilder struct { metricRedisMemoryPeak metricRedisMemoryPeak metricRedisMemoryRss metricRedisMemoryRss metricRedisMemoryUsed metricRedisMemoryUsed + metricRedisMode metricRedisMode metricRedisNetInput metricRedisNetInput metricRedisNetOutput metricRedisNetOutput metricRedisRdbChangesSinceLastSave metricRedisRdbChangesSinceLastSave @@ -2071,6 +2530,13 @@ type MetricsBuilder struct { metricRedisReplicationOffset metricRedisReplicationOffset metricRedisReplicationReplicaOffset metricRedisReplicationReplicaOffset metricRedisRole metricRedisRole + metricRedisSentinelMasters metricRedisSentinelMasters + metricRedisSentinelRunningScripts metricRedisSentinelRunningScripts + metricRedisSentinelScriptsQueueLength metricRedisSentinelScriptsQueueLength + metricRedisSentinelSimulateFailureFlags metricRedisSentinelSimulateFailureFlags + metricRedisSentinelTilt metricRedisSentinelTilt + metricRedisSentinelTiltSinceSeconds metricRedisSentinelTiltSinceSeconds + metricRedisSentinelTotalTilt metricRedisSentinelTotalTilt metricRedisSlavesConnected metricRedisSlavesConnected metricRedisUptime metricRedisUptime } @@ -2124,6 +2590,7 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.Settings, opt metricRedisMemoryPeak: newMetricRedisMemoryPeak(mbc.Metrics.RedisMemoryPeak), metricRedisMemoryRss: newMetricRedisMemoryRss(mbc.Metrics.RedisMemoryRss), metricRedisMemoryUsed: newMetricRedisMemoryUsed(mbc.Metrics.RedisMemoryUsed), + metricRedisMode: newMetricRedisMode(mbc.Metrics.RedisMode), metricRedisNetInput: newMetricRedisNetInput(mbc.Metrics.RedisNetInput), metricRedisNetOutput: newMetricRedisNetOutput(mbc.Metrics.RedisNetOutput), metricRedisRdbChangesSinceLastSave: newMetricRedisRdbChangesSinceLastSave(mbc.Metrics.RedisRdbChangesSinceLastSave), @@ -2131,6 +2598,13 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.Settings, opt metricRedisReplicationOffset: newMetricRedisReplicationOffset(mbc.Metrics.RedisReplicationOffset), metricRedisReplicationReplicaOffset: newMetricRedisReplicationReplicaOffset(mbc.Metrics.RedisReplicationReplicaOffset), metricRedisRole: newMetricRedisRole(mbc.Metrics.RedisRole), + metricRedisSentinelMasters: newMetricRedisSentinelMasters(mbc.Metrics.RedisSentinelMasters), + metricRedisSentinelRunningScripts: newMetricRedisSentinelRunningScripts(mbc.Metrics.RedisSentinelRunningScripts), + metricRedisSentinelScriptsQueueLength: newMetricRedisSentinelScriptsQueueLength(mbc.Metrics.RedisSentinelScriptsQueueLength), + metricRedisSentinelSimulateFailureFlags: newMetricRedisSentinelSimulateFailureFlags(mbc.Metrics.RedisSentinelSimulateFailureFlags), + metricRedisSentinelTilt: newMetricRedisSentinelTilt(mbc.Metrics.RedisSentinelTilt), + metricRedisSentinelTiltSinceSeconds: newMetricRedisSentinelTiltSinceSeconds(mbc.Metrics.RedisSentinelTiltSinceSeconds), + metricRedisSentinelTotalTilt: newMetricRedisSentinelTotalTilt(mbc.Metrics.RedisSentinelTotalTilt), metricRedisSlavesConnected: newMetricRedisSlavesConnected(mbc.Metrics.RedisSlavesConnected), metricRedisUptime: newMetricRedisUptime(mbc.Metrics.RedisUptime), resourceAttributeIncludeFilter: make(map[string]filter.Filter), @@ -2249,6 +2723,7 @@ func (mb *MetricsBuilder) EmitForResource(options ...ResourceMetricsOption) { mb.metricRedisMemoryPeak.emit(ils.Metrics()) mb.metricRedisMemoryRss.emit(ils.Metrics()) mb.metricRedisMemoryUsed.emit(ils.Metrics()) + mb.metricRedisMode.emit(ils.Metrics()) mb.metricRedisNetInput.emit(ils.Metrics()) mb.metricRedisNetOutput.emit(ils.Metrics()) mb.metricRedisRdbChangesSinceLastSave.emit(ils.Metrics()) @@ -2256,6 +2731,13 @@ func (mb *MetricsBuilder) EmitForResource(options ...ResourceMetricsOption) { mb.metricRedisReplicationOffset.emit(ils.Metrics()) mb.metricRedisReplicationReplicaOffset.emit(ils.Metrics()) mb.metricRedisRole.emit(ils.Metrics()) + mb.metricRedisSentinelMasters.emit(ils.Metrics()) + mb.metricRedisSentinelRunningScripts.emit(ils.Metrics()) + mb.metricRedisSentinelScriptsQueueLength.emit(ils.Metrics()) + mb.metricRedisSentinelSimulateFailureFlags.emit(ils.Metrics()) + mb.metricRedisSentinelTilt.emit(ils.Metrics()) + mb.metricRedisSentinelTiltSinceSeconds.emit(ils.Metrics()) + mb.metricRedisSentinelTotalTilt.emit(ils.Metrics()) mb.metricRedisSlavesConnected.emit(ils.Metrics()) mb.metricRedisUptime.emit(ils.Metrics()) @@ -2419,6 +2901,11 @@ func (mb *MetricsBuilder) RecordRedisMemoryUsedDataPoint(ts pcommon.Timestamp, v mb.metricRedisMemoryUsed.recordDataPoint(mb.startTime, ts, val) } +// RecordRedisModeDataPoint adds a data point to redis.mode metric. +func (mb *MetricsBuilder) RecordRedisModeDataPoint(ts pcommon.Timestamp, val int64, modeAttributeValue AttributeMode) { + mb.metricRedisMode.recordDataPoint(mb.startTime, ts, val, modeAttributeValue.String()) +} + // RecordRedisNetInputDataPoint adds a data point to redis.net.input metric. func (mb *MetricsBuilder) RecordRedisNetInputDataPoint(ts pcommon.Timestamp, val int64) { mb.metricRedisNetInput.recordDataPoint(mb.startTime, ts, val) @@ -2454,6 +2941,41 @@ func (mb *MetricsBuilder) RecordRedisRoleDataPoint(ts pcommon.Timestamp, val int mb.metricRedisRole.recordDataPoint(mb.startTime, ts, val, roleAttributeValue.String()) } +// RecordRedisSentinelMastersDataPoint adds a data point to redis.sentinel.masters metric. +func (mb *MetricsBuilder) RecordRedisSentinelMastersDataPoint(ts pcommon.Timestamp, val int64) { + mb.metricRedisSentinelMasters.recordDataPoint(mb.startTime, ts, val) +} + +// RecordRedisSentinelRunningScriptsDataPoint adds a data point to redis.sentinel.running_scripts metric. +func (mb *MetricsBuilder) RecordRedisSentinelRunningScriptsDataPoint(ts pcommon.Timestamp, val int64) { + mb.metricRedisSentinelRunningScripts.recordDataPoint(mb.startTime, ts, val) +} + +// RecordRedisSentinelScriptsQueueLengthDataPoint adds a data point to redis.sentinel.scripts_queue_length metric. +func (mb *MetricsBuilder) RecordRedisSentinelScriptsQueueLengthDataPoint(ts pcommon.Timestamp, val int64) { + mb.metricRedisSentinelScriptsQueueLength.recordDataPoint(mb.startTime, ts, val) +} + +// RecordRedisSentinelSimulateFailureFlagsDataPoint adds a data point to redis.sentinel.simulate_failure_flags metric. +func (mb *MetricsBuilder) RecordRedisSentinelSimulateFailureFlagsDataPoint(ts pcommon.Timestamp, val int64) { + mb.metricRedisSentinelSimulateFailureFlags.recordDataPoint(mb.startTime, ts, val) +} + +// RecordRedisSentinelTiltDataPoint adds a data point to redis.sentinel.tilt metric. +func (mb *MetricsBuilder) RecordRedisSentinelTiltDataPoint(ts pcommon.Timestamp, val int64) { + mb.metricRedisSentinelTilt.recordDataPoint(mb.startTime, ts, val) +} + +// RecordRedisSentinelTiltSinceSecondsDataPoint adds a data point to redis.sentinel.tilt_since_seconds metric. +func (mb *MetricsBuilder) RecordRedisSentinelTiltSinceSecondsDataPoint(ts pcommon.Timestamp, val int64) { + mb.metricRedisSentinelTiltSinceSeconds.recordDataPoint(mb.startTime, ts, val) +} + +// RecordRedisSentinelTotalTiltDataPoint adds a data point to redis.sentinel.total_tilt metric. +func (mb *MetricsBuilder) RecordRedisSentinelTotalTiltDataPoint(ts pcommon.Timestamp, val int64) { + mb.metricRedisSentinelTotalTilt.recordDataPoint(mb.startTime, ts, val) +} + // RecordRedisSlavesConnectedDataPoint adds a data point to redis.slaves.connected metric. func (mb *MetricsBuilder) RecordRedisSlavesConnectedDataPoint(ts pcommon.Timestamp, val int64) { mb.metricRedisSlavesConnected.recordDataPoint(mb.startTime, ts, val) diff --git a/receiver/redisreceiver/internal/metadata/generated_metrics_test.go b/receiver/redisreceiver/internal/metadata/generated_metrics_test.go index f4a12b8bf60a8..aca961cd77ce9 100644 --- a/receiver/redisreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/redisreceiver/internal/metadata/generated_metrics_test.go @@ -168,6 +168,10 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordRedisMemoryUsedDataPoint(ts, 1) + defaultMetricsCount++ + allMetricsCount++ + mb.RecordRedisModeDataPoint(ts, 1, AttributeModeCluster) + defaultMetricsCount++ allMetricsCount++ mb.RecordRedisNetInputDataPoint(ts, 1) @@ -194,6 +198,34 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordRedisRoleDataPoint(ts, 1, AttributeRoleReplica) + defaultMetricsCount++ + allMetricsCount++ + mb.RecordRedisSentinelMastersDataPoint(ts, 1) + + defaultMetricsCount++ + allMetricsCount++ + mb.RecordRedisSentinelRunningScriptsDataPoint(ts, 1) + + defaultMetricsCount++ + allMetricsCount++ + mb.RecordRedisSentinelScriptsQueueLengthDataPoint(ts, 1) + + defaultMetricsCount++ + allMetricsCount++ + mb.RecordRedisSentinelSimulateFailureFlagsDataPoint(ts, 1) + + defaultMetricsCount++ + allMetricsCount++ + mb.RecordRedisSentinelTiltDataPoint(ts, 1) + + defaultMetricsCount++ + allMetricsCount++ + mb.RecordRedisSentinelTiltSinceSecondsDataPoint(ts, 1) + + defaultMetricsCount++ + allMetricsCount++ + mb.RecordRedisSentinelTotalTiltDataPoint(ts, 1) + defaultMetricsCount++ allMetricsCount++ mb.RecordRedisSlavesConnectedDataPoint(ts, 1) @@ -588,6 +620,21 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, ts, dp.Timestamp()) assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) assert.Equal(t, int64(1), dp.IntValue()) + case "redis.mode": + assert.False(t, validatedMetrics["redis.mode"], "Found a duplicate in the metrics slice: redis.mode") + validatedMetrics["redis.mode"] = true + assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) + assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) + assert.Equal(t, "Redis server mode", ms.At(i).Description()) + assert.Equal(t, "{state}", 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("mode") + assert.True(t, ok) + assert.Equal(t, "cluster", attrVal.Str()) case "redis.net.input": assert.False(t, validatedMetrics["redis.net.input"], "Found a duplicate in the metrics slice: redis.net.input") validatedMetrics["redis.net.input"] = true @@ -683,6 +730,92 @@ func TestMetricsBuilder(t *testing.T) { attrVal, ok := dp.Attributes().Get("role") assert.True(t, ok) assert.Equal(t, "replica", attrVal.Str()) + case "redis.sentinel.masters": + assert.False(t, validatedMetrics["redis.sentinel.masters"], "Found a duplicate in the metrics slice: redis.sentinel.masters") + validatedMetrics["redis.sentinel.masters"] = true + assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) + assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) + assert.Equal(t, "Number of masters monitored by Sentinel.", ms.At(i).Description()) + assert.Equal(t, "{masters}", 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 "redis.sentinel.running_scripts": + assert.False(t, validatedMetrics["redis.sentinel.running_scripts"], "Found a duplicate in the metrics slice: redis.sentinel.running_scripts") + validatedMetrics["redis.sentinel.running_scripts"] = true + assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) + assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) + assert.Equal(t, "Number of running Sentinel scripts.", ms.At(i).Description()) + assert.Equal(t, "{scripts}", 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 "redis.sentinel.scripts_queue_length": + assert.False(t, validatedMetrics["redis.sentinel.scripts_queue_length"], "Found a duplicate in the metrics slice: redis.sentinel.scripts_queue_length") + validatedMetrics["redis.sentinel.scripts_queue_length"] = true + assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) + assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) + assert.Equal(t, "Length of Sentinel scripts queue.", ms.At(i).Description()) + assert.Equal(t, "{scripts}", 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 "redis.sentinel.simulate_failure_flags": + assert.False(t, validatedMetrics["redis.sentinel.simulate_failure_flags"], "Found a duplicate in the metrics slice: redis.sentinel.simulate_failure_flags") + validatedMetrics["redis.sentinel.simulate_failure_flags"] = true + assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) + assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) + assert.Equal(t, "Simulated failure flags bitmask.", ms.At(i).Description()) + assert.Equal(t, "{flags}", 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 "redis.sentinel.tilt": + assert.False(t, validatedMetrics["redis.sentinel.tilt"], "Found a duplicate in the metrics slice: redis.sentinel.tilt") + validatedMetrics["redis.sentinel.tilt"] = true + assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) + assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) + assert.Equal(t, "Whether Sentinel is in TILT mode (1 = tilt, 0 = normal).", ms.At(i).Description()) + assert.Equal(t, "{state}", 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 "redis.sentinel.tilt_since_seconds": + assert.False(t, validatedMetrics["redis.sentinel.tilt_since_seconds"], "Found a duplicate in the metrics slice: redis.sentinel.tilt_since_seconds") + validatedMetrics["redis.sentinel.tilt_since_seconds"] = true + assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) + assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) + assert.Equal(t, "Duration in seconds of current TILT, or -1 if not in TILT mode.", ms.At(i).Description()) + assert.Equal(t, "s", 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 "redis.sentinel.total_tilt": + assert.False(t, validatedMetrics["redis.sentinel.total_tilt"], "Found a duplicate in the metrics slice: redis.sentinel.total_tilt") + validatedMetrics["redis.sentinel.total_tilt"] = true + assert.Equal(t, pmetric.MetricTypeSum, ms.At(i).Type()) + assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) + assert.Equal(t, "Total TILT occurrences since start.", ms.At(i).Description()) + assert.Equal(t, "{events}", ms.At(i).Unit()) + assert.True(t, 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 "redis.slaves.connected": assert.False(t, validatedMetrics["redis.slaves.connected"], "Found a duplicate in the metrics slice: redis.slaves.connected") validatedMetrics["redis.slaves.connected"] = true diff --git a/receiver/redisreceiver/internal/metadata/testdata/config.yaml b/receiver/redisreceiver/internal/metadata/testdata/config.yaml index be12a9f4cdf89..2329fb528cfb3 100644 --- a/receiver/redisreceiver/internal/metadata/testdata/config.yaml +++ b/receiver/redisreceiver/internal/metadata/testdata/config.yaml @@ -53,6 +53,8 @@ all_set: enabled: true redis.memory.used: enabled: true + redis.mode: + enabled: true redis.net.input: enabled: true redis.net.output: @@ -67,6 +69,20 @@ all_set: enabled: true redis.role: enabled: true + redis.sentinel.masters: + enabled: true + redis.sentinel.running_scripts: + enabled: true + redis.sentinel.scripts_queue_length: + enabled: true + redis.sentinel.simulate_failure_flags: + enabled: true + redis.sentinel.tilt: + enabled: true + redis.sentinel.tilt_since_seconds: + enabled: true + redis.sentinel.total_tilt: + enabled: true redis.slaves.connected: enabled: true redis.uptime: @@ -132,6 +148,8 @@ none_set: enabled: false redis.memory.used: enabled: false + redis.mode: + enabled: false redis.net.input: enabled: false redis.net.output: @@ -146,6 +164,20 @@ none_set: enabled: false redis.role: enabled: false + redis.sentinel.masters: + enabled: false + redis.sentinel.running_scripts: + enabled: false + redis.sentinel.scripts_queue_length: + enabled: false + redis.sentinel.simulate_failure_flags: + enabled: false + redis.sentinel.tilt: + enabled: false + redis.sentinel.tilt_since_seconds: + enabled: false + redis.sentinel.total_tilt: + enabled: false redis.slaves.connected: enabled: false redis.uptime: diff --git a/receiver/redisreceiver/latencystats.go b/receiver/redisreceiver/latencystats.go index fdfecc08a1b6a..1dcabab9c270d 100644 --- a/receiver/redisreceiver/latencystats.go +++ b/receiver/redisreceiver/latencystats.go @@ -17,9 +17,9 @@ type latencies map[string]float64 func parseLatencyStats(str string) (latencies, error) { res := make(latencies) - pairs := strings.Split(strings.TrimSpace(str), ",") + pairs := strings.SplitSeq(strings.TrimSpace(str), ",") - for _, pairStr := range pairs { + for pairStr := range pairs { pair := strings.Split(pairStr, "=") if len(pair) != 2 { return nil, fmt.Errorf("unexpected latency percentiles pair '%s'", pairStr) diff --git a/receiver/redisreceiver/metadata.yaml b/receiver/redisreceiver/metadata.yaml index 7153d9fada763..39ee9688b65af 100644 --- a/receiver/redisreceiver/metadata.yaml +++ b/receiver/redisreceiver/metadata.yaml @@ -60,6 +60,13 @@ attributes: - p50 - p99 - p99.9 + mode: + description: Redis server mode + type: string + enum: + - cluster + - sentinel + - standalone metrics: redis.maxmemory: @@ -167,7 +174,6 @@ metrics: monotonic: true aggregation_temporality: cumulative - redis.keys.evicted: enabled: true description: Number of evicted keys due to maxmemory limit @@ -200,7 +206,7 @@ metrics: description: Total number of bytes allocated by Redis using its allocator unit: By gauge: - value_type: int + value_type: int redis.memory.peak: enabled: true @@ -291,6 +297,14 @@ metrics: monotonic: true aggregation_temporality: cumulative + redis.mode: + enabled: true + description: Redis server mode + unit: "{state}" + gauge: + value_type: int + attributes: [mode] + redis.latest_fork: enabled: true description: Duration of the latest fork operation in microseconds @@ -321,6 +335,57 @@ metrics: gauge: value_type: int + redis.sentinel.masters: + enabled: true + description: Number of masters monitored by Sentinel. + unit: "{masters}" + gauge: + value_type: int + + redis.sentinel.tilt: + enabled: true + description: Whether Sentinel is in TILT mode (1 = tilt, 0 = normal). + unit: "{state}" + gauge: + value_type: int + + redis.sentinel.tilt_since_seconds: + enabled: true + description: Duration in seconds of current TILT, or -1 if not in TILT mode. + unit: "s" + gauge: + value_type: int + + redis.sentinel.total_tilt: + enabled: true + description: Total TILT occurrences since start. + unit: "{events}" + sum: + value_type: int + monotonic: true + aggregation_temporality: cumulative + + redis.sentinel.running_scripts: + enabled: true + description: Number of running Sentinel scripts. + unit: "{scripts}" + gauge: + value_type: int + + redis.sentinel.scripts_queue_length: + enabled: true + description: Length of Sentinel scripts queue. + unit: "{scripts}" + gauge: + value_type: int + + redis.sentinel.simulate_failure_flags: + enabled: true + description: Simulated failure flags bitmask. + unit: "{flags}" + gauge: + value_type: int + redis.db.keys: enabled: true description: "Number of keyspace keys" diff --git a/receiver/redisreceiver/redis_scraper.go b/receiver/redisreceiver/redis_scraper.go index f568e2e4be486..9cb14b43922e0 100644 --- a/receiver/redisreceiver/redis_scraper.go +++ b/receiver/redisreceiver/redis_scraper.go @@ -95,10 +95,18 @@ func (rs *redisScraper) Scrape(context.Context) (pmetric.Metrics, error) { } rs.uptime = currentUptime + mode := rs.getRedisMode(inf) + rs.recordCommonMetrics(now, inf) rs.recordKeyspaceMetrics(now, inf) rs.recordRoleMetrics(now, inf) rs.recordCmdMetrics(now, inf) + rs.recordModeMetrics(now, mode) + + if mode == "sentinel" { + rs.recordSentinelMetrics(now, inf) + } + rb := rs.mb.NewResourceBuilder() rb.SetRedisVersion(rs.getRedisVersion(inf)) rb.SetServerAddress(rs.configInfo.Address) @@ -164,6 +172,28 @@ func (*redisScraper) getRedisVersion(inf info) string { return "unknown" } +// getRedisMode retrieves mode string from 'redis_mode' Redis info key-value pairs +// e.g. "redis_mode:standalone" +func (*redisScraper) getRedisMode(inf info) string { + if str, ok := inf["redis_mode"]; ok { + return str + } + return "unknown" +} + +// recordModeMetrics records metrics from 'redis_mode' Redis info key-value pairs +// e.g. "redis_mode:standalone" +func (rs *redisScraper) recordModeMetrics(ts pcommon.Timestamp, mode string) { + switch mode { + case "cluster": + rs.mb.RecordRedisModeDataPoint(ts, 1, metadata.AttributeModeCluster) + case "sentinel": + rs.mb.RecordRedisModeDataPoint(ts, 1, metadata.AttributeModeSentinel) + case "standalone": + rs.mb.RecordRedisModeDataPoint(ts, 1, metadata.AttributeModeStandalone) + } +} + // recordRoleMetrics records metrics from 'role' Redis info key-value pairs // e.g. "role:master" func (rs *redisScraper) recordRoleMetrics(ts pcommon.Timestamp, inf info) { @@ -199,8 +229,8 @@ func (rs *redisScraper) recordCmdMetrics(ts pcommon.Timestamp, inf info) { // Only 'calls' and 'usec' are recorded at the moment. // 'cmd' is the Redis command, 'val' is the values string (e.g. "calls=1685,usec=6032,usec_per_call=3.58,rejected_calls=0,failed_calls=0"). func (rs *redisScraper) recordCmdStatsMetrics(ts pcommon.Timestamp, cmd, val string) { - parts := strings.Split(strings.TrimSpace(val), ",") - for _, element := range parts { + parts := strings.SplitSeq(strings.TrimSpace(val), ",") + for element := range parts { subParts := strings.Split(element, "=") if len(subParts) == 1 { continue @@ -234,3 +264,52 @@ func (rs *redisScraper) recordCmdLatencyMetrics(ts pcommon.Timestamp, cmd, val s } } } + +// recordSentinelMetrics records metrics from Redis INFO when running in Sentinel mode. +// Runs only when rs.getRedisMode(inf) == "sentinel". +func (rs *redisScraper) recordSentinelMetrics(ts pcommon.Timestamp, inf info) { + recorders := rs.sentinelDataPointRecorders() + for infoKey, infoVal := range inf { + recorder, ok := recorders[infoKey] + if !ok { + continue // skip unrelated keys + } + + switch recordDataPoint := recorder.(type) { + case func(pcommon.Timestamp, int64): + val, err := strconv.ParseInt(infoVal, 10, 64) + if err != nil { + rs.settings.Logger.Warn("failed to parse sentinel int val", + zap.String("key", infoKey), + zap.String("val", infoVal), + zap.Error(err)) + continue + } + recordDataPoint(ts, val) + + case func(pcommon.Timestamp, float64): + val, err := strconv.ParseFloat(infoVal, 64) + if err != nil { + rs.settings.Logger.Warn("failed to parse sentinel float val", + zap.String("key", infoKey), + zap.String("val", infoVal), + zap.Error(err)) + continue + } + recordDataPoint(ts, val) + } + } +} + +// sentinelDataPointRecorders returns the map of supported Sentinel metrics. +func (rs *redisScraper) sentinelDataPointRecorders() map[string]any { + return map[string]any{ + "sentinel_masters": rs.mb.RecordRedisSentinelMastersDataPoint, + "sentinel_tilt": rs.mb.RecordRedisSentinelTiltDataPoint, + "sentinel_tilt_since_seconds": rs.mb.RecordRedisSentinelTiltSinceSecondsDataPoint, + "sentinel_total_tilt": rs.mb.RecordRedisSentinelTotalTiltDataPoint, + "sentinel_running_scripts": rs.mb.RecordRedisSentinelRunningScriptsDataPoint, + "sentinel_scripts_queue_length": rs.mb.RecordRedisSentinelScriptsQueueLengthDataPoint, + "sentinel_simulate_failure_flags": rs.mb.RecordRedisSentinelSimulateFailureFlagsDataPoint, + } +} diff --git a/receiver/redisreceiver/redis_scraper_test.go b/receiver/redisreceiver/redis_scraper_test.go index 1761204262524..7ed4bb50915d4 100644 --- a/receiver/redisreceiver/redis_scraper_test.go +++ b/receiver/redisreceiver/redis_scraper_test.go @@ -31,8 +31,10 @@ func TestRedisRunnable(t *testing.T) { md, err := runner.ScrapeMetrics(t.Context()) require.NoError(t, err) // + 9 because there are three keyspace entries each of which has three metrics - // -2 because maxmemory and slave_repl_offset is by default disabled, so recorder is there, but there won't be data point - assert.Equal(t, len(rs.dataPointRecorders())+9-2, md.DataPointCount()) + // -2 because maxmemory and slave_repl_offset are disabled by default (recorders exist but no data points) + // +1 for redis.mode (one-hot, exactly one sample per scrape) + expected := len(rs.dataPointRecorders()) + 9 - 2 + 1 + assert.Equal(t, expected, md.DataPointCount()) rm := md.ResourceMetrics().At(0) ilm := rm.ScopeMetrics().At(0) il := ilm.Scope() From 9ef6d12278d154940725efca71b8614163a10bfc Mon Sep 17 00:00:00 2001 From: Paulo Dias Date: Tue, 2 Sep 2025 00:35:03 +0100 Subject: [PATCH 02/12] feat: add TestIntegrationV8Sentinel tests Signed-off-by: Paulo Dias --- receiver/redisreceiver/documentation.md | 2 +- receiver/redisreceiver/integration_test.go | 37 +++ .../internal/metadata/generated_metrics.go | 2 +- .../metadata/generated_metrics_test.go | 2 +- receiver/redisreceiver/metadata.yaml | 2 +- .../integration/expected-cluster.yaml | 36 ++- .../testdata/integration/expected-old.yaml | 36 ++- .../integration/expected-sentinel.yaml | 280 ++++++++++++++++++ .../testdata/integration/redis-sentinel.conf | 11 + 9 files changed, 380 insertions(+), 28 deletions(-) create mode 100644 receiver/redisreceiver/testdata/integration/expected-sentinel.yaml create mode 100644 receiver/redisreceiver/testdata/integration/redis-sentinel.conf diff --git a/receiver/redisreceiver/documentation.md b/receiver/redisreceiver/documentation.md index e5f801b52408e..742fea03db4e5 100644 --- a/receiver/redisreceiver/documentation.md +++ b/receiver/redisreceiver/documentation.md @@ -218,7 +218,7 @@ Redis server mode | Unit | Metric Type | Value Type | | ---- | ----------- | ---------- | -| {state} | Gauge | Int | +| {mode} | Gauge | Int | #### Attributes diff --git a/receiver/redisreceiver/integration_test.go b/receiver/redisreceiver/integration_test.go index 65fea884d6f2d..7516913a2172b 100644 --- a/receiver/redisreceiver/integration_test.go +++ b/receiver/redisreceiver/integration_test.go @@ -20,6 +20,7 @@ import ( ) const redisPort = "6379" +const sentinelPort = "26379" func TestIntegrationV6(t *testing.T) { scraperinttest.NewIntegrationTest( @@ -91,3 +92,39 @@ func TestIntegrationV7Cluster(t *testing.T) { scraperinttest.WithCompareTimeout(time.Minute), ).Run(t) } + +func TestIntegrationV8Sentinel(t *testing.T) { + scraperinttest.NewIntegrationTest( + NewFactory(), + scraperinttest.WithContainerRequest( + testcontainers.ContainerRequest{ + Image: "redis:8.2.1", + ExposedPorts: []string{sentinelPort}, + Cmd: []string{ + "redis-sentinel", + "/etc/redis/sentinel.conf", + }, + Files: []testcontainers.ContainerFile{ + { + HostFilePath: filepath.Join("testdata", "integration", "redis-sentinel.conf"), + ContainerFilePath: "/etc/redis/sentinel.conf", + FileMode: 0644, + }, + }, + WaitingFor: wait.ForListeningPort(sentinelPort), + }), + scraperinttest.WithCustomConfig( + func(t *testing.T, cfg component.Config, ci *scraperinttest.ContainerInfo) { + rCfg := cfg.(*Config) + rCfg.Endpoint = fmt.Sprintf("%s:%s", ci.Host(t), ci.MappedPort(t, sentinelPort)) + }), + scraperinttest.WithCompareOptions( + pmetrictest.IgnoreMetricValues(), + pmetrictest.IgnoreMetricDataPointsOrder(), + pmetrictest.IgnoreStartTimestamp(), + pmetrictest.IgnoreTimestamp(), + ), + scraperinttest.WithExpectedFile(filepath.Join("testdata", "integration", "expected-sentinel.yaml")), + scraperinttest.WithCreateContainerTimeout(time.Minute), + ).Run(t) +} diff --git a/receiver/redisreceiver/internal/metadata/generated_metrics.go b/receiver/redisreceiver/internal/metadata/generated_metrics.go index 17de50220ef30..c6968d86f081f 100644 --- a/receiver/redisreceiver/internal/metadata/generated_metrics.go +++ b/receiver/redisreceiver/internal/metadata/generated_metrics.go @@ -1645,7 +1645,7 @@ type metricRedisMode struct { func (m *metricRedisMode) init() { m.data.SetName("redis.mode") m.data.SetDescription("Redis server mode") - m.data.SetUnit("{state}") + m.data.SetUnit("{mode}") m.data.SetEmptyGauge() m.data.Gauge().DataPoints().EnsureCapacity(m.capacity) } diff --git a/receiver/redisreceiver/internal/metadata/generated_metrics_test.go b/receiver/redisreceiver/internal/metadata/generated_metrics_test.go index aca961cd77ce9..155aced85081c 100644 --- a/receiver/redisreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/redisreceiver/internal/metadata/generated_metrics_test.go @@ -626,7 +626,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) assert.Equal(t, "Redis server mode", ms.At(i).Description()) - assert.Equal(t, "{state}", ms.At(i).Unit()) + assert.Equal(t, "{mode}", ms.At(i).Unit()) dp := ms.At(i).Gauge().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) assert.Equal(t, ts, dp.Timestamp()) diff --git a/receiver/redisreceiver/metadata.yaml b/receiver/redisreceiver/metadata.yaml index 39ee9688b65af..d581b8f34b7c3 100644 --- a/receiver/redisreceiver/metadata.yaml +++ b/receiver/redisreceiver/metadata.yaml @@ -300,7 +300,7 @@ metrics: redis.mode: enabled: true description: Redis server mode - unit: "{state}" + unit: "{mode}" gauge: value_type: int attributes: [mode] diff --git a/receiver/redisreceiver/testdata/integration/expected-cluster.yaml b/receiver/redisreceiver/testdata/integration/expected-cluster.yaml index 3519980749581..cc8f815fb3294 100644 --- a/receiver/redisreceiver/testdata/integration/expected-cluster.yaml +++ b/receiver/redisreceiver/testdata/integration/expected-cluster.yaml @@ -14,7 +14,7 @@ resourceMetrics: - asInt: "0" startTimeUnixNano: "1000000" timeUnixNano: "2000000" - unit: '{client}' + unit: "{client}" - description: Number of client connections (excluding connections from replicas) name: redis.clients.connected sum: @@ -23,7 +23,7 @@ resourceMetrics: - asInt: "2" startTimeUnixNano: "1000000" timeUnixNano: "2000000" - unit: '{client}' + unit: "{client}" - description: Biggest input buffer among current client connections gauge: dataPoints: @@ -47,7 +47,7 @@ resourceMetrics: startTimeUnixNano: "1000000" timeUnixNano: "2000000" name: redis.commands - unit: '{ops}/s' + unit: "{ops}/s" - description: Total number of commands processed by the server name: redis.commands.processed sum: @@ -57,7 +57,7 @@ resourceMetrics: startTimeUnixNano: "1000000" timeUnixNano: "2000000" isMonotonic: true - unit: '{command}' + unit: "{command}" - description: Total number of connections accepted by the server name: redis.connections.received sum: @@ -67,7 +67,7 @@ resourceMetrics: startTimeUnixNano: "1000000" timeUnixNano: "2000000" isMonotonic: true - unit: '{connection}' + unit: "{connection}" - description: Number of connections rejected because of maxclients limit name: redis.connections.rejected sum: @@ -77,7 +77,7 @@ resourceMetrics: startTimeUnixNano: "1000000" timeUnixNano: "2000000" isMonotonic: true - unit: '{connection}' + unit: "{connection}" - description: System CPU consumed by the Redis server in seconds since server start name: redis.cpu.time sum: @@ -136,7 +136,7 @@ resourceMetrics: startTimeUnixNano: "1000000" timeUnixNano: "2000000" isMonotonic: true - unit: '{key}' + unit: "{key}" - description: Total number of key expiration events name: redis.keys.expired sum: @@ -146,7 +146,7 @@ resourceMetrics: startTimeUnixNano: "1000000" timeUnixNano: "2000000" isMonotonic: true - unit: '{event}' + unit: "{event}" - description: Number of successful lookup of keys in the main dictionary name: redis.keyspace.hits sum: @@ -156,7 +156,7 @@ resourceMetrics: startTimeUnixNano: "1000000" timeUnixNano: "2000000" isMonotonic: true - unit: '{hit}' + unit: "{hit}" - description: Number of failed lookup of keys in the main dictionary name: redis.keyspace.misses sum: @@ -166,7 +166,7 @@ resourceMetrics: startTimeUnixNano: "1000000" timeUnixNano: "2000000" isMonotonic: true - unit: '{miss}' + unit: "{miss}" - description: Duration of the latest fork operation in microseconds gauge: dataPoints: @@ -215,6 +215,18 @@ resourceMetrics: timeUnixNano: "2000000" name: redis.memory.used unit: By + - description: Redis server mode + gauge: + dataPoints: + - asInt: "1" + attributes: + - key: mode + value: + stringValue: cluster + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + name: redis.mode + unit: "{mode}" - description: The total number of bytes read from the network name: redis.net.input sum: @@ -243,7 +255,7 @@ resourceMetrics: - asInt: "0" startTimeUnixNano: "1000000" timeUnixNano: "2000000" - unit: '{change}' + unit: "{change}" - description: The master offset of the replication backlog buffer gauge: dataPoints: @@ -276,7 +288,7 @@ resourceMetrics: - asInt: "0" startTimeUnixNano: "1000000" timeUnixNano: "2000000" - unit: '{replica}' + unit: "{replica}" - description: Number of seconds since Redis server start name: redis.uptime sum: diff --git a/receiver/redisreceiver/testdata/integration/expected-old.yaml b/receiver/redisreceiver/testdata/integration/expected-old.yaml index 125be719b42dc..7782006955d36 100644 --- a/receiver/redisreceiver/testdata/integration/expected-old.yaml +++ b/receiver/redisreceiver/testdata/integration/expected-old.yaml @@ -14,7 +14,7 @@ resourceMetrics: - asInt: "0" startTimeUnixNano: "1687339331739210000" timeUnixNano: "1687339332739210000" - unit: '{client}' + unit: "{client}" - description: Number of client connections (excluding connections from replicas) name: redis.clients.connected sum: @@ -23,7 +23,7 @@ resourceMetrics: - asInt: "1" startTimeUnixNano: "1687339331739210000" timeUnixNano: "1687339332739210000" - unit: '{client}' + unit: "{client}" - description: Biggest input buffer among current client connections gauge: dataPoints: @@ -47,7 +47,7 @@ resourceMetrics: startTimeUnixNano: "1687339331739210000" timeUnixNano: "1687339332739210000" name: redis.commands - unit: '{ops}/s' + unit: "{ops}/s" - description: Total number of commands processed by the server name: redis.commands.processed sum: @@ -57,7 +57,7 @@ resourceMetrics: startTimeUnixNano: "1687339331739210000" timeUnixNano: "1687339332739210000" isMonotonic: true - unit: '{command}' + unit: "{command}" - description: Total number of connections accepted by the server name: redis.connections.received sum: @@ -67,7 +67,7 @@ resourceMetrics: startTimeUnixNano: "1687339331739210000" timeUnixNano: "1687339332739210000" isMonotonic: true - unit: '{connection}' + unit: "{connection}" - description: Number of connections rejected because of maxclients limit name: redis.connections.rejected sum: @@ -77,7 +77,7 @@ resourceMetrics: startTimeUnixNano: "1687339331739210000" timeUnixNano: "1687339332739210000" isMonotonic: true - unit: '{connection}' + unit: "{connection}" - description: System CPU consumed by the Redis server in seconds since server start name: redis.cpu.time sum: @@ -122,7 +122,7 @@ resourceMetrics: startTimeUnixNano: "1687339331739210000" timeUnixNano: "1687339332739210000" isMonotonic: true - unit: '{key}' + unit: "{key}" - description: Total number of key expiration events name: redis.keys.expired sum: @@ -132,7 +132,7 @@ resourceMetrics: startTimeUnixNano: "1687339331739210000" timeUnixNano: "1687339332739210000" isMonotonic: true - unit: '{event}' + unit: "{event}" - description: Number of successful lookup of keys in the main dictionary name: redis.keyspace.hits sum: @@ -142,7 +142,7 @@ resourceMetrics: startTimeUnixNano: "1687339331739210000" timeUnixNano: "1687339332739210000" isMonotonic: true - unit: '{hit}' + unit: "{hit}" - description: Number of failed lookup of keys in the main dictionary name: redis.keyspace.misses sum: @@ -152,7 +152,7 @@ resourceMetrics: startTimeUnixNano: "1687339331739210000" timeUnixNano: "1687339332739210000" isMonotonic: true - unit: '{miss}' + unit: "{miss}" - description: Duration of the latest fork operation in microseconds gauge: dataPoints: @@ -211,6 +211,18 @@ resourceMetrics: timeUnixNano: "1687339332739210000" isMonotonic: true unit: By + - description: Redis server mode + gauge: + dataPoints: + - asInt: "1" + attributes: + - key: mode + value: + stringValue: standalone + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + name: redis.mode + unit: "{mode}" - description: The total number of bytes written to the network name: redis.net.output sum: @@ -229,7 +241,7 @@ resourceMetrics: - asInt: "0" startTimeUnixNano: "1687339331739210000" timeUnixNano: "1687339332739210000" - unit: '{change}' + unit: "{change}" - description: The master offset of the replication backlog buffer gauge: dataPoints: @@ -254,7 +266,7 @@ resourceMetrics: - asInt: "0" startTimeUnixNano: "1687339331739210000" timeUnixNano: "1687339332739210000" - unit: '{replica}' + unit: "{replica}" - description: Number of seconds since Redis server start name: redis.uptime sum: diff --git a/receiver/redisreceiver/testdata/integration/expected-sentinel.yaml b/receiver/redisreceiver/testdata/integration/expected-sentinel.yaml new file mode 100644 index 0000000000000..a914ccd397e4f --- /dev/null +++ b/receiver/redisreceiver/testdata/integration/expected-sentinel.yaml @@ -0,0 +1,280 @@ +resourceMetrics: + - resource: + attributes: + - key: redis.version + value: + stringValue: 8.2.1 + scopeMetrics: + - metrics: + - description: Number of clients pending on a blocking call + name: redis.clients.blocked + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "0" + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + unit: "{client}" + - description: Number of client connections (excluding connections from replicas) + name: redis.clients.connected + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "1" + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + unit: "{client}" + - description: Biggest input buffer among current client connections + gauge: + dataPoints: + - asInt: "0" + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + name: redis.clients.max_input_buffer + unit: By + - description: Longest output list among current client connections + gauge: + dataPoints: + - asInt: "0" + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + name: redis.clients.max_output_buffer + unit: By + - description: Number of commands processed per second + gauge: + dataPoints: + - asInt: "0" + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + name: redis.commands + unit: "{ops}/s" + - description: Total number of commands processed by the server + name: redis.commands.processed + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "8" + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + isMonotonic: true + unit: "{command}" + - description: Total number of connections accepted by the server + name: redis.connections.received + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "1" + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + isMonotonic: true + unit: "{connection}" + - description: Number of connections rejected because of maxclients limit + name: redis.connections.rejected + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "0" + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + isMonotonic: true + unit: "{connection}" + - description: System CPU consumed by the Redis server in seconds since server start + name: redis.cpu.time + sum: + aggregationTemporality: 2 + dataPoints: + - asDouble: 0.31895 + attributes: + - key: state + value: + stringValue: sys + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + - asDouble: 0.004504 + attributes: + - key: state + value: + stringValue: sys_children + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + - asDouble: 0.31858 + attributes: + - key: state + value: + stringValue: sys_main_thread + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + - asDouble: 1.101488 + attributes: + - key: state + value: + stringValue: user + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + - asDouble: 0.004405 + attributes: + - key: state + value: + stringValue: user_children + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + - asDouble: 1.100888 + attributes: + - key: state + value: + stringValue: user_main_thread + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + isMonotonic: true + unit: s + - description: Number of evicted keys due to maxmemory limit + name: redis.keys.evicted + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "0" + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + isMonotonic: true + unit: "{key}" + - description: Total number of key expiration events + name: redis.keys.expired + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "0" + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + isMonotonic: true + unit: "{event}" + - description: Number of successful lookup of keys in the main dictionary + name: redis.keyspace.hits + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "0" + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + isMonotonic: true + unit: "{hit}" + - description: Number of failed lookup of keys in the main dictionary + name: redis.keyspace.misses + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "0" + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + isMonotonic: true + unit: "{miss}" + - description: Duration of the latest fork operation in microseconds + gauge: + dataPoints: + - asInt: "0" + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + name: redis.latest_fork + unit: us + - description: Redis server mode + gauge: + dataPoints: + - asInt: "1" + attributes: + - key: mode + value: + stringValue: sentinel + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + name: redis.mode + unit: "{mode}" + - description: The total number of bytes read from the network + name: redis.net.input + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "458" + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + isMonotonic: true + unit: By + - description: The total number of bytes written to the network + name: redis.net.output + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "42172" + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + isMonotonic: true + unit: By + - description: Number of masters monitored by Sentinel. + name: redis.sentinel.masters + gauge: + dataPoints: + - asInt: "1" + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + unit: "{masters}" + - description: Number of running Sentinel scripts. + gauge: + dataPoints: + - asInt: "0" + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + name: redis.sentinel.running_scripts + unit: "{scripts}" + - description: Length of Sentinel scripts queue. + gauge: + dataPoints: + - asInt: "0" + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + name: redis.sentinel.scripts_queue_length + unit: "{scripts}" + - description: Simulated failure flags bitmask. + gauge: + dataPoints: + - asInt: "0" + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + name: redis.sentinel.simulate_failure_flags + unit: "{flags}" + - description: Whether Sentinel is in TILT mode (1 = tilt, 0 = normal). + gauge: + dataPoints: + - asInt: "0" + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + name: redis.sentinel.tilt + unit: "{state}" + - description: Duration in seconds of current TILT, or -1 if not in TILT mode. + gauge: + dataPoints: + - asInt: "-1" + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + name: redis.sentinel.tilt_since_seconds + unit: s + - description: Total TILT occurrences since start. + name: redis.sentinel.total_tilt + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "0" + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + isMonotonic: true + unit: "{events}" + - description: Number of seconds since Redis server start + name: redis.uptime + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "156" + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + isMonotonic: true + unit: s + scope: + name: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/redisreceiver + version: latest diff --git a/receiver/redisreceiver/testdata/integration/redis-sentinel.conf b/receiver/redisreceiver/testdata/integration/redis-sentinel.conf new file mode 100644 index 0000000000000..c9686dd14ee91 --- /dev/null +++ b/receiver/redisreceiver/testdata/integration/redis-sentinel.conf @@ -0,0 +1,11 @@ +port 26379 +protected-mode no +daemonize no +dir /data + +# Define one monitor; it doesn't have to be reachable for Sentinel to run. +# quorum=1 keeps it simple. +sentinel monitor mymaster 127.0.0.1 6379 1 +sentinel down-after-milliseconds mymaster 5000 +sentinel parallel-syncs mymaster 1 +sentinel failover-timeout mymaster 10000 From d3043cecbd0bffa5c67c203673b11399d8eaee98 Mon Sep 17 00:00:00 2001 From: Paulo Dias Date: Tue, 2 Sep 2025 00:36:45 +0100 Subject: [PATCH 03/12] chore: make fmt Signed-off-by: Paulo Dias --- receiver/redisreceiver/integration_test.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/receiver/redisreceiver/integration_test.go b/receiver/redisreceiver/integration_test.go index 7516913a2172b..31ddd8b338cd6 100644 --- a/receiver/redisreceiver/integration_test.go +++ b/receiver/redisreceiver/integration_test.go @@ -19,8 +19,10 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest/pmetrictest" ) -const redisPort = "6379" -const sentinelPort = "26379" +const ( + redisPort = "6379" + sentinelPort = "26379" +) func TestIntegrationV6(t *testing.T) { scraperinttest.NewIntegrationTest( @@ -108,7 +110,7 @@ func TestIntegrationV8Sentinel(t *testing.T) { { HostFilePath: filepath.Join("testdata", "integration", "redis-sentinel.conf"), ContainerFilePath: "/etc/redis/sentinel.conf", - FileMode: 0644, + FileMode: 0o644, }, }, WaitingFor: wait.ForListeningPort(sentinelPort), From fbd99627105a934263288fc5b01ed6723afc5fa9 Mon Sep 17 00:00:00 2001 From: Paulo Dias Date: Tue, 2 Sep 2025 00:45:25 +0100 Subject: [PATCH 04/12] feat: add IgnoreMetricsOrder and IgnoreResourceMetricsOrder Signed-off-by: Paulo Dias --- receiver/redisreceiver/integration_test.go | 6 ++++++ .../testdata/integration/expected-old.yaml | 20 +++++++++---------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/receiver/redisreceiver/integration_test.go b/receiver/redisreceiver/integration_test.go index 31ddd8b338cd6..7b4c90d6867c4 100644 --- a/receiver/redisreceiver/integration_test.go +++ b/receiver/redisreceiver/integration_test.go @@ -41,6 +41,8 @@ func TestIntegrationV6(t *testing.T) { scraperinttest.WithCompareOptions( pmetrictest.IgnoreMetricValues(), pmetrictest.IgnoreMetricDataPointsOrder(), + pmetrictest.IgnoreMetricsOrder(), + pmetrictest.IgnoreResourceMetricsOrder(), pmetrictest.IgnoreStartTimestamp(), pmetrictest.IgnoreTimestamp(), pmetrictest.ChangeResourceAttributeValue("server.address", func(_ string) string { @@ -86,6 +88,8 @@ func TestIntegrationV7Cluster(t *testing.T) { scraperinttest.WithCompareOptions( pmetrictest.IgnoreMetricValues(), pmetrictest.IgnoreMetricDataPointsOrder(), + pmetrictest.IgnoreMetricsOrder(), + pmetrictest.IgnoreResourceMetricsOrder(), pmetrictest.IgnoreStartTimestamp(), pmetrictest.IgnoreTimestamp(), ), @@ -123,6 +127,8 @@ func TestIntegrationV8Sentinel(t *testing.T) { scraperinttest.WithCompareOptions( pmetrictest.IgnoreMetricValues(), pmetrictest.IgnoreMetricDataPointsOrder(), + pmetrictest.IgnoreMetricsOrder(), + pmetrictest.IgnoreResourceMetricsOrder(), pmetrictest.IgnoreStartTimestamp(), pmetrictest.IgnoreTimestamp(), ), diff --git a/receiver/redisreceiver/testdata/integration/expected-old.yaml b/receiver/redisreceiver/testdata/integration/expected-old.yaml index 7782006955d36..abb0e4582a0a5 100644 --- a/receiver/redisreceiver/testdata/integration/expected-old.yaml +++ b/receiver/redisreceiver/testdata/integration/expected-old.yaml @@ -201,16 +201,6 @@ resourceMetrics: timeUnixNano: "1687339332739210000" name: redis.memory.used unit: By - - description: The total number of bytes read from the network - name: redis.net.input - sum: - aggregationTemporality: 2 - dataPoints: - - asInt: "23" - startTimeUnixNano: "1687339331739210000" - timeUnixNano: "1687339332739210000" - isMonotonic: true - unit: By - description: Redis server mode gauge: dataPoints: @@ -223,6 +213,16 @@ resourceMetrics: timeUnixNano: "1687339332739210000" name: redis.mode unit: "{mode}" + - description: The total number of bytes read from the network + name: redis.net.input + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "23" + startTimeUnixNano: "1687339331739210000" + timeUnixNano: "1687339332739210000" + isMonotonic: true + unit: By - description: The total number of bytes written to the network name: redis.net.output sum: From f3ce7a69adc94788f2746202fa509f63f187d656 Mon Sep 17 00:00:00 2001 From: Paulo Dias Date: Mon, 13 Oct 2025 23:22:58 +0100 Subject: [PATCH 05/12] chore: rebase Signed-off-by: Paulo Dias --- .../internal/metadata/generated_config.go | 54 +---- .../metadata/generated_config_test.go | 62 ++--- .../internal/metadata/generated_metrics.go | 227 ++++-------------- receiver/redisreceiver/metadata.yaml | 91 +++---- receiver/redisreceiver/redis_scraper_test.go | 5 +- 5 files changed, 122 insertions(+), 317 deletions(-) diff --git a/receiver/redisreceiver/internal/metadata/generated_config.go b/receiver/redisreceiver/internal/metadata/generated_config.go index 138420cd338bf..f01d4e615f985 100644 --- a/receiver/redisreceiver/internal/metadata/generated_config.go +++ b/receiver/redisreceiver/internal/metadata/generated_config.go @@ -28,51 +28,6 @@ func (ms *MetricConfig) Unmarshal(parser *confmap.Conf) error { // MetricsConfig provides config for redis metrics. type MetricsConfig struct { -<<<<<<< HEAD - RedisClientsBlocked MetricConfig `mapstructure:"redis.clients.blocked"` - RedisClientsConnected MetricConfig `mapstructure:"redis.clients.connected"` - RedisClientsMaxInputBuffer MetricConfig `mapstructure:"redis.clients.max_input_buffer"` - RedisClientsMaxOutputBuffer MetricConfig `mapstructure:"redis.clients.max_output_buffer"` - RedisCmdCalls MetricConfig `mapstructure:"redis.cmd.calls"` - RedisCmdLatency MetricConfig `mapstructure:"redis.cmd.latency"` - RedisCmdUsec MetricConfig `mapstructure:"redis.cmd.usec"` - RedisCommands MetricConfig `mapstructure:"redis.commands"` - RedisCommandsProcessed MetricConfig `mapstructure:"redis.commands.processed"` - RedisConnectionsReceived MetricConfig `mapstructure:"redis.connections.received"` - RedisConnectionsRejected MetricConfig `mapstructure:"redis.connections.rejected"` - RedisCPUTime MetricConfig `mapstructure:"redis.cpu.time"` - RedisDbAvgTTL MetricConfig `mapstructure:"redis.db.avg_ttl"` - RedisDbExpires MetricConfig `mapstructure:"redis.db.expires"` - RedisDbKeys MetricConfig `mapstructure:"redis.db.keys"` - RedisKeysEvicted MetricConfig `mapstructure:"redis.keys.evicted"` - RedisKeysExpired MetricConfig `mapstructure:"redis.keys.expired"` - RedisKeyspaceHits MetricConfig `mapstructure:"redis.keyspace.hits"` - RedisKeyspaceMisses MetricConfig `mapstructure:"redis.keyspace.misses"` - RedisLatestFork MetricConfig `mapstructure:"redis.latest_fork"` - RedisMaxmemory MetricConfig `mapstructure:"redis.maxmemory"` - RedisMemoryFragmentationRatio MetricConfig `mapstructure:"redis.memory.fragmentation_ratio"` - RedisMemoryLua MetricConfig `mapstructure:"redis.memory.lua"` - RedisMemoryPeak MetricConfig `mapstructure:"redis.memory.peak"` - RedisMemoryRss MetricConfig `mapstructure:"redis.memory.rss"` - RedisMemoryUsed MetricConfig `mapstructure:"redis.memory.used"` - RedisMode MetricConfig `mapstructure:"redis.mode"` - RedisNetInput MetricConfig `mapstructure:"redis.net.input"` - RedisNetOutput MetricConfig `mapstructure:"redis.net.output"` - RedisRdbChangesSinceLastSave MetricConfig `mapstructure:"redis.rdb.changes_since_last_save"` - RedisReplicationBacklogFirstByteOffset MetricConfig `mapstructure:"redis.replication.backlog_first_byte_offset"` - RedisReplicationOffset MetricConfig `mapstructure:"redis.replication.offset"` - RedisReplicationReplicaOffset MetricConfig `mapstructure:"redis.replication.replica_offset"` - RedisRole MetricConfig `mapstructure:"redis.role"` - RedisSentinelMasters MetricConfig `mapstructure:"redis.sentinel.masters"` - RedisSentinelRunningScripts MetricConfig `mapstructure:"redis.sentinel.running_scripts"` - RedisSentinelScriptsQueueLength MetricConfig `mapstructure:"redis.sentinel.scripts_queue_length"` - RedisSentinelSimulateFailureFlags MetricConfig `mapstructure:"redis.sentinel.simulate_failure_flags"` - RedisSentinelTilt MetricConfig `mapstructure:"redis.sentinel.tilt"` - RedisSentinelTiltSinceSeconds MetricConfig `mapstructure:"redis.sentinel.tilt_since_seconds"` - RedisSentinelTotalTilt MetricConfig `mapstructure:"redis.sentinel.total_tilt"` - RedisSlavesConnected MetricConfig `mapstructure:"redis.slaves.connected"` - RedisUptime MetricConfig `mapstructure:"redis.uptime"` -======= RedisClientsBlocked MetricConfig `mapstructure:"redis.clients.blocked"` RedisClientsConnected MetricConfig `mapstructure:"redis.clients.connected"` RedisClientsMaxInputBuffer MetricConfig `mapstructure:"redis.clients.max_input_buffer"` @@ -111,6 +66,7 @@ type MetricsConfig struct { RedisMemoryPeak MetricConfig `mapstructure:"redis.memory.peak"` RedisMemoryRss MetricConfig `mapstructure:"redis.memory.rss"` RedisMemoryUsed MetricConfig `mapstructure:"redis.memory.used"` + RedisMode MetricConfig `mapstructure:"redis.mode"` RedisNetInput MetricConfig `mapstructure:"redis.net.input"` RedisNetOutput MetricConfig `mapstructure:"redis.net.output"` RedisRdbChangesSinceLastSave MetricConfig `mapstructure:"redis.rdb.changes_since_last_save"` @@ -118,9 +74,15 @@ type MetricsConfig struct { RedisReplicationOffset MetricConfig `mapstructure:"redis.replication.offset"` RedisReplicationReplicaOffset MetricConfig `mapstructure:"redis.replication.replica_offset"` RedisRole MetricConfig `mapstructure:"redis.role"` + RedisSentinelMasters MetricConfig `mapstructure:"redis.sentinel.masters"` + RedisSentinelRunningScripts MetricConfig `mapstructure:"redis.sentinel.running_scripts"` + RedisSentinelScriptsQueueLength MetricConfig `mapstructure:"redis.sentinel.scripts_queue_length"` + RedisSentinelSimulateFailureFlags MetricConfig `mapstructure:"redis.sentinel.simulate_failure_flags"` + RedisSentinelTilt MetricConfig `mapstructure:"redis.sentinel.tilt"` + RedisSentinelTiltSinceSeconds MetricConfig `mapstructure:"redis.sentinel.tilt_since_seconds"` + RedisSentinelTotalTilt MetricConfig `mapstructure:"redis.sentinel.total_tilt"` RedisSlavesConnected MetricConfig `mapstructure:"redis.slaves.connected"` RedisUptime MetricConfig `mapstructure:"redis.uptime"` ->>>>>>> b0687d7f57944ce400438563304f4f934f59c4b9 } func DefaultMetricsConfig() MetricsConfig { diff --git a/receiver/redisreceiver/internal/metadata/generated_config_test.go b/receiver/redisreceiver/internal/metadata/generated_config_test.go index 661c5b9a4ea45..d014a9353499e 100644 --- a/receiver/redisreceiver/internal/metadata/generated_config_test.go +++ b/receiver/redisreceiver/internal/metadata/generated_config_test.go @@ -65,6 +65,7 @@ func TestMetricsBuilderConfig(t *testing.T) { RedisMemoryPeak: MetricConfig{Enabled: true}, RedisMemoryRss: MetricConfig{Enabled: true}, RedisMemoryUsed: MetricConfig{Enabled: true}, + RedisMode: MetricConfig{Enabled: true}, RedisNetInput: MetricConfig{Enabled: true}, RedisNetOutput: MetricConfig{Enabled: true}, RedisRdbChangesSinceLastSave: MetricConfig{Enabled: true}, @@ -72,6 +73,13 @@ func TestMetricsBuilderConfig(t *testing.T) { RedisReplicationOffset: MetricConfig{Enabled: true}, RedisReplicationReplicaOffset: MetricConfig{Enabled: true}, RedisRole: MetricConfig{Enabled: true}, + RedisSentinelMasters: MetricConfig{Enabled: true}, + RedisSentinelRunningScripts: MetricConfig{Enabled: true}, + RedisSentinelScriptsQueueLength: MetricConfig{Enabled: true}, + RedisSentinelSimulateFailureFlags: MetricConfig{Enabled: true}, + RedisSentinelTilt: MetricConfig{Enabled: true}, + RedisSentinelTiltSinceSeconds: MetricConfig{Enabled: true}, + RedisSentinelTotalTilt: MetricConfig{Enabled: true}, RedisSlavesConnected: MetricConfig{Enabled: true}, RedisUptime: MetricConfig{Enabled: true}, }, @@ -86,51 +94,6 @@ func TestMetricsBuilderConfig(t *testing.T) { name: "none_set", want: MetricsBuilderConfig{ Metrics: MetricsConfig{ -<<<<<<< HEAD - RedisClientsBlocked: MetricConfig{Enabled: false}, - RedisClientsConnected: MetricConfig{Enabled: false}, - RedisClientsMaxInputBuffer: MetricConfig{Enabled: false}, - RedisClientsMaxOutputBuffer: MetricConfig{Enabled: false}, - RedisCmdCalls: MetricConfig{Enabled: false}, - RedisCmdLatency: MetricConfig{Enabled: false}, - RedisCmdUsec: MetricConfig{Enabled: false}, - RedisCommands: MetricConfig{Enabled: false}, - RedisCommandsProcessed: MetricConfig{Enabled: false}, - RedisConnectionsReceived: MetricConfig{Enabled: false}, - RedisConnectionsRejected: MetricConfig{Enabled: false}, - RedisCPUTime: MetricConfig{Enabled: false}, - RedisDbAvgTTL: MetricConfig{Enabled: false}, - RedisDbExpires: MetricConfig{Enabled: false}, - RedisDbKeys: MetricConfig{Enabled: false}, - RedisKeysEvicted: MetricConfig{Enabled: false}, - RedisKeysExpired: MetricConfig{Enabled: false}, - RedisKeyspaceHits: MetricConfig{Enabled: false}, - RedisKeyspaceMisses: MetricConfig{Enabled: false}, - RedisLatestFork: MetricConfig{Enabled: false}, - RedisMaxmemory: MetricConfig{Enabled: false}, - RedisMemoryFragmentationRatio: MetricConfig{Enabled: false}, - RedisMemoryLua: MetricConfig{Enabled: false}, - RedisMemoryPeak: MetricConfig{Enabled: false}, - RedisMemoryRss: MetricConfig{Enabled: false}, - RedisMemoryUsed: MetricConfig{Enabled: false}, - RedisMode: MetricConfig{Enabled: false}, - RedisNetInput: MetricConfig{Enabled: false}, - RedisNetOutput: MetricConfig{Enabled: false}, - RedisRdbChangesSinceLastSave: MetricConfig{Enabled: false}, - RedisReplicationBacklogFirstByteOffset: MetricConfig{Enabled: false}, - RedisReplicationOffset: MetricConfig{Enabled: false}, - RedisReplicationReplicaOffset: MetricConfig{Enabled: false}, - RedisRole: MetricConfig{Enabled: false}, - RedisSentinelMasters: MetricConfig{Enabled: false}, - RedisSentinelRunningScripts: MetricConfig{Enabled: false}, - RedisSentinelScriptsQueueLength: MetricConfig{Enabled: false}, - RedisSentinelSimulateFailureFlags: MetricConfig{Enabled: false}, - RedisSentinelTilt: MetricConfig{Enabled: false}, - RedisSentinelTiltSinceSeconds: MetricConfig{Enabled: false}, - RedisSentinelTotalTilt: MetricConfig{Enabled: false}, - RedisSlavesConnected: MetricConfig{Enabled: false}, - RedisUptime: MetricConfig{Enabled: false}, -======= RedisClientsBlocked: MetricConfig{Enabled: false}, RedisClientsConnected: MetricConfig{Enabled: false}, RedisClientsMaxInputBuffer: MetricConfig{Enabled: false}, @@ -169,6 +132,7 @@ func TestMetricsBuilderConfig(t *testing.T) { RedisMemoryPeak: MetricConfig{Enabled: false}, RedisMemoryRss: MetricConfig{Enabled: false}, RedisMemoryUsed: MetricConfig{Enabled: false}, + RedisMode: MetricConfig{Enabled: false}, RedisNetInput: MetricConfig{Enabled: false}, RedisNetOutput: MetricConfig{Enabled: false}, RedisRdbChangesSinceLastSave: MetricConfig{Enabled: false}, @@ -176,9 +140,15 @@ func TestMetricsBuilderConfig(t *testing.T) { RedisReplicationOffset: MetricConfig{Enabled: false}, RedisReplicationReplicaOffset: MetricConfig{Enabled: false}, RedisRole: MetricConfig{Enabled: false}, + RedisSentinelMasters: MetricConfig{Enabled: false}, + RedisSentinelRunningScripts: MetricConfig{Enabled: false}, + RedisSentinelScriptsQueueLength: MetricConfig{Enabled: false}, + RedisSentinelSimulateFailureFlags: MetricConfig{Enabled: false}, + RedisSentinelTilt: MetricConfig{Enabled: false}, + RedisSentinelTiltSinceSeconds: MetricConfig{Enabled: false}, + RedisSentinelTotalTilt: MetricConfig{Enabled: false}, RedisSlavesConnected: MetricConfig{Enabled: false}, RedisUptime: MetricConfig{Enabled: false}, ->>>>>>> b0687d7f57944ce400438563304f4f934f59c4b9 }, ResourceAttributes: ResourceAttributesConfig{ RedisVersion: ResourceAttributeConfig{Enabled: false}, diff --git a/receiver/redisreceiver/internal/metadata/generated_metrics.go b/receiver/redisreceiver/internal/metadata/generated_metrics.go index 2c0ecc2ac9fed..b8dbb9c966b36 100644 --- a/receiver/redisreceiver/internal/metadata/generated_metrics.go +++ b/receiver/redisreceiver/internal/metadata/generated_metrics.go @@ -12,7 +12,32 @@ import ( "go.opentelemetry.io/collector/receiver" ) -<<<<<<< HEAD +// AttributeClusterState specifies the value cluster_state attribute. +type AttributeClusterState int + +const ( + _ AttributeClusterState = iota + AttributeClusterStateOk + AttributeClusterStateFail +) + +// String returns the string representation of the AttributeClusterState. +func (av AttributeClusterState) String() string { + switch av { + case AttributeClusterStateOk: + return "ok" + case AttributeClusterStateFail: + return "fail" + } + return "" +} + +// MapAttributeClusterState is a helper map of string to AttributeClusterState attribute value. +var MapAttributeClusterState = map[string]AttributeClusterState{ + "ok": AttributeClusterStateOk, + "fail": AttributeClusterStateFail, +} + // AttributeMode specifies the value mode attribute. type AttributeMode int @@ -32,40 +57,15 @@ func (av AttributeMode) String() string { return "sentinel" case AttributeModeStandalone: return "standalone" -======= -// AttributeClusterState specifies the value cluster_state attribute. -type AttributeClusterState int - -const ( - _ AttributeClusterState = iota - AttributeClusterStateOk - AttributeClusterStateFail -) - -// String returns the string representation of the AttributeClusterState. -func (av AttributeClusterState) String() string { - switch av { - case AttributeClusterStateOk: - return "ok" - case AttributeClusterStateFail: - return "fail" ->>>>>>> b0687d7f57944ce400438563304f4f934f59c4b9 } return "" } -<<<<<<< HEAD // MapAttributeMode is a helper map of string to AttributeMode attribute value. var MapAttributeMode = map[string]AttributeMode{ "cluster": AttributeModeCluster, "sentinel": AttributeModeSentinel, "standalone": AttributeModeStandalone, -======= -// MapAttributeClusterState is a helper map of string to AttributeClusterState attribute value. -var MapAttributeClusterState = map[string]AttributeClusterState{ - "ok": AttributeClusterStateOk, - "fail": AttributeClusterStateFail, ->>>>>>> b0687d7f57944ce400438563304f4f934f59c4b9 } // AttributePercentile specifies the value percentile attribute. @@ -335,51 +335,6 @@ var MetricsInfo = metricsInfo{ } type metricsInfo struct { -<<<<<<< HEAD - RedisClientsBlocked metricInfo - RedisClientsConnected metricInfo - RedisClientsMaxInputBuffer metricInfo - RedisClientsMaxOutputBuffer metricInfo - RedisCmdCalls metricInfo - RedisCmdLatency metricInfo - RedisCmdUsec metricInfo - RedisCommands metricInfo - RedisCommandsProcessed metricInfo - RedisConnectionsReceived metricInfo - RedisConnectionsRejected metricInfo - RedisCPUTime metricInfo - RedisDbAvgTTL metricInfo - RedisDbExpires metricInfo - RedisDbKeys metricInfo - RedisKeysEvicted metricInfo - RedisKeysExpired metricInfo - RedisKeyspaceHits metricInfo - RedisKeyspaceMisses metricInfo - RedisLatestFork metricInfo - RedisMaxmemory metricInfo - RedisMemoryFragmentationRatio metricInfo - RedisMemoryLua metricInfo - RedisMemoryPeak metricInfo - RedisMemoryRss metricInfo - RedisMemoryUsed metricInfo - RedisMode metricInfo - RedisNetInput metricInfo - RedisNetOutput metricInfo - RedisRdbChangesSinceLastSave metricInfo - RedisReplicationBacklogFirstByteOffset metricInfo - RedisReplicationOffset metricInfo - RedisReplicationReplicaOffset metricInfo - RedisRole metricInfo - RedisSentinelMasters metricInfo - RedisSentinelRunningScripts metricInfo - RedisSentinelScriptsQueueLength metricInfo - RedisSentinelSimulateFailureFlags metricInfo - RedisSentinelTilt metricInfo - RedisSentinelTiltSinceSeconds metricInfo - RedisSentinelTotalTilt metricInfo - RedisSlavesConnected metricInfo - RedisUptime metricInfo -======= RedisClientsBlocked metricInfo RedisClientsConnected metricInfo RedisClientsMaxInputBuffer metricInfo @@ -418,6 +373,7 @@ type metricsInfo struct { RedisMemoryPeak metricInfo RedisMemoryRss metricInfo RedisMemoryUsed metricInfo + RedisMode metricInfo RedisNetInput metricInfo RedisNetOutput metricInfo RedisRdbChangesSinceLastSave metricInfo @@ -425,9 +381,15 @@ type metricsInfo struct { RedisReplicationOffset metricInfo RedisReplicationReplicaOffset metricInfo RedisRole metricInfo + RedisSentinelMasters metricInfo + RedisSentinelRunningScripts metricInfo + RedisSentinelScriptsQueueLength metricInfo + RedisSentinelSimulateFailureFlags metricInfo + RedisSentinelTilt metricInfo + RedisSentinelTiltSinceSeconds metricInfo + RedisSentinelTotalTilt metricInfo RedisSlavesConnected metricInfo RedisUptime metricInfo ->>>>>>> b0687d7f57944ce400438563304f4f934f59c4b9 } type metricInfo struct { @@ -3197,58 +3159,6 @@ func newMetricRedisUptime(cfg MetricConfig) metricRedisUptime { // 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 { -<<<<<<< HEAD - 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. - resourceAttributeIncludeFilter map[string]filter.Filter - resourceAttributeExcludeFilter map[string]filter.Filter - metricRedisClientsBlocked metricRedisClientsBlocked - metricRedisClientsConnected metricRedisClientsConnected - metricRedisClientsMaxInputBuffer metricRedisClientsMaxInputBuffer - metricRedisClientsMaxOutputBuffer metricRedisClientsMaxOutputBuffer - metricRedisCmdCalls metricRedisCmdCalls - metricRedisCmdLatency metricRedisCmdLatency - metricRedisCmdUsec metricRedisCmdUsec - metricRedisCommands metricRedisCommands - metricRedisCommandsProcessed metricRedisCommandsProcessed - metricRedisConnectionsReceived metricRedisConnectionsReceived - metricRedisConnectionsRejected metricRedisConnectionsRejected - metricRedisCPUTime metricRedisCPUTime - metricRedisDbAvgTTL metricRedisDbAvgTTL - metricRedisDbExpires metricRedisDbExpires - metricRedisDbKeys metricRedisDbKeys - metricRedisKeysEvicted metricRedisKeysEvicted - metricRedisKeysExpired metricRedisKeysExpired - metricRedisKeyspaceHits metricRedisKeyspaceHits - metricRedisKeyspaceMisses metricRedisKeyspaceMisses - metricRedisLatestFork metricRedisLatestFork - metricRedisMaxmemory metricRedisMaxmemory - metricRedisMemoryFragmentationRatio metricRedisMemoryFragmentationRatio - metricRedisMemoryLua metricRedisMemoryLua - metricRedisMemoryPeak metricRedisMemoryPeak - metricRedisMemoryRss metricRedisMemoryRss - metricRedisMemoryUsed metricRedisMemoryUsed - metricRedisMode metricRedisMode - metricRedisNetInput metricRedisNetInput - metricRedisNetOutput metricRedisNetOutput - metricRedisRdbChangesSinceLastSave metricRedisRdbChangesSinceLastSave - metricRedisReplicationBacklogFirstByteOffset metricRedisReplicationBacklogFirstByteOffset - metricRedisReplicationOffset metricRedisReplicationOffset - metricRedisReplicationReplicaOffset metricRedisReplicationReplicaOffset - metricRedisRole metricRedisRole - metricRedisSentinelMasters metricRedisSentinelMasters - metricRedisSentinelRunningScripts metricRedisSentinelRunningScripts - metricRedisSentinelScriptsQueueLength metricRedisSentinelScriptsQueueLength - metricRedisSentinelSimulateFailureFlags metricRedisSentinelSimulateFailureFlags - metricRedisSentinelTilt metricRedisSentinelTilt - metricRedisSentinelTiltSinceSeconds metricRedisSentinelTiltSinceSeconds - metricRedisSentinelTotalTilt metricRedisSentinelTotalTilt - metricRedisSlavesConnected metricRedisSlavesConnected - metricRedisUptime metricRedisUptime -======= 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. @@ -3294,6 +3204,7 @@ type MetricsBuilder struct { metricRedisMemoryPeak metricRedisMemoryPeak metricRedisMemoryRss metricRedisMemoryRss metricRedisMemoryUsed metricRedisMemoryUsed + metricRedisMode metricRedisMode metricRedisNetInput metricRedisNetInput metricRedisNetOutput metricRedisNetOutput metricRedisRdbChangesSinceLastSave metricRedisRdbChangesSinceLastSave @@ -3301,9 +3212,15 @@ type MetricsBuilder struct { metricRedisReplicationOffset metricRedisReplicationOffset metricRedisReplicationReplicaOffset metricRedisReplicationReplicaOffset metricRedisRole metricRedisRole + metricRedisSentinelMasters metricRedisSentinelMasters + metricRedisSentinelRunningScripts metricRedisSentinelRunningScripts + metricRedisSentinelScriptsQueueLength metricRedisSentinelScriptsQueueLength + metricRedisSentinelSimulateFailureFlags metricRedisSentinelSimulateFailureFlags + metricRedisSentinelTilt metricRedisSentinelTilt + metricRedisSentinelTiltSinceSeconds metricRedisSentinelTiltSinceSeconds + metricRedisSentinelTotalTilt metricRedisSentinelTotalTilt metricRedisSlavesConnected metricRedisSlavesConnected metricRedisUptime metricRedisUptime ->>>>>>> b0687d7f57944ce400438563304f4f934f59c4b9 } // MetricBuilderOption applies changes to default metrics builder. @@ -3325,57 +3242,6 @@ func WithStartTime(startTime pcommon.Timestamp) MetricBuilderOption { } func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.Settings, options ...MetricBuilderOption) *MetricsBuilder { mb := &MetricsBuilder{ -<<<<<<< HEAD - config: mbc, - startTime: pcommon.NewTimestampFromTime(time.Now()), - metricsBuffer: pmetric.NewMetrics(), - buildInfo: settings.BuildInfo, - metricRedisClientsBlocked: newMetricRedisClientsBlocked(mbc.Metrics.RedisClientsBlocked), - metricRedisClientsConnected: newMetricRedisClientsConnected(mbc.Metrics.RedisClientsConnected), - metricRedisClientsMaxInputBuffer: newMetricRedisClientsMaxInputBuffer(mbc.Metrics.RedisClientsMaxInputBuffer), - metricRedisClientsMaxOutputBuffer: newMetricRedisClientsMaxOutputBuffer(mbc.Metrics.RedisClientsMaxOutputBuffer), - metricRedisCmdCalls: newMetricRedisCmdCalls(mbc.Metrics.RedisCmdCalls), - metricRedisCmdLatency: newMetricRedisCmdLatency(mbc.Metrics.RedisCmdLatency), - metricRedisCmdUsec: newMetricRedisCmdUsec(mbc.Metrics.RedisCmdUsec), - metricRedisCommands: newMetricRedisCommands(mbc.Metrics.RedisCommands), - metricRedisCommandsProcessed: newMetricRedisCommandsProcessed(mbc.Metrics.RedisCommandsProcessed), - metricRedisConnectionsReceived: newMetricRedisConnectionsReceived(mbc.Metrics.RedisConnectionsReceived), - metricRedisConnectionsRejected: newMetricRedisConnectionsRejected(mbc.Metrics.RedisConnectionsRejected), - metricRedisCPUTime: newMetricRedisCPUTime(mbc.Metrics.RedisCPUTime), - metricRedisDbAvgTTL: newMetricRedisDbAvgTTL(mbc.Metrics.RedisDbAvgTTL), - metricRedisDbExpires: newMetricRedisDbExpires(mbc.Metrics.RedisDbExpires), - metricRedisDbKeys: newMetricRedisDbKeys(mbc.Metrics.RedisDbKeys), - metricRedisKeysEvicted: newMetricRedisKeysEvicted(mbc.Metrics.RedisKeysEvicted), - metricRedisKeysExpired: newMetricRedisKeysExpired(mbc.Metrics.RedisKeysExpired), - metricRedisKeyspaceHits: newMetricRedisKeyspaceHits(mbc.Metrics.RedisKeyspaceHits), - metricRedisKeyspaceMisses: newMetricRedisKeyspaceMisses(mbc.Metrics.RedisKeyspaceMisses), - metricRedisLatestFork: newMetricRedisLatestFork(mbc.Metrics.RedisLatestFork), - metricRedisMaxmemory: newMetricRedisMaxmemory(mbc.Metrics.RedisMaxmemory), - metricRedisMemoryFragmentationRatio: newMetricRedisMemoryFragmentationRatio(mbc.Metrics.RedisMemoryFragmentationRatio), - metricRedisMemoryLua: newMetricRedisMemoryLua(mbc.Metrics.RedisMemoryLua), - metricRedisMemoryPeak: newMetricRedisMemoryPeak(mbc.Metrics.RedisMemoryPeak), - metricRedisMemoryRss: newMetricRedisMemoryRss(mbc.Metrics.RedisMemoryRss), - metricRedisMemoryUsed: newMetricRedisMemoryUsed(mbc.Metrics.RedisMemoryUsed), - metricRedisMode: newMetricRedisMode(mbc.Metrics.RedisMode), - metricRedisNetInput: newMetricRedisNetInput(mbc.Metrics.RedisNetInput), - metricRedisNetOutput: newMetricRedisNetOutput(mbc.Metrics.RedisNetOutput), - metricRedisRdbChangesSinceLastSave: newMetricRedisRdbChangesSinceLastSave(mbc.Metrics.RedisRdbChangesSinceLastSave), - metricRedisReplicationBacklogFirstByteOffset: newMetricRedisReplicationBacklogFirstByteOffset(mbc.Metrics.RedisReplicationBacklogFirstByteOffset), - metricRedisReplicationOffset: newMetricRedisReplicationOffset(mbc.Metrics.RedisReplicationOffset), - metricRedisReplicationReplicaOffset: newMetricRedisReplicationReplicaOffset(mbc.Metrics.RedisReplicationReplicaOffset), - metricRedisRole: newMetricRedisRole(mbc.Metrics.RedisRole), - metricRedisSentinelMasters: newMetricRedisSentinelMasters(mbc.Metrics.RedisSentinelMasters), - metricRedisSentinelRunningScripts: newMetricRedisSentinelRunningScripts(mbc.Metrics.RedisSentinelRunningScripts), - metricRedisSentinelScriptsQueueLength: newMetricRedisSentinelScriptsQueueLength(mbc.Metrics.RedisSentinelScriptsQueueLength), - metricRedisSentinelSimulateFailureFlags: newMetricRedisSentinelSimulateFailureFlags(mbc.Metrics.RedisSentinelSimulateFailureFlags), - metricRedisSentinelTilt: newMetricRedisSentinelTilt(mbc.Metrics.RedisSentinelTilt), - metricRedisSentinelTiltSinceSeconds: newMetricRedisSentinelTiltSinceSeconds(mbc.Metrics.RedisSentinelTiltSinceSeconds), - metricRedisSentinelTotalTilt: newMetricRedisSentinelTotalTilt(mbc.Metrics.RedisSentinelTotalTilt), - metricRedisSlavesConnected: newMetricRedisSlavesConnected(mbc.Metrics.RedisSlavesConnected), - metricRedisUptime: newMetricRedisUptime(mbc.Metrics.RedisUptime), - resourceAttributeIncludeFilter: make(map[string]filter.Filter), - resourceAttributeExcludeFilter: make(map[string]filter.Filter), -======= config: mbc, startTime: pcommon.NewTimestampFromTime(time.Now()), metricsBuffer: pmetric.NewMetrics(), @@ -3418,6 +3284,7 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.Settings, opt metricRedisMemoryPeak: newMetricRedisMemoryPeak(mbc.Metrics.RedisMemoryPeak), metricRedisMemoryRss: newMetricRedisMemoryRss(mbc.Metrics.RedisMemoryRss), metricRedisMemoryUsed: newMetricRedisMemoryUsed(mbc.Metrics.RedisMemoryUsed), + metricRedisMode: newMetricRedisMode(mbc.Metrics.RedisMode), metricRedisNetInput: newMetricRedisNetInput(mbc.Metrics.RedisNetInput), metricRedisNetOutput: newMetricRedisNetOutput(mbc.Metrics.RedisNetOutput), metricRedisRdbChangesSinceLastSave: newMetricRedisRdbChangesSinceLastSave(mbc.Metrics.RedisRdbChangesSinceLastSave), @@ -3425,11 +3292,17 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.Settings, opt metricRedisReplicationOffset: newMetricRedisReplicationOffset(mbc.Metrics.RedisReplicationOffset), metricRedisReplicationReplicaOffset: newMetricRedisReplicationReplicaOffset(mbc.Metrics.RedisReplicationReplicaOffset), metricRedisRole: newMetricRedisRole(mbc.Metrics.RedisRole), + metricRedisSentinelMasters: newMetricRedisSentinelMasters(mbc.Metrics.RedisSentinelMasters), + metricRedisSentinelRunningScripts: newMetricRedisSentinelRunningScripts(mbc.Metrics.RedisSentinelRunningScripts), + metricRedisSentinelScriptsQueueLength: newMetricRedisSentinelScriptsQueueLength(mbc.Metrics.RedisSentinelScriptsQueueLength), + metricRedisSentinelSimulateFailureFlags: newMetricRedisSentinelSimulateFailureFlags(mbc.Metrics.RedisSentinelSimulateFailureFlags), + metricRedisSentinelTilt: newMetricRedisSentinelTilt(mbc.Metrics.RedisSentinelTilt), + metricRedisSentinelTiltSinceSeconds: newMetricRedisSentinelTiltSinceSeconds(mbc.Metrics.RedisSentinelTiltSinceSeconds), + metricRedisSentinelTotalTilt: newMetricRedisSentinelTotalTilt(mbc.Metrics.RedisSentinelTotalTilt), metricRedisSlavesConnected: newMetricRedisSlavesConnected(mbc.Metrics.RedisSlavesConnected), metricRedisUptime: newMetricRedisUptime(mbc.Metrics.RedisUptime), resourceAttributeIncludeFilter: make(map[string]filter.Filter), resourceAttributeExcludeFilter: make(map[string]filter.Filter), ->>>>>>> b0687d7f57944ce400438563304f4f934f59c4b9 } if mbc.ResourceAttributes.RedisVersion.MetricsInclude != nil { mb.resourceAttributeIncludeFilter["redis.version"] = filter.CreateFilter(mbc.ResourceAttributes.RedisVersion.MetricsInclude) diff --git a/receiver/redisreceiver/metadata.yaml b/receiver/redisreceiver/metadata.yaml index e01ac24b9e702..7e25401568106 100644 --- a/receiver/redisreceiver/metadata.yaml +++ b/receiver/redisreceiver/metadata.yaml @@ -86,7 +86,6 @@ metrics: monotonic: false aggregation_temporality: cumulative - redis.clients.connected: enabled: true description: Number of client connections (excluding connections from replicas) @@ -154,7 +153,6 @@ metrics: gauge: value_type: int - redis.cluster.slots_assigned: enabled: false description: "Number of slots assigned in the cluster" @@ -200,6 +198,7 @@ metrics: gauge: value_type: int attributes: [cluster_state] + redis.cluster.stats_messages_received: enabled: false description: "Total number of messages received by the cluster" @@ -264,6 +263,7 @@ metrics: monotonic: true aggregation_temporality: cumulative attributes: [cmd] + redis.commands: enabled: true description: Number of commands processed per second @@ -393,13 +393,6 @@ metrics: monotonic: true aggregation_temporality: cumulative - redis.mode: - enabled: true - description: Redis server mode - unit: "{mode}" - gauge: - value_type: int - attributes: [mode] redis.latest_fork: enabled: true @@ -464,6 +457,14 @@ metrics: gauge: value_type: int + redis.mode: + enabled: true + description: Redis server mode + unit: "{mode}" + gauge: + value_type: int + attributes: [mode] + redis.net.input: enabled: true description: The total number of bytes read from the network @@ -515,36 +516,35 @@ metrics: gauge: value_type: int - redis.sentinel.masters: - enabled: true - description: Number of masters monitored by Sentinel. - unit: "{masters}" + # below are all disabled by default + redis.replication.replica_offset: + enabled: false + description: "Offset for redis replica" + stability: + level: development + unit: "By" gauge: value_type: int - redis.sentinel.tilt: - enabled: true - description: Whether Sentinel is in TILT mode (1 = tilt, 0 = normal). - unit: "{state}" - gauge: + redis.role: + enabled: false + description: Redis node's role + stability: + level: development + unit: "{role}" + sum: value_type: int + monotonic: false + aggregation_temporality: cumulative + attributes: [role] - redis.sentinel.tilt_since_seconds: + redis.sentinel.masters: enabled: true - description: Duration in seconds of current TILT, or -1 if not in TILT mode. - unit: "s" + description: Number of masters monitored by Sentinel. + unit: "{masters}" gauge: value_type: int - redis.sentinel.total_tilt: - enabled: true - description: Total TILT occurrences since start. - unit: "{events}" - sum: - value_type: int - monotonic: true - aggregation_temporality: cumulative - redis.sentinel.running_scripts: enabled: true description: Number of running Sentinel scripts. @@ -566,27 +566,28 @@ metrics: gauge: value_type: int - # below are all disabled by default - redis.replication.replica_offset: - enabled: false - description: "Offset for redis replica" - stability: - level: development - unit: "By" + redis.sentinel.tilt: + enabled: true + description: Whether Sentinel is in TILT mode (1 = tilt, 0 = normal). + unit: "{state}" gauge: value_type: int - redis.role: - enabled: false - description: Redis node's role - stability: - level: development - unit: "{role}" + redis.sentinel.tilt_since_seconds: + enabled: true + description: Duration in seconds of current TILT, or -1 if not in TILT mode. + unit: "s" + gauge: + value_type: int + + redis.sentinel.total_tilt: + enabled: true + description: Total TILT occurrences since start. + unit: "{events}" sum: value_type: int - monotonic: false + monotonic: true aggregation_temporality: cumulative - attributes: [role] redis.slaves.connected: enabled: true diff --git a/receiver/redisreceiver/redis_scraper_test.go b/receiver/redisreceiver/redis_scraper_test.go index 7ed4bb50915d4..4791d9ca1f494 100644 --- a/receiver/redisreceiver/redis_scraper_test.go +++ b/receiver/redisreceiver/redis_scraper_test.go @@ -31,10 +31,9 @@ func TestRedisRunnable(t *testing.T) { md, err := runner.ScrapeMetrics(t.Context()) require.NoError(t, err) // + 9 because there are three keyspace entries each of which has three metrics - // -2 because maxmemory and slave_repl_offset are disabled by default (recorders exist but no data points) + // -2 because maxmemory and slave_repl_offset is by default disabled, so recorder is there, but there won't be data point // +1 for redis.mode (one-hot, exactly one sample per scrape) - expected := len(rs.dataPointRecorders()) + 9 - 2 + 1 - assert.Equal(t, expected, md.DataPointCount()) + assert.Equal(t, len(rs.dataPointRecorders())+9-14+1, md.DataPointCount()) rm := md.ResourceMetrics().At(0) ilm := rm.ScopeMetrics().At(0) il := ilm.Scope() From f69805f88693004a8bf59a2edf115e202d0a3ff0 Mon Sep 17 00:00:00 2001 From: Paulo Dias Date: Mon, 13 Oct 2025 23:23:44 +0100 Subject: [PATCH 06/12] chore: update changelog Signed-off-by: Paulo Dias --- .chloggen/feat_42365.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.chloggen/feat_42365.yaml b/.chloggen/feat_42365.yaml index 8ff293468e5c4..b0525ce84adad 100644 --- a/.chloggen/feat_42365.yaml +++ b/.chloggen/feat_42365.yaml @@ -4,7 +4,7 @@ change_type: "enhancement" # The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) -component: "redisreceiver" +component: "receiver/redis" # A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). note: "Add support for redis.mode and redis.sentinel.* metrics" From 4689f77dfc334f7f61c3ac6881204177265dc20a Mon Sep 17 00:00:00 2001 From: Paulo Dias Date: Tue, 21 Oct 2025 21:59:09 +0100 Subject: [PATCH 07/12] feat: improvements Signed-off-by: Paulo Dias --- receiver/redisreceiver/documentation.md | 148 +++++++++--------- .../internal/metadata/generated_config.go | 20 +-- .../metadata/generated_config_test.go | 2 - .../internal/metadata/generated_metrics.go | 71 +-------- .../metadata/generated_metrics_test.go | 34 +--- .../internal/metadata/testdata/config.yaml | 4 - receiver/redisreceiver/metadata.yaml | 33 ++-- receiver/redisreceiver/redis_scraper.go | 53 +------ receiver/redisreceiver/redis_scraper_test.go | 3 +- .../integration/expected-sentinel.yaml | 18 +-- 10 files changed, 115 insertions(+), 271 deletions(-) diff --git a/receiver/redisreceiver/documentation.md b/receiver/redisreceiver/documentation.md index 39df760e09ccf..176413d11d87a 100644 --- a/receiver/redisreceiver/documentation.md +++ b/receiver/redisreceiver/documentation.md @@ -212,20 +212,6 @@ Total number of bytes allocated by Redis using its allocator | ---- | ----------- | ---------- | --------- | | By | Gauge | Int | development | -### redis.mode - -Redis server mode - -| Unit | Metric Type | Value Type | -| ---- | ----------- | ---------- | -| {mode} | Gauge | Int | - -#### Attributes - -| Name | Description | Values | Optional | -| ---- | ----------- | ------ | -------- | -| mode | Redis server mode | Str: ``cluster``, ``sentinel``, ``standalone`` | false | - ### redis.net.input The total number of bytes read from the network @@ -266,70 +252,6 @@ The server's current replication offset | ---- | ----------- | ---------- | --------- | | By | Gauge | Int | development | -### redis.sentinel.masters - -Number of masters monitored by Sentinel. - -| Unit | Metric Type | Value Type | -| ---- | ----------- | ---------- | -| {masters} | Gauge | Int | - -### redis.sentinel.running_scripts - -Number of running Sentinel scripts. - -| Unit | Metric Type | Value Type | -| ---- | ----------- | ---------- | -| {scripts} | Gauge | Int | - -### redis.sentinel.scripts_queue_length - -Length of Sentinel scripts queue. - -| Unit | Metric Type | Value Type | -| ---- | ----------- | ---------- | -| {scripts} | Gauge | Int | - -### redis.sentinel.simulate_failure_flags - -Simulated failure flags bitmask. - -| Unit | Metric Type | Value Type | -| ---- | ----------- | ---------- | -| {flags} | Gauge | Int | - -### redis.sentinel.tilt - -Whether Sentinel is in TILT mode (1 = tilt, 0 = normal). - -| Unit | Metric Type | Value Type | -| ---- | ----------- | ---------- | -| {state} | Gauge | Int | - -### redis.sentinel.tilt_since_seconds - -Duration in seconds of current TILT, or -1 if not in TILT mode. - -| Unit | Metric Type | Value Type | -| ---- | ----------- | ---------- | -| s | Gauge | Int | - -### redis.sentinel.total_tilt - -Total TILT occurrences since start. - -| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic | -| ---- | ----------- | ---------- | ----------------------- | --------- | -| {events} | Sum | Int | Cumulative | true | - -### redis.slaves.connected - -Number of connected replicas - -| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic | Stability | -| ---- | ----------- | ---------- | ----------------------- | --------- | --------- | -| {replica} | Sum | Int | Cumulative | false | development | - ### redis.uptime Number of seconds since Redis server start @@ -501,6 +423,20 @@ The value of the maxmemory configuration directive | ---- | ----------- | ---------- | --------- | | By | Gauge | Int | development | +### redis.mode + +Redis server mode + +| Unit | Metric Type | Value Type | +| ---- | ----------- | ---------- | +| {mode} | Gauge | Int | + +#### Attributes + +| Name | Description | Values | Optional | +| ---- | ----------- | ------ | -------- | +| mode | Redis server mode | Str: ``cluster``, ``sentinel``, ``standalone`` | false | + ### redis.replication.replica_offset Offset for redis replica @@ -523,6 +459,62 @@ Redis node's role | ---- | ----------- | ------ | -------- | | role | Redis node's role | Str: ``replica``, ``primary`` | false | +### redis.sentinel.masters + +Number of masters monitored by Sentinel. + +| Unit | Metric Type | Value Type | +| ---- | ----------- | ---------- | +| {master} | Gauge | Int | + +### redis.sentinel.running_scripts + +Number of running Sentinel scripts. + +| Unit | Metric Type | Value Type | +| ---- | ----------- | ---------- | +| {script} | Gauge | Int | + +### redis.sentinel.scripts_queue_length + +Length of Sentinel scripts queue. + +| Unit | Metric Type | Value Type | +| ---- | ----------- | ---------- | +| {script} | Gauge | Int | + +### redis.sentinel.simulate_failure_flags + +Simulated failure flags bitmask. + +| Unit | Metric Type | Value Type | +| ---- | ----------- | ---------- | +| {flag} | Gauge | Int | + +### redis.sentinel.tilt_since_seconds + +Duration in seconds of current TILT, or -1 if not in TILT mode. + +| Unit | Metric Type | Value Type | +| ---- | ----------- | ---------- | +| s | Gauge | Int | + +### redis.sentinel.total_tilt + +Total TILT occurrences since start. + +| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic | +| ---- | ----------- | ---------- | ----------------------- | --------- | +| {event} | Sum | Int | Cumulative | true | + +### redis.slaves.connected + +Number of connected replicas + +| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic | Stability | +| ---- | ----------- | ---------- | ----------------------- | --------- | --------- | +| {replica} | Sum | Int | Cumulative | false | development | + ## Resource Attributes | Name | Description | Values | Enabled | diff --git a/receiver/redisreceiver/internal/metadata/generated_config.go b/receiver/redisreceiver/internal/metadata/generated_config.go index f01d4e615f985..34b4aa58c6d76 100644 --- a/receiver/redisreceiver/internal/metadata/generated_config.go +++ b/receiver/redisreceiver/internal/metadata/generated_config.go @@ -78,7 +78,6 @@ type MetricsConfig struct { RedisSentinelRunningScripts MetricConfig `mapstructure:"redis.sentinel.running_scripts"` RedisSentinelScriptsQueueLength MetricConfig `mapstructure:"redis.sentinel.scripts_queue_length"` RedisSentinelSimulateFailureFlags MetricConfig `mapstructure:"redis.sentinel.simulate_failure_flags"` - RedisSentinelTilt MetricConfig `mapstructure:"redis.sentinel.tilt"` RedisSentinelTiltSinceSeconds MetricConfig `mapstructure:"redis.sentinel.tilt_since_seconds"` RedisSentinelTotalTilt MetricConfig `mapstructure:"redis.sentinel.total_tilt"` RedisSlavesConnected MetricConfig `mapstructure:"redis.slaves.connected"` @@ -202,7 +201,7 @@ func DefaultMetricsConfig() MetricsConfig { Enabled: true, }, RedisMode: MetricConfig{ - Enabled: true, + Enabled: false, }, RedisNetInput: MetricConfig{ Enabled: true, @@ -226,28 +225,25 @@ func DefaultMetricsConfig() MetricsConfig { Enabled: false, }, RedisSentinelMasters: MetricConfig{ - Enabled: true, + Enabled: false, }, RedisSentinelRunningScripts: MetricConfig{ - Enabled: true, + Enabled: false, }, RedisSentinelScriptsQueueLength: MetricConfig{ - Enabled: true, + Enabled: false, }, RedisSentinelSimulateFailureFlags: MetricConfig{ - Enabled: true, - }, - RedisSentinelTilt: MetricConfig{ - Enabled: true, + Enabled: false, }, RedisSentinelTiltSinceSeconds: MetricConfig{ - Enabled: true, + Enabled: false, }, RedisSentinelTotalTilt: MetricConfig{ - Enabled: true, + Enabled: false, }, RedisSlavesConnected: MetricConfig{ - Enabled: true, + Enabled: false, }, RedisUptime: MetricConfig{ Enabled: true, diff --git a/receiver/redisreceiver/internal/metadata/generated_config_test.go b/receiver/redisreceiver/internal/metadata/generated_config_test.go index d014a9353499e..e53089640991b 100644 --- a/receiver/redisreceiver/internal/metadata/generated_config_test.go +++ b/receiver/redisreceiver/internal/metadata/generated_config_test.go @@ -77,7 +77,6 @@ func TestMetricsBuilderConfig(t *testing.T) { RedisSentinelRunningScripts: MetricConfig{Enabled: true}, RedisSentinelScriptsQueueLength: MetricConfig{Enabled: true}, RedisSentinelSimulateFailureFlags: MetricConfig{Enabled: true}, - RedisSentinelTilt: MetricConfig{Enabled: true}, RedisSentinelTiltSinceSeconds: MetricConfig{Enabled: true}, RedisSentinelTotalTilt: MetricConfig{Enabled: true}, RedisSlavesConnected: MetricConfig{Enabled: true}, @@ -144,7 +143,6 @@ func TestMetricsBuilderConfig(t *testing.T) { RedisSentinelRunningScripts: MetricConfig{Enabled: false}, RedisSentinelScriptsQueueLength: MetricConfig{Enabled: false}, RedisSentinelSimulateFailureFlags: MetricConfig{Enabled: false}, - RedisSentinelTilt: MetricConfig{Enabled: false}, RedisSentinelTiltSinceSeconds: MetricConfig{Enabled: false}, RedisSentinelTotalTilt: MetricConfig{Enabled: false}, RedisSlavesConnected: MetricConfig{Enabled: false}, diff --git a/receiver/redisreceiver/internal/metadata/generated_metrics.go b/receiver/redisreceiver/internal/metadata/generated_metrics.go index b8dbb9c966b36..5843e4ae0d01c 100644 --- a/receiver/redisreceiver/internal/metadata/generated_metrics.go +++ b/receiver/redisreceiver/internal/metadata/generated_metrics.go @@ -317,9 +317,6 @@ var MetricsInfo = metricsInfo{ RedisSentinelSimulateFailureFlags: metricInfo{ Name: "redis.sentinel.simulate_failure_flags", }, - RedisSentinelTilt: metricInfo{ - Name: "redis.sentinel.tilt", - }, RedisSentinelTiltSinceSeconds: metricInfo{ Name: "redis.sentinel.tilt_since_seconds", }, @@ -385,7 +382,6 @@ type metricsInfo struct { RedisSentinelRunningScripts metricInfo RedisSentinelScriptsQueueLength metricInfo RedisSentinelSimulateFailureFlags metricInfo - RedisSentinelTilt metricInfo RedisSentinelTiltSinceSeconds metricInfo RedisSentinelTotalTilt metricInfo RedisSlavesConnected metricInfo @@ -2719,7 +2715,7 @@ type metricRedisSentinelMasters struct { func (m *metricRedisSentinelMasters) init() { m.data.SetName("redis.sentinel.masters") m.data.SetDescription("Number of masters monitored by Sentinel.") - m.data.SetUnit("{masters}") + m.data.SetUnit("{master}") m.data.SetEmptyGauge() } @@ -2768,7 +2764,7 @@ type metricRedisSentinelRunningScripts struct { func (m *metricRedisSentinelRunningScripts) init() { m.data.SetName("redis.sentinel.running_scripts") m.data.SetDescription("Number of running Sentinel scripts.") - m.data.SetUnit("{scripts}") + m.data.SetUnit("{script}") m.data.SetEmptyGauge() } @@ -2817,7 +2813,7 @@ type metricRedisSentinelScriptsQueueLength struct { func (m *metricRedisSentinelScriptsQueueLength) init() { m.data.SetName("redis.sentinel.scripts_queue_length") m.data.SetDescription("Length of Sentinel scripts queue.") - m.data.SetUnit("{scripts}") + m.data.SetUnit("{script}") m.data.SetEmptyGauge() } @@ -2866,7 +2862,7 @@ type metricRedisSentinelSimulateFailureFlags struct { func (m *metricRedisSentinelSimulateFailureFlags) init() { m.data.SetName("redis.sentinel.simulate_failure_flags") m.data.SetDescription("Simulated failure flags bitmask.") - m.data.SetUnit("{flags}") + m.data.SetUnit("{flag}") m.data.SetEmptyGauge() } @@ -2905,55 +2901,6 @@ func newMetricRedisSentinelSimulateFailureFlags(cfg MetricConfig) metricRedisSen return m } -type metricRedisSentinelTilt 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 redis.sentinel.tilt metric with initial data. -func (m *metricRedisSentinelTilt) init() { - m.data.SetName("redis.sentinel.tilt") - m.data.SetDescription("Whether Sentinel is in TILT mode (1 = tilt, 0 = normal).") - m.data.SetUnit("{state}") - m.data.SetEmptyGauge() -} - -func (m *metricRedisSentinelTilt) 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 *metricRedisSentinelTilt) 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 *metricRedisSentinelTilt) emit(metrics pmetric.MetricSlice) { - if m.config.Enabled && m.data.Gauge().DataPoints().Len() > 0 { - m.updateCapacity() - m.data.MoveTo(metrics.AppendEmpty()) - m.init() - } -} - -func newMetricRedisSentinelTilt(cfg MetricConfig) metricRedisSentinelTilt { - m := metricRedisSentinelTilt{config: cfg} - if cfg.Enabled { - m.data = pmetric.NewMetric() - m.init() - } - return m -} - type metricRedisSentinelTiltSinceSeconds struct { data pmetric.Metric // data buffer for generated metric. config MetricConfig // metric config provided by user. @@ -3013,7 +2960,7 @@ type metricRedisSentinelTotalTilt struct { func (m *metricRedisSentinelTotalTilt) init() { m.data.SetName("redis.sentinel.total_tilt") m.data.SetDescription("Total TILT occurrences since start.") - m.data.SetUnit("{events}") + m.data.SetUnit("{event}") m.data.SetEmptySum() m.data.Sum().SetIsMonotonic(true) m.data.Sum().SetAggregationTemporality(pmetric.AggregationTemporalityCumulative) @@ -3216,7 +3163,6 @@ type MetricsBuilder struct { metricRedisSentinelRunningScripts metricRedisSentinelRunningScripts metricRedisSentinelScriptsQueueLength metricRedisSentinelScriptsQueueLength metricRedisSentinelSimulateFailureFlags metricRedisSentinelSimulateFailureFlags - metricRedisSentinelTilt metricRedisSentinelTilt metricRedisSentinelTiltSinceSeconds metricRedisSentinelTiltSinceSeconds metricRedisSentinelTotalTilt metricRedisSentinelTotalTilt metricRedisSlavesConnected metricRedisSlavesConnected @@ -3296,7 +3242,6 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.Settings, opt metricRedisSentinelRunningScripts: newMetricRedisSentinelRunningScripts(mbc.Metrics.RedisSentinelRunningScripts), metricRedisSentinelScriptsQueueLength: newMetricRedisSentinelScriptsQueueLength(mbc.Metrics.RedisSentinelScriptsQueueLength), metricRedisSentinelSimulateFailureFlags: newMetricRedisSentinelSimulateFailureFlags(mbc.Metrics.RedisSentinelSimulateFailureFlags), - metricRedisSentinelTilt: newMetricRedisSentinelTilt(mbc.Metrics.RedisSentinelTilt), metricRedisSentinelTiltSinceSeconds: newMetricRedisSentinelTiltSinceSeconds(mbc.Metrics.RedisSentinelTiltSinceSeconds), metricRedisSentinelTotalTilt: newMetricRedisSentinelTotalTilt(mbc.Metrics.RedisSentinelTotalTilt), metricRedisSlavesConnected: newMetricRedisSlavesConnected(mbc.Metrics.RedisSlavesConnected), @@ -3441,7 +3386,6 @@ func (mb *MetricsBuilder) EmitForResource(options ...ResourceMetricsOption) { mb.metricRedisSentinelRunningScripts.emit(ils.Metrics()) mb.metricRedisSentinelScriptsQueueLength.emit(ils.Metrics()) mb.metricRedisSentinelSimulateFailureFlags.emit(ils.Metrics()) - mb.metricRedisSentinelTilt.emit(ils.Metrics()) mb.metricRedisSentinelTiltSinceSeconds.emit(ils.Metrics()) mb.metricRedisSentinelTotalTilt.emit(ils.Metrics()) mb.metricRedisSlavesConnected.emit(ils.Metrics()) @@ -3727,11 +3671,6 @@ func (mb *MetricsBuilder) RecordRedisSentinelSimulateFailureFlagsDataPoint(ts pc mb.metricRedisSentinelSimulateFailureFlags.recordDataPoint(mb.startTime, ts, val) } -// RecordRedisSentinelTiltDataPoint adds a data point to redis.sentinel.tilt metric. -func (mb *MetricsBuilder) RecordRedisSentinelTiltDataPoint(ts pcommon.Timestamp, val int64) { - mb.metricRedisSentinelTilt.recordDataPoint(mb.startTime, ts, val) -} - // RecordRedisSentinelTiltSinceSecondsDataPoint adds a data point to redis.sentinel.tilt_since_seconds metric. func (mb *MetricsBuilder) RecordRedisSentinelTiltSinceSecondsDataPoint(ts pcommon.Timestamp, val int64) { mb.metricRedisSentinelTiltSinceSeconds.recordDataPoint(mb.startTime, ts, val) diff --git a/receiver/redisreceiver/internal/metadata/generated_metrics_test.go b/receiver/redisreceiver/internal/metadata/generated_metrics_test.go index 36afeb135244e..02f7221faadde 100644 --- a/receiver/redisreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/redisreceiver/internal/metadata/generated_metrics_test.go @@ -204,7 +204,6 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordRedisMemoryUsedDataPoint(ts, 1) - defaultMetricsCount++ allMetricsCount++ mb.RecordRedisModeDataPoint(ts, 1, AttributeModeCluster) @@ -234,35 +233,24 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordRedisRoleDataPoint(ts, 1, AttributeRoleReplica) - defaultMetricsCount++ allMetricsCount++ mb.RecordRedisSentinelMastersDataPoint(ts, 1) - defaultMetricsCount++ allMetricsCount++ mb.RecordRedisSentinelRunningScriptsDataPoint(ts, 1) - defaultMetricsCount++ allMetricsCount++ mb.RecordRedisSentinelScriptsQueueLengthDataPoint(ts, 1) - defaultMetricsCount++ allMetricsCount++ mb.RecordRedisSentinelSimulateFailureFlagsDataPoint(ts, 1) - defaultMetricsCount++ - allMetricsCount++ - mb.RecordRedisSentinelTiltDataPoint(ts, 1) - - defaultMetricsCount++ allMetricsCount++ mb.RecordRedisSentinelTiltSinceSecondsDataPoint(ts, 1) - defaultMetricsCount++ allMetricsCount++ mb.RecordRedisSentinelTotalTiltDataPoint(ts, 1) - defaultMetricsCount++ allMetricsCount++ mb.RecordRedisSlavesConnectedDataPoint(ts, 1) @@ -925,7 +913,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) assert.Equal(t, "Number of masters monitored by Sentinel.", ms.At(i).Description()) - assert.Equal(t, "{masters}", ms.At(i).Unit()) + assert.Equal(t, "{master}", ms.At(i).Unit()) dp := ms.At(i).Gauge().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) assert.Equal(t, ts, dp.Timestamp()) @@ -937,7 +925,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) assert.Equal(t, "Number of running Sentinel scripts.", ms.At(i).Description()) - assert.Equal(t, "{scripts}", ms.At(i).Unit()) + assert.Equal(t, "{script}", ms.At(i).Unit()) dp := ms.At(i).Gauge().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) assert.Equal(t, ts, dp.Timestamp()) @@ -949,7 +937,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) assert.Equal(t, "Length of Sentinel scripts queue.", ms.At(i).Description()) - assert.Equal(t, "{scripts}", ms.At(i).Unit()) + assert.Equal(t, "{script}", ms.At(i).Unit()) dp := ms.At(i).Gauge().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) assert.Equal(t, ts, dp.Timestamp()) @@ -961,19 +949,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) assert.Equal(t, "Simulated failure flags bitmask.", ms.At(i).Description()) - assert.Equal(t, "{flags}", 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 "redis.sentinel.tilt": - assert.False(t, validatedMetrics["redis.sentinel.tilt"], "Found a duplicate in the metrics slice: redis.sentinel.tilt") - validatedMetrics["redis.sentinel.tilt"] = true - assert.Equal(t, pmetric.MetricTypeGauge, ms.At(i).Type()) - assert.Equal(t, 1, ms.At(i).Gauge().DataPoints().Len()) - assert.Equal(t, "Whether Sentinel is in TILT mode (1 = tilt, 0 = normal).", ms.At(i).Description()) - assert.Equal(t, "{state}", ms.At(i).Unit()) + assert.Equal(t, "{flag}", ms.At(i).Unit()) dp := ms.At(i).Gauge().DataPoints().At(0) assert.Equal(t, start, dp.StartTimestamp()) assert.Equal(t, ts, dp.Timestamp()) @@ -997,7 +973,7 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, pmetric.MetricTypeSum, ms.At(i).Type()) assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) assert.Equal(t, "Total TILT occurrences since start.", ms.At(i).Description()) - assert.Equal(t, "{events}", ms.At(i).Unit()) + assert.Equal(t, "{event}", ms.At(i).Unit()) assert.True(t, ms.At(i).Sum().IsMonotonic()) assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) dp := ms.At(i).Sum().DataPoints().At(0) diff --git a/receiver/redisreceiver/internal/metadata/testdata/config.yaml b/receiver/redisreceiver/internal/metadata/testdata/config.yaml index 23e97ea7fbbf2..dcd9639fbcf23 100644 --- a/receiver/redisreceiver/internal/metadata/testdata/config.yaml +++ b/receiver/redisreceiver/internal/metadata/testdata/config.yaml @@ -101,8 +101,6 @@ all_set: enabled: true redis.sentinel.simulate_failure_flags: enabled: true - redis.sentinel.tilt: - enabled: true redis.sentinel.tilt_since_seconds: enabled: true redis.sentinel.total_tilt: @@ -220,8 +218,6 @@ none_set: enabled: false redis.sentinel.simulate_failure_flags: enabled: false - redis.sentinel.tilt: - enabled: false redis.sentinel.tilt_since_seconds: enabled: false redis.sentinel.total_tilt: diff --git a/receiver/redisreceiver/metadata.yaml b/receiver/redisreceiver/metadata.yaml index 7e25401568106..97671629cc3b2 100644 --- a/receiver/redisreceiver/metadata.yaml +++ b/receiver/redisreceiver/metadata.yaml @@ -458,7 +458,7 @@ metrics: value_type: int redis.mode: - enabled: true + enabled: false description: Redis server mode unit: "{mode}" gauge: @@ -539,58 +539,51 @@ metrics: attributes: [role] redis.sentinel.masters: - enabled: true + enabled: false description: Number of masters monitored by Sentinel. - unit: "{masters}" + unit: "{master}" gauge: value_type: int redis.sentinel.running_scripts: - enabled: true + enabled: false description: Number of running Sentinel scripts. - unit: "{scripts}" + unit: "{script}" gauge: value_type: int redis.sentinel.scripts_queue_length: - enabled: true + enabled: false description: Length of Sentinel scripts queue. - unit: "{scripts}" + unit: "{script}" gauge: value_type: int redis.sentinel.simulate_failure_flags: - enabled: true + enabled: false description: Simulated failure flags bitmask. - unit: "{flags}" - gauge: - value_type: int - - redis.sentinel.tilt: - enabled: true - description: Whether Sentinel is in TILT mode (1 = tilt, 0 = normal). - unit: "{state}" + unit: "{flag}" gauge: value_type: int redis.sentinel.tilt_since_seconds: - enabled: true + enabled: false description: Duration in seconds of current TILT, or -1 if not in TILT mode. unit: "s" gauge: value_type: int redis.sentinel.total_tilt: - enabled: true + enabled: false description: Total TILT occurrences since start. - unit: "{events}" + unit: "{event}" sum: value_type: int monotonic: true aggregation_temporality: cumulative redis.slaves.connected: - enabled: true + enabled: false description: Number of connected replicas stability: level: development diff --git a/receiver/redisreceiver/redis_scraper.go b/receiver/redisreceiver/redis_scraper.go index 3f6a838e290b0..7616ac1f9d4ee 100644 --- a/receiver/redisreceiver/redis_scraper.go +++ b/receiver/redisreceiver/redis_scraper.go @@ -97,16 +97,12 @@ func (rs *redisScraper) Scrape(context.Context) (pmetric.Metrics, error) { mode := rs.getRedisMode(inf) - rs.recordCommonMetrics(now, inf) + rs.recordCommonMetrics(now, inf, rs.dataPointRecorders()) + rs.recordCommonMetrics(now, inf, rs.sentinelDataPointRecorders()) rs.recordKeyspaceMetrics(now, inf) rs.recordRoleMetrics(now, inf) rs.recordCmdMetrics(now, inf) rs.recordModeMetrics(now, mode) - - if mode == "sentinel" { - rs.recordSentinelMetrics(now, inf) - } - rb := rs.mb.NewResourceBuilder() rb.SetRedisVersion(rs.getRedisVersion(inf)) rb.SetServerAddress(rs.configInfo.Address) @@ -115,8 +111,7 @@ func (rs *redisScraper) Scrape(context.Context) (pmetric.Metrics, error) { } // recordCommonMetrics records metrics from Redis info key-value pairs. -func (rs *redisScraper) recordCommonMetrics(ts pcommon.Timestamp, inf info) { - recorders := rs.dataPointRecorders() +func (rs *redisScraper) recordCommonMetrics(ts pcommon.Timestamp, inf info, recorders map[string]any) { for infoKey, infoVal := range inf { recorder, ok := recorders[infoKey] if !ok { @@ -129,20 +124,25 @@ func (rs *redisScraper) recordCommonMetrics(ts pcommon.Timestamp, inf info) { if err != nil { rs.settings.Logger.Warn("failed to parse info int val", zap.String("key", infoKey), zap.String("val", infoVal), zap.Error(err)) + continue } recordDataPoint(ts, val) + case func(pcommon.Timestamp, float64): val, err := strconv.ParseFloat(infoVal, 64) if err != nil { rs.settings.Logger.Warn("failed to parse info float val", zap.String("key", infoKey), zap.String("val", infoVal), zap.Error(err)) + continue } recordDataPoint(ts, val) + case func(pcommon.Timestamp, int64, metadata.AttributeClusterState): val, err := strconv.ParseInt(infoVal, 10, 64) if err != nil { rs.settings.Logger.Warn("failed to parse info int val", zap.String("key", infoKey), zap.String("val", infoVal), zap.Error(err)) + continue } var state metadata.AttributeClusterState if infoKey == "cluster_state" { @@ -279,47 +279,10 @@ func (rs *redisScraper) recordCmdLatencyMetrics(ts pcommon.Timestamp, cmd, val s } } -// recordSentinelMetrics records metrics from Redis INFO when running in Sentinel mode. -// Runs only when rs.getRedisMode(inf) == "sentinel". -func (rs *redisScraper) recordSentinelMetrics(ts pcommon.Timestamp, inf info) { - recorders := rs.sentinelDataPointRecorders() - for infoKey, infoVal := range inf { - recorder, ok := recorders[infoKey] - if !ok { - continue // skip unrelated keys - } - - switch recordDataPoint := recorder.(type) { - case func(pcommon.Timestamp, int64): - val, err := strconv.ParseInt(infoVal, 10, 64) - if err != nil { - rs.settings.Logger.Warn("failed to parse sentinel int val", - zap.String("key", infoKey), - zap.String("val", infoVal), - zap.Error(err)) - continue - } - recordDataPoint(ts, val) - - case func(pcommon.Timestamp, float64): - val, err := strconv.ParseFloat(infoVal, 64) - if err != nil { - rs.settings.Logger.Warn("failed to parse sentinel float val", - zap.String("key", infoKey), - zap.String("val", infoVal), - zap.Error(err)) - continue - } - recordDataPoint(ts, val) - } - } -} - // sentinelDataPointRecorders returns the map of supported Sentinel metrics. func (rs *redisScraper) sentinelDataPointRecorders() map[string]any { return map[string]any{ "sentinel_masters": rs.mb.RecordRedisSentinelMastersDataPoint, - "sentinel_tilt": rs.mb.RecordRedisSentinelTiltDataPoint, "sentinel_tilt_since_seconds": rs.mb.RecordRedisSentinelTiltSinceSecondsDataPoint, "sentinel_total_tilt": rs.mb.RecordRedisSentinelTotalTiltDataPoint, "sentinel_running_scripts": rs.mb.RecordRedisSentinelRunningScriptsDataPoint, diff --git a/receiver/redisreceiver/redis_scraper_test.go b/receiver/redisreceiver/redis_scraper_test.go index 4791d9ca1f494..a5b57445d6fe8 100644 --- a/receiver/redisreceiver/redis_scraper_test.go +++ b/receiver/redisreceiver/redis_scraper_test.go @@ -32,8 +32,7 @@ func TestRedisRunnable(t *testing.T) { require.NoError(t, err) // + 9 because there are three keyspace entries each of which has three metrics // -2 because maxmemory and slave_repl_offset is by default disabled, so recorder is there, but there won't be data point - // +1 for redis.mode (one-hot, exactly one sample per scrape) - assert.Equal(t, len(rs.dataPointRecorders())+9-14+1, md.DataPointCount()) + assert.Equal(t, len(rs.dataPointRecorders())+9-15, md.DataPointCount()) rm := md.ResourceMetrics().At(0) ilm := rm.ScopeMetrics().At(0) il := ilm.Scope() diff --git a/receiver/redisreceiver/testdata/integration/expected-sentinel.yaml b/receiver/redisreceiver/testdata/integration/expected-sentinel.yaml index a914ccd397e4f..248c12147a944 100644 --- a/receiver/redisreceiver/testdata/integration/expected-sentinel.yaml +++ b/receiver/redisreceiver/testdata/integration/expected-sentinel.yaml @@ -214,7 +214,7 @@ resourceMetrics: - asInt: "1" startTimeUnixNano: "1687339331739210000" timeUnixNano: "1687339332739210000" - unit: "{masters}" + unit: "{master}" - description: Number of running Sentinel scripts. gauge: dataPoints: @@ -222,7 +222,7 @@ resourceMetrics: startTimeUnixNano: "1687339331739210000" timeUnixNano: "1687339332739210000" name: redis.sentinel.running_scripts - unit: "{scripts}" + unit: "{script}" - description: Length of Sentinel scripts queue. gauge: dataPoints: @@ -230,7 +230,7 @@ resourceMetrics: startTimeUnixNano: "1687339331739210000" timeUnixNano: "1687339332739210000" name: redis.sentinel.scripts_queue_length - unit: "{scripts}" + unit: "{script}" - description: Simulated failure flags bitmask. gauge: dataPoints: @@ -238,15 +238,7 @@ resourceMetrics: startTimeUnixNano: "1687339331739210000" timeUnixNano: "1687339332739210000" name: redis.sentinel.simulate_failure_flags - unit: "{flags}" - - description: Whether Sentinel is in TILT mode (1 = tilt, 0 = normal). - gauge: - dataPoints: - - asInt: "0" - startTimeUnixNano: "1687339331739210000" - timeUnixNano: "1687339332739210000" - name: redis.sentinel.tilt - unit: "{state}" + unit: "{flag}" - description: Duration in seconds of current TILT, or -1 if not in TILT mode. gauge: dataPoints: @@ -264,7 +256,7 @@ resourceMetrics: startTimeUnixNano: "1687339331739210000" timeUnixNano: "1687339332739210000" isMonotonic: true - unit: "{events}" + unit: "{event}" - description: Number of seconds since Redis server start name: redis.uptime sum: From 65fbb9dc51f82d860c7b496fd685df4f576969bd Mon Sep 17 00:00:00 2001 From: Paulo Dias Date: Tue, 21 Oct 2025 23:14:52 +0100 Subject: [PATCH 08/12] fix: fix integration test Signed-off-by: Paulo Dias --- receiver/redisreceiver/integration_test.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/receiver/redisreceiver/integration_test.go b/receiver/redisreceiver/integration_test.go index 7b4c90d6867c4..8a031bfa2f69b 100644 --- a/receiver/redisreceiver/integration_test.go +++ b/receiver/redisreceiver/integration_test.go @@ -123,6 +123,13 @@ func TestIntegrationV8Sentinel(t *testing.T) { func(t *testing.T, cfg component.Config, ci *scraperinttest.ContainerInfo) { rCfg := cfg.(*Config) rCfg.Endpoint = fmt.Sprintf("%s:%s", ci.Host(t), ci.MappedPort(t, sentinelPort)) + rCfg.MetricsBuilderConfig.Metrics.RedisMode.Enabled = true + rCfg.MetricsBuilderConfig.Metrics.RedisSentinelMasters.Enabled = true + rCfg.MetricsBuilderConfig.Metrics.RedisSentinelRunningScripts.Enabled = true + rCfg.MetricsBuilderConfig.Metrics.RedisSentinelScriptsQueueLength.Enabled = true + rCfg.MetricsBuilderConfig.Metrics.RedisSentinelSimulateFailureFlags.Enabled = true + rCfg.MetricsBuilderConfig.Metrics.RedisSentinelTiltSinceSeconds.Enabled = true + rCfg.MetricsBuilderConfig.Metrics.RedisSentinelTotalTilt.Enabled = true }), scraperinttest.WithCompareOptions( pmetrictest.IgnoreMetricValues(), From f06a1909545396b6c3be906680ad8affedb228c1 Mon Sep 17 00:00:00 2001 From: Paulo Dias Date: Wed, 22 Oct 2025 13:18:16 +0100 Subject: [PATCH 09/12] chore: add missing stability to metrics Signed-off-by: Paulo Dias --- receiver/redisreceiver/documentation.md | 42 ++++++++++++------------- receiver/redisreceiver/metadata.yaml | 14 +++++++++ 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/receiver/redisreceiver/documentation.md b/receiver/redisreceiver/documentation.md index 176413d11d87a..8c87c0d98301d 100644 --- a/receiver/redisreceiver/documentation.md +++ b/receiver/redisreceiver/documentation.md @@ -427,9 +427,9 @@ The value of the maxmemory configuration directive Redis server mode -| Unit | Metric Type | Value Type | -| ---- | ----------- | ---------- | -| {mode} | Gauge | Int | +| Unit | Metric Type | Value Type | Stability | +| ---- | ----------- | ---------- | --------- | +| {mode} | Gauge | Int | development | #### Attributes @@ -463,49 +463,49 @@ Redis node's role Number of masters monitored by Sentinel. -| Unit | Metric Type | Value Type | -| ---- | ----------- | ---------- | -| {master} | Gauge | Int | +| Unit | Metric Type | Value Type | Stability | +| ---- | ----------- | ---------- | --------- | +| {master} | Gauge | Int | development | ### redis.sentinel.running_scripts Number of running Sentinel scripts. -| Unit | Metric Type | Value Type | -| ---- | ----------- | ---------- | -| {script} | Gauge | Int | +| Unit | Metric Type | Value Type | Stability | +| ---- | ----------- | ---------- | --------- | +| {script} | Gauge | Int | development | ### redis.sentinel.scripts_queue_length Length of Sentinel scripts queue. -| Unit | Metric Type | Value Type | -| ---- | ----------- | ---------- | -| {script} | Gauge | Int | +| Unit | Metric Type | Value Type | Stability | +| ---- | ----------- | ---------- | --------- | +| {script} | Gauge | Int | development | ### redis.sentinel.simulate_failure_flags Simulated failure flags bitmask. -| Unit | Metric Type | Value Type | -| ---- | ----------- | ---------- | -| {flag} | Gauge | Int | +| Unit | Metric Type | Value Type | Stability | +| ---- | ----------- | ---------- | --------- | +| {flag} | Gauge | Int | development | ### redis.sentinel.tilt_since_seconds Duration in seconds of current TILT, or -1 if not in TILT mode. -| Unit | Metric Type | Value Type | -| ---- | ----------- | ---------- | -| s | Gauge | Int | +| Unit | Metric Type | Value Type | Stability | +| ---- | ----------- | ---------- | --------- | +| s | Gauge | Int | development | ### redis.sentinel.total_tilt Total TILT occurrences since start. -| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic | -| ---- | ----------- | ---------- | ----------------------- | --------- | -| {event} | Sum | Int | Cumulative | true | +| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic | Stability | +| ---- | ----------- | ---------- | ----------------------- | --------- | --------- | +| {event} | Sum | Int | Cumulative | true | development | ### redis.slaves.connected diff --git a/receiver/redisreceiver/metadata.yaml b/receiver/redisreceiver/metadata.yaml index 97671629cc3b2..23e2c35b49905 100644 --- a/receiver/redisreceiver/metadata.yaml +++ b/receiver/redisreceiver/metadata.yaml @@ -460,6 +460,8 @@ metrics: redis.mode: enabled: false description: Redis server mode + stability: + level: development unit: "{mode}" gauge: value_type: int @@ -541,6 +543,8 @@ metrics: redis.sentinel.masters: enabled: false description: Number of masters monitored by Sentinel. + stability: + level: development unit: "{master}" gauge: value_type: int @@ -548,6 +552,8 @@ metrics: redis.sentinel.running_scripts: enabled: false description: Number of running Sentinel scripts. + stability: + level: development unit: "{script}" gauge: value_type: int @@ -555,6 +561,8 @@ metrics: redis.sentinel.scripts_queue_length: enabled: false description: Length of Sentinel scripts queue. + stability: + level: development unit: "{script}" gauge: value_type: int @@ -562,6 +570,8 @@ metrics: redis.sentinel.simulate_failure_flags: enabled: false description: Simulated failure flags bitmask. + stability: + level: development unit: "{flag}" gauge: value_type: int @@ -569,6 +579,8 @@ metrics: redis.sentinel.tilt_since_seconds: enabled: false description: Duration in seconds of current TILT, or -1 if not in TILT mode. + stability: + level: development unit: "s" gauge: value_type: int @@ -576,6 +588,8 @@ metrics: redis.sentinel.total_tilt: enabled: false description: Total TILT occurrences since start. + stability: + level: development unit: "{event}" sum: value_type: int From 71e7db823beb680c16914aa0e614fc626ed4387d Mon Sep 17 00:00:00 2001 From: Paulo Dias Date: Wed, 22 Oct 2025 13:43:22 +0100 Subject: [PATCH 10/12] chore: make generate Signed-off-by: Paulo Dias --- receiver/redisreceiver/documentation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/receiver/redisreceiver/documentation.md b/receiver/redisreceiver/documentation.md index 8a22ab3cde541..f90d4d314c8dc 100644 --- a/receiver/redisreceiver/documentation.md +++ b/receiver/redisreceiver/documentation.md @@ -433,9 +433,9 @@ Redis server mode #### Attributes -| Name | Description | Values | Optional | +| Name | Description | Values | Requirement Level | | ---- | ----------- | ------ | -------- | -| mode | Redis server mode | Str: ``cluster``, ``sentinel``, ``standalone`` | false | +| mode | Redis server mode | Str: ``cluster``, ``sentinel``, ``standalone`` | Recommended | ### redis.replication.replica_offset From 769010051f5a622dceea097f44d1701f46d575f0 Mon Sep 17 00:00:00 2001 From: Paulo Dias Date: Wed, 22 Oct 2025 22:04:24 +0100 Subject: [PATCH 11/12] chore: revert to main Signed-off-by: Paulo Dias --- .../integration/expected-cluster.yaml | 36 +++++++------------ .../testdata/integration/expected-old.yaml | 36 +++++++------------ 2 files changed, 24 insertions(+), 48 deletions(-) diff --git a/receiver/redisreceiver/testdata/integration/expected-cluster.yaml b/receiver/redisreceiver/testdata/integration/expected-cluster.yaml index cc8f815fb3294..3519980749581 100644 --- a/receiver/redisreceiver/testdata/integration/expected-cluster.yaml +++ b/receiver/redisreceiver/testdata/integration/expected-cluster.yaml @@ -14,7 +14,7 @@ resourceMetrics: - asInt: "0" startTimeUnixNano: "1000000" timeUnixNano: "2000000" - unit: "{client}" + unit: '{client}' - description: Number of client connections (excluding connections from replicas) name: redis.clients.connected sum: @@ -23,7 +23,7 @@ resourceMetrics: - asInt: "2" startTimeUnixNano: "1000000" timeUnixNano: "2000000" - unit: "{client}" + unit: '{client}' - description: Biggest input buffer among current client connections gauge: dataPoints: @@ -47,7 +47,7 @@ resourceMetrics: startTimeUnixNano: "1000000" timeUnixNano: "2000000" name: redis.commands - unit: "{ops}/s" + unit: '{ops}/s' - description: Total number of commands processed by the server name: redis.commands.processed sum: @@ -57,7 +57,7 @@ resourceMetrics: startTimeUnixNano: "1000000" timeUnixNano: "2000000" isMonotonic: true - unit: "{command}" + unit: '{command}' - description: Total number of connections accepted by the server name: redis.connections.received sum: @@ -67,7 +67,7 @@ resourceMetrics: startTimeUnixNano: "1000000" timeUnixNano: "2000000" isMonotonic: true - unit: "{connection}" + unit: '{connection}' - description: Number of connections rejected because of maxclients limit name: redis.connections.rejected sum: @@ -77,7 +77,7 @@ resourceMetrics: startTimeUnixNano: "1000000" timeUnixNano: "2000000" isMonotonic: true - unit: "{connection}" + unit: '{connection}' - description: System CPU consumed by the Redis server in seconds since server start name: redis.cpu.time sum: @@ -136,7 +136,7 @@ resourceMetrics: startTimeUnixNano: "1000000" timeUnixNano: "2000000" isMonotonic: true - unit: "{key}" + unit: '{key}' - description: Total number of key expiration events name: redis.keys.expired sum: @@ -146,7 +146,7 @@ resourceMetrics: startTimeUnixNano: "1000000" timeUnixNano: "2000000" isMonotonic: true - unit: "{event}" + unit: '{event}' - description: Number of successful lookup of keys in the main dictionary name: redis.keyspace.hits sum: @@ -156,7 +156,7 @@ resourceMetrics: startTimeUnixNano: "1000000" timeUnixNano: "2000000" isMonotonic: true - unit: "{hit}" + unit: '{hit}' - description: Number of failed lookup of keys in the main dictionary name: redis.keyspace.misses sum: @@ -166,7 +166,7 @@ resourceMetrics: startTimeUnixNano: "1000000" timeUnixNano: "2000000" isMonotonic: true - unit: "{miss}" + unit: '{miss}' - description: Duration of the latest fork operation in microseconds gauge: dataPoints: @@ -215,18 +215,6 @@ resourceMetrics: timeUnixNano: "2000000" name: redis.memory.used unit: By - - description: Redis server mode - gauge: - dataPoints: - - asInt: "1" - attributes: - - key: mode - value: - stringValue: cluster - startTimeUnixNano: "1687339331739210000" - timeUnixNano: "1687339332739210000" - name: redis.mode - unit: "{mode}" - description: The total number of bytes read from the network name: redis.net.input sum: @@ -255,7 +243,7 @@ resourceMetrics: - asInt: "0" startTimeUnixNano: "1000000" timeUnixNano: "2000000" - unit: "{change}" + unit: '{change}' - description: The master offset of the replication backlog buffer gauge: dataPoints: @@ -288,7 +276,7 @@ resourceMetrics: - asInt: "0" startTimeUnixNano: "1000000" timeUnixNano: "2000000" - unit: "{replica}" + unit: '{replica}' - description: Number of seconds since Redis server start name: redis.uptime sum: diff --git a/receiver/redisreceiver/testdata/integration/expected-old.yaml b/receiver/redisreceiver/testdata/integration/expected-old.yaml index abb0e4582a0a5..125be719b42dc 100644 --- a/receiver/redisreceiver/testdata/integration/expected-old.yaml +++ b/receiver/redisreceiver/testdata/integration/expected-old.yaml @@ -14,7 +14,7 @@ resourceMetrics: - asInt: "0" startTimeUnixNano: "1687339331739210000" timeUnixNano: "1687339332739210000" - unit: "{client}" + unit: '{client}' - description: Number of client connections (excluding connections from replicas) name: redis.clients.connected sum: @@ -23,7 +23,7 @@ resourceMetrics: - asInt: "1" startTimeUnixNano: "1687339331739210000" timeUnixNano: "1687339332739210000" - unit: "{client}" + unit: '{client}' - description: Biggest input buffer among current client connections gauge: dataPoints: @@ -47,7 +47,7 @@ resourceMetrics: startTimeUnixNano: "1687339331739210000" timeUnixNano: "1687339332739210000" name: redis.commands - unit: "{ops}/s" + unit: '{ops}/s' - description: Total number of commands processed by the server name: redis.commands.processed sum: @@ -57,7 +57,7 @@ resourceMetrics: startTimeUnixNano: "1687339331739210000" timeUnixNano: "1687339332739210000" isMonotonic: true - unit: "{command}" + unit: '{command}' - description: Total number of connections accepted by the server name: redis.connections.received sum: @@ -67,7 +67,7 @@ resourceMetrics: startTimeUnixNano: "1687339331739210000" timeUnixNano: "1687339332739210000" isMonotonic: true - unit: "{connection}" + unit: '{connection}' - description: Number of connections rejected because of maxclients limit name: redis.connections.rejected sum: @@ -77,7 +77,7 @@ resourceMetrics: startTimeUnixNano: "1687339331739210000" timeUnixNano: "1687339332739210000" isMonotonic: true - unit: "{connection}" + unit: '{connection}' - description: System CPU consumed by the Redis server in seconds since server start name: redis.cpu.time sum: @@ -122,7 +122,7 @@ resourceMetrics: startTimeUnixNano: "1687339331739210000" timeUnixNano: "1687339332739210000" isMonotonic: true - unit: "{key}" + unit: '{key}' - description: Total number of key expiration events name: redis.keys.expired sum: @@ -132,7 +132,7 @@ resourceMetrics: startTimeUnixNano: "1687339331739210000" timeUnixNano: "1687339332739210000" isMonotonic: true - unit: "{event}" + unit: '{event}' - description: Number of successful lookup of keys in the main dictionary name: redis.keyspace.hits sum: @@ -142,7 +142,7 @@ resourceMetrics: startTimeUnixNano: "1687339331739210000" timeUnixNano: "1687339332739210000" isMonotonic: true - unit: "{hit}" + unit: '{hit}' - description: Number of failed lookup of keys in the main dictionary name: redis.keyspace.misses sum: @@ -152,7 +152,7 @@ resourceMetrics: startTimeUnixNano: "1687339331739210000" timeUnixNano: "1687339332739210000" isMonotonic: true - unit: "{miss}" + unit: '{miss}' - description: Duration of the latest fork operation in microseconds gauge: dataPoints: @@ -201,18 +201,6 @@ resourceMetrics: timeUnixNano: "1687339332739210000" name: redis.memory.used unit: By - - description: Redis server mode - gauge: - dataPoints: - - asInt: "1" - attributes: - - key: mode - value: - stringValue: standalone - startTimeUnixNano: "1687339331739210000" - timeUnixNano: "1687339332739210000" - name: redis.mode - unit: "{mode}" - description: The total number of bytes read from the network name: redis.net.input sum: @@ -241,7 +229,7 @@ resourceMetrics: - asInt: "0" startTimeUnixNano: "1687339331739210000" timeUnixNano: "1687339332739210000" - unit: "{change}" + unit: '{change}' - description: The master offset of the replication backlog buffer gauge: dataPoints: @@ -266,7 +254,7 @@ resourceMetrics: - asInt: "0" startTimeUnixNano: "1687339331739210000" timeUnixNano: "1687339332739210000" - unit: "{replica}" + unit: '{replica}' - description: Number of seconds since Redis server start name: redis.uptime sum: From d8dc725c92f1e4f49527db4fcbabe1ade4ae8b63 Mon Sep 17 00:00:00 2001 From: Paulo Dias Date: Wed, 22 Oct 2025 22:27:04 +0100 Subject: [PATCH 12/12] fix: fix integration tests Signed-off-by: Paulo Dias --- receiver/redisreceiver/documentation.md | 16 ++++++++-------- .../internal/metadata/generated_config.go | 2 +- .../internal/metadata/generated_metrics_test.go | 1 + receiver/redisreceiver/metadata.yaml | 2 +- receiver/redisreceiver/redis_scraper_test.go | 2 +- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/receiver/redisreceiver/documentation.md b/receiver/redisreceiver/documentation.md index f90d4d314c8dc..d78fbbf70d308 100644 --- a/receiver/redisreceiver/documentation.md +++ b/receiver/redisreceiver/documentation.md @@ -252,6 +252,14 @@ The server's current replication offset | ---- | ----------- | ---------- | --------- | | By | Gauge | Int | development | +### redis.slaves.connected + +Number of connected replicas + +| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic | Stability | +| ---- | ----------- | ---------- | ----------------------- | --------- | --------- | +| {replica} | Sum | Int | Cumulative | false | development | + ### redis.uptime Number of seconds since Redis server start @@ -507,14 +515,6 @@ Total TILT occurrences since start. | ---- | ----------- | ---------- | ----------------------- | --------- | --------- | | {event} | Sum | Int | Cumulative | true | development | -### redis.slaves.connected - -Number of connected replicas - -| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic | Stability | -| ---- | ----------- | ---------- | ----------------------- | --------- | --------- | -| {replica} | Sum | Int | Cumulative | false | development | - ## Resource Attributes | Name | Description | Values | Enabled | diff --git a/receiver/redisreceiver/internal/metadata/generated_config.go b/receiver/redisreceiver/internal/metadata/generated_config.go index 34b4aa58c6d76..67a2dc64996bb 100644 --- a/receiver/redisreceiver/internal/metadata/generated_config.go +++ b/receiver/redisreceiver/internal/metadata/generated_config.go @@ -243,7 +243,7 @@ func DefaultMetricsConfig() MetricsConfig { Enabled: false, }, RedisSlavesConnected: MetricConfig{ - Enabled: false, + Enabled: true, }, RedisUptime: MetricConfig{ Enabled: true, diff --git a/receiver/redisreceiver/internal/metadata/generated_metrics_test.go b/receiver/redisreceiver/internal/metadata/generated_metrics_test.go index 02f7221faadde..711ca7f6c4703 100644 --- a/receiver/redisreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/redisreceiver/internal/metadata/generated_metrics_test.go @@ -251,6 +251,7 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordRedisSentinelTotalTiltDataPoint(ts, 1) + defaultMetricsCount++ allMetricsCount++ mb.RecordRedisSlavesConnectedDataPoint(ts, 1) diff --git a/receiver/redisreceiver/metadata.yaml b/receiver/redisreceiver/metadata.yaml index 23e2c35b49905..88025f7ea71fc 100644 --- a/receiver/redisreceiver/metadata.yaml +++ b/receiver/redisreceiver/metadata.yaml @@ -597,7 +597,7 @@ metrics: aggregation_temporality: cumulative redis.slaves.connected: - enabled: false + enabled: true description: Number of connected replicas stability: level: development diff --git a/receiver/redisreceiver/redis_scraper_test.go b/receiver/redisreceiver/redis_scraper_test.go index a5b57445d6fe8..cf11c629ac691 100644 --- a/receiver/redisreceiver/redis_scraper_test.go +++ b/receiver/redisreceiver/redis_scraper_test.go @@ -32,7 +32,7 @@ func TestRedisRunnable(t *testing.T) { require.NoError(t, err) // + 9 because there are three keyspace entries each of which has three metrics // -2 because maxmemory and slave_repl_offset is by default disabled, so recorder is there, but there won't be data point - assert.Equal(t, len(rs.dataPointRecorders())+9-15, md.DataPointCount()) + assert.Equal(t, len(rs.dataPointRecorders())+9-14, md.DataPointCount()) rm := md.ResourceMetrics().At(0) ilm := rm.ScopeMetrics().At(0) il := ilm.Scope()