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

# Monitor Qodo with Prometheus and Grafana

> Enable metrics through the Qodo Helm chart, verify Prometheus targets, and display application metrics in Grafana.

* **Deployment model**: On-premises

Use your Prometheus deployment to scrape Qodo components and Grafana to
display the results. The Qodo Helm chart can create ServiceMonitor resources
for individual components. It does not install Prometheus, Prometheus
Operator, or Grafana.

This guide uses Prometheus Operator. For standalone Prometheus, configure
scraping in your collector using the ports below; standalone Prometheus does
not consume ServiceMonitor resources.

## Before you begin

Prepare:

* The Qodo chart and values files for your installation.
* A running Prometheus Operator and the `servicemonitors.monitoring.coreos.com` CRD.
* A running Prometheus instance configured to discover monitors in your Qodo namespace.
* Permission to create ServiceMonitors, plus Prometheus discovery permissions for the namespace's Services, Pods, and endpoints.
* Network access from the collector to the selected metrics ports.
* A Grafana instance that can query your Prometheus server.

You can use your existing monitoring stack. Keep collection and dashboards
within your environment according to your monitoring policy. For more
information, see [Infrastructure requirements](/on-prem/qodo-on-premise/infrastructure-requirements).

## 1. Check Prometheus discovery

The examples use namespace `qodo` and monitor label `release: monitoring`.
Replace these with your namespace and the labels your Prometheus selects.

```bash theme={null}
kubectl get crd servicemonitors.monitoring.coreos.com
kubectl get prometheus -A
kubectl get prometheus <prometheus-name> \
  -n <monitoring-namespace> -o yaml
```

Check both selectors on the Prometheus resource:

| Field | What it must select |
| - | - |
| `spec.serviceMonitorSelector` | The monitors' metadata labels, such as `release: monitoring` |
| `spec.serviceMonitorNamespaceSelector` | The namespace containing the monitors, in this example `qodo` |

An omitted namespace selector discovers monitors only in the Prometheus
resource's own namespace. If Prometheus runs elsewhere, include Qodo's
namespace in its discovery scope. Preserve the namespaces and labels already
used by your monitoring stack.

