✅ Added 3 new files:
config/config-observability.yaml (ConfigMap for metrics)
config/metrics-service.yaml (Service for metrics endpoint)
deploy-with-metrics.sh (Deployment script)
✅ Modified 1 file:
config/controller.yaml (Added metrics port + env vars)
✅ No changes needed:
cmd/labeler/main.go (Already perfect!)
cmd/labeler/controller.go (Already perfect!)
# This ConfigMap tells Knative how to export metrics
apiVersion: v1
kind: ConfigMap
metadata:
name: config-observability
data:
metrics-protocol: prometheus # ← Use Prometheus
metrics-endpoint: ":9090" # ← Port 9090Why: Knative's sharedmain reads this and automatically sets up OpenTelemetry
# This Service provides a stable endpoint for Prometheus
apiVersion: v1
kind: Service
metadata:
name: label-controller-metrics
spec:
ports:
- port: 9090
selector:
app: label-controllerWhy: Makes it easy to access metrics via kubectl port-forward svc/...
# Added:
ports:
- name: metrics
containerPort: 9090 # ← Expose metrics port
env:
- name: POD_NAMESPACE # ← For resource attributes
- name: POD_NAME # ← For resource attributesWhy: Exposes port 9090 so we can scrape metrics
# Automated deployment script
ko apply -Rf config/ -n labeler
kubectl port-forward ...
curl http://localhost:9090/metricsWhy: One command to deploy and test everything
┌─────────────────────────────────────────────────────────────┐
│ 1. You call: sharedmain.Main("custom-labeler", ...) │
│ │
│ 2. sharedmain reads: config-observability ConfigMap │
│ ├── metrics-protocol: prometheus │
│ └── metrics-endpoint: ":9090" │
│ │
│ 3. sharedmain automatically: │
│ ├── Creates OTel MeterProvider │
│ ├── Sets up Prometheus exporter │
│ ├── Registers ALL workqueue metrics │
│ ├── Registers client-go metrics │
│ ├── Starts Go runtime metrics │
│ └── Starts HTTP server on :9090 │
│ │
│ 4. Your workqueue automatically reports metrics │
│ No code changes needed! │
└─────────────────────────────────────────────────────────────┘
↓
HTTP Server :9090/metrics
↓
Prometheus scrapes
kn.workqueue.depth ← Current queue size
kn.workqueue.adds ← Items added
kn.workqueue.queue.duration ← Time in queue
kn.workqueue.process.duration ← Processing time
kn.workqueue.unfinished_work ← Unfinished duration
kn.workqueue.longest_running_processor ← Longest item
kn.workqueue.retries ← Retry count
kn.k8s.client.request.duration ← K8s API latency
kn.k8s.client.request.count ← K8s API calls
go.memory.used ← Memory usage
go.goroutine.count ← Goroutines
go.memory.allocated ← Heap allocations
... and more
./deploy-with-metrics.sh# 1. Deploy
ko apply -Rf config/ -n labeler
# 2. Port-forward
kubectl port-forward -n labeler svc/label-controller-metrics 9090:9090
# 3. Check metrics
curl http://localhost:9090/metrics | grep kn_workqueuekn_workqueue_depth{name="labeler-controller"} 0
kn_workqueue_adds_total{name="labeler-controller"} 5
kn_workqueue_queue_duration_seconds_bucket{name="labeler-controller",le="0.005"} 5
go_memory_used_bytes 1.2345e+07
go_goroutine_count 42
- No custom metrics code - Knative does it all
- ConfigMap-based - Change config without rebuilding
- All metrics included - Workqueue + client-go + runtime
- Production-ready - Used by all Knative components
- Uses OpenTelemetry SDK (via knative.dev/pkg)
- Metric name:
kn.workqueue.depth✓ - Prometheus Protocol support ✓
- OTLP gRPC/HTTP support ✓
- Resource attributes ✓
- ConfigMap configuration ✓
Your main.go already uses sharedmain.Main() which:
- Automatically reads
config-observability - Automatically sets up OTel
- Automatically registers all metrics
- Automatically starts metrics server
That's the magic of Knative!
-
Deploy:
./deploy-with-metrics.sh
-
Verify:
kubectl port-forward -n labeler svc/label-controller-metrics 9090:9090 curl http://localhost:9090/metrics | grep kn_ -
Integrate with Prometheus (see COMPLETE_GUIDE.md)
-
Optional: Add custom application metrics:
meter := otel.GetMeterProvider().Meter("my-app") counter, _ := meter.Int64Counter("my.custom.metric") counter.Add(ctx, 1)
Read COMPLETE_GUIDE.md for full documentation including:
- Detailed explanations
- Troubleshooting guide
- Prometheus integration
- Metric reference
- Examples
🎉 That's it! You now have full OpenTelemetry metrics with zero custom code!