How to enable monitoring and logging

This guide provides instructions for integrating Charmed Valkey with the Canonical Observability Stack (COS). After you integrate the two, COS receives:

  • metrics from a Redis exporter that runs next to each Valkey unit

  • the Valkey and Sentinel logs

  • a Grafana dashboard and the alert rules that ship with the charm

It also shows where each unit keeps its log files and how they rotate.

Prerequisites

Note

The Best practice is using a dedicated model for COS deployment.

This guide uses the following placeholders:

  • <cos_controller> is the Kubernetes controller that hosts COS

  • <cos_model> is the model where COS (or COS Lite) runs

  • <valkey_controller> is the controller that hosts Charmed Valkey

  • <valkey_model> is the model where Charmed Valkey runs

  • valkey is the name of the Charmed Valkey application. Replace it if you deployed it under another name.

Connection options

You can connect Charmed Valkey to COS in two ways:

  • Separate models (recommended): COS runs in its own model. Offers connect the two models and an OpenTelemetry Collector sends the data to COS.

  • Same model: Charmed Valkey runs on Kubernetes in the same model as COS. You integrate the COS applications with Charmed Valkey directly.

Separate models

Offer the COS endpoints

The COS Lite Terraform module creates the offers below for you. If you deployed COS Lite another way, create them from the COS model:

juju switch <cos_controller>:<cos_model>
juju offer grafana:grafana-dashboard grafana-dashboards
juju offer loki:logging loki-logging
juju offer prometheus:receive-remote-write prometheus-receive-remote-write

Consume the offers

Switch to the Charmed Valkey model and consume the offers:

juju switch <valkey_controller>:<valkey_model>
juju consume <cos_controller>:admin/<cos_model>.grafana-dashboards
juju consume <cos_controller>:admin/<cos_model>.loki-logging
juju consume <cos_controller>:admin/<cos_model>.prometheus-receive-remote-write

These URLs assume that the admin user owns the COS model. To list the exact URLs, run juju find-offers <cos_controller>:.

Deploy the OpenTelemetry Collector

The OpenTelemetry Collector reads metrics, logs, dashboards and alert rules from Charmed Valkey and sends them to COS.

The opentelemetry-collector charm runs as a subordinate on each Valkey machine. It gets its data from Charmed Valkey over the cos-agent endpoint.

Deploy the collector and integrate it with Charmed Valkey:

juju deploy opentelemetry-collector --channel 0.130/stable --base ubuntu@26.04
juju integrate valkey:cos-agent opentelemetry-collector

Integrate the collector with the consumed offers:

juju integrate opentelemetry-collector:send-remote-write prometheus-receive-remote-write
juju integrate opentelemetry-collector:send-loki-logs loki-logging
juju integrate opentelemetry-collector:grafana-dashboards-provider grafana-dashboards

The collector pushes data to the addresses that COS advertises through its ingress, so each Valkey machine must reach those addresses.

The opentelemetry-collector-k8s charm runs as its own application in the Valkey model. Charmed Valkey uses three endpoints: metrics-endpoint, grafana-dashboard and logging.

Deploy the collector and integrate it with Charmed Valkey:

juju deploy opentelemetry-collector-k8s --channel 0.130/stable --trust
juju integrate valkey:metrics-endpoint opentelemetry-collector-k8s:metrics-endpoint
juju integrate valkey:grafana-dashboard opentelemetry-collector-k8s:grafana-dashboards-consumer
juju integrate valkey:logging opentelemetry-collector-k8s:receive-loki-logs

Integrate the collector with the consumed offers:

juju integrate opentelemetry-collector-k8s:send-remote-write prometheus-receive-remote-write
juju integrate opentelemetry-collector-k8s:send-loki-logs loki-logging
juju integrate opentelemetry-collector-k8s:grafana-dashboards-provider grafana-dashboards

The collector pushes data to the addresses that COS advertises through its ingress, so the Kubernetes cluster that runs the collector must reach those addresses.

If COS serves its ingress over TLS, integrate the collector’s receive-ca-cert endpoint with the charm that provides the ingress CA.

Check both models and wait until every application is active and idle:

juju status -m <valkey_controller>:<valkey_model>
juju status -m <cos_controller>:<cos_model>

The Charmed Valkey model then looks like this:

Model      Controller  Cloud/Region         Version  SLA          Timestamp
valkey-vm  lxd         localhost/localhost  3.6.28   unsupported  07:50:15+04:00

SAAS                             Status  Store  URL
grafana-dashboards               active  k8s    admin/cos.grafana-dashboards
loki-logging                     active  k8s    admin/cos.loki-logging
prometheus-receive-remote-write  active  k8s    admin/cos.prometheus-receive-remote-write

App                      Version  Status  Scale  Charm                    Channel       Rev  Exposed  Message
opentelemetry-collector  0.130.0  active      3  opentelemetry-collector  0.130/stable  561  no
valkey                            active      3  valkey                   9/edge        115  no

Unit                          Workload  Agent  Machine  Public address  Ports                      Message
valkey/0*                     active    idle   0        10.42.6.156     6379-6380,26379-26380/tcp
  opentelemetry-collector/2   active    idle            10.42.6.156
valkey/1                      active    idle   1        10.42.6.3       6379-6380,26379-26380/tcp
  opentelemetry-collector/0*  active    idle            10.42.6.3
valkey/2                      active    idle   2        10.42.6.151     6379-6380,26379-26380/tcp
  opentelemetry-collector/3   active    idle            10.42.6.151

