> ## Documentation Index
> Fetch the complete documentation index at: https://cockroachlabs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Cluster Monitoring

export const InternalLink = ({version, path = "", children, ...props}) => {
  let detectedVersion = version || "stable";
  if (typeof window !== 'undefined' && !version) {
    const match = window.location.pathname.match(/\/docs\/([^/]+)/);
    if (match) {
      detectedVersion = match[1];
    }
  }
  const normalizedPath = path.startsWith("/") ? path.slice(1) : path;
  return <a href={`/docs/${detectedVersion}/${normalizedPath}`} {...props}>
      {children}
    </a>;
};

<Note>
  This article assumes you have already <InternalLink path="deploy-cockroachdb-with-kubernetes">deployed CockroachDB on a single Kubernetes cluster</InternalLink>.
</Note>

Despite CockroachDB's various <InternalLink path="architecture/replication-layer">built-in safeguards against failure</InternalLink>, it is critical to actively monitor the overall health and performance of a cluster running in production and to create alerting rules that promptly send notifications when there are events that require investigation or intervention.

<Note>
  All `kubectl` steps should be performed in the <InternalLink path="deploy-cockroachdb-with-kubernetes#install-the-operator">namespace where you installed the Operator</InternalLink>. By default, this is `cockroach-operator-system`.
</Note>

<Tip>
  If you <InternalLink path="deploy-cockroachdb-with-kubernetes-openshift">deployed CockroachDB on Red Hat OpenShift</InternalLink>, substitute `kubectl` with `oc` in the following commands.
</Tip>

## Configure Prometheus

