Pipelines as Code exposes Prometheus metrics for monitoring controller performance, PipelineRun execution, and Git provider API usage. These metrics help you understand system behavior, identify bottlenecks, and set up alerting.
Accessing Metrics
Metrics are exposed by the pipelines-as-code-watcher service on port 9090:
# Port-forward to access metrics locally
kubectl port-forward -n pipelines-as-code svc/pipelines-as-code-watcher 9090:9090
# Access metrics endpoint
curl http://localhost:9090/metrics
Configuring Exporters
Pipelines as Code supports multiple metrics backends including Prometheus, Google Stackdriver, and other exporters. Configuration is managed through the pipelines-as-code-config-observability ConfigMap.
Observability ConfigMap
kubectl get configmap pipelines-as-code-config-observability -n pipelines-as-code -o yaml
Example Configuration
apiVersion: v1
kind: ConfigMap
metadata:
name: pipelines-as-code-config-observability
namespace: pipelines-as-code
data:
# Prometheus (default)
metrics.backend-destination: prometheus
# For Stackdriver (Google Cloud)
# metrics.backend-destination: stackdriver
# metrics.stackdriver-project-id: "your-gcp-project-id"
# metrics.allow-stackdriver-custom-metrics: "false"
metrics.backend-destination
string
default:"prometheus"
The metrics backend to use. Supported values:
prometheus - Prometheus format (default)
stackdriver - Google Cloud Stackdriver
metrics.stackdriver-project-id
Google Cloud project ID for Stackdriver. When running on GCE, this is optional and defaults to the cluster’s project.
metrics.allow-stackdriver-custom-metrics
Allow sending metrics to Stackdriver using “global” resource type and custom metric type. Enabling this may incur additional charges.
Available Metrics
Pipelines as Code exports the following metrics:
Git Provider API Requests
pipelines_as_code_git_provider_api_request_count
Total number of API requests made to Git providers (GitHub, GitLab, Bitbucket).Labels:
provider - Git provider name (github, gitlab, bitbucket-cloud, etc.)
event-type - Event type triggering the request (pull_request, push, etc.)
namespace - PipelineRun namespace
repository - Repository CR name
This metric is emitted by both the Controller and Watcher services. When analyzing, combine metrics from both sources using PromQL aggregation.
Example PromQL queries:
# Total API requests across both services
sum(
pac_controller_pipelines_as_code_git_provider_api_request_count
or
pac_watcher_pipelines_as_code_git_provider_api_request_count
)
# API request rate per minute
sum(
rate(pac_controller_pipelines_as_code_git_provider_api_request_count[1m])
or
rate(pac_watcher_pipelines_as_code_git_provider_api_request_count[1m])
)
# API requests by provider
sum by (provider) (
pac_controller_pipelines_as_code_git_provider_api_request_count
or
pac_watcher_pipelines_as_code_git_provider_api_request_count
)
PipelineRun Count
pipelines_as_code_pipelinerun_count
Total number of PipelineRuns created by Pipelines as Code.Labels:
provider - Git provider name
event-type - Event type (pull_request, push, incoming)
namespace - PipelineRun namespace
repository - Repository CR name
Example PromQL queries:
# Total PipelineRuns created
sum(pipelines_as_code_pipelinerun_count)
# PipelineRuns by event type
sum by (event_type) (pipelines_as_code_pipelinerun_count)
# PipelineRun creation rate
rate(pipelines_as_code_pipelinerun_count[5m])
# PipelineRuns per repository
sum by (repository, namespace) (pipelines_as_code_pipelinerun_count)
PipelineRun Duration
pipelines_as_code_pipelinerun_duration_seconds_sum
Total number of seconds all PipelineRuns have taken to complete.Labels:
namespace - PipelineRun namespace
repository - Repository CR name
status - PipelineRun status (Succeeded, Failed, etc.)
reason - Status reason (Completed, TaskRunFailed, etc.)
Example PromQL queries:
# Average PipelineRun duration
rate(pipelines_as_code_pipelinerun_duration_seconds_sum[5m])
/
rate(pipelines_as_code_pipelinerun_count[5m])
# Failed PipelineRun duration
sum by (repository) (
pipelines_as_code_pipelinerun_duration_seconds_sum{status="Failed"}
)
# Success rate by repository
sum by (repository) (pipelines_as_code_pipelinerun_count{status="Succeeded"})
/
sum by (repository) (pipelines_as_code_pipelinerun_count)
Running PipelineRuns
pipelines_as_code_running_pipelineruns_count
Current number of running PipelineRuns.Labels:
namespace - PipelineRun namespace
repository - Repository CR name
Example PromQL queries:
# Current running PipelineRuns
sum(pipelines_as_code_running_pipelineruns_count)
# Running PipelineRuns per namespace
sum by (namespace) (pipelines_as_code_running_pipelineruns_count)
# Maximum concurrent PipelineRuns (over 1 hour)
max_over_time(pipelines_as_code_running_pipelineruns_count[1h])
Prometheus ServiceMonitor
To scrape metrics with Prometheus Operator, create a ServiceMonitor:
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: pipelines-as-code-watcher
namespace: pipelines-as-code
labels:
app: pipelines-as-code
spec:
selector:
matchLabels:
app.kubernetes.io/name: watcher
app.kubernetes.io/part-of: pipelines-as-code
endpoints:
- port: metrics
interval: 30s
path: /metrics
Apply the ServiceMonitor:
kubectl apply -f servicemonitor.yaml
Grafana Dashboard
Create a Grafana dashboard to visualize Pipelines as Code metrics:
Example Dashboard Panels
PipelineRun Creation Rate:
sum(rate(pipelines_as_code_pipelinerun_count[5m])) by (event_type)
Average PipelineRun Duration:
rate(pipelines_as_code_pipelinerun_duration_seconds_sum[5m])
/
rate(pipelines_as_code_pipelinerun_count[5m])
Success Rate:
sum(rate(pipelines_as_code_pipelinerun_count{status="Succeeded"}[5m]))
/
sum(rate(pipelines_as_code_pipelinerun_count[5m]))
* 100
API Request Rate by Provider:
sum by (provider) (
rate(pac_controller_pipelines_as_code_git_provider_api_request_count[1m])
or
rate(pac_watcher_pipelines_as_code_git_provider_api_request_count[1m])
)
Currently Running PipelineRuns:
sum(pipelines_as_code_running_pipelineruns_count)
Alerting Rules
Set up Prometheus alerts for critical conditions:
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: pipelines-as-code-alerts
namespace: pipelines-as-code
spec:
groups:
- name: pipelines-as-code
interval: 30s
rules:
# High failure rate
- alert: HighPipelineRunFailureRate
expr: |
sum(rate(pipelines_as_code_pipelinerun_count{status="Failed"}[5m]))
/
sum(rate(pipelines_as_code_pipelinerun_count[5m]))
> 0.2
for: 10m
labels:
severity: warning
annotations:
summary: "High PipelineRun failure rate"
description: "More than 20% of PipelineRuns are failing (current: {{ $value | humanizePercentage }})"
# Too many concurrent runs
- alert: HighConcurrentPipelineRuns
expr: |
sum(pipelines_as_code_running_pipelineruns_count) > 50
for: 5m
labels:
severity: warning
annotations:
summary: "High number of concurrent PipelineRuns"
description: "Currently {{ $value }} PipelineRuns are running concurrently"
# High API usage
- alert: HighGitProviderAPIUsage
expr: |
sum(
rate(pac_controller_pipelines_as_code_git_provider_api_request_count[1m])
or
rate(pac_watcher_pipelines_as_code_git_provider_api_request_count[1m])
) > 100
for: 5m
labels:
severity: info
annotations:
summary: "High Git provider API usage"
description: "API request rate is {{ $value | humanize }} requests/second"
# No PipelineRuns created recently
- alert: NoPipelineRunsCreated
expr: |
rate(pipelines_as_code_pipelinerun_count[30m]) == 0
for: 1h
labels:
severity: info
annotations:
summary: "No PipelineRuns created recently"
description: "No PipelineRuns have been created in the last hour"
Apply the alerts:
kubectl apply -f prometheus-rules.yaml
Metrics Cardinality
Be aware of metrics cardinality when you have many repositories:
Metrics with namespace and repository labels create a unique time series for each repository. With hundreds of repositories, this can significantly increase Prometheus storage requirements.
Managing High Cardinality
- Adjust retention period - Reduce Prometheus retention for high-cardinality metrics
- Use recording rules - Pre-aggregate metrics to reduce query load
- Filter by namespace - Query specific namespaces instead of all metrics
Example recording rule:
groups:
- name: pipelines-as-code-aggregates
interval: 60s
rules:
# Aggregate API requests by provider only
- record: pac:api_requests:rate1m
expr: |
sum by (provider) (
rate(pac_controller_pipelines_as_code_git_provider_api_request_count[1m])
or
rate(pac_watcher_pipelines_as_code_git_provider_api_request_count[1m])
)
# Aggregate PipelineRun count by status
- record: pac:pipelineruns:total
expr: |
sum by (status) (pipelines_as_code_pipelinerun_count)
Troubleshooting Metrics
Metrics Not Available
Verify the watcher service is running:
kubectl get svc pipelines-as-code-watcher -n pipelines-as-code
kubectl get pods -n pipelines-as-code -l app.kubernetes.io/name=watcher
Check if metrics endpoint is accessible:
kubectl port-forward -n pipelines-as-code svc/pipelines-as-code-watcher 9090:9090
curl http://localhost:9090/metrics | grep pipelines_as_code
Missing Controller Metrics
Remember that pipelines_as_code_git_provider_api_request_count is emitted by both controller and watcher. Check both sources:
# Query both services
kubectl port-forward -n pipelines-as-code svc/pipelines-as-code-watcher 9090:9090 &
curl http://localhost:9090/metrics | grep git_provider_api_request_count
# If available, also check controller directly
kubectl port-forward -n pipelines-as-code deployment/pipelines-as-code-controller 8080:8080 &
curl http://localhost:8080/metrics | grep git_provider_api_request_count
Prometheus Not Scraping
Verify Prometheus can reach the watcher:
# Check Prometheus targets
kubectl port-forward -n monitoring svc/prometheus-k8s 9090:9090
# Open http://localhost:9090/targets and search for pipelines-as-code
Check ServiceMonitor is created and matches the service:
kubectl get servicemonitor -n pipelines-as-code
kubectl get svc pipelines-as-code-watcher -n pipelines-as-code -o yaml
See Also