Monitor your self-hosted Redis instance by installing the OpenTelemetry Collector directly on a server or virtual machine. This guide walks you through configuring the collector to scrape Redis metrics, collect logs, and send all telemetry to New Relic using the OTLP protocol.
Before you begin
You'll need the following before you set up the collector:
- Your New Relic
- A Linux host with root or sudo privileges
- Redis running and accessible — version 6.0 or later recommended (4.0 and later works with a reduced metric set)
- Network connectivity to your Redis endpoint (default
localhost:6379) - Outbound HTTPS (port 443) to New Relic's OTLP endpoint
- An OpenTelemetry Collector installed on that host — either the NRDOT collector or the OpenTelemetry Collector Contrib — which you choose in Installation options
- For the Prometheus receiver path only, the redis_exporter running alongside Redis
Each path's setup steps cover any installation you still need, whether that's the NRDOT collector, otelcol-contrib, or the redis_exporter.
Installation options
Choose the collector distribution that matches your environment:
Configure Redis monitoring
This configuration tells the collector how to gather Redis metrics and send them to New Relic. It handles three main jobs:
- Collect metrics from Redis through the
redisreceiver - Shape the data — reduce cardinality, convert counters to deltas, and tag it for entity synthesis
- Export the processed metrics to New Relic over OTLP
Create the collector configuration file:
$sudo nano /etc/nrdot-collector/redis-collector-config.yamlPaste the following configuration, updating the Redis endpoint if it isn't localhost:6379:
extensions: health_check: endpoint: "0.0.0.0:13133"
receivers: redis: endpoint: "localhost:6379" # Update with your Redis host:port collection_interval: 10s metrics: redis.maxmemory: enabled: true redis.role: enabled: false redis.cmd.calls: enabled: true redis.cmd.usec: enabled: true redis.clients.max_input_buffer: enabled: false redis.clients.max_output_buffer: enabled: false redis.replication.backlog_first_byte_offset: enabled: false resource_attributes: server.address: enabled: true server.port: enabled: true
processors: memory_limiter: check_interval: 5s limit_mib: 512 spike_limit_mib: 128
resource_detection: detectors: [env, system] timeout: 5s override: false system: resource_attributes: host.name: enabled: true host.id: enabled: true
# Uncomment the section below to use a custom human-readable name for your # Redis entity instead of the default server.address:server.port identifier. # resource/redis: # attributes: # - key: redis.instance.id # value: "my-redis-instance" # action: upsert
attributes/entity_tags: actions: - key: instrumentation.provider value: opentelemetry action: upsert
cumulativetodelta: include: match_type: regexp metrics: - redis\.commands\.processed - redis\.connections\.received - redis\.connections\.rejected - redis\.keys\.evicted - redis\.keys\.expired - redis\.keyspace\.hits - redis\.keyspace\.misses - redis\.net\.input - redis\.net\.output - redis\.cpu\.time - redis\.cmd\.calls - redis\.cmd\.usec - redis\.uptime
filter/cardinality: metrics: datapoint: - 'metric.name == "redis.cpu.time" and attributes["state"] != "sys" and attributes["state"] != "user"' - 'metric.name == "redis.cmd.calls" and attributes["cmd"] != "get" and attributes["cmd"] != "set" and attributes["cmd"] != "del" and attributes["cmd"] != "hget" and attributes["cmd"] != "hset" and attributes["cmd"] != "hgetall" and attributes["cmd"] != "lpush" and attributes["cmd"] != "rpop" and attributes["cmd"] != "zadd" and attributes["cmd"] != "expire"' - 'metric.name == "redis.cmd.usec" and attributes["cmd"] != "get" and attributes["cmd"] != "set" and attributes["cmd"] != "del" and attributes["cmd"] != "hget" and attributes["cmd"] != "hset" and attributes["cmd"] != "hgetall" and attributes["cmd"] != "lpush" and attributes["cmd"] != "rpop" and attributes["cmd"] != "zadd" and attributes["cmd"] != "expire"'
transform/metadata_nullify: metric_statements: - context: metric statements: - set(description, "") - set(unit, "")
batch: send_batch_size: 2048 send_batch_max_size: 4096 timeout: 10s
exporters: otlp_http: endpoint: ${env:OTEL_EXPORTER_OTLP_ENDPOINT} headers: api-key: ${env:NEW_RELIC_LICENSE_KEY} compression: gzip
service: extensions: [health_check] pipelines: metrics/redis: receivers: [redis] # If using resource/redis for custom name, add it to the processors list: # processors: [memory_limiter, resource_detection, resource/redis, attributes/entity_tags, cumulativetodelta, filter/cardinality, transform/metadata_nullify, batch] processors: [memory_limiter, resource_detection, attributes/entity_tags, cumulativetodelta, filter/cardinality, transform/metadata_nullify, batch] exporters: [otlp_http]What this configuration does
Each component in the pipeline has a specific job:
| Component | Description |
|---|---|
health_check | Exposes a health endpoint on 0.0.0.0:13133 so you can confirm the collector is running. |
redis receiver | Connects to your Redis endpoint every 10 seconds and reads metrics from the Redis INFO command. server.address and server.port become the entity's identity. |
memory_limiter | Caps collector memory usage (512 MiB soft limit, 128 MiB spike) to protect the host. |
resource_detection | Detects the host and adds host.name and host.id, linking Redis metrics to the underlying host entity. |
attributes/entity_tags | Stamps instrumentation.provider: opentelemetry on every metric so you can scope queries to the OpenTelemetry path. |
cumulativetodelta | Converts Redis's cumulative counters — commands, keyspace hits, evictions, and so on — to delta values so New Relic charts rates correctly. |
filter/cardinality | Drops high-cardinality data points (CPU states other than user and sys, and per-command metrics for uncommon commands) to control ingest cost. |
transform/metadata_nullify | Clears metric descriptions and units to reduce payload size. |
batch | Groups data points before export (2,048 per batch, up to 4,096) and flushes at least every 10 seconds to reduce network overhead. |
otlp_http | Exports the processed metrics to New Relic over OTLP with gzip compression, authenticated with your license key. |
Dica
Want a user-friendly entity name? By default, your Redis entity is named using the server.address:server.port combination. To use a custom human-readable name instead, uncomment the resource/redis section in the config above, set your preferred name in the redis.instance.id value, and add resource/redis to the processors pipeline.
Optional: Configure authentication
By default, the collector connects to Redis without credentials. If your Redis instance requires authentication, add the matching credentials to the redis receiver. Choose the option that matches your setup:
Optional: Collect Redis logs
Beyond metrics, the collector can forward Redis's log file to New Relic so you can correlate log events — restarts, persistence events, or errors — with metric spikes on the same entity. Add the filelog receiver to tail the Redis log:
receivers: # ... existing redis receiver ... file_log/redis: include: - /var/log/redis/redis-server.log start_at: end operators: - type: regex_parser regex: '^\d+:[XCSM] \d+ \w+ \d+ \d+:\d+:\d+\.\d+ (?P<level>.) ' on_error: send resource: db.system: redisLog lines from the file have no Redis connection context on their own — you must explicitly attach identity attributes so New Relic associates the logs with your Redis entity. Add a resource/redis_logs processor with hardcoded values matching your Redis entity's identity:
processors: # ... existing processors ... resource/redis_logs: attributes: - key: server.address value: "localhost" # Must match your redis receiver endpoint host action: upsert - key: server.port value: 6379 # Must match your redis receiver endpoint port action: upsert - key: instrumentation.provider value: opentelemetry action: upsertDica
Using a custom instance ID? If you enabled the resource/redis processor for custom entity naming, replace server.address and server.port above with your redis.instance.id:
resource/redis_logs: attributes: - key: redis.instance.id value: "my-redis-instance" # Must match the value in resource/redis action: upsert - key: instrumentation.provider value: opentelemetry action: upsertAdd a separate logs pipeline to the service section:
service: pipelines: metrics/redis: receivers: [redis] processors: [memory_limiter, resource_detection, attributes/entity_tags, cumulativetodelta, filter/cardinality, transform/metadata_nullify, batch] exporters: [otlp_http] logs/redis: receivers: [file_log/redis] processors: [memory_limiter, resource/redis_logs, batch] exporters: [otlp_http]Importante
The collector must have read access to both the Redis log file and its parent directory. Run:
$sudo chmod 755 /var/log/redis$sudo chmod 644 /var/log/redis/redis-server.logOptional: Collect host metrics
Redis performance often tracks host resource pressure — CPU saturation, memory exhaustion, or disk I/O contention. Add the hostmetrics receiver to collect system metrics from the host alongside Redis, so you can correlate the two in New Relic:
receivers: # ... existing receivers ... host_metrics: collection_interval: 10s scrapers: cpu: metrics: system.cpu.utilization: {enabled: true} system.cpu.time: {enabled: true} load: metrics: system.cpu.load_average.1m: {enabled: true} system.cpu.load_average.5m: {enabled: true} system.cpu.load_average.15m: {enabled: true} memory: metrics: system.memory.usage: {enabled: true} system.memory.utilization: {enabled: true} disk: metrics: system.disk.io: {enabled: true} system.disk.operations: {enabled: true} filesystem: metrics: system.filesystem.usage: {enabled: true} system.filesystem.utilization: {enabled: true} network: metrics: system.network.io: {enabled: true} system.network.packets: {enabled: true}Add a separate metrics/host pipeline for host metrics (do not add hostmetrics to the Redis pipeline):
service: pipelines: metrics/redis: receivers: [redis] processors: [memory_limiter, resource_detection, attributes/entity_tags, cumulativetodelta, filter/cardinality, transform/metadata_nullify, batch] exporters: [otlp_http] metrics/host: receivers: [host_metrics] processors: [memory_limiter, resource_detection, attributes/entity_tags, cumulativetodelta, batch] exporters: [otlp_http]Optional: Add custom metadata
Custom resource attributes tag every Redis metric with context — environment, team, or tier — so you can filter and group your data in New Relic. Add a resource/custom processor with the tags you want:
processors: # ... existing processors ... resource/custom: attributes: - key: environment value: "production" action: upsert - key: team value: "platform" action: upsert - key: redis.cluster value: "cache-tier-1" action: upsertInclude the processor in your pipeline:
service: pipelines: metrics/redis: receivers: [redis] processors: [memory_limiter, resource_detection, resource/custom, attributes/entity_tags, cumulativetodelta, filter/cardinality, transform/metadata_nullify, batch] exporters: [otlp_http]Optional: Enable Redis Cluster monitoring
Redis Cluster monitoring currently requires the Prometheus receiver approach (using redis_exporter). The NRDOT Collector's native Redis receiver does not yet support the CLUSTER INFO command needed for cluster metrics. Use the Prometheus receiver tab for cluster monitoring setup.
Set environment variables
The collector reads deployment-specific values — your license key, OTLP endpoint, and config path — from an environment file, which keeps secrets out of the config YAML. Create the environment file:
$sudo tee /etc/nrdot-collector/nrdot-collector.conf > /dev/null <<'EOF'$NEW_RELIC_LICENSE_KEY=YOUR_LICENSE_KEY$OTEL_EXPORTER_OTLP_ENDPOINT=YOUR_OTLP_ENDPOINT$# Set the New Relic OTLP endpoint for your region.$# See https://docs.newrelic.com/docs/opentelemetry/best-practices/opentelemetry-otlp$OTELCOL_OPTIONS="--config=/etc/nrdot-collector/redis-collector-config.yaml"$EOF$sudo chmod 600 /etc/nrdot-collector/nrdot-collector.confReplace the placeholders with your own values:
| Variable | Required | Description |
|---|---|---|
NEW_RELIC_LICENSE_KEY | Yes | Your New Relic ingest license key. |
OTEL_EXPORTER_OTLP_ENDPOINT | Yes | New Relic OTLP endpoint for your region. For more information, see New Relic OTLP endpoint. |
OTELCOL_OPTIONS | Yes | Points the collector at your Redis configuration file. |
Dica
This configuration replaces the default NRDot configuration. If you need to preserve the default NRDot pipelines alongside Redis monitoring, add the default config file as well:
$OTELCOL_OPTIONS="--config=/etc/nrdot-collector/config.yaml --config=/etc/nrdot-collector/redis-collector-config.yaml"When using multiple config files, ensure there are no conflicting component names between them. Rename any duplicate processors in your Redis config by adding a suffix (e.g., memory_limiter/redis instead of memory_limiter).
Restart and verify
Restart the collector to load the new configuration:
$sudo systemctl daemon-reload$sudo systemctl restart nrdot-collector$sudo systemctl status nrdot-collectorThe status command should show Active: active (running). If it shows Active: failed, check the logs with journalctl -u nrdot-collector -n 100 --no-pager — the most common causes are YAML indentation errors and an unreachable Redis endpoint.
Then confirm your metrics are reaching New Relic. Wait about a minute after the restart, then run this query in the query builder:
SELECT count(*) FROM Metric WHERE metricName LIKE 'redis.%' AND instrumentation.provider = 'opentelemetry' SINCE 5 minutes agoA non-zero count confirms Redis metrics are flowing. If it returns 0, see Troubleshoot Redis (OpenTelemetry).
Install the collector
Install the OpenTelemetry Collector Contrib if it's not already present:
After installation, the collector is available as a systemd service named otelcol-contrib.service.
Configure Redis monitoring
This configuration tells the collector how to gather Redis metrics and send them to New Relic. It handles three main jobs:
- Collect metrics from Redis through the
redisreceiver - Shape the data — reduce cardinality, convert counters to deltas, and tag it for entity synthesis
- Export the processed metrics to New Relic over OTLP
Create the collector configuration file:
$sudo nano /etc/otelcol-contrib/redis-collector-config.yamlPaste the following configuration, updating the Redis endpoint if it isn't localhost:6379:
extensions: health_check: endpoint: "0.0.0.0:13133"
receivers: redis: endpoint: "localhost:6379" # Update with your Redis host:port collection_interval: 10s metrics: redis.maxmemory: enabled: true redis.role: enabled: false redis.cmd.calls: enabled: true redis.cmd.usec: enabled: true redis.clients.max_input_buffer: enabled: false redis.clients.max_output_buffer: enabled: false redis.replication.backlog_first_byte_offset: enabled: false resource_attributes: server.address: enabled: true server.port: enabled: true
processors: memory_limiter: check_interval: 5s limit_mib: 512 spike_limit_mib: 128
resource_detection: detectors: [env, system] timeout: 5s override: false system: resource_attributes: host.name: enabled: true host.id: enabled: true
# Uncomment the section below to use a custom human-readable name for your # Redis entity instead of the default server.address:server.port identifier. # resource/redis: # attributes: # - key: redis.instance.id # value: "my-redis-instance" # action: upsert
attributes/entity_tags: actions: - key: instrumentation.provider value: opentelemetry action: upsert
cumulativetodelta: include: match_type: regexp metrics: - redis\.commands\.processed - redis\.connections\.received - redis\.connections\.rejected - redis\.keys\.evicted - redis\.keys\.expired - redis\.keyspace\.hits - redis\.keyspace\.misses - redis\.net\.input - redis\.net\.output - redis\.cpu\.time - redis\.cmd\.calls - redis\.cmd\.usec - redis\.uptime
filter/cardinality: metrics: datapoint: - 'metric.name == "redis.cpu.time" and attributes["state"] != "sys" and attributes["state"] != "user"' - 'metric.name == "redis.cmd.calls" and attributes["cmd"] != "get" and attributes["cmd"] != "set" and attributes["cmd"] != "del" and attributes["cmd"] != "hget" and attributes["cmd"] != "hset" and attributes["cmd"] != "hgetall" and attributes["cmd"] != "lpush" and attributes["cmd"] != "rpop" and attributes["cmd"] != "zadd" and attributes["cmd"] != "expire"' - 'metric.name == "redis.cmd.usec" and attributes["cmd"] != "get" and attributes["cmd"] != "set" and attributes["cmd"] != "del" and attributes["cmd"] != "hget" and attributes["cmd"] != "hset" and attributes["cmd"] != "hgetall" and attributes["cmd"] != "lpush" and attributes["cmd"] != "rpop" and attributes["cmd"] != "zadd" and attributes["cmd"] != "expire"'
transform/metadata_nullify: metric_statements: - context: metric statements: - set(description, "") - set(unit, "")
batch: send_batch_size: 2048 send_batch_max_size: 4096 timeout: 10s
exporters: otlp_http: endpoint: ${env:OTEL_EXPORTER_OTLP_ENDPOINT} headers: api-key: ${env:NEW_RELIC_LICENSE_KEY} compression: gzip
service: extensions: [health_check] pipelines: metrics/redis: receivers: [redis] # If using resource/redis for custom name, add it to the processors list: # processors: [memory_limiter, resource_detection, resource/redis, attributes/entity_tags, cumulativetodelta, filter/cardinality, transform/metadata_nullify, batch] processors: [memory_limiter, resource_detection, attributes/entity_tags, cumulativetodelta, filter/cardinality, transform/metadata_nullify, batch] exporters: [otlp_http]What this configuration does
Each component in the pipeline has a specific job:
| Component | Description |
|---|---|
health_check | Exposes a health endpoint on 0.0.0.0:13133 so you can confirm the collector is running. |
redis receiver | Connects to your Redis endpoint every 10 seconds and reads metrics from the Redis INFO command. server.address and server.port become the entity's identity. |
memory_limiter | Caps collector memory usage (512 MiB soft limit, 128 MiB spike) to protect the host. |
resource_detection | Detects the host and adds host.name and host.id, linking Redis metrics to the underlying host entity. |
attributes/entity_tags | Stamps instrumentation.provider: opentelemetry on every metric so you can scope queries to the OpenTelemetry path. |
cumulativetodelta | Converts Redis's cumulative counters — commands, keyspace hits, evictions, and so on — to delta values so New Relic charts rates correctly. |
filter/cardinality | Drops high-cardinality data points (CPU states other than user and sys, and per-command metrics for uncommon commands) to control ingest cost. |
transform/metadata_nullify | Clears metric descriptions and units to reduce payload size. |
batch | Groups data points before export (2,048 per batch, up to 4,096) and flushes at least every 10 seconds to reduce network overhead. |
otlp_http | Exports the processed metrics to New Relic over OTLP with gzip compression, authenticated with your license key. |
Dica
Want a user-friendly entity name? By default, your Redis entity is named using the server.address:server.port combination. To use a custom human-readable name instead, uncomment the resource/redis section in the config above, set your preferred name in the redis.instance.id value, and add resource/redis to the processors pipeline.
Optional: Configure authentication
By default, the collector connects to Redis without credentials. If your Redis instance requires authentication, add the matching credentials to the redis receiver. Choose the option that matches your setup:
Optional: Collect Redis logs
Beyond metrics, the collector can forward Redis's log file to New Relic so you can correlate log events — restarts, persistence events, or errors — with metric spikes on the same entity. Add the filelog receiver to tail the Redis log:
receivers: # ... existing redis receiver ... file_log/redis: include: - /var/log/redis/redis-server.log start_at: end operators: - type: regex_parser regex: '^\d+:[XCSM] \d+ \w+ \d+ \d+:\d+:\d+\.\d+ (?P<level>.) ' on_error: send resource: db.system: redisLog lines from the file have no Redis connection context on their own — you must explicitly attach identity attributes so New Relic associates the logs with your Redis entity. Add a resource/redis_logs processor with hardcoded values matching your Redis entity's identity:
processors: # ... existing processors ... resource/redis_logs: attributes: - key: server.address value: "localhost" # Must match your redis receiver endpoint host action: upsert - key: server.port value: 6379 # Must match your redis receiver endpoint port action: upsert - key: instrumentation.provider value: opentelemetry action: upsertDica
Using a custom instance ID? If you enabled the resource/redis processor for custom entity naming, replace server.address and server.port above with your redis.instance.id:
resource/redis_logs: attributes: - key: redis.instance.id value: "my-redis-instance" # Must match the value in resource/redis action: upsert - key: instrumentation.provider value: opentelemetry action: upsertAdd a separate logs pipeline to the service section:
service: pipelines: metrics/redis: receivers: [redis] processors: [memory_limiter, resource_detection, attributes/entity_tags, cumulativetodelta, filter/cardinality, transform/metadata_nullify, batch] exporters: [otlp_http] logs/redis: receivers: [file_log/redis] processors: [memory_limiter, resource/redis_logs, batch] exporters: [otlp_http]Importante
The collector must have read access to both the Redis log file and its parent directory. Run:
$sudo chmod 755 /var/log/redis$sudo chmod 644 /var/log/redis/redis-server.logOptional: Collect host metrics
Redis performance often tracks host resource pressure — CPU saturation, memory exhaustion, or disk I/O contention. Add the hostmetrics receiver to collect system metrics from the host alongside Redis, so you can correlate the two in New Relic:
receivers: # ... existing receivers ... host_metrics: collection_interval: 10s scrapers: cpu: metrics: system.cpu.utilization: {enabled: true} system.cpu.time: {enabled: true} load: metrics: system.cpu.load_average.1m: {enabled: true} system.cpu.load_average.5m: {enabled: true} system.cpu.load_average.15m: {enabled: true} memory: metrics: system.memory.usage: {enabled: true} system.memory.utilization: {enabled: true} disk: metrics: system.disk.io: {enabled: true} system.disk.operations: {enabled: true} filesystem: metrics: system.filesystem.usage: {enabled: true} system.filesystem.utilization: {enabled: true} network: metrics: system.network.io: {enabled: true} system.network.packets: {enabled: true}Add a separate metrics/host pipeline for host metrics (do not add host_metrics to the Redis pipeline):
service: pipelines: metrics/redis: receivers: [redis] processors: [memory_limiter, resource_detection, attributes/entity_tags, cumulativetodelta, filter/cardinality, transform/metadata_nullify, batch] exporters: [otlp_http] metrics/host: receivers: [host_metrics] processors: [memory_limiter, resource_detection, attributes/entity_tags, cumulativetodelta, batch] exporters: [otlp_http]Optional: Enable Redis Cluster monitoring
Redis Cluster monitoring currently requires the Prometheus receiver approach (using redis_exporter). The OpenTelemetry Collector Contrib's native Redis receiver does not yet support the CLUSTER INFO command needed for cluster metrics. Use the Prometheus receiver tab for cluster monitoring setup.
Set environment variables
The collector reads deployment-specific values — your license key, OTLP endpoint, and config path — from an environment file, which keeps secrets out of the config YAML. Create the environment file:
$sudo tee /etc/otelcol-contrib/otelcol-contrib.conf > /dev/null <<'EOF'$NEW_RELIC_LICENSE_KEY=YOUR_LICENSE_KEY$OTEL_EXPORTER_OTLP_ENDPOINT=YOUR_OTLP_ENDPOINT$# Set the New Relic OTLP endpoint for your region.$# See https://docs.newrelic.com/docs/opentelemetry/best-practices/opentelemetry-otlp$OTELCOL_OPTIONS="--config=/etc/otelcol-contrib/redis-collector-config.yaml"$EOF$sudo chmod 600 /etc/otelcol-contrib/otelcol-contrib.confReplace the placeholders with your own values:
| Variable | Required | Description |
|---|---|---|
NEW_RELIC_LICENSE_KEY | Yes | Your New Relic ingest license key. |
OTEL_EXPORTER_OTLP_ENDPOINT | Yes | New Relic OTLP endpoint for your region. For more information, see New Relic OTLP endpoint. |
OTELCOL_OPTIONS | Yes | Points the collector at your Redis configuration file. |
Dica
This configuration replaces the default OTel Collector Contrib configuration. If you need to preserve the default config alongside Redis monitoring, add the default config file as well:
$OTELCOL_OPTIONS="--config=/etc/otelcol-contrib/config.yaml --config=/etc/otelcol-contrib/redis-collector-config.yaml"When using multiple config files, ensure there are no conflicting component names between them. Rename any duplicate processors in your Redis config by adding a suffix (e.g., memory_limiter/redis instead of memory_limiter).
Restart and verify
Restart the collector to load the new configuration:
$sudo systemctl daemon-reload$sudo systemctl restart otelcol-contrib$sudo systemctl status otelcol-contribThe status command should show Active: active (running). If it shows Active: failed, check the logs with journalctl -u otelcol-contrib -n 100 --no-pager — the most common causes are YAML indentation errors and an unreachable Redis endpoint.
Then confirm your metrics are reaching New Relic. Wait about a minute after the restart, then run this query in the query builder:
SELECT count(*) FROM Metric WHERE metricName LIKE 'redis.%' AND instrumentation.provider = 'opentelemetry' SINCE 5 minutes agoA non-zero count confirms Redis metrics are flowing. If it returns 0, see Troubleshoot Redis (OpenTelemetry).
Install redis_exporter
The redis_exporter exposes Redis metrics in Prometheus format on port 9121.
Create a systemd service for redis_exporter:
$sudo tee /etc/systemd/system/redis_exporter.service > /dev/null <<'EOF'$[Unit]$Description=Redis Exporter$After=network.target$
$[Service]$ExecStart=/usr/local/bin/redis_exporter --redis.addr=redis://localhost:6379$Restart=always$User=nobody$
$[Install]$WantedBy=multi-user.target$EOF$
$sudo systemctl daemon-reload$sudo systemctl enable --now redis_exporterVerify the exporter is running:
$curl -s http://localhost:9121/metrics | grep redis_upYou should see redis_up 1.
Create the collector configuration
This configuration scrapes metrics from redis_exporter and sends them to New Relic. It handles these main jobs:
- Scrape the
redis_exporterPrometheus endpoint through theprometheusreceiver - Rename the Prometheus metrics to New Relic's Redis metric names
- Shape the data — reduce cardinality, convert counters to deltas, and tag it for entity synthesis
- Export the processed metrics to New Relic over OTLP
Create the config file. Use the path appropriate for your collector:
- NRDOT:
/etc/nrdot-collector/redis-prometheus-config.yaml - OTel Contrib:
/etc/otelcol-contrib/redis-prometheus-config.yaml
extensions: health_check: endpoint: "0.0.0.0:13133"
receivers: prometheus: config: scrape_configs: - job_name: 'redis' scrape_interval: 10s static_configs: - targets: ['localhost:9121'] # Update with your Redis exporter host:port metric_relabel_configs: - source_labels: [__name__] regex: '(go_|process_|promhttp_|redis_exporter_).*' action: drop
processors: memory_limiter: check_interval: 5s limit_mib: 512 spike_limit_mib: 128
resource_detection: detectors: [env, system] timeout: 5s override: false system: resource_attributes: host.name: enabled: true host.id: enabled: true
# Required: Set a unique identifier for your Redis entity. # The Prometheus receiver does not provide server.address/server.port, # so redis.instance.id is required for entity creation in New Relic. resource/redis_identity: attributes: - key: redis.instance.id value: "my-redis-instance:6379" # Update with a unique name for this Redis instance action: upsert
attributes/entity_tags: actions: - key: instrumentation.provider value: opentelemetry action: upsert
metricstransform: transforms: - include: redis_uptime_in_seconds action: update new_name: redis.uptime - include: redis_connected_clients action: update new_name: redis.clients.connected - include: redis_blocked_clients action: update new_name: redis.clients.blocked - include: redis_memory_used_bytes action: update new_name: redis.memory.used - include: redis_memory_max_bytes action: update new_name: redis.maxmemory - include: redis_mem_fragmentation_ratio action: update new_name: redis.memory.fragmentation_ratio - include: redis_memory_used_rss_bytes action: update new_name: redis.memory.rss - include: redis_memory_used_peak_bytes action: update new_name: redis.memory.peak - include: redis_memory_used_lua_bytes action: update new_name: redis.memory.lua - include: redis_connections_received_total action: update new_name: redis.connections.received - include: redis_rejected_connections_total action: update new_name: redis.connections.rejected - include: redis_commands_processed_total action: update new_name: redis.commands.processed - include: redis_keyspace_hits_total action: update new_name: redis.keyspace.hits - include: redis_keyspace_misses_total action: update new_name: redis.keyspace.misses - include: redis_evicted_keys_total action: update new_name: redis.keys.evicted - include: redis_expired_keys_total action: update new_name: redis.keys.expired - include: redis_net_input_bytes_total action: update new_name: redis.net.input - include: redis_net_output_bytes_total action: update new_name: redis.net.output - include: redis_connected_slaves action: update new_name: redis.slaves.connected - include: redis_db_keys action: update new_name: redis.db.keys - include: redis_db_keys_expiring action: update new_name: redis.db.expires - include: redis_rdb_changes_since_last_save action: update new_name: redis.rdb.changes_since_last_save - include: redis_db_avg_ttl_seconds action: update new_name: redis.db.avg_ttl - include: redis_latest_fork_seconds action: update new_name: redis.latest_fork - include: redis_master_repl_offset action: update new_name: redis.replication.offset - include: redis_repl_backlog_first_byte_offset action: update new_name: redis.replication.backlog_first_byte_offset - include: redis_commands_total action: update new_name: redis.cmd.calls - include: redis_commands_duration_seconds_total action: update new_name: redis.cmd.usec - include: redis_cpu_sys_seconds_total action: update new_name: redis.cpu.time operations: - action: add_label new_label: state new_value: sys - include: redis_cpu_user_seconds_total action: update new_name: redis.cpu.time operations: - action: add_label new_label: state new_value: user
cumulativetodelta: include: match_type: regexp metrics: - redis\.commands\.processed - redis\.connections\.received - redis\.connections\.rejected - redis\.keys\.evicted - redis\.keys\.expired - redis\.keyspace\.hits - redis\.keyspace\.misses - redis\.net\.input - redis\.net\.output - redis\.cpu\.time - redis\.cmd\.calls - redis\.cmd\.usec - redis\.uptime
filter/cardinality: metrics: datapoint: - 'metric.name == "redis.cpu.time" and attributes["state"] != "sys" and attributes["state"] != "user"' - 'metric.name == "redis.cmd.calls" and attributes["cmd"] != "get" and attributes["cmd"] != "set" and attributes["cmd"] != "del" and attributes["cmd"] != "hget" and attributes["cmd"] != "hset" and attributes["cmd"] != "hgetall" and attributes["cmd"] != "lpush" and attributes["cmd"] != "rpop" and attributes["cmd"] != "zadd" and attributes["cmd"] != "expire"' - 'metric.name == "redis.cmd.usec" and attributes["cmd"] != "get" and attributes["cmd"] != "set" and attributes["cmd"] != "del" and attributes["cmd"] != "hget" and attributes["cmd"] != "hset" and attributes["cmd"] != "hgetall" and attributes["cmd"] != "lpush" and attributes["cmd"] != "rpop" and attributes["cmd"] != "zadd" and attributes["cmd"] != "expire"'
transform/metadata_nullify: metric_statements: - context: metric statements: - set(description, "") - set(unit, "")
batch: send_batch_size: 2048 send_batch_max_size: 4096 timeout: 10s
exporters: otlp_http: endpoint: ${env:OTEL_EXPORTER_OTLP_ENDPOINT} headers: api-key: ${env:NEW_RELIC_LICENSE_KEY} compression: gzip
service: extensions: [health_check] pipelines: metrics/redis: receivers: [prometheus] processors: [memory_limiter, resource_detection, resource/redis_identity, attributes/entity_tags, metricstransform, cumulativetodelta, filter/cardinality, transform/metadata_nullify, batch] exporters: [otlp_http]What this configuration does
Each component in the pipeline has a specific job:
| Component | Description |
|---|---|
health_check | Exposes a health endpoint on 0.0.0.0:13133 so you can confirm the collector is running. |
prometheus receiver | Scrapes the redis_exporter endpoint (default localhost:9121) every 10 seconds and drops the exporter's own go_*, process_*, promhttp_*, and redis_exporter_* metrics. |
memory_limiter | Caps collector memory usage (512 MiB soft limit, 128 MiB spike) to protect the host. |
resource_detection | Detects the host and adds host.name and host.id, linking Redis metrics to the underlying host entity. |
resource/redis_identity | Sets redis.instance.id, which identifies the Redis entity in New Relic. It's required here because the Prometheus receiver doesn't provide server.address or server.port. |
attributes/entity_tags | Stamps instrumentation.provider: opentelemetry on every metric so you can scope queries to the OpenTelemetry path. |
metricstransform | Renames the exporter's Prometheus metrics (for example, redis_uptime_in_seconds) to New Relic's Redis names (redis.uptime) and adds the state label to CPU metrics. |
cumulativetodelta | Converts cumulative counters — commands, keyspace hits, evictions, and so on — to delta values so New Relic charts rates correctly. |
filter/cardinality | Drops high-cardinality data points (CPU states other than user and sys, and per-command metrics for uncommon commands) to control ingest cost. |
transform/metadata_nullify | Clears metric descriptions and units to reduce payload size. |
batch | Groups data points before export (2,048 per batch, up to 4,096) and flushes at least every 10 seconds to reduce network overhead. |
otlp_http | Exports the processed metrics to New Relic over OTLP with gzip compression, authenticated with your license key. |
Importante
The resource/redis_identity processor with redis.instance.id is required for the Prometheus receiver approach. Unlike the native Redis receiver, the Prometheus receiver does not provide server.address or server.port — so redis.instance.id is the only way to identify your Redis entity in New Relic. Set it to a unique, descriptive name for each instance (e.g., prod-redis-cache:6379).
Optional: Enable Redis Cluster monitoring
If your Redis is running in Cluster mode, start redis_exporter with the --is-cluster flag to automatically collect cluster health metrics from all nodes:
$redis_exporter --redis.addr=redis://localhost:7000 --is-clusterThe Prometheus receiver configuration above already renames cluster metrics (e.g., redis_cluster_state → redis.cluster.state). To create a separate cluster entity in New Relic, add a redis.cluster.name resource attribute to a separate pipeline that does NOT include redis.instance.id:
resource/cluster: attributes: - key: redis.cluster.name value: "my-redis-cluster" # Update with your cluster name action: upsertAdd a cluster pipeline to your service section:
metrics/cluster: receivers: [prometheus] processors: [memory_limiter, resource_detection, resource/cluster, attributes/entity_tags, metricstransform, cumulativetodelta, filter/cardinality, transform/metadata_nullify, batch] exporters: [otlp_http]Importante
The cluster entity requires redis.cluster.name to be present AND redis.instance.id to be absent. If both are set on the same metrics, only the instance entity will be created. Use separate pipelines for instance and cluster metrics.
Optional: Collect Redis logs
Beyond metrics, the collector can forward Redis's log file to New Relic so you can correlate log events — restarts, persistence events, or errors — with metric spikes on the same entity. Add the filelog receiver to tail the Redis log:
receivers: # ... existing prometheus receiver ... file_log/redis: include: - /var/log/redis/redis-server.log start_at: end operators: - type: regex_parser regex: '^\d+:[XCSM] \d+ \w+ \d+ \d+:\d+:\d+\.\d+ (?P<level>.) ' on_error: send resource: db.system: redisLog lines from the file have no Redis connection context on their own — you must explicitly attach identity attributes so New Relic associates the logs with your Redis entity. Add a resource/redis_logs processor with hardcoded values matching your Redis entity's identity:
processors: # ... existing processors ... resource/redis_logs: attributes: - key: redis.instance.id value: "my-redis-instance:6379" # Must match the value in resource/redis_identity action: upsert - key: instrumentation.provider value: opentelemetry action: upsertAdd a separate logs pipeline to the service section:
service: pipelines: metrics/redis: receivers: [prometheus] processors: [memory_limiter, resource_detection, resource/redis_identity, attributes/entity_tags, metricstransform, cumulativetodelta, filter/cardinality, transform/metadata_nullify, batch] exporters: [otlp_http] logs/redis: receivers: [file_log/redis] processors: [memory_limiter, resource/redis_logs, batch] exporters: [otlp_http]Importante
The collector must have read access to both the Redis log file and its parent directory. Run:
$sudo chmod 755 /var/log/redis$sudo chmod 644 /var/log/redis/redis-server.logOptional: Collect host metrics
Redis performance often tracks host resource pressure — CPU saturation, memory exhaustion, or disk I/O contention. Add the hostmetrics receiver to collect system metrics from the host alongside Redis, so you can correlate the two in New Relic:
receivers: # ... existing receivers ... host_metrics: collection_interval: 10s scrapers: cpu: metrics: system.cpu.utilization: {enabled: true} system.cpu.time: {enabled: true} load: metrics: system.cpu.load_average.1m: {enabled: true} system.cpu.load_average.5m: {enabled: true} system.cpu.load_average.15m: {enabled: true} memory: metrics: system.memory.usage: {enabled: true} system.memory.utilization: {enabled: true} disk: metrics: system.disk.io: {enabled: true} system.disk.operations: {enabled: true} filesystem: metrics: system.filesystem.usage: {enabled: true} system.filesystem.utilization: {enabled: true} network: metrics: system.network.io: {enabled: true} system.network.packets: {enabled: true}Add a separate metrics/host pipeline for host metrics (do not add host_metrics to the Redis pipeline):
service: pipelines: metrics/redis: receivers: [prometheus] processors: [memory_limiter, resource_detection, resource/redis_identity, attributes/entity_tags, metricstransform, cumulativetodelta, filter/cardinality, transform/metadata_nullify, batch] exporters: [otlp_http] metrics/host: receivers: [host_metrics] processors: [memory_limiter, resource_detection, attributes/entity_tags, cumulativetodelta, batch] exporters: [otlp_http]Set environment variables and config path
The collector reads deployment-specific values — your license key, OTLP endpoint, and config path — from an environment file, which keeps secrets out of the config YAML. Set these for whichever collector you installed:
| Variable | Required | Description |
|---|---|---|
NEW_RELIC_LICENSE_KEY | Yes | Your New Relic ingest license key. |
OTEL_EXPORTER_OTLP_ENDPOINT | Yes | New Relic OTLP endpoint for your region. For more information, see New Relic OTLP endpoint. |
OTELCOL_OPTIONS | Yes | Points the collector at your Redis Prometheus configuration file. |
For NRDOT:
$sudo tee /etc/nrdot-collector/nrdot-collector.conf > /dev/null <<'EOF'$NEW_RELIC_LICENSE_KEY=YOUR_LICENSE_KEY$OTEL_EXPORTER_OTLP_ENDPOINT=YOUR_OTLP_ENDPOINT$# Set the New Relic OTLP endpoint for your region.$# See https://docs.newrelic.com/docs/opentelemetry/best-practices/opentelemetry-otlp$OTELCOL_OPTIONS="--config=/etc/nrdot-collector/redis-prometheus-config.yaml"$EOF$sudo chmod 600 /etc/nrdot-collector/nrdot-collector.confDica
This configuration replaces the default NRDot configuration. If you need to preserve the default NRDot pipelines alongside Redis monitoring, add the default config file as well:
$OTELCOL_OPTIONS="--config=/etc/nrdot-collector/config.yaml --config=/etc/nrdot-collector/redis-prometheus-config.yaml"When using multiple config files, ensure there are no conflicting component names between them. Rename any duplicate processors in your Redis config by adding a suffix (e.g., memory_limiter/redis instead of memory_limiter).
For OTel Collector Contrib:
$sudo tee /etc/otelcol-contrib/otelcol-contrib.conf > /dev/null <<'EOF'$NEW_RELIC_LICENSE_KEY=YOUR_LICENSE_KEY$OTEL_EXPORTER_OTLP_ENDPOINT=YOUR_OTLP_ENDPOINT$# Set the New Relic OTLP endpoint for your region.$# See https://docs.newrelic.com/docs/opentelemetry/best-practices/opentelemetry-otlp$OTELCOL_OPTIONS="--config=/etc/otelcol-contrib/redis-prometheus-config.yaml"$EOF$sudo chmod 600 /etc/otelcol-contrib/otelcol-contrib.confRestart and verify
Restart the collector to load the new configuration.
For NRDOT:
$sudo systemctl daemon-reload$sudo systemctl restart nrdot-collector$sudo systemctl status nrdot-collectorFor OTel Collector Contrib:
$sudo systemctl daemon-reload$sudo systemctl restart otelcol-contrib$sudo systemctl status otelcol-contribThe status command should show Active: active (running). If it shows Active: failed, check the logs with journalctl -u nrdot-collector -n 100 --no-pager (or otelcol-contrib) — the most common causes are YAML indentation errors, an unreachable redis_exporter, or the exporter not running.
Then confirm your metrics are reaching New Relic. Wait about a minute after the restart, then run this query in the query builder:
SELECT count(*) FROM Metric WHERE metricName LIKE 'redis.%' AND instrumentation.provider = 'opentelemetry' SINCE 5 minutes agoA non-zero count confirms Redis metrics are flowing. If it returns 0, see Troubleshoot Redis (OpenTelemetry).
Dica
Correlate APM with Redis: To connect your APM application and Redis instance in service maps, include db.system="redis" along with your chosen entity identifier pattern — either redis.instance.id or server.address and server.port — as resource attributes in your APM metrics. The values must match what you configured in the collector. This enables cross-service visibility and faster troubleshooting within New Relic.
Next steps
- Docker installation: Deploy with Docker Compose
- Kubernetes installation: Deploy on Kubernetes with the DaemonSet pattern
- View your data: Explore dashboards and set up alerts
- Metrics reference: Complete list of available metrics
- Troubleshooting: Common issues and solutions