Every node of a CockroachDB cluster exports granular timeseries metrics formatted for easy integration with [Prometheus](https://prometheus.io/), a tool for storing, aggregating, and querying timeseries data. This section shows you how to orchestrate Prometheus as part of your Kubernetes cluster and pull these metrics into Prometheus for external monitoring.

This guidance is based on [CoreOS's Prometheus Operator](https://github.com/coreos/prometheus-operator/blob/master/Documentation/user-guides/getting-started.md), which allows a Prometheus instance to be managed using built-in Kubernetes concepts.

<Note>
  If you're on Hosted GKE, before starting, make sure the email address associated with your Google Cloud account is part of the `cluster-admin` RBAC group, as shown in <InternalLink path="deploy-cockroachdb-with-kubernetes#hosted-gke">Deploy CockroachDB with Kubernetes</InternalLink>.
</Note>

1. From your local workstation, edit the `cockroachdb` service to add the `prometheus: cockroachdb` label:

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   $ kubectl label svc cockroachdb prometheus=cockroachdb
   ```

   ```
   service/cockroachdb labeled
   ```

   This ensures that only the `cockroachdb` (not the `cockroach-public` service) is being monitored by a Prometheus job.

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   $ kubectl label svc cockroachdb prometheus=cockroachdb
   ```

   ```
   service/cockroachdb labeled
   ```

   This ensures that only the `cockroachdb` (not the `cockroach-public` service) is being monitored by a Prometheus job.

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   $ kubectl label svc my-release-cockroachdb prometheus=cockroachdb
   ```

   ```
   service/my-release-cockroachdb labeled
   ```

   This ensures that there is a Prometheus job and monitoring data only for the `my-release-cockroachdb` service, not for the `my-release-cockroach-public` service.

2. Determine the latest version of [CoreOS's Prometheus Operator](https://github.com/prometheus-operator/prometheus-operator/releases/) and run the following to download and apply the latest `bundle.yaml` definition file:

<Note>
  Be sure to specify the latest [CoreOS Prometheus Operator](https://github.com/prometheus-operator/prometheus-operator/releases/) version in the following command, in place of this example's use of version `v0.58.0`.
</Note>

```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
$ kubectl apply \
-f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.58.0/bundle.yaml \
--server-side
```

```
customresourcedefinition.apiextensions.k8s.io/alertmanagers.monitoring.coreos.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/podmonitors.monitoring.coreos.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/probes.monitoring.coreos.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/prometheuses.monitoring.coreos.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/prometheusrules.monitoring.coreos.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/servicemonitors.monitoring.coreos.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/thanosrulers.monitoring.coreos.com serverside-applied
clusterrolebinding.rbac.authorization.k8s.io/prometheus-operator serverside-applied
clusterrole.rbac.authorization.k8s.io/prometheus-operator serverside-applied
deployment.apps/prometheus-operator serverside-applied
serviceaccount/prometheus-operator serverside-applied
service/prometheus-operator serverside-applied
```

1. Confirm that the `prometheus-operator` has started:

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   $ kubectl get deploy prometheus-operator
   ```

   ```
   NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
   prometheus-operator   1/1     1            1           27s
   ```

2. Download our Prometheus manifest:

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   $ curl -O https://www.cockroachlabs.com/docs/files/cockroach/cloud/kubernetes/prometheus/prometheus.yaml
   ```

<Note>
  By default, this manifest uses the secret name generated by the CockroachDB Kubernetes Operator. If you generated your own certificates and keys when <InternalLink path="deploy-cockroachdb-with-kubernetes#step-2-start-cockroachdb">starting CockroachDB</InternalLink>, be sure that `ca.secret.name` matches the name of the node secret you created.
</Note>

1. Apply the Prometheus manifest. This creates the various objects necessary to run a Prometheus instance:

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   $ kubectl apply -f prometheus.yaml
   ```

   ```
   serviceaccount/prometheus created
   clusterrole.rbac.authorization.k8s.io/prometheus created
   clusterrolebinding.rbac.authorization.k8s.io/prometheus created
   servicemonitor.monitoring.coreos.com/cockroachdb created
   prometheus.monitoring.coreos.com/cockroachdb created
   ```

2. Access the Prometheus UI locally and verify that CockroachDB is feeding data into Prometheus:

   1. Port-forward from your local machine to the pod running Prometheus:

      ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
      $ kubectl port-forward prometheus-cockroachdb-0 9090
      ```

   2. Go to [http://localhost:9090](http://localhost:9090) in your browser.

   3. To verify that each CockroachDB node is connected to Prometheus, go to **Status > Targets**. The screen should look like this:

      <img src="https://mintcdn.com/cockroachlabs/8zDbQ_0RVb0kBBdl/images/v25.1/kubernetes-prometheus-targets.png?fit=max&auto=format&n=8zDbQ_0RVb0kBBdl&q=85&s=18fbbdd4133e74567a9a5c41a16a1b35" alt="Prometheus targets" width="2232" height="710" data-path="images/v25.1/kubernetes-prometheus-targets.png" />

   4. To verify that data is being collected, go to **Graph**, enter the `sys_uptime` variable in the field, click **Execute**, and then click the **Graph** tab. The screen should like this:

      <img src="https://mintcdn.com/cockroachlabs/8zDbQ_0RVb0kBBdl/images/v25.1/kubernetes-prometheus-graph.png?fit=max&auto=format&n=8zDbQ_0RVb0kBBdl&q=85&s=951b2eca4b5e00ffebc7370be3a0995a" alt="Prometheus graph" width="2842" height="1448" data-path="images/v25.1/kubernetes-prometheus-graph.png" />

<Tip>
  Prometheus auto-completes CockroachDB time series metrics for you, but if you want to see a full listing, with descriptions, port-forward as described in <InternalLink path="deploy-cockroachdb-with-kubernetes#step-4-access-the-db-console">Access the DB Console</InternalLink><InternalLink path="deploy-cockroachdb-with-kubernetes#step-4-access-the-db-console">Access the DB Console</InternalLink> and then point your browser to [http://localhost:8080/\_status/vars](http://localhost:8080/_status/vars).

  For more details on using the Prometheus UI, see their [official documentation](https://prometheus.io/docs/introduction/getting_started/).
</Tip>

## Configure Alertmanager

Active monitoring helps you spot problems early, but it is also essential to send notifications when there are events that require investigation or intervention. This section shows you how to use [Alertmanager](https://prometheus.io/docs/alerting/alertmanager/) and CockroachDB's starter <InternalLink path="cockroach/cloud/kubernetes/prometheus/alert-rules.yaml">alerting rules</InternalLink> to do this.

1. Download our `alertmanager-config.yaml` configuration file:

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   $ curl -O \
   https://www.cockroachlabs.com/docs/files/cockroach/cloud/kubernetes/prometheus/alertmanager-config.yaml
   ```

2. Edit the `alertmanager-config.yaml` file to [specify the desired receivers for notifications](https://prometheus.io/docs/alerting/configuration/#receiver). Initially, the file contains a placeholder web hook.

3. Add this configuration to the Kubernetes cluster as a secret, renaming it to `alertmanager.yaml` and labelling it to make it easier to find:

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   $ kubectl create secret generic alertmanager-cockroachdb \
   --from-file=alertmanager.yaml=alertmanager-config.yaml
   ```

   ```
   secret/alertmanager-cockroachdb created
   ```

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   $ kubectl label secret alertmanager-cockroachdb app=cockroachdb
   ```

   ```
   secret/alertmanager-cockroachdb labeled
   ```

<Danger>
  The name of the secret, `alertmanager-cockroachdb`, must match the name used in the `alertmanager.yaml` file. If they differ, the Alertmanager instance will start without configuration, and nothing will happen.
</Danger>

1. Use our <InternalLink path="cockroach/cloud/kubernetes/prometheus/alertmanager.yaml">`alertmanager.yaml`</InternalLink> file to create the various objects necessary to run an Alertmanager instance, including a ClusterIP service so that Prometheus can forward alerts:

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   $ kubectl apply \
   -f https://www.cockroachlabs.com/docs/files/cockroach/cloud/kubernetes/prometheus/alertmanager.yaml
   ```

   ```
   alertmanager.monitoring.coreos.com/cockroachdb created
   service/alertmanager-cockroachdb created
   ```

2. Verify that Alertmanager is running:

   1. Port-forward from your local machine to the pod running Alertmanager:

      ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
      $ kubectl port-forward alertmanager-cockroachdb-0 9093
      ```

   2. Go to [http://localhost:9093](http://localhost:9093) in your browser. The screen should look like this:

      <img src="https://mintcdn.com/cockroachlabs/8zDbQ_0RVb0kBBdl/images/v25.1/kubernetes-alertmanager-home.png?fit=max&auto=format&n=8zDbQ_0RVb0kBBdl&q=85&s=cd4b7562725407577d7edbb396416574" alt="Alertmanager" width="1133" height="405" data-path="images/v25.1/kubernetes-alertmanager-home.png" />

3. Ensure that the Alertmanagers are visible to Prometheus by opening [http://localhost:9090/status](http://localhost:9090/status). The screen should look like this:

   <img src="https://mintcdn.com/cockroachlabs/8zDbQ_0RVb0kBBdl/images/v25.1/kubernetes-prometheus-alertmanagers.png?fit=max&auto=format&n=8zDbQ_0RVb0kBBdl&q=85&s=4c963b09b57524a51a7ba75dfe66dda9" alt="Alertmanager" width="701" height="657" data-path="images/v25.1/kubernetes-prometheus-alertmanagers.png" />

4. Add CockroachDB's starter <InternalLink path="cockroach/cloud/kubernetes/prometheus/alert-rules.yaml">alerting rules</InternalLink>:

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   $ kubectl apply \
   -f https://www.cockroachlabs.com/docs/files/cockroach/cloud/kubernetes/prometheus/alert-rules.yaml
   ```

   ```
   prometheusrule.monitoring.coreos.com/prometheus-cockroachdb-rules created
   ```

5. Ensure that the rules are visible to Prometheus by opening [http://localhost:9090/rules](http://localhost:9090/rules). The screen should look like this:

   <img src="https://mintcdn.com/cockroachlabs/8zDbQ_0RVb0kBBdl/images/v25.1/kubernetes-prometheus-alertrules.png?fit=max&auto=format&n=8zDbQ_0RVb0kBBdl&q=85&s=1cf60b2fff8ffebfd102baa445af434e" alt="Alertmanager" width="2316" height="1322" data-path="images/v25.1/kubernetes-prometheus-alertrules.png" />

6. Verify that the `TestAlertManager` example alert is firing by opening [http://localhost:9090/alerts](http://localhost:9090/alerts). The screen should look like this:

   <img src="https://mintcdn.com/cockroachlabs/8zDbQ_0RVb0kBBdl/images/v25.1/kubernetes-prometheus-alerts.png?fit=max&auto=format&n=8zDbQ_0RVb0kBBdl&q=85&s=1f6e55aec2987f75ed1b2e4db0da6752" alt="Alertmanager" width="2312" height="1332" data-path="images/v25.1/kubernetes-prometheus-alerts.png" />

7. To remove the example alert:

   1. Use the `kubectl edit` command to open the rules for editing:

      ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
      $ kubectl edit prometheusrules prometheus-cockroachdb-rules
      ```

   2. Remove the `dummy.rules` block and save the file:

      ```
      - name: rules/dummy.rules
        rules:
        - alert: TestAlertManager
          expr: vector(1)
      ```

## Configure logging

When running CockroachDB v21.1 and later, you can use the Operator to configure the CockroachDB logging system. This allows you to output logs to <InternalLink path="configure-logs#configure-log-sinks">configurable log sinks</InternalLink> such as file or network logging destinations.

<Note>
  By default, Kubernetes deployments running CockroachDB v20.2 or earlier output all logs to `stderr`.
</Note>

The logging configuration is defined in a [ConfigMap](https://kubernetes.io/docs/concepts/configuration/configmap/) object, using a key named `logging.yaml`. For example:

```yaml theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
apiVersion: v1
data:
  logging.yaml: |
    sinks:
      file-groups:
        dev:
          channels: DEV
          filter: WARNING
      fluent-servers:
        ops:
          channels: [OPS, HEALTH, SQL_SCHEMA]
          address: 127.0.0.1:5170
          net: tcp
          redact: true
        security:
          channels: [SESSIONS, USER_ADMIN, PRIVILEGES, SENSITIVE_ACCESS]
          address: 127.0.0.1:5170
          net: tcp
          auditable: true
kind: ConfigMap
metadata:
  name: logconfig
  namespace: cockroach-operator-system
```

The above configuration overrides the <InternalLink path="configure-logs#default-logging-configuration">default logging configuration</InternalLink> and reflects our recommended Kubernetes logging configuration:

* Save debug-level logs (the `DEV` <InternalLink path="logging-overview#logging-channels">log channel</InternalLink>) to disk for troubleshooting.
* Send operational- and security-level logs to a <InternalLink path="logging-use-cases#network-logging">network collector</InternalLink>, in this case <InternalLink path="configure-logs#fluentd-logging-format">Fluentd</InternalLink>.

The ConfigMap `name` must match the `logConfigMap` object of the Operator's custom resource, which is used to <InternalLink path="deploy-cockroachdb-with-kubernetes#initialize-the-cluster">deploy the cluster</InternalLink>:

```yaml theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
spec:
  logConfigMap: logconfig
```

By default, the Operator also modifies the <InternalLink path="configure-logs#default-logging-configuration">default logging configuration</InternalLink> with the following:

```yaml theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
sinks:
  stderr:
    channels: OPS
      redact: true
```

This outputs logging events in the <InternalLink path="logging#ops">`OPS`</InternalLink> channel to a `cockroach-stderr.log` file.

### Example: Creating a troubleshooting log file on pods

In this example, CockroachDB has already been deployed on a Kubernetes cluster. We override the <InternalLink path="configure-logs#default-logging-configuration">default logging configuration</InternalLink> to output <InternalLink path="logging#dev">`DEV`</InternalLink> logs to a `cockroach-dev.log` file.

1. Create a ConfigMap named `logconfig`. Note that `namespace` is set to the Operator's default namespace (`cockroach-operator-system`):

   ```yaml theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   apiVersion: v1
   data:
     logging.yaml: |
       sinks:
         file-groups:
           dev:
             channels: DEV
             filter: WARNING
   kind: ConfigMap
   metadata:
     name: logconfig
     namespace: cockroach-operator-system
   ```

   For simplicity, also name the YAML file `logconfig.yaml`.

<Note>
  The ConfigMap key is not related to the ConfigMap `name` or YAML filename, and **must** be named `logging.yaml`.
</Note>

This configuration outputs `DEV` logs that have severity <InternalLink path="logging#logging-levels-severities">`WARNING`</InternalLink> to a `cockroach-dev.log` file on each pod.

1. Apply the ConfigMap to the cluster:

   ```
   kubectl apply -f logconfig.yaml
   ```

   ```
   configmap/logconfig created
   ```

2. Add the `name` of the ConfigMap in `logConfigMap` to the <InternalLink path="deploy-cockroachdb-with-kubernetes#initialize-the-cluster">Operator's custom resource</InternalLink>:

   ```yaml theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   spec:
     logConfigMap: logconfig
   ```

3. Apply the new settings to the cluster:

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   $ kubectl apply -f example.yaml
   ```

   The changes will be rolled out to each pod.

4. See the log files available on a pod:

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   $ kubectl exec cockroachdb-2 -- ls cockroach-data/logs
   ```

   ```
   cockroach-dev.cockroachdb-2.unknownuser.2022-05-02T19_03_03Z.000001.log
   cockroach-dev.log
   cockroach-health.cockroachdb-2.unknownuser.2022-05-02T18_53_01Z.000001.log
   cockroach-health.log
   cockroach-pebble.cockroachdb-2.unknownuser.2022-05-02T18_52_48Z.000001.log
   cockroach-pebble.log
   cockroach-stderr.cockroachdb-2.unknownuser.2022-05-02T18_52_48Z.000001.log
   cockroach-stderr.cockroachdb-2.unknownuser.2022-05-02T19_03_03Z.000001.log
   cockroach-stderr.cockroachdb-2.unknownuser.2022-05-02T20_04_03Z.000001.log
   cockroach-stderr.log
   cockroach.cockroachdb-2.unknownuser.2022-05-02T18_52_48Z.000001.log
   cockroach.log
   ...
   ```

5. View a specific log file:

   ```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   $ kubectl exec cockroachdb-2 -- cat cockroach-data/logs/cockroach-dev.log
   ```

## See also

* <InternalLink path="monitoring-and-alerting">Monitoring and Alerting</InternalLink>
* <InternalLink path="metrics">Metrics</InternalLink>
