Metrics Extension

The metrics extension surfaces Prometheus metrics directly inside ArgoCD’s resource detail views. Developers can see CPU, memory, network, container-level breakdowns, and custom metrics for their Deployments, StatefulSets, and Pods without leaving ArgoCD.

Registration

The extension registers as:

  • Resource tab on apps/Deployment, apps/StatefulSet, and core Pod resources
  • App view in the application detail for namespace-wide metrics and a query builder

What it shows

Resource tab (per-resource)

When viewing a Deployment, StatefulSet, or Pod, the Metrics tab shows:

  • Instant summary cards (CPU, Memory, Network RX/TX, Restarts)
  • Config-driven charts organized in tabs (e.g., “Resource Usage”, “Container Breakdown”)
  • Per-pod and per-container breakdowns via configurable PromQL
  • Pod details table with per-pod instant metrics

Charts are rendered with recharts: responsive width, synchronized hover across all charts, dark tooltip overlay, and clickable legend to toggle series.

App view

The application-level view provides:

  • Namespace-wide summary metrics
  • Same config-driven dashboard with tabs
  • Interactive Query Builder for custom PromQL (visual builder and raw mode)
  • Pod details table

Default dashboards

Without any custom config, the extension ships built-in dashboards:

Deployments and StatefulSets:

TabCharts
Resource UsageCPU by pod, Memory by pod, Network RX/TX by pod
Container BreakdownCPU by container, Memory by container, Restarts by container

Pods:

TabCharts
Resource UsageCPU by container, Memory by container, Network RX/TX

For pods, metrics are always broken down by container (not summed) so you can see sidecar vs app container resource usage.

Custom dashboards

Dashboards are fully customizable via a JSON config file mounted as a ConfigMap. This lets you add custom PromQL queries, organize metrics into tabs, define per-application dashboards, and add Golden Signal or SLO graphs.

Config format

{
  "applications": [
    {
      "name": "default",
      "default": true,
      "dashboards": [
        {
          "groupKind": "deployment",
          "tabs": ["Resource Usage", "Golden Signal"],
          "intervals": ["1h", "6h", "24h", "7d"],
          "rows": [
            {
              "name": "cpu-memory",
              "title": "CPU & Memory",
              "tab": "Resource Usage",
              "graphs": [
                {
                  "name": "cpu-by-pod",
                  "title": "CPU Usage",
                  "description": "CPU usage per pod",
                  "graphType": "line",
                  "metricName": "pod",
                  "queryExpression": "sum by (pod) (rate(container_cpu_usage_seconds_total{namespace="{{.namespace}}",pod=~"{{.name}}",container!=""}[5m])) * 1000",
                  "yAxisUnit": "millicores"
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

Template variables

PromQL query expressions support Go text/template syntax. All URL query parameters are available as variables:

VariableDescriptionExample value
{{.namespace}}Kubernetes namespace of the resourcedefault
{{.name}}Resource name pattern (pods: exact, workloads: name-.*)guestbook-ui-.*
{{.application}}ArgoCD application nameguestbook
{{.duration}}Selected time range1h

Config structure

FieldTypeDescription
applications[].namestringArgoCD application name (or “default” for fallback)
applications[].defaultboolUse as fallback when no app-specific config matches
dashboards[].groupKindstringKubernetes resource kind: deployment, statefulset, pod
dashboards[].tabsstring[]Tab names for organizing rows
dashboards[].intervalsstring[]Time range options (e.g., ["1h", "6h", "24h", "7d"])
rows[].namestringURL-safe row identifier
rows[].titlestringDisplay title
rows[].tabstringWhich tab this row appears under
graphs[].namestringURL-safe graph identifier
graphs[].titlestringDisplay title
graphs[].graphTypestringChart type: line (default)
graphs[].metricNamestringPrometheus label to group by (e.g., pod, container)
graphs[].queryExpressionstringPromQL with template variables
graphs[].yAxisUnitstringUnit: millicores, bytes, bytes/s, count, or custom

Deploying a custom config

  1. Create a ConfigMap with your config:
apiVersion: v1
kind: ConfigMap
metadata:
  name: argoplane-metrics-config
  namespace: argocd
data:
  config.json: |
    {
      "applications": [
        {
          "name": "default",
          "default": true,
          "dashboards": [ ... ]
        }
      ]
    }
  1. Mount the ConfigMap and set CONFIG_PATH in the metrics backend deployment:
env:
  - name: CONFIG_PATH
    value: "/app/config.json"
volumeMounts:
  - name: dashboard-config
    mountPath: /app/config.json
    subPath: config.json
    readOnly: true
volumes:
  - name: dashboard-config
    configMap:
      name: argoplane-metrics-config
  1. The backend reads the config on startup. Restart the pod to pick up changes.

Per-application dashboards

You can define different dashboards for different ArgoCD applications. The backend matches by application name and falls back to the entry with "default": true.

{
  "applications": [
    {
      "name": "my-api",
      "dashboards": [
        {
          "groupKind": "deployment",
          "tabs": ["Resource Usage", "HTTP Metrics"],
          "rows": [ ... ]
        }
      ]
    },
    {
      "name": "default",
      "default": true,
      "dashboards": [ ... ]
    }
  ]
}

Backend configuration

Environment VariableRequiredDefaultDescription
PROMETHEUS_URLNohttp://kube-prometheus-kube-prome-prometheus.monitoring.svc:9090Prometheus server URL
PORTNo8080HTTP server port
LOG_LEVELNoinfoLog level (debug, info, warn, error)
CONFIG_PATHNo(empty)Path to custom dashboard config JSON. Omit to use built-in defaults.

Proxy configuration

In deploy/argocd/proxy-extensions.json:

{
  "extension.config.metrics": "services:\n- url: http://argoplane-metrics-backend.argocd.svc:8080\n"
}

RBAC

p, role:developer, extensions, invoke, metrics, allow