Machine  State    Address      Inst id        Base          AZ   Message
0        started  10.42.6.156  juju-7f9a80-0  ubuntu@26.04  xof  Running
1        started  10.42.6.3    juju-7f9a80-1  ubuntu@26.04  xof  Running
2        started  10.42.6.151  juju-7f9a80-2  ubuntu@26.04  xof  Running
Model       Controller  Cloud/Region     Version  SLA          Timestamp
valkey-k8s  lxd         k8s-lxd/default  3.6.28   unsupported  08:09:05+04:00

SAAS                             Status  Store  URL
grafana-dashboards               active  k8s    admin/cos.grafana-dashboards
loki-logging                     active  k8s    admin/cos.loki-logging
prometheus-receive-remote-write  active  k8s    admin/cos.prometheus-receive-remote-write

App                          Version  Status  Scale  Charm                        Channel       Rev  Address        Exposed  Message
opentelemetry-collector-k8s  0.130.1  active      1  opentelemetry-collector-k8s  0.130/stable  272  10.152.183.88  no
valkey                                active      3  valkey                       9/edge        115  10.152.183.85  no

Unit                            Workload  Agent  Address     Ports  Message
opentelemetry-collector-k8s/0*  active    idle   10.1.0.2
valkey/0*                       active    idle   10.1.0.236
valkey/1                        active    idle   10.1.0.104
valkey/2                        active    idle   10.1.0.204

Same model

Note

Use this method only if Charmed Valkey runs on Kubernetes in the same model as COS. Otherwise, use separate models.

In this setup you do not need the offers or the collector. Integrate the COS applications with Charmed Valkey directly:

juju switch <cos_controller>:<cos_model>
juju integrate valkey:metrics-endpoint prometheus
juju integrate valkey:grafana-dashboard grafana
juju integrate valkey:logging loki

Next, follow the steps in Open the Valkey dashboard. For the remainder of this guide, replace <valkey_model> with <cos_model>.

Open the Valkey dashboard

Get the Grafana URL and the admin password:

juju run grafana/leader get-admin-password --model <cos_controller>:<cos_model>

The output looks like this:

admin-password: <password>
url: http://<cos_ingress_address>/<cos_model>-grafana

Open the URL and log in as admin with that password. Go to Dashboards and open the Valkey dashboard.

The Valkey dashboard in Grafana for a three-unit deployment

View logs

Loki receives the Valkey and Sentinel logs. To read them, open Explore in Grafana, pick the Loki data source and filter on juju_application="valkey".

Valkey logs in Grafana Explore

Each unit also keeps the log files on disk:

valkey.log and sentinel.log are in /var/snap/valkey-charmed/common/var/log/valkey/. The directory belongs to snap_daemon, so list it with sudo:

juju ssh valkey/0 sudo ls -l /var/snap/valkey-charmed/common/var/log/valkey/

The output looks like this:

total 32
-rw-r--r-- 1 snap_daemon snap_daemon  1683 Oct  7 03:46 sentinel.log
-rw-r--r-- 1 snap_daemon snap_daemon 23722 Oct  7 04:13 valkey.log

valkey.log and sentinel.log are in /var/log/valkey/ in the valkey container:

juju ssh --container valkey valkey/0 ls -l /var/log/valkey/

The output looks like this:

total 616
drwxrws--- 2 root     170  16384 Oct  7 03:55 lost+found
-rw-r--r-- 1 _daemon_ 170    743 Oct  7 03:57 sentinel.log
-rw-r--r-- 1 _daemon_ 170 602834 Oct  7 04:14 valkey.log

Both files rotate daily, or earlier once one passes 200 MB. Rotated files are kept for up to 10 days, 14 files at most. All but the newest are compressed, so the names are valkey.log.1, valkey.log.2.gz, and so on.

Important

For production environments, use a logs volume of at least 8 GB.

To set the logs volume size when you deploy, pass --storage logs=<size>:

juju deploy valkey --channel 9/edge -n 3 --storage logs=8G
juju deploy valkey --channel 9/edge -n 3 --storage logs=8G --trust

Query the metrics endpoint

The exporter serves metrics on port 9121 at /metrics. It connects to Valkey over TLS as the charmed-stats user, which can run only the commands the exporter needs. Metric names start with redis_, the exporter’s prefix. The exporter documentation lists them.

The exporter listens on 127.0.0.1 only, so only the collector on the same machine can scrape it. To read the metrics yourself, run curl on the unit:

juju ssh valkey/0 curl -s http://127.0.0.1:9121/metrics

The exporter listens on all interfaces of the pod. To read the metrics from your machine, forward the port and run curl. The Kubernetes namespace has the same name as the Juju model:

kubectl -n <valkey_model> port-forward pod/valkey-0 9121:9121
curl -s http://127.0.0.1:9121/metrics

The output has several hundred lines. On the primary, part of it looks like this:

# HELP redis_up Information about the Redis instance
# TYPE redis_up gauge
redis_up 1
# HELP redis_connected_slaves connected_slaves metric
# TYPE redis_connected_slaves gauge
redis_connected_slaves 2
# HELP redis_connected_clients connected_clients metric
# TYPE redis_connected_clients gauge
redis_connected_clients 7
# HELP redis_memory_used_bytes memory_used_bytes metric
# TYPE redis_memory_used_bytes gauge
redis_memory_used_bytes 1.92476e+06

redis_up is 1 when the exporter reaches Valkey and 0 when it does not.

Next steps

For the alerts that Charmed Valkey ships, see Alert rules.