Overview
The project uses grafonnet for declarative Grafana dashboard development. Dashboards are written in Jsonnet, compiled at build time, and deployed as Kubernetes ConfigMaps.Architecture
Dashboards follow this workflow:- Write Jsonnet dashboard code in
dashboards/src/ - Compile with go-jsonnet (via Nix build)
- Inject into ConfigMaps using nixidy module
- Deploy via ArgoCD
- Auto-discover by Grafana dashboard sidecar
Directory Structure
Grafonnet Setup
Dependency Declaration
Dashboard dependencies are declared injsonnetfile.json:
Library Import
Theg.libsonnet file provides a simple import (dashboards/src/g.libsonnet):
Writing Dashboards
Basic Structure
All dashboards follow this pattern:Sample Application Dashboard
Here’s a real example from dashboards/src/sample-app.jsonnet showing OTel metrics:Kubernetes Cluster Dashboard
The k8s-cluster.jsonnet provides comprehensive cluster monitoring with:- Stat Panels: Node count, pod counts by phase, cluster CPU/memory
- Time Series: Node resource usage, pod restarts, network I/O
- Resource Comparison: CPU/memory requests vs actual usage
- Uses
node_exporterandkube-state-metricsdata - Filters virtual network devices:
device!~"lo|veth.*|docker.*|flannel.*|cali.*|cbr.*" - Shows top 10 restarting pods
- Compares resource requests vs actual consumption by namespace
Panel Types
Grafonnet supports multiple panel types:Time Series
Stat Panel
Common Units
percentunit- 0.0 to 1.0 as percentagepercent- 0 to 100bytes- Bytes with SI prefixesBps- Bytes per secondms- Millisecondss- Secondsreqps- Requests per secondshort- Plain number with abbreviations
Build Integration
Dashboards are compiled and injected via nixidy (nixidy/env/local/grafana-dashboards.nix):Build Process
- Fetch grafonnet: Downloads specific commit from GitHub
- Setup vendor directory: Creates symlink to grafonnet library
- Set JSONNET_PATH: Configures import resolution
- Compile: Runs
go-jsonnetto generate JSON - Inject into ConfigMap: Embeds compiled JSON with label
grafana_dashboard = "1"
Grafana Discovery
Grafana’s dashboard sidecar automatically discovers ConfigMaps with the label:Development Workflow
1. Create Dashboard
Create a new Jsonnet file indashboards/src/:
2. Add to Nixidy Module
Editnixidy/env/local/grafana-dashboards.nix to include your dashboard:
3. Generate and Deploy
4. Verify in Grafana
Grafana is exposed on NodePort 30300:Testing Dashboards Locally
You can test compilation without deploying:Query Tips
Using Rate Intervals
Always use$__rate_interval instead of hardcoded intervals:
Histogram Quantiles
For percentiles from histograms:Error Rate Calculation
Best Practices
- Use Variables: Define queries as local variables for reusability
- Shared Crosshair: Always use
dashboard.graphTooltip.withSharedCrosshair() - Auto-refresh: Set reasonable refresh intervals (30s for most dashboards)
- Panel Layout: Use grid positions to create organized layouts
- Legend Format: Use meaningful legend templates like
{{ namespace }}/{{ pod }} - Units: Always specify appropriate units for clarity
- Tags: Add tags for discoverability
- Descriptions: Add dashboard and panel descriptions
Troubleshooting
Dashboard Not Appearing
-
Check ConfigMap was created:
-
Verify label is present:
-
Check Grafana sidecar logs:
Compilation Errors
Ifgen-manifests fails with Jsonnet errors:
-
Test compilation directly:
- Check JSONNET_PATH is correct
- Verify all imports are available
Query Not Showing Data
- Test query in Grafana’s Explore view
- Check Prometheus has the metrics:
- Verify ServiceMonitor/PodMonitor is scraping the target
Next Steps
- Learn about nixidy module structure
- Set up development environment
- Run performance benchmarks