The Operator must watch that namespace, and the Prometheus service account
must be able to discover its targets. A monitor can exist without being
selected or scraped. For more information, see [Getting started with Prometheus Operator](https://prometheus-operator.dev/docs/developer/getting-started/).

## 2. Choose the components to scrape

The examples collect these application endpoints at `/metrics`:

| Component | Helm values key | Service port name | Port |
| - | - | - | - |
| Platform API | `platform` | `metrics` | `9090` |
| Qodo Agent Runtime | `qar` | `metrics` | `9090` |
| Git integration gateway | `litegit` | `http` | `8000` |
| Git repository gateway | `gitway` | `metrics` | `9090` |
| Code review worker | `pr-agent-litegit` | `http` | `8765` |
| Context Engine retriever | `engine-retriever` | `http` | `8001` |
| Context Engine knowledge consumer | `engine-pr-kn-consumer` | `metrics` | `9090` |

The monitor's `port` is a Service port name, not a number. The chart defaults
to `metrics`; components exposing metrics on their ordinary HTTP listener
need `port: http`. The code review worker's separate `health` port serves
probes. Use its `http` port for metrics.

The values below add missing metrics Service ports and enable a Service for
the knowledge consumer. Existing HTTP ports remain available.

This example does not add database, Redis, RabbitMQ, or Kubernetes exporters.
Manage those with your monitoring stack. Use cluster metrics for Pod restarts,
CPU, memory, and volume usage across all workloads, including workloads
without a metrics endpoint listed above.

## 3. Configure the Qodo Helm values

Save this as `monitoring-values.yaml`. Keep only the components you deploy and
replace every `release: monitoring` label if your selector requires another.

```yaml monitoring-values.yaml theme={null}
platform:
  service:
    ports:
      metrics:
        svcPort: 9090
        targetPort: 9090
        protocol: TCP
  prometheus:
    serviceMonitor:
      enabled: true
      port: metrics
      metricsPath: /metrics
      labels:
        release: monitoring

qar:
  service:
    ports:
      metrics:
        svcPort: 9090
        targetPort: 9090
        protocol: TCP
  prometheus:
    serviceMonitor:
      enabled: true
      port: metrics
      metricsPath: /metrics
      labels:
        release: monitoring

litegit:
  prometheus:
    serviceMonitor:
      enabled: true
      port: http
      metricsPath: /metrics
      labels:
        release: monitoring

gitway:
  service:
    ports:
      metrics:
        svcPort: 9090
        targetPort: 9090
        protocol: TCP
  prometheus:
    serviceMonitor:
      enabled: true
      port: metrics
      metricsPath: /metrics
      labels:
        release: monitoring

pr-agent-litegit:
  prometheus:
    serviceMonitor:
      enabled: true
      port: http
      metricsPath: /metrics
      labels:
        release: monitoring

engine-retriever:
  prometheus:
    serviceMonitor:
      enabled: true
      port: http
      metricsPath: /metrics
      labels:
        release: monitoring

engine-pr-kn-consumer:
  service:
    enabled: true
    type: ClusterIP
    ports:
      metrics:
        svcPort: 9090
        targetPort: 9090
        protocol: TCP
  prometheus:
    serviceMonitor:
      enabled: true
      port: metrics
      metricsPath: /metrics
      labels:
        release: monitoring
```

These ports stay inside the cluster. Keep your existing HTTP ports and permit
only the required monitoring traffic through your network policies. The
example does not require a public metrics Ingress.

The `prometheus.serviceMonitor` settings create discovery resources. They do
not start an exporter in an application that does not expose metrics.

Preview with all your existing values layers:

```bash theme={null}
helm template qodo ./qodo-onprem \
  --namespace qodo \
  -f onprem-base.yaml \
  -f my-values.yaml \
  -f monitoring-values.yaml > qodo-rendered.yaml
```

Treat the rendered file as sensitive because it can contain Secrets. Check
that each monitor references an existing named Service port and has labels
matching your Prometheus selector.

Apply the same files through your normal deployment process:

```bash theme={null}
helm upgrade --install qodo ./qodo-onprem \
  --namespace qodo \
  -f onprem-base.yaml \
  -f my-values.yaml \
  -f monitoring-values.yaml \
  --wait --wait-for-jobs --timeout 20m
```

Use the chart release approved for your installation. Include the monitoring
file on subsequent upgrades. For more information, see [Deploy Qodo using Helm](/on-prem/qodo-on-prem-helm-chart-overview).

## 4. Verify collection in Prometheus

Check the monitors and Services:

```bash theme={null}
kubectl get servicemonitor -n qodo
kubectl get service qodo-agent-runtime-qar -n qodo -o yaml
```

To test the runtime exporter directly, forward its metrics port:

```bash theme={null}
kubectl port-forward -n qodo service/qodo-agent-runtime-qar 19090:9090
```

In another terminal:

```bash theme={null}
curl --fail --silent --show-error http://localhost:19090/metrics
```

Expect Prometheus exposition text with metric names and `HELP` or `TYPE`
comments. This verifies one exporter; it does not establish that Prometheus
can discover or reach it from the monitoring namespace.

In your Prometheus UI, open the targets page and find the Qodo targets. Wait
for at least two scrape intervals. Each expected endpoint should report `UP`.
Query scrape health:

```promql theme={null}
up{namespace="qodo"}
```

Each target should return `1`. A value of `0` means the scrape failed. An
absent target means discovery, filtering, or relabeling needs investigation.
Check actual target labels if your collector rewrites or omits `namespace`,
`service`, or `pod`.

Trigger a test code review and a Context Engine request, then check their
metric series. Some series appear only after the relevant operation occurs.
Scrape health alone does not confirm a successful code review.

## 5. Display metrics in Grafana

1. Go to Connections > Data sources and add or select a Prometheus data source.
2. Set the server URL to the Prometheus query endpoint reachable from the Grafana server. Use the Prometheus server address, rather than an application's `/metrics` URL.
3. Configure authentication and TLS for your monitoring stack, then select **Save & test**.
4. Open **Explore**, select the data source, and run `up{namespace="qodo"}`.
5. Create a dashboard with panels using the queries below. Select a time range that includes your test traffic.

For more information, see [Configure the Prometheus data source](https://grafana.com/docs/grafana/latest/datasources/prometheus/configure/).

| Panel | PromQL | Expected result |
| - | - | - |
| Scrape health | `up{namespace="qodo"}` | One series per target; `1` indicates a successful scrape |
| Code review worker readiness | `litegit_app_ready{namespace="qodo"}` | `1` when the worker subscription is active |
| Code review work in progress | `litegit_app_in_flight{namespace="qodo"}` | Events being processed by each worker |
| Runtime HTTP request rate | `sum(rate(qar_http_requests_total{namespace="qodo"}[5m]))` | Requests per second after runtime traffic and enough samples |
| Runtime HTTP latency, 95th percentile | `histogram_quantile(0.95, sum by (le) (rate(qar_http_request_duration_seconds_bucket{namespace="qodo"}[5m])))` | Duration in seconds after runtime traffic and enough samples |

Use state or stat panels for readiness, and time-series panels for rates and
latency. Filter or group by the labels present in your installation for
per-service or per-Pod views. Add alerts through your monitoring process after
establishing normal behavior for your workload.

## Troubleshoot missing metrics

| Symptom | Check and recovery |
| - | - |
| Helm reports no match for `ServiceMonitor` | Install the Operator CRDs first, or remove the monitoring override until your collector is ready |
| Helm cannot create ServiceMonitors | Have your cluster administrator grant the installer namespaced permissions for that resource |
| A monitor exists but its target is absent | Check both Prometheus selectors, the Operator's watched namespaces, discovery RBAC, and the monitor's Service selector |
| A target has no endpoints | Confirm the Service selects ready Pods and its named port exists. Inspect its EndpointSlices |
| A scrape times out or is refused | Check NetworkPolicies and the exporter listener. Permit the collector to reach the metrics port |
| A scrape returns `404` or probe responses | Check `/metrics` and the port in the table. Do not scrape the code review worker's `health` port |
| A scrape returns `401` or `403` | Check proxy or service-mesh authentication. Use a monitor configuration that matches that policy |
| Prometheus has data but Grafana is empty | Check the data source, server connectivity, time range, and actual series labels |
| Scrapes succeed but an application panel is empty | Generate relevant traffic, allow enough samples for rate queries, and inspect metric names in your installed images |

Useful discovery checks:

```bash theme={null}
kubectl describe servicemonitor qodo-agent-runtime-qar -n qodo
kubectl get endpointslice -n qodo \
  -l kubernetes.io/service-name=qodo-agent-runtime-qar
```

For more information, see [Troubleshooting Prometheus Operator](https://prometheus-operator.dev/docs/platform/troubleshooting/).

## Next steps

* [Infrastructure requirements](/on-prem/qodo-on-premise/infrastructure-requirements): Check storage, networking, and dependency readiness.
* [Helm chart configuration reference](/on-prem/on-prem-helm-chart-reference): Review the customer configuration for your installation.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.