diff --git a/infra/cert-manager-application.yaml b/infra/cert-manager-application.yaml
index 8580416..3adddf6 100644
--- a/infra/cert-manager-application.yaml
+++ b/infra/cert-manager-application.yaml
@@ -48,10 +48,10 @@ spec:
resources:
requests:
cpu: 50m
- memory: 64Mi
+ memory: 128Mi
limits:
cpu: 100m
- memory: 128Mi
+ memory: 256Mi
# Service account
serviceAccount:
diff --git a/infra/dashboards/dot-ai-logs.json b/infra/dashboards/dot-ai-logs.json
new file mode 100644
index 0000000..ae23276
--- /dev/null
+++ b/infra/dashboards/dot-ai-logs.json
@@ -0,0 +1,148 @@
+{
+ "annotations": {
+ "list": []
+ },
+ "editable": true,
+ "fiscalYearStartMonth": 0,
+ "graphTooltip": 0,
+ "links": [],
+ "panels": [
+ {
+ "title": "Log Volume",
+ "type": "timeseries",
+ "gridPos": {
+ "h": 6,
+ "w": 24,
+ "x": 0,
+ "y": 0
+ },
+ "datasource": {
+ "type": "loki",
+ "uid": "loki"
+ },
+ "targets": [
+ {
+ "expr": "sum(count_over_time({namespace=\"dot-ai\"} [1m])) by (pod)",
+ "legendFormat": "{{pod}}",
+ "refId": "A"
+ }
+ ],
+ "fieldConfig": {
+ "defaults": {
+ "custom": {
+ "drawStyle": "bars",
+ "fillOpacity": 50,
+ "stacking": {
+ "mode": "normal"
+ }
+ }
+ },
+ "overrides": []
+ }
+ },
+ {
+ "title": "Logs by Pod",
+ "type": "logs",
+ "gridPos": {
+ "h": 16,
+ "w": 24,
+ "x": 0,
+ "y": 6
+ },
+ "datasource": {
+ "type": "loki",
+ "uid": "loki"
+ },
+ "targets": [
+ {
+ "expr": "{namespace=\"dot-ai\", pod=~\"$pod\"} | json log=\"log\", message=\"message\", msg=\"msg\", level=\"level\", stream=\"stream\" | label_format level=`{{if .level}}{{.level}}{{else if eq .stream \"stderr\"}}error{{else}}info{{end}}` | line_format `{{.pod}} |{{or .message .msg .log}}`",
+ "refId": "A"
+ }
+ ],
+ "options": {
+ "showTime": true,
+ "showLabels": false,
+ "showCommonLabels": false,
+ "wrapLogMessage": true,
+ "prettifyLogMessage": false,
+ "enableLogDetails": true,
+ "sortOrder": "Descending",
+ "dedupStrategy": "none",
+ "displayedFields": [
+ "pod",
+ "level"
+ ]
+ }
+ },
+ {
+ "title": "Errors & Warnings",
+ "type": "logs",
+ "gridPos": {
+ "h": 10,
+ "w": 24,
+ "x": 0,
+ "y": 22
+ },
+ "datasource": {
+ "type": "loki",
+ "uid": "loki"
+ },
+ "targets": [
+ {
+ "expr": "{namespace=\"dot-ai\", pod=~\"$pod\"} | json log=\"log\", message=\"message\", msg=\"msg\", level=\"level\", stream=\"stream\" | label_format level=`{{if .level}}{{.level}}{{else if eq .stream \"stderr\"}}error{{else}}info{{end}}` | level=~`error|warn|warning|fatal|panic` | line_format `{{.pod}} |{{or .message .msg .log}}`",
+ "refId": "A"
+ }
+ ],
+ "options": {
+ "showTime": true,
+ "showLabels": false,
+ "showCommonLabels": false,
+ "wrapLogMessage": true,
+ "prettifyLogMessage": false,
+ "enableLogDetails": true,
+ "sortOrder": "Descending",
+ "dedupStrategy": "none",
+ "displayedFields": [
+ "pod",
+ "level"
+ ]
+ }
+ }
+ ],
+ "schemaVersion": 39,
+ "tags": [
+ "dot-ai",
+ "logs",
+ "loki"
+ ],
+ "templating": {
+ "list": [
+ {
+ "name": "pod",
+ "type": "query",
+ "datasource": {
+ "type": "loki",
+ "uid": "loki"
+ },
+ "query": {
+ "label": "pod",
+ "stream": "{namespace=\"dot-ai\"}",
+ "type": 1
+ },
+ "includeAll": true,
+ "multi": true,
+ "current": {
+ "selected": true,
+ "text": "All",
+ "value": "$__all"
+ }
+ }
+ ]
+ },
+ "time": {
+ "from": "now-1h",
+ "to": "now"
+ },
+ "title": "dot-ai Logs",
+ "uid": "dot-ai-logs"
+}
diff --git a/infra/dashboards/kustomization.yaml b/infra/dashboards/kustomization.yaml
new file mode 100644
index 0000000..ecf5662
--- /dev/null
+++ b/infra/dashboards/kustomization.yaml
@@ -0,0 +1,22 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+namespace: monitoring
+
+generatorOptions:
+ disableNameSuffixHash: true
+ labels:
+ grafana_dashboard: "1"
+
+configMapGenerator:
+- name: grafana-dashboard-trivy
+ files:
+ - trivy.json
+- name: grafana-dashboard-traefik-loki
+ files:
+ - traefik-loki.json
+- name: grafana-dashboard-dot-ai-logs
+ files:
+ - dot-ai-logs.json
+- name: grafana-dashboard-opencost
+ files:
+ - opencost.json
diff --git a/infra/dashboards/opencost.json b/infra/dashboards/opencost.json
new file mode 100644
index 0000000..aa34b31
--- /dev/null
+++ b/infra/dashboards/opencost.json
@@ -0,0 +1,1510 @@
+{
+ "annotations": {
+ "list": [
+ {
+ "builtIn": 1,
+ "datasource": {
+ "type": "datasource",
+ "uid": "grafana"
+ },
+ "enable": true,
+ "hide": true,
+ "iconColor": "rgba(0, 211, 255, 1)",
+ "name": "Annotations & Alerts",
+ "target": {
+ "limit": 100,
+ "matchAny": false,
+ "tags": [],
+ "type": "dashboard"
+ },
+ "type": "dashboard"
+ }
+ ]
+ },
+ "description": "UpCloud 4-node cluster cost monitoring powered by OpenCost with custom pricing.",
+ "editable": true,
+ "fiscalYearStartMonth": 0,
+ "graphTooltip": 1,
+ "links": [],
+ "liveNow": false,
+ "panels": [
+ {
+ "collapsed": false,
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 0
+ },
+ "id": 100,
+ "title": "Monthly Cost Overview",
+ "type": "row"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "description": "Monthly CPU cost based on provisioned capacity and OpenCost custom pricing.",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "fixedColor": "green",
+ "mode": "fixed"
+ },
+ "decimals": 2,
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ }
+ ]
+ },
+ "unit": "currencyEUR"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 4,
+ "w": 6,
+ "x": 0,
+ "y": 1
+ },
+ "id": 1,
+ "options": {
+ "colorMode": "value",
+ "graphMode": "none",
+ "justifyMode": "auto",
+ "orientation": "auto",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "textMode": "auto"
+ },
+ "title": "Monthly CPU Cost",
+ "type": "stat",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "expr": "sum(avg(kube_node_status_capacity{resource=\"cpu\", unit=\"core\"}) by (node) * avg(node_cpu_hourly_cost) by (node) * 730 * (1-$useDiscount/100))",
+ "legendFormat": "CPU Cost",
+ "refId": "A"
+ }
+ ]
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "description": "Monthly memory cost based on provisioned capacity and OpenCost custom pricing.",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "fixedColor": "green",
+ "mode": "fixed"
+ },
+ "decimals": 2,
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ }
+ ]
+ },
+ "unit": "currencyEUR"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 4,
+ "w": 6,
+ "x": 6,
+ "y": 1
+ },
+ "id": 2,
+ "options": {
+ "colorMode": "value",
+ "graphMode": "none",
+ "justifyMode": "auto",
+ "orientation": "auto",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "textMode": "auto"
+ },
+ "title": "Monthly Memory Cost",
+ "type": "stat",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "expr": "sum(avg(kube_node_status_capacity{resource=\"memory\", unit=\"byte\"}) by (node) / 1024/1024/1024 * avg(node_ram_hourly_cost) by (node) * 730 * (1-$useDiscount/100))",
+ "legendFormat": "Memory Cost",
+ "refId": "A"
+ }
+ ]
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "description": "Monthly storage cost from PV hourly costs and local disk at $localStorageGBCost/GB.",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "fixedColor": "green",
+ "mode": "fixed"
+ },
+ "decimals": 2,
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ }
+ ]
+ },
+ "unit": "currencyEUR"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 4,
+ "w": 6,
+ "x": 12,
+ "y": 1
+ },
+ "id": 3,
+ "options": {
+ "colorMode": "value",
+ "graphMode": "none",
+ "justifyMode": "auto",
+ "orientation": "auto",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "textMode": "auto"
+ },
+ "title": "Monthly Storage Cost",
+ "type": "stat",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "expr": "sum(avg(pv_hourly_cost) by (persistentvolume) * 730 * avg(kube_persistentvolume_capacity_bytes) by (persistentvolume) / 1024/1024/1024) + (sum(sum(container_fs_limit_bytes{device!=\"tmpfs\", id=\"/\"}) by (instance) / 1024/1024/1024) * $localStorageGBCost OR on() vector(0))",
+ "legendFormat": "Storage Cost",
+ "refId": "A"
+ }
+ ]
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "description": "Total monthly infrastructure cost (CPU + Memory + Storage).",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "fixedColor": "green",
+ "mode": "fixed"
+ },
+ "decimals": 2,
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ }
+ ]
+ },
+ "unit": "currencyEUR"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 4,
+ "w": 6,
+ "x": 18,
+ "y": 1
+ },
+ "id": 4,
+ "options": {
+ "colorMode": "value",
+ "graphMode": "none",
+ "justifyMode": "auto",
+ "orientation": "auto",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "textMode": "auto"
+ },
+ "title": "Total Monthly Cost",
+ "type": "stat",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "expr": "sum(avg(kube_node_status_capacity{resource=\"cpu\", unit=\"core\"}) by (node) * avg(node_cpu_hourly_cost) by (node) * 730 * (1-$useDiscount/100)) + sum(avg(kube_node_status_capacity{resource=\"memory\", unit=\"byte\"}) by (node) / 1024/1024/1024 * avg(node_ram_hourly_cost) by (node) * 730 * (1-$useDiscount/100)) + sum(avg(pv_hourly_cost) by (persistentvolume) * 730 * avg(kube_persistentvolume_capacity_bytes) by (persistentvolume) / 1024/1024/1024) + (sum(sum(container_fs_limit_bytes{device!=\"tmpfs\", id=\"/\"}) by (instance) / 1024/1024/1024) * $localStorageGBCost OR on() vector(0))",
+ "legendFormat": "Total Cost",
+ "refId": "A"
+ }
+ ]
+ },
+ {
+ "collapsed": false,
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 5
+ },
+ "id": 101,
+ "title": "Resource Utilization",
+ "type": "row"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "description": "Percentage of total CPU capacity currently in use.",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "thresholds"
+ },
+ "decimals": 1,
+ "max": 100,
+ "min": 0,
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "yellow",
+ "value": 60
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "percent"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 6,
+ "w": 6,
+ "x": 0,
+ "y": 6
+ },
+ "id": 5,
+ "options": {
+ "minVizHeight": 75,
+ "minVizWidth": 75,
+ "orientation": "auto",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "showThresholdLabels": false,
+ "showThresholdMarkers": true
+ },
+ "title": "CPU Utilization",
+ "type": "gauge",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "expr": "sum(rate(container_cpu_usage_seconds_total{image!=\"\"}[5m])) / sum(kube_node_status_capacity{resource=\"cpu\", unit=\"core\"}) * 100",
+ "legendFormat": "CPU Utilization",
+ "refId": "A"
+ }
+ ]
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "description": "Percentage of total CPU capacity reserved by resource requests.",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "thresholds"
+ },
+ "decimals": 1,
+ "max": 100,
+ "min": 0,
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "yellow",
+ "value": 60
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "percent"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 6,
+ "w": 6,
+ "x": 6,
+ "y": 6
+ },
+ "id": 6,
+ "options": {
+ "minVizHeight": 75,
+ "minVizWidth": 75,
+ "orientation": "auto",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "showThresholdLabels": false,
+ "showThresholdMarkers": true
+ },
+ "title": "CPU Requests",
+ "type": "gauge",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "expr": "sum(kube_pod_container_resource_requests{resource=\"cpu\", unit=\"core\"}) / sum(kube_node_status_capacity{resource=\"cpu\", unit=\"core\"}) * 100",
+ "legendFormat": "CPU Requests",
+ "refId": "A"
+ }
+ ]
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "description": "Percentage of total memory capacity currently in use.",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "thresholds"
+ },
+ "decimals": 1,
+ "max": 100,
+ "min": 0,
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "yellow",
+ "value": 60
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "percent"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 6,
+ "w": 6,
+ "x": 12,
+ "y": 6
+ },
+ "id": 7,
+ "options": {
+ "minVizHeight": 75,
+ "minVizWidth": 75,
+ "orientation": "auto",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "showThresholdLabels": false,
+ "showThresholdMarkers": true
+ },
+ "title": "RAM Utilization",
+ "type": "gauge",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "expr": "sum(container_memory_working_set_bytes{image!=\"\"}) / sum(kube_node_status_capacity{resource=\"memory\", unit=\"byte\"}) * 100",
+ "legendFormat": "RAM Utilization",
+ "refId": "A"
+ }
+ ]
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "description": "Percentage of total memory capacity reserved by resource requests.",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "thresholds"
+ },
+ "decimals": 1,
+ "max": 100,
+ "min": 0,
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "yellow",
+ "value": 60
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "percent"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 6,
+ "w": 6,
+ "x": 18,
+ "y": 6
+ },
+ "id": 8,
+ "options": {
+ "minVizHeight": 75,
+ "minVizWidth": 75,
+ "orientation": "auto",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "showThresholdLabels": false,
+ "showThresholdMarkers": true
+ },
+ "title": "RAM Requests",
+ "type": "gauge",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "expr": "sum(kube_pod_container_resource_requests{resource=\"memory\", unit=\"byte\"}) / sum(kube_node_status_capacity{resource=\"memory\", unit=\"byte\"}) * 100",
+ "legendFormat": "RAM Requests",
+ "refId": "A"
+ }
+ ]
+ },
+ {
+ "collapsed": true,
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 12
+ },
+ "id": 102,
+ "title": "Cost Trends",
+ "type": "row",
+ "panels": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "description": "Hourly cost trend stacked by resource type.",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 30,
+ "gradientMode": "none",
+ "lineInterpolation": "smooth",
+ "lineWidth": 2,
+ "pointSize": 5,
+ "showPoints": "never",
+ "stacking": {
+ "group": "A",
+ "mode": "normal"
+ }
+ },
+ "decimals": 2,
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ }
+ ]
+ },
+ "unit": "currencyEUR"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 0,
+ "y": 13
+ },
+ "id": 9,
+ "options": {
+ "legend": {
+ "calcs": [
+ "mean",
+ "lastNotNull"
+ ],
+ "displayMode": "table",
+ "placement": "bottom"
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "desc"
+ }
+ },
+ "title": "Total Cost Over Time",
+ "type": "timeseries",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "expr": "sum(avg(kube_node_status_capacity{resource=\"cpu\", unit=\"core\"}) by (node) * avg(node_cpu_hourly_cost) by (node))",
+ "legendFormat": "CPU",
+ "refId": "A"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "expr": "sum(avg(kube_node_status_capacity{resource=\"memory\", unit=\"byte\"}) by (node) / 1024/1024/1024 * avg(node_ram_hourly_cost) by (node))",
+ "legendFormat": "Memory",
+ "refId": "B"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "expr": "sum(avg(pv_hourly_cost) by (persistentvolume) * avg(kube_persistentvolume_capacity_bytes) by (persistentvolume) / 1024/1024/1024) + (sum(sum(container_fs_limit_bytes{device!=\"tmpfs\", id=\"/\"}) by (instance) / 1024/1024/1024) * $localStorageGBCost / 730 OR on() vector(0))",
+ "legendFormat": "Storage",
+ "refId": "C"
+ }
+ ]
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "description": "Hourly cost trend broken down by namespace.",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 15,
+ "gradientMode": "none",
+ "lineInterpolation": "smooth",
+ "lineWidth": 2,
+ "pointSize": 5,
+ "showPoints": "never",
+ "stacking": {
+ "group": "A",
+ "mode": "normal"
+ }
+ },
+ "decimals": 4,
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ }
+ ]
+ },
+ "unit": "currencyEUR"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 12,
+ "y": 13
+ },
+ "id": 10,
+ "options": {
+ "legend": {
+ "calcs": [
+ "mean",
+ "lastNotNull"
+ ],
+ "displayMode": "table",
+ "placement": "bottom"
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "desc"
+ }
+ },
+ "title": "Cost by Namespace Over Time",
+ "type": "timeseries",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "expr": "sum(container_cpu_allocation{namespace=~\"$namespace\"} * on(node) group_left() node_cpu_hourly_cost + container_memory_allocation_bytes{namespace=~\"$namespace\"} / 1024/1024/1024 * on(node) group_left() node_ram_hourly_cost) by (namespace)",
+ "legendFormat": "{{namespace}}",
+ "refId": "A"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "collapsed": true,
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 13
+ },
+ "id": 103,
+ "title": "Cost Breakdown",
+ "type": "row",
+ "panels": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "description": "Monthly cost breakdown per node showing CPU and memory costs.",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "thresholds"
+ },
+ "custom": {
+ "align": "auto",
+ "cellOptions": {
+ "type": "auto"
+ },
+ "inspect": false
+ },
+ "decimals": 2,
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ }
+ ]
+ },
+ "unit": "currencyEUR"
+ },
+ "overrides": [
+ {
+ "matcher": {
+ "id": "byName",
+ "options": "Node"
+ },
+ "properties": [
+ {
+ "id": "custom.width",
+ "value": 250
+ }
+ ]
+ }
+ ]
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 0,
+ "y": 14
+ },
+ "id": 11,
+ "options": {
+ "cellHeight": "sm",
+ "footer": {
+ "countRows": false,
+ "enablePagination": false,
+ "fields": "",
+ "reducer": [
+ "sum"
+ ],
+ "show": true
+ },
+ "showHeader": true,
+ "sortBy": [
+ {
+ "desc": true,
+ "displayName": "CPU Cost"
+ }
+ ]
+ },
+ "title": "Monthly Cost by Node",
+ "type": "table",
+ "transformations": [
+ {
+ "id": "seriesToColumns",
+ "options": {
+ "byField": "node"
+ }
+ },
+ {
+ "id": "organize",
+ "options": {
+ "excludeByName": {
+ "Time 1": true,
+ "Time 2": true
+ },
+ "renameByName": {
+ "Value #A": "CPU Cost",
+ "Value #B": "Memory Cost",
+ "node": "Node"
+ }
+ }
+ }
+ ],
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "expr": "avg(kube_node_status_capacity{resource=\"cpu\", unit=\"core\"}) by (node) * avg(node_cpu_hourly_cost) by (node) * 730",
+ "format": "table",
+ "instant": true,
+ "legendFormat": "CPU Cost",
+ "refId": "A"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "expr": "avg(kube_node_status_capacity{resource=\"memory\", unit=\"byte\"}) by (node) / 1024/1024/1024 * avg(node_ram_hourly_cost) by (node) * 730",
+ "format": "table",
+ "instant": true,
+ "legendFormat": "Memory Cost",
+ "refId": "B"
+ }
+ ]
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "description": "Monthly cost split by resource type.",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "decimals": 2,
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ }
+ ]
+ },
+ "unit": "currencyEUR"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 12,
+ "y": 14
+ },
+ "id": 12,
+ "options": {
+ "displayMode": "gradient",
+ "minVizHeight": 10,
+ "minVizWidth": 0,
+ "namePlacement": "auto",
+ "orientation": "horizontal",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "showUnfilled": true,
+ "valueMode": "color"
+ },
+ "title": "Monthly Cost by Resource",
+ "type": "bargauge",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "expr": "sum(avg(kube_node_status_capacity{resource=\"cpu\", unit=\"core\"}) by (node) * avg(node_cpu_hourly_cost) by (node) * 730)",
+ "legendFormat": "CPU",
+ "refId": "A"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "expr": "sum(avg(kube_node_status_capacity{resource=\"memory\", unit=\"byte\"}) by (node) / 1024/1024/1024 * avg(node_ram_hourly_cost) by (node) * 730)",
+ "legendFormat": "Memory",
+ "refId": "B"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "expr": "sum(avg(pv_hourly_cost) by (persistentvolume) * 730 * avg(kube_persistentvolume_capacity_bytes) by (persistentvolume) / 1024/1024/1024) + (sum(sum(container_fs_limit_bytes{device!=\"tmpfs\", id=\"/\"}) by (instance) / 1024/1024/1024) * $localStorageGBCost OR on() vector(0))",
+ "legendFormat": "Storage",
+ "refId": "C"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "collapsed": true,
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 14
+ },
+ "id": 104,
+ "title": "Namespace & Container Costs",
+ "type": "row",
+ "panels": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "description": "Hourly cost distribution across namespaces.",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "decimals": 4,
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ }
+ ]
+ },
+ "unit": "currencyEUR"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 0,
+ "y": 15
+ },
+ "id": 13,
+ "options": {
+ "displayLabels": [
+ "name",
+ "percent"
+ ],
+ "legend": {
+ "displayMode": "table",
+ "placement": "right",
+ "values": [
+ "value",
+ "percent"
+ ]
+ },
+ "pieType": "donut",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "tooltip": {
+ "mode": "single",
+ "sort": "none"
+ }
+ },
+ "title": "Hourly Cost by Namespace",
+ "type": "piechart",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "expr": "sum(container_cpu_allocation * on(node) group_left() node_cpu_hourly_cost + container_memory_allocation_bytes / 1024/1024/1024 * on(node) group_left() node_ram_hourly_cost) by (namespace)",
+ "legendFormat": "{{namespace}}",
+ "refId": "A"
+ }
+ ]
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "description": "Hourly cost distribution across containers in the selected namespace(s).",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "decimals": 4,
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ }
+ ]
+ },
+ "unit": "currencyEUR"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 12,
+ "y": 15
+ },
+ "id": 14,
+ "options": {
+ "displayLabels": [
+ "name",
+ "percent"
+ ],
+ "legend": {
+ "displayMode": "table",
+ "placement": "right",
+ "values": [
+ "value",
+ "percent"
+ ]
+ },
+ "pieType": "donut",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "tooltip": {
+ "mode": "single",
+ "sort": "none"
+ }
+ },
+ "title": "Hourly Cost by Container",
+ "type": "piechart",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "expr": "sum(container_cpu_allocation{namespace=~\"$namespace\"} * on(node) group_left() node_cpu_hourly_cost + container_memory_allocation_bytes{namespace=~\"$namespace\"} / 1024/1024/1024 * on(node) group_left() node_ram_hourly_cost) by (container)",
+ "legendFormat": "{{container}}",
+ "refId": "A"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "collapsed": true,
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 15
+ },
+ "id": 105,
+ "title": "Cost Efficiency",
+ "type": "row",
+ "panels": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "description": "Compare CPU requests against actual usage to identify over-provisioning.",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisLabel": "CPU Cores",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 10,
+ "gradientMode": "none",
+ "lineInterpolation": "smooth",
+ "lineWidth": 2,
+ "pointSize": 5,
+ "showPoints": "never",
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ }
+ },
+ "decimals": 2,
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ }
+ ]
+ },
+ "unit": "short"
+ },
+ "overrides": [
+ {
+ "matcher": {
+ "id": "byRegexp",
+ "options": "/Requested/"
+ },
+ "properties": [
+ {
+ "id": "custom.lineStyle",
+ "value": {
+ "dash": [
+ 10,
+ 10
+ ],
+ "fill": "dash"
+ }
+ },
+ {
+ "id": "custom.fillOpacity",
+ "value": 0
+ }
+ ]
+ }
+ ]
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 0,
+ "y": 16
+ },
+ "id": 15,
+ "options": {
+ "legend": {
+ "calcs": [
+ "mean",
+ "lastNotNull"
+ ],
+ "displayMode": "table",
+ "placement": "bottom"
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "desc"
+ }
+ },
+ "title": "CPU Request vs Actual Usage by Namespace",
+ "type": "timeseries",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "expr": "sum(kube_pod_container_resource_requests{resource=\"cpu\", unit=\"core\", namespace=~\"$namespace\"}) by (namespace)",
+ "legendFormat": "{{namespace}} - Requested",
+ "refId": "A"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "expr": "sum(rate(container_cpu_usage_seconds_total{namespace=~\"$namespace\", image!=\"\"}[5m])) by (namespace)",
+ "legendFormat": "{{namespace}} - Actual",
+ "refId": "B"
+ }
+ ]
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "description": "Compare memory requests against actual usage to identify over-provisioning.",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisLabel": "Memory",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 10,
+ "gradientMode": "none",
+ "lineInterpolation": "smooth",
+ "lineWidth": 2,
+ "pointSize": 5,
+ "showPoints": "never",
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ }
+ },
+ "decimals": 2,
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ }
+ ]
+ },
+ "unit": "bytes"
+ },
+ "overrides": [
+ {
+ "matcher": {
+ "id": "byRegexp",
+ "options": "/Requested/"
+ },
+ "properties": [
+ {
+ "id": "custom.lineStyle",
+ "value": {
+ "dash": [
+ 10,
+ 10
+ ],
+ "fill": "dash"
+ }
+ },
+ {
+ "id": "custom.fillOpacity",
+ "value": 0
+ }
+ ]
+ }
+ ]
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 12,
+ "y": 16
+ },
+ "id": 16,
+ "options": {
+ "legend": {
+ "calcs": [
+ "mean",
+ "lastNotNull"
+ ],
+ "displayMode": "table",
+ "placement": "bottom"
+ },
+ "tooltip": {
+ "mode": "multi",
+ "sort": "desc"
+ }
+ },
+ "title": "Memory Request vs Actual Usage by Namespace",
+ "type": "timeseries",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "expr": "sum(kube_pod_container_resource_requests{resource=\"memory\", unit=\"byte\", namespace=~\"$namespace\"}) by (namespace)",
+ "legendFormat": "{{namespace}} - Requested",
+ "refId": "A"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "expr": "sum(container_memory_working_set_bytes{namespace=~\"$namespace\", image!=\"\"}) by (namespace)",
+ "legendFormat": "{{namespace}} - Actual",
+ "refId": "B"
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "refresh": "30s",
+ "schemaVersion": 38,
+ "tags": [
+ "cost",
+ "opencost",
+ "upcloud"
+ ],
+ "templating": {
+ "list": [
+ {
+ "current": {
+ "selected": false,
+ "text": "Prometheus",
+ "value": "Prometheus"
+ },
+ "hide": 0,
+ "includeAll": false,
+ "multi": false,
+ "name": "datasource",
+ "options": [],
+ "query": "prometheus",
+ "queryValue": "",
+ "refresh": 1,
+ "regex": "",
+ "skipUrlSync": false,
+ "type": "datasource"
+ },
+ {
+ "allValue": ".*",
+ "current": {
+ "selected": true,
+ "text": [
+ "All"
+ ],
+ "value": [
+ "$__all"
+ ]
+ },
+ "datasource": {
+ "type": "prometheus",
+ "uid": "${datasource}"
+ },
+ "definition": "label_values(namespace)",
+ "hide": 0,
+ "includeAll": true,
+ "multi": true,
+ "name": "namespace",
+ "options": [],
+ "query": {
+ "query": "label_values(namespace)",
+ "refId": "StandardVariableQuery"
+ },
+ "refresh": 2,
+ "regex": "",
+ "skipUrlSync": false,
+ "sort": 1,
+ "type": "query"
+ },
+ {
+ "current": {
+ "selected": false,
+ "text": "0",
+ "value": "0"
+ },
+ "hide": 0,
+ "label": "Sustained Use Discount %",
+ "name": "useDiscount",
+ "options": [
+ {
+ "selected": true,
+ "text": "0",
+ "value": "0"
+ }
+ ],
+ "query": "0",
+ "skipUrlSync": false,
+ "type": "textbox"
+ },
+ {
+ "current": {
+ "selected": false,
+ "text": "0.03",
+ "value": "0.03"
+ },
+ "hide": 2,
+ "label": "Local Storage GB Cost",
+ "name": "localStorageGBCost",
+ "options": [
+ {
+ "selected": true,
+ "text": "0.03",
+ "value": "0.03"
+ }
+ ],
+ "query": "0.03",
+ "skipUrlSync": false,
+ "type": "constant"
+ }
+ ]
+ },
+ "time": {
+ "from": "now-7d",
+ "to": "now"
+ },
+ "timepicker": {
+ "refresh_intervals": [
+ "5s",
+ "10s",
+ "30s",
+ "1m",
+ "5m",
+ "15m",
+ "30m",
+ "1h"
+ ],
+ "time_options": [
+ "5m",
+ "15m",
+ "1h",
+ "6h",
+ "12h",
+ "24h",
+ "2d",
+ "7d",
+ "30d"
+ ]
+ },
+ "timezone": "",
+ "title": "Cluster Cost Overview",
+ "uid": "JOUdHGZZz",
+ "version": 1,
+ "weekStart": ""
+}
diff --git a/infra/dashboards/traefik-loki.json b/infra/dashboards/traefik-loki.json
new file mode 100644
index 0000000..113ddfe
--- /dev/null
+++ b/infra/dashboards/traefik-loki.json
@@ -0,0 +1,1192 @@
+{
+ "annotations": {
+ "list": [
+ {
+ "builtIn": 1,
+ "datasource": {
+ "type": "datasource",
+ "uid": "grafana"
+ },
+ "enable": true,
+ "hide": true,
+ "iconColor": "rgba(0, 211, 255, 1)",
+ "name": "Annotations & Alerts",
+ "type": "dashboard"
+ }
+ ]
+ },
+ "description": "Loki version 2 showcase using JSON Traefik access logs.",
+ "editable": true,
+ "fiscalYearStartMonth": 0,
+ "gnetId": 13713,
+ "graphTooltip": 0,
+ "links": [],
+ "panels": [
+ {
+ "datasource": {
+ "type": "loki",
+ "uid": "loki"
+ },
+ "description": "",
+ "gridPos": {
+ "h": 2,
+ "w": 24,
+ "x": 0,
+ "y": 0
+ },
+ "id": 32,
+ "interval": "",
+ "options": {
+ "code": {
+ "language": "plaintext",
+ "showLineNumbers": false,
+ "showMiniMap": false
+ },
+ "content": "
\n

\n
Traefik Dashboard\n
",
+ "mode": "html"
+ },
+ "pluginVersion": "11.0.0",
+ "targets": [
+ {
+ "datasource": {
+ "type": "loki",
+ "uid": "loki"
+ },
+ "expr": "loki_build_info",
+ "format": "table",
+ "instant": false,
+ "interval": "",
+ "legendFormat": "",
+ "refId": "A"
+ }
+ ],
+ "transparent": true,
+ "type": "text"
+ },
+ {
+ "datasource": {
+ "type": "loki",
+ "uid": "loki"
+ },
+ "description": "",
+ "fieldConfig": {
+ "defaults": {
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "purple",
+ "value": null
+ }
+ ]
+ },
+ "unit": "short"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 4,
+ "w": 6,
+ "x": 0,
+ "y": 2
+ },
+ "id": 4,
+ "interval": "1m",
+ "options": {
+ "colorMode": "background",
+ "graphMode": "area",
+ "justifyMode": "auto",
+ "orientation": "auto",
+ "reduceOptions": {
+ "calcs": [
+ "sum"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "showPercentChange": false,
+ "textMode": "value",
+ "wideLayout": true
+ },
+ "pluginVersion": "11.0.0",
+ "targets": [
+ {
+ "datasource": {
+ "type": "loki",
+ "uid": "loki"
+ },
+ "editorMode": "code",
+ "expr": "sum(count_over_time({namespace=\"traefik-system\"} |= \"RequestProtocol\" [$__interval]))",
+ "legendFormat": "",
+ "queryType": "range",
+ "refId": "A"
+ }
+ ],
+ "title": "Total requests ",
+ "transparent": true,
+ "type": "stat"
+ },
+ {
+ "datasource": {
+ "type": "loki",
+ "uid": "loki"
+ },
+ "description": "",
+ "fieldConfig": {
+ "defaults": {
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "light-blue",
+ "value": null
+ }
+ ]
+ },
+ "unit": "short"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 9,
+ "x": 6,
+ "y": 2
+ },
+ "id": 5,
+ "interval": "30s",
+ "options": {
+ "colorMode": "background",
+ "graphMode": "area",
+ "justifyMode": "auto",
+ "orientation": "auto",
+ "reduceOptions": {
+ "calcs": [
+ "sum"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "showPercentChange": false,
+ "textMode": "auto",
+ "wideLayout": true
+ },
+ "pluginVersion": "11.0.0",
+ "targets": [
+ {
+ "datasource": {
+ "type": "loki",
+ "uid": "loki"
+ },
+ "editorMode": "code",
+ "expr": "sum by (OriginStatus) (count_over_time({namespace=\"traefik-system\"}|= \"RequestProtocol\" | json | __error__=\"\" [$__interval]))",
+ "legendFormat": "HTTP Status: {{OriginStatus}}",
+ "queryType": "range",
+ "refId": "A"
+ }
+ ],
+ "title": "Requests per status code",
+ "transparent": true,
+ "type": "stat"
+ },
+ {
+ "datasource": {
+ "type": "loki",
+ "uid": "loki"
+ },
+ "description": "",
+ "fieldConfig": {
+ "defaults": {
+ "mappings": [],
+ "max": 100,
+ "min": 0,
+ "noValue": "0",
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "purple",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "percent"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 4,
+ "w": 4,
+ "x": 15,
+ "y": 2
+ },
+ "id": 19,
+ "interval": "5m",
+ "maxDataPoints": 1,
+ "options": {
+ "colorMode": "background",
+ "graphMode": "none",
+ "justifyMode": "center",
+ "orientation": "auto",
+ "reduceOptions": {
+ "calcs": [
+ "mean"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "showPercentChange": false,
+ "textMode": "value",
+ "wideLayout": true
+ },
+ "pluginVersion": "11.0.0",
+ "targets": [
+ {
+ "datasource": {
+ "type": "loki",
+ "uid": "loki"
+ },
+ "expr": " sum(rate({namespace=\"traefik-system\"} |~ \"RequestProtocol\" | json | OriginStatus >= 400 |__error__=\"\"[$__interval])) / (sum(rate({namespace=\"traefik-system\"} |~ \"RequestProtocol\" | json | __error__=\"\"[$__interval])) / 100)",
+ "legendFormat": "",
+ "refId": "A"
+ }
+ ],
+ "title": "% of 4/5xx ",
+ "transparent": true,
+ "type": "stat"
+ },
+ {
+ "datasource": {
+ "type": "loki",
+ "uid": "loki"
+ },
+ "description": "",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 10,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "never",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "decimals": 0,
+ "mappings": [],
+ "min": 0,
+ "noValue": "0",
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "purple",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ },
+ "unit": "none"
+ },
+ "overrides": [
+ {
+ "matcher": {
+ "id": "byValue",
+ "options": {
+ "op": "gte",
+ "reducer": "allIsZero",
+ "value": 0
+ }
+ },
+ "properties": [
+ {
+ "id": "custom.hideFrom",
+ "value": {
+ "legend": true,
+ "tooltip": true,
+ "viz": false
+ }
+ }
+ ]
+ },
+ {
+ "matcher": {
+ "id": "byValue",
+ "options": {
+ "op": "gte",
+ "reducer": "allIsNull",
+ "value": 0
+ }
+ },
+ "properties": [
+ {
+ "id": "custom.hideFrom",
+ "value": {
+ "legend": true,
+ "tooltip": true,
+ "viz": false
+ }
+ }
+ ]
+ },
+ {
+ "matcher": {
+ "id": "byType",
+ "options": "time"
+ },
+ "properties": [
+ {
+ "id": "custom.axisPlacement",
+ "value": "hidden"
+ }
+ ]
+ }
+ ]
+ },
+ "gridPos": {
+ "h": 4,
+ "w": 5,
+ "x": 19,
+ "y": 2
+ },
+ "id": 36,
+ "interval": "1m",
+ "options": {
+ "legend": {
+ "calcs": [],
+ "displayMode": "list",
+ "placement": "bottom",
+ "showLegend": false
+ },
+ "tooltip": {
+ "maxHeight": 600,
+ "mode": "multi",
+ "sort": "none"
+ }
+ },
+ "pluginVersion": "7.3.6",
+ "targets": [
+ {
+ "datasource": {
+ "type": "loki",
+ "uid": "loki"
+ },
+ "expr": " sum by (OriginStatus,ServiceName) (count_over_time({namespace=\"traefik-system\"} |~ \"RequestProtocol\" | json | OriginStatus >= 400 |__error__=\"\"[$__interval]))",
+ "legendFormat": " {{ServiceName}} / {{OriginStatus}} ",
+ "refId": "A"
+ }
+ ],
+ "title": " 4/5xx Services",
+ "transparent": true,
+ "type": "timeseries"
+ },
+ {
+ "datasource": {
+ "type": "loki",
+ "uid": "loki"
+ },
+ "description": "",
+ "fieldConfig": {
+ "defaults": {
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "purple",
+ "value": null
+ }
+ ]
+ }
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 4,
+ "w": 6,
+ "x": 0,
+ "y": 6
+ },
+ "id": 22,
+ "interval": "5m",
+ "options": {
+ "colorMode": "background",
+ "graphMode": "none",
+ "justifyMode": "auto",
+ "orientation": "auto",
+ "reduceOptions": {
+ "calcs": [
+ "mean"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "showPercentChange": false,
+ "textMode": "value",
+ "wideLayout": true
+ },
+ "pluginVersion": "11.0.0",
+ "targets": [
+ {
+ "datasource": {
+ "type": "loki",
+ "uid": "loki"
+ },
+ "expr": "count(sum by (ClientHost) (count_over_time({namespace=\"traefik-system\"}|= \"RequestProtocol\" | json | __error__=\"\" [$__interval])))",
+ "legendFormat": "",
+ "refId": "A"
+ }
+ ],
+ "title": "Users right now",
+ "transparent": true,
+ "type": "stat"
+ },
+ {
+ "datasource": {
+ "type": "loki",
+ "uid": "loki"
+ },
+ "description": "",
+ "fieldConfig": {
+ "defaults": {
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "purple",
+ "value": null
+ }
+ ]
+ },
+ "unit": "decbytes"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 4,
+ "w": 9,
+ "x": 15,
+ "y": 6
+ },
+ "id": 8,
+ "interval": "1m",
+ "options": {
+ "colorMode": "background",
+ "graphMode": "none",
+ "justifyMode": "center",
+ "orientation": "auto",
+ "reduceOptions": {
+ "calcs": [
+ "sum"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "showPercentChange": false,
+ "textMode": "value",
+ "wideLayout": true
+ },
+ "pluginVersion": "11.0.0",
+ "targets": [
+ {
+ "datasource": {
+ "type": "loki",
+ "uid": "loki"
+ },
+ "expr": "sum_over_time({namespace=\"traefik-system\"}|= \"RequestProtocol\" | json | OriginStatus=200 | unwrap DownstreamContentSize | __error__=\"\" [$__interval])",
+ "legendFormat": "Bytes sent",
+ "refId": "A"
+ }
+ ],
+ "title": "Total Bytes Sent",
+ "transformations": [
+ {
+ "id": "reduce",
+ "options": {
+ "reducers": [
+ "sum"
+ ]
+ }
+ },
+ {
+ "id": "organize",
+ "options": {
+ "excludeByName": {},
+ "indexByName": {},
+ "renameByName": {
+ "Total": "Bytes Sent"
+ }
+ }
+ }
+ ],
+ "transparent": true,
+ "type": "stat"
+ },
+ {
+ "datasource": {
+ "type": "loki",
+ "uid": "loki"
+ },
+ "description": "",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ }
+ },
+ "decimals": 0,
+ "mappings": [],
+ "unit": "short"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 8,
+ "x": 0,
+ "y": 10
+ },
+ "id": 33,
+ "interval": "5m",
+ "maxDataPoints": 3,
+ "options": {
+ "legend": {
+ "calcs": [],
+ "displayMode": "table",
+ "placement": "right",
+ "showLegend": true,
+ "values": [
+ "value",
+ "percent"
+ ]
+ },
+ "pieType": "pie",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "tooltip": {
+ "maxHeight": 600,
+ "mode": "single",
+ "sort": "none"
+ }
+ },
+ "pluginVersion": "7.3.4",
+ "targets": [
+ {
+ "datasource": {
+ "type": "loki",
+ "uid": "loki"
+ },
+ "expr": "sum by (RouterName) (count_over_time({namespace=\"traefik-system\"}|= \"RequestProtocol\" | json | __error__=\"\" [$__interval]))",
+ "legendFormat": "{{RouterName}}",
+ "refId": "A"
+ }
+ ],
+ "title": "Requests Route",
+ "transparent": true,
+ "type": "piechart"
+ },
+ {
+ "datasource": {
+ "type": "tempo",
+ "uid": "tempo"
+ },
+ "gridPos": {
+ "h": 17,
+ "w": 16,
+ "x": 8,
+ "y": 10
+ },
+ "id": 37,
+ "options": {
+ "edges": {},
+ "nodes": {}
+ },
+ "targets": [
+ {
+ "datasource": {
+ "type": "tempo",
+ "uid": "tempo"
+ },
+ "limit": 20,
+ "queryType": "serviceMap",
+ "refId": "A",
+ "tableType": "traces"
+ }
+ ],
+ "title": "Service graph",
+ "type": "nodeGraph"
+ },
+ {
+ "datasource": {
+ "type": "loki",
+ "uid": "loki"
+ },
+ "description": "",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 90,
+ "gradientMode": "opacity",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "never",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "line+area"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "transparent",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 0.3
+ }
+ ]
+ },
+ "unit": "ns"
+ },
+ "overrides": [
+ {
+ "matcher": {
+ "id": "byName",
+ "options": "95th percentile"
+ },
+ "properties": [
+ {
+ "id": "color",
+ "value": {
+ "fixedColor": "blue",
+ "mode": "fixed"
+ }
+ }
+ ]
+ },
+ {
+ "matcher": {
+ "id": "byName",
+ "options": "max latency"
+ },
+ "properties": [
+ {
+ "id": "color",
+ "value": {
+ "fixedColor": "super-light-blue",
+ "mode": "fixed"
+ }
+ }
+ ]
+ },
+ {
+ "matcher": {
+ "id": "byName",
+ "options": "max latency"
+ },
+ "properties": [
+ {
+ "id": "custom.fillOpacity",
+ "value": 30
+ },
+ {
+ "id": "custom.lineStyle",
+ "value": {
+ "dash": [
+ 10,
+ 10
+ ],
+ "fill": "dash"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ "gridPos": {
+ "h": 9,
+ "w": 8,
+ "x": 0,
+ "y": 18
+ },
+ "id": 16,
+ "interval": "30s",
+ "options": {
+ "legend": {
+ "calcs": [
+ "max"
+ ],
+ "displayMode": "list",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "maxHeight": 600,
+ "mode": "multi",
+ "sort": "none"
+ }
+ },
+ "pluginVersion": "7.3.6",
+ "targets": [
+ {
+ "datasource": {
+ "type": "loki",
+ "uid": "loki"
+ },
+ "expr": "quantile_over_time(0.95,{namespace=\"traefik-system\"} |= \"RequestProtocol\"| json | unwrap Duration | __error__=\"\" [$__interval]) by (ServiceName)",
+ "hide": false,
+ "legendFormat": " {{ ServiceName }}",
+ "refId": "C"
+ }
+ ],
+ "title": "95th percentile of Request Time",
+ "transparent": true,
+ "type": "timeseries"
+ },
+ {
+ "datasource": {
+ "type": "loki",
+ "uid": "loki"
+ },
+ "description": "",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 90,
+ "gradientMode": "opacity",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "never",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "line+area"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "transparent",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 0.3
+ }
+ ]
+ },
+ "unit": "ns"
+ },
+ "overrides": [
+ {
+ "matcher": {
+ "id": "byName",
+ "options": "95th percentile"
+ },
+ "properties": [
+ {
+ "id": "color",
+ "value": {
+ "fixedColor": "blue",
+ "mode": "fixed"
+ }
+ }
+ ]
+ },
+ {
+ "matcher": {
+ "id": "byName",
+ "options": "max latency"
+ },
+ "properties": [
+ {
+ "id": "color",
+ "value": {
+ "fixedColor": "super-light-blue",
+ "mode": "fixed"
+ }
+ }
+ ]
+ },
+ {
+ "matcher": {
+ "id": "byName",
+ "options": "max latency"
+ },
+ "properties": [
+ {
+ "id": "custom.fillOpacity",
+ "value": 30
+ },
+ {
+ "id": "custom.lineStyle",
+ "value": {
+ "dash": [
+ 10,
+ 10
+ ],
+ "fill": "dash"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ "gridPos": {
+ "h": 9,
+ "w": 8,
+ "x": 0,
+ "y": 27
+ },
+ "id": 34,
+ "interval": "30s",
+ "options": {
+ "legend": {
+ "calcs": [],
+ "displayMode": "list",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "maxHeight": 600,
+ "mode": "multi",
+ "sort": "none"
+ }
+ },
+ "pluginVersion": "7.3.6",
+ "targets": [
+ {
+ "datasource": {
+ "type": "loki",
+ "uid": "loki"
+ },
+ "expr": "max by (ServiceName) (max_over_time({namespace=\"traefik-system\"} |= \"RequestProtocol\" |json | unwrap Duration | __error__=\"\" [$__interval]))",
+ "hide": false,
+ "legendFormat": "{{ ServiceName}}",
+ "refId": "D"
+ }
+ ],
+ "title": "Max Age of Request Time",
+ "transparent": true,
+ "type": "timeseries"
+ },
+ {
+ "datasource": {
+ "type": "loki",
+ "uid": "loki"
+ },
+ "gridPos": {
+ "h": 16,
+ "w": 16,
+ "x": 8,
+ "y": 27
+ },
+ "id": 11,
+ "interval": "",
+ "options": {
+ "dedupStrategy": "none",
+ "enableLogDetails": true,
+ "prettifyLogMessage": false,
+ "showCommonLabels": false,
+ "showLabels": false,
+ "showTime": true,
+ "sortOrder": "Descending",
+ "wrapLogMessage": false
+ },
+ "targets": [
+ {
+ "datasource": {
+ "type": "loki",
+ "uid": "loki"
+ },
+ "expr": "{namespace=\"traefik-system\"} |= \"RequestProtocol\" | json | line_format \"{{.OriginStatus}} {{.RequestMethod}} {{.RequestAddr}}{{.RequestPath}} -> {{.ServiceAddr}}\"",
+ "legendFormat": "",
+ "refId": "A"
+ }
+ ],
+ "title": "Logs",
+ "transparent": true,
+ "type": "logs"
+ },
+ {
+ "datasource": {
+ "type": "loki",
+ "uid": "loki"
+ },
+ "description": "",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 90,
+ "gradientMode": "opacity",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "never",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "line+area"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "transparent",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 0.3
+ }
+ ]
+ },
+ "unit": "decbytes"
+ },
+ "overrides": [
+ {
+ "matcher": {
+ "id": "byName",
+ "options": "95th percentile"
+ },
+ "properties": [
+ {
+ "id": "color",
+ "value": {
+ "fixedColor": "blue",
+ "mode": "fixed"
+ }
+ }
+ ]
+ },
+ {
+ "matcher": {
+ "id": "byName",
+ "options": "max latency"
+ },
+ "properties": [
+ {
+ "id": "color",
+ "value": {
+ "fixedColor": "super-light-blue",
+ "mode": "fixed"
+ }
+ }
+ ]
+ },
+ {
+ "matcher": {
+ "id": "byName",
+ "options": "max latency"
+ },
+ "properties": [
+ {
+ "id": "custom.fillOpacity",
+ "value": 30
+ },
+ {
+ "id": "custom.lineStyle",
+ "value": {
+ "dash": [
+ 10,
+ 10
+ ],
+ "fill": "dash"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ "gridPos": {
+ "h": 9,
+ "w": 8,
+ "x": 0,
+ "y": 36
+ },
+ "id": 35,
+ "interval": "30s",
+ "options": {
+ "legend": {
+ "calcs": [],
+ "displayMode": "list",
+ "placement": "bottom",
+ "showLegend": true
+ },
+ "tooltip": {
+ "maxHeight": 600,
+ "mode": "multi",
+ "sort": "none"
+ }
+ },
+ "pluginVersion": "7.3.6",
+ "targets": [
+ {
+ "datasource": {
+ "type": "loki",
+ "uid": "loki"
+ },
+ "expr": "sum by (ServiceName) (sum_over_time({namespace=\"traefik-system\"} |= \"RequestProtocol\" |json | unwrap RequestContentSize | __error__=\"\" [$__interval]))",
+ "hide": false,
+ "legendFormat": "{{ ServiceName}}",
+ "refId": "D"
+ }
+ ],
+ "title": "Requests Size",
+ "transparent": true,
+ "type": "timeseries"
+ }
+ ],
+ "refresh": false,
+ "schemaVersion": 39,
+ "tags": [],
+ "templating": {
+ "list": []
+ },
+ "time": {
+ "from": "now-12h",
+ "to": "now"
+ },
+ "timeRangeUpdatedDuringEditOrView": false,
+ "timepicker": {
+ "refresh_intervals": [
+ "10s",
+ "30s",
+ "1m",
+ "5m",
+ "15m",
+ "30m",
+ "1h",
+ "2h",
+ "1d"
+ ]
+ },
+ "timezone": "",
+ "title": "Traefik Via Loki",
+ "uid": "fJarCeaGk",
+ "version": 1,
+ "weekStart": ""
+}
diff --git a/infra/dashboards/trivy.json b/infra/dashboards/trivy.json
new file mode 100644
index 0000000..79d80eb
--- /dev/null
+++ b/infra/dashboards/trivy.json
@@ -0,0 +1,931 @@
+{
+ "annotations": {
+ "list": [
+ {
+ "builtIn": 1,
+ "datasource": {
+ "type": "datasource",
+ "uid": "grafana"
+ },
+ "enable": true,
+ "hide": true,
+ "iconColor": "rgba(0, 211, 255, 1)",
+ "name": "Annotations & Alerts",
+ "target": {
+ "limit": 100,
+ "matchAny": false,
+ "tags": [],
+ "type": "dashboard"
+ },
+ "type": "dashboard"
+ }
+ ]
+ },
+ "description": "Monitore Trivy Image Vulnerabilities.\r\n\r\nBased on https://grafana.com/grafana/dashboards/17080-trivy-image-vulnerabilities/ and https://grafana.com/grafana/dashboards/16652-trivy-operator-reports/.",
+ "editable": true,
+ "fiscalYearStartMonth": 0,
+ "gnetId": 17214,
+ "graphTooltip": 1,
+ "id": 8,
+ "links": [],
+ "liveNow": false,
+ "panels": [
+ {
+ "collapsed": false,
+ "datasource": {
+ "type": "datasource",
+ "uid": "grafana"
+ },
+ "gridPos": {
+ "h": 1,
+ "w": 24,
+ "x": 0,
+ "y": 0
+ },
+ "id": 43,
+ "panels": [],
+ "targets": [
+ {
+ "datasource": {
+ "type": "datasource",
+ "uid": "grafana"
+ },
+ "refId": "A"
+ }
+ ],
+ "title": "Image Vulnerabilities",
+ "type": "row"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "thresholds"
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "purple",
+ "value": 1
+ }
+ ]
+ },
+ "unit": "none"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 3,
+ "w": 4,
+ "x": 0,
+ "y": 1
+ },
+ "id": 52,
+ "options": {
+ "colorMode": "value",
+ "graphMode": "area",
+ "justifyMode": "auto",
+ "orientation": "auto",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "showPercentChange": false,
+ "text": {},
+ "textMode": "auto",
+ "wideLayout": true
+ },
+ "pluginVersion": "11.0.0",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "editorMode": "code",
+ "exemplar": false,
+ "expr": "sum(trivy_vulnerability_id{severity=\"Unknown\", namespace=~\"$namespace\"})",
+ "instant": true,
+ "interval": "",
+ "legendFormat": "",
+ "refId": "A"
+ }
+ ],
+ "title": "UNKNOWN",
+ "type": "stat"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "thresholds"
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "blue",
+ "value": 1
+ }
+ ]
+ },
+ "unit": "none"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 3,
+ "w": 4,
+ "x": 4,
+ "y": 1
+ },
+ "id": 60,
+ "options": {
+ "colorMode": "value",
+ "graphMode": "area",
+ "justifyMode": "auto",
+ "orientation": "auto",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "showPercentChange": false,
+ "textMode": "auto",
+ "wideLayout": true
+ },
+ "pluginVersion": "11.0.0",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "editorMode": "code",
+ "exemplar": false,
+ "expr": "sum(trivy_vulnerability_id{severity=\"Low\", namespace=~\"$namespace\"})",
+ "format": "time_series",
+ "hide": false,
+ "instant": true,
+ "interval": "",
+ "legendFormat": "",
+ "refId": "A"
+ }
+ ],
+ "title": "LOW",
+ "type": "stat"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "thresholds"
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "yellow",
+ "value": 1
+ }
+ ]
+ },
+ "unit": "none"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 3,
+ "w": 4,
+ "x": 8,
+ "y": 1
+ },
+ "id": 49,
+ "options": {
+ "colorMode": "value",
+ "graphMode": "area",
+ "justifyMode": "auto",
+ "orientation": "auto",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "showPercentChange": false,
+ "textMode": "auto",
+ "wideLayout": true
+ },
+ "pluginVersion": "11.0.0",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "editorMode": "code",
+ "exemplar": false,
+ "expr": "sum(trivy_vulnerability_id{severity=\"Medium\", namespace=~\"$namespace\"})",
+ "instant": true,
+ "interval": "",
+ "legendFormat": "",
+ "refId": "A"
+ }
+ ],
+ "title": "MEDIUM",
+ "type": "stat"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "thresholds"
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "orange",
+ "value": 1
+ }
+ ]
+ },
+ "unit": "none"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 3,
+ "w": 4,
+ "x": 12,
+ "y": 1
+ },
+ "id": 50,
+ "options": {
+ "colorMode": "value",
+ "graphMode": "area",
+ "justifyMode": "auto",
+ "orientation": "auto",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "showPercentChange": false,
+ "textMode": "auto",
+ "wideLayout": true
+ },
+ "pluginVersion": "11.0.0",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "editorMode": "code",
+ "exemplar": false,
+ "expr": "sum(trivy_vulnerability_id{severity=\"High\", namespace=~\"$namespace\"})",
+ "instant": true,
+ "interval": "",
+ "legendFormat": "",
+ "refId": "A"
+ }
+ ],
+ "title": "HIGH",
+ "type": "stat"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "thresholds"
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "red",
+ "value": 1
+ }
+ ]
+ },
+ "unit": "none"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 3,
+ "w": 4,
+ "x": 16,
+ "y": 1
+ },
+ "id": 51,
+ "options": {
+ "colorMode": "value",
+ "graphMode": "area",
+ "justifyMode": "auto",
+ "orientation": "auto",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "showPercentChange": false,
+ "textMode": "auto",
+ "wideLayout": true
+ },
+ "pluginVersion": "11.0.0",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "editorMode": "code",
+ "exemplar": false,
+ "expr": "sum(trivy_vulnerability_id{severity=\"Critical\", namespace=~\"$namespace\"})",
+ "instant": true,
+ "interval": "",
+ "legendFormat": "",
+ "refId": "A"
+ }
+ ],
+ "title": "CRITICAL",
+ "type": "stat"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "thresholds"
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "text",
+ "value": 1
+ }
+ ]
+ },
+ "unit": "none"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 3,
+ "w": 4,
+ "x": 20,
+ "y": 1
+ },
+ "id": 39,
+ "options": {
+ "colorMode": "value",
+ "graphMode": "area",
+ "justifyMode": "auto",
+ "orientation": "auto",
+ "reduceOptions": {
+ "calcs": [
+ "lastNotNull"
+ ],
+ "fields": "",
+ "values": false
+ },
+ "showPercentChange": false,
+ "textMode": "auto",
+ "wideLayout": true
+ },
+ "pluginVersion": "11.0.0",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "editorMode": "code",
+ "exemplar": false,
+ "expr": "sum(trivy_vulnerability_id{namespace=~\"$namespace\"})",
+ "instant": true,
+ "interval": "",
+ "legendFormat": "",
+ "refId": "A"
+ }
+ ],
+ "title": "TOTAL",
+ "type": "stat"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 15,
+ "gradientMode": "opacity",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineStyle": {
+ "fill": "solid"
+ },
+ "lineWidth": 2,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "never",
+ "spanNulls": true,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "blue",
+ "value": 1
+ }
+ ]
+ },
+ "unit": "none"
+ },
+ "overrides": [
+ {
+ "__systemRef": "hideSeriesFrom",
+ "matcher": {
+ "id": "byNames",
+ "options": {
+ "mode": "exclude",
+ "names": [
+ "kube-system"
+ ],
+ "prefix": "All except:",
+ "readOnly": true
+ }
+ },
+ "properties": [
+ {
+ "id": "custom.hideFrom",
+ "value": {
+ "legend": false,
+ "tooltip": false,
+ "viz": true
+ }
+ }
+ ]
+ }
+ ]
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 0,
+ "y": 4
+ },
+ "id": 58,
+ "options": {
+ "legend": {
+ "calcs": [],
+ "displayMode": "table",
+ "placement": "right",
+ "showLegend": true
+ },
+ "tooltip": {
+ "maxHeight": 600,
+ "mode": "single",
+ "sort": "none"
+ }
+ },
+ "pluginVersion": "8.5.0",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "editorMode": "code",
+ "exemplar": false,
+ "expr": "sum(trivy_vulnerability_id{namespace=~\"$namespace\"}) by (namespace)",
+ "instant": false,
+ "interval": "",
+ "legendFormat": "{{namespace}}",
+ "range": true,
+ "refId": "A"
+ }
+ ],
+ "title": "Image Vulnerabilities by namespace",
+ "type": "timeseries"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisBorderShow": false,
+ "axisCenteredZero": false,
+ "axisColorMode": "text",
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 15,
+ "gradientMode": "opacity",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "insertNulls": false,
+ "lineInterpolation": "linear",
+ "lineWidth": 2,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "never",
+ "spanNulls": true,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ },
+ {
+ "color": "blue",
+ "value": 1
+ }
+ ]
+ },
+ "unit": "none"
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 12,
+ "y": 4
+ },
+ "id": 61,
+ "options": {
+ "legend": {
+ "calcs": [],
+ "displayMode": "table",
+ "placement": "right",
+ "showLegend": true
+ },
+ "tooltip": {
+ "maxHeight": 600,
+ "mode": "multi",
+ "sort": "desc"
+ }
+ },
+ "pluginVersion": "8.5.0",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "editorMode": "code",
+ "exemplar": false,
+ "expr": "sum(trivy_vulnerability_id{namespace=~\"$namespace\"}) by (severity)",
+ "instant": false,
+ "interval": "",
+ "legendFormat": "{{severity}}",
+ "range": true,
+ "refId": "A"
+ }
+ ],
+ "title": "Image Vulnerabilities by severity",
+ "type": "timeseries"
+ },
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "description": "",
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "fixedColor": "transparent",
+ "mode": "fixed"
+ },
+ "custom": {
+ "align": "left",
+ "cellOptions": {
+ "mode": "basic",
+ "type": "color-background"
+ },
+ "filterable": true,
+ "inspect": false
+ },
+ "links": [
+ {
+ "targetBlank": true,
+ "title": "Go to CVE",
+ "url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=${__data.fields.vuln_id}"
+ }
+ ],
+ "mappings": [
+ {
+ "options": {
+ "CRITICAL": {
+ "color": "dark-red",
+ "index": 0
+ },
+ "HIGH": {
+ "color": "yellow",
+ "index": 1
+ },
+ "LOW": {
+ "color": "dark-blue",
+ "index": 3
+ },
+ "MEDIUM": {
+ "color": "dark-orange",
+ "index": 2
+ },
+ "UNKNOWN": {
+ "color": "super-light-blue",
+ "index": 4
+ }
+ },
+ "type": "value"
+ }
+ ],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green",
+ "value": null
+ }
+ ]
+ },
+ "unit": "short"
+ },
+ "overrides": [
+ {
+ "matcher": {
+ "id": "byName",
+ "options": "namespace"
+ },
+ "properties": [
+ {
+ "id": "custom.width"
+ }
+ ]
+ },
+ {
+ "matcher": {
+ "id": "byName",
+ "options": "pod"
+ },
+ "properties": [
+ {
+ "id": "custom.width"
+ }
+ ]
+ }
+ ]
+ },
+ "gridPos": {
+ "h": 10,
+ "w": 24,
+ "x": 0,
+ "y": 12
+ },
+ "id": 67,
+ "options": {
+ "cellHeight": "sm",
+ "footer": {
+ "countRows": false,
+ "fields": "",
+ "reducer": [
+ "sum"
+ ],
+ "show": false
+ },
+ "frameIndex": 2,
+ "showHeader": true,
+ "sortBy": [
+ {
+ "desc": false,
+ "displayName": "severity"
+ }
+ ]
+ },
+ "pluginVersion": "11.0.0",
+ "targets": [
+ {
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "editorMode": "code",
+ "exemplar": false,
+ "expr": "sum(trivy_vulnerability_id{namespace=~\"$namespace\"}) without (namespace, last_modified_date, instance, job, endpoint, service, container, image_digest, resource, resource_name)",
+ "format": "table",
+ "instant": true,
+ "interval": "",
+ "legendFormat": "",
+ "refId": "A"
+ }
+ ],
+ "title": "Image by CVE",
+ "transformations": [
+ {
+ "id": "organize",
+ "options": {
+ "excludeByName": {
+ "Time": true,
+ "Value": true,
+ "instance": true,
+ "job": true
+ },
+ "indexByName": {
+ "Time": 10,
+ "Value": 9,
+ "image_digest": 7,
+ "image_registry": 4,
+ "image_repository": 5,
+ "image_tag": 6,
+ "name": 8,
+ "namespace": 2,
+ "pod": 3,
+ "severity": 0,
+ "vuln_id": 1
+ },
+ "renameByName": {
+ "image_digest": "",
+ "name": "source workload"
+ }
+ }
+ }
+ ],
+ "type": "table"
+ }
+ ],
+ "refresh": "30s",
+ "schemaVersion": 39,
+ "tags": [
+ "Prometheus",
+ "Addons",
+ "Trivy"
+ ],
+ "templating": {
+ "list": [
+ {
+ "current": {
+ "selected": true,
+ "text": [
+ "kube-system"
+ ],
+ "value": [
+ "kube-system"
+ ]
+ },
+ "datasource": {
+ "type": "prometheus",
+ "uid": "PBFA97CFB590B2093"
+ },
+ "definition": "label_values(trivy_vulnerability_id{job=\"trivy-operator\"}, namespace)",
+ "hide": 0,
+ "includeAll": false,
+ "label": "namespace",
+ "multi": true,
+ "name": "namespace",
+ "options": [],
+ "query": {
+ "query": "label_values(trivy_vulnerability_id{job=\"trivy-operator\"}, namespace)",
+ "refId": "StandardVariableQuery"
+ },
+ "refresh": 2,
+ "regex": "",
+ "skipUrlSync": false,
+ "sort": 1,
+ "type": "query"
+ }
+ ]
+ },
+ "time": {
+ "from": "now-3h",
+ "to": "now"
+ },
+ "timeRangeUpdatedDuringEditOrView": false,
+ "timepicker": {},
+ "timezone": "",
+ "title": "Trivy Operator / Image Vulnerability",
+ "uid": "trivy_starboard_operator",
+ "version": 7,
+ "weekStart": ""
+}
diff --git a/infra/grafana-dashboards.yaml b/infra/grafana-dashboards.yaml
new file mode 100644
index 0000000..782d8bf
--- /dev/null
+++ b/infra/grafana-dashboards.yaml
@@ -0,0 +1,34 @@
+apiVersion: argoproj.io/v1alpha1
+kind: Application
+metadata:
+ name: grafana-dashboards
+ namespace: argocd
+ annotations:
+ argocd.argoproj.io/sync-wave: "2"
+ labels:
+ app.kubernetes.io/name: grafana-dashboards
+ app.kubernetes.io/part-of: monitoring
+ app.kubernetes.io/managed-by: argocd
+ finalizers:
+ - resources-finalizer.argocd.argoproj.io
+spec:
+ project: default
+
+ source:
+ repoURL: git@github.com:fortedigital/sturdy-adventure.git
+ targetRevision: HEAD
+ path: infra/dashboards
+
+ destination:
+ server: https://kubernetes.default.svc
+ namespace: monitoring
+
+ syncPolicy:
+ automated:
+ prune: true
+ selfHeal: true
+ allowEmpty: false
+ syncOptions:
+ - CreateNamespace=true
+ - Validate=true
+ - ServerSideApply=true
diff --git a/infra/kyverno.yaml b/infra/kyverno.yaml
index 77e3ac8..ebc2aa5 100644
--- a/infra/kyverno.yaml
+++ b/infra/kyverno.yaml
@@ -39,6 +39,10 @@ spec:
targetRevision: v3.7.0 # Update to latest stable version
helm:
releaseName: kyverno
+ valuesObject:
+ grafana:
+ enabled: true
+ namespace: monitoring
destination:
server: https://kubernetes.default.svc
diff --git a/infra/values/grafana-values.yaml b/infra/values/grafana-values.yaml
index b8cd033..d6acbcf 100644
--- a/infra/values/grafana-values.yaml
+++ b/infra/values/grafana-values.yaml
@@ -48,6 +48,16 @@ datasources:
enabled: true
serviceMap:
datasourceUid: Prometheus
+
+sidecar:
+ dashboards:
+ enabled: true
+ label: grafana_dashboard
+ labelValue: "1"
+ folder: /tmp/dashboards
+ provider:
+ foldersFromFilesStructure: false
+
dashboardProviders:
dashboardproviders.yaml:
apiVersion: 1
@@ -66,2867 +76,3 @@ dashboards:
gnetId: 15758
revision: 1
datasource: Prometheus
- trivy:
- json: |
- {
- "annotations": {
- "list": [
- {
- "builtIn": 1,
- "datasource": {
- "type": "datasource",
- "uid": "grafana"
- },
- "enable": true,
- "hide": true,
- "iconColor": "rgba(0, 211, 255, 1)",
- "name": "Annotations & Alerts",
- "target": {
- "limit": 100,
- "matchAny": false,
- "tags": [],
- "type": "dashboard"
- },
- "type": "dashboard"
- }
- ]
- },
- "description": "Monitore Trivy Image Vulnerabilities.\r\n\r\nBased on https://grafana.com/grafana/dashboards/17080-trivy-image-vulnerabilities/ and https://grafana.com/grafana/dashboards/16652-trivy-operator-reports/.",
- "editable": true,
- "fiscalYearStartMonth": 0,
- "gnetId": 17214,
- "graphTooltip": 1,
- "id": 8,
- "links": [],
- "liveNow": false,
- "panels": [
- {
- "collapsed": false,
- "datasource": {
- "type": "datasource",
- "uid": "grafana"
- },
- "gridPos": {
- "h": 1,
- "w": 24,
- "x": 0,
- "y": 0
- },
- "id": 43,
- "panels": [],
- "targets": [
- {
- "datasource": {
- "type": "datasource",
- "uid": "grafana"
- },
- "refId": "A"
- }
- ],
- "title": "Image Vulnerabilities",
- "type": "row"
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "PBFA97CFB590B2093"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "thresholds"
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "purple",
- "value": 1
- }
- ]
- },
- "unit": "none"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 3,
- "w": 4,
- "x": 0,
- "y": 1
- },
- "id": 52,
- "options": {
- "colorMode": "value",
- "graphMode": "area",
- "justifyMode": "auto",
- "orientation": "auto",
- "reduceOptions": {
- "calcs": [
- "lastNotNull"
- ],
- "fields": "",
- "values": false
- },
- "showPercentChange": false,
- "text": {},
- "textMode": "auto",
- "wideLayout": true
- },
- "pluginVersion": "11.0.0",
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "PBFA97CFB590B2093"
- },
- "editorMode": "code",
- "exemplar": false,
- "expr": "sum(trivy_vulnerability_id{severity=\"Unknown\", namespace=~\"$namespace\"})",
- "instant": true,
- "interval": "",
- "legendFormat": "",
- "refId": "A"
- }
- ],
- "title": "UNKNOWN",
- "type": "stat"
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "PBFA97CFB590B2093"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "thresholds"
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "blue",
- "value": 1
- }
- ]
- },
- "unit": "none"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 3,
- "w": 4,
- "x": 4,
- "y": 1
- },
- "id": 60,
- "options": {
- "colorMode": "value",
- "graphMode": "area",
- "justifyMode": "auto",
- "orientation": "auto",
- "reduceOptions": {
- "calcs": [
- "lastNotNull"
- ],
- "fields": "",
- "values": false
- },
- "showPercentChange": false,
- "textMode": "auto",
- "wideLayout": true
- },
- "pluginVersion": "11.0.0",
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "PBFA97CFB590B2093"
- },
- "editorMode": "code",
- "exemplar": false,
- "expr": "sum(trivy_vulnerability_id{severity=\"Low\", namespace=~\"$namespace\"})",
- "format": "time_series",
- "hide": false,
- "instant": true,
- "interval": "",
- "legendFormat": "",
- "refId": "A"
- }
- ],
- "title": "LOW",
- "type": "stat"
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "PBFA97CFB590B2093"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "thresholds"
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "yellow",
- "value": 1
- }
- ]
- },
- "unit": "none"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 3,
- "w": 4,
- "x": 8,
- "y": 1
- },
- "id": 49,
- "options": {
- "colorMode": "value",
- "graphMode": "area",
- "justifyMode": "auto",
- "orientation": "auto",
- "reduceOptions": {
- "calcs": [
- "lastNotNull"
- ],
- "fields": "",
- "values": false
- },
- "showPercentChange": false,
- "textMode": "auto",
- "wideLayout": true
- },
- "pluginVersion": "11.0.0",
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "PBFA97CFB590B2093"
- },
- "editorMode": "code",
- "exemplar": false,
- "expr": "sum(trivy_vulnerability_id{severity=\"Medium\", namespace=~\"$namespace\"})",
- "instant": true,
- "interval": "",
- "legendFormat": "",
- "refId": "A"
- }
- ],
- "title": "MEDIUM",
- "type": "stat"
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "PBFA97CFB590B2093"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "thresholds"
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "orange",
- "value": 1
- }
- ]
- },
- "unit": "none"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 3,
- "w": 4,
- "x": 12,
- "y": 1
- },
- "id": 50,
- "options": {
- "colorMode": "value",
- "graphMode": "area",
- "justifyMode": "auto",
- "orientation": "auto",
- "reduceOptions": {
- "calcs": [
- "lastNotNull"
- ],
- "fields": "",
- "values": false
- },
- "showPercentChange": false,
- "textMode": "auto",
- "wideLayout": true
- },
- "pluginVersion": "11.0.0",
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "PBFA97CFB590B2093"
- },
- "editorMode": "code",
- "exemplar": false,
- "expr": "sum(trivy_vulnerability_id{severity=\"High\", namespace=~\"$namespace\"})",
- "instant": true,
- "interval": "",
- "legendFormat": "",
- "refId": "A"
- }
- ],
- "title": "HIGH",
- "type": "stat"
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "PBFA97CFB590B2093"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "thresholds"
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "red",
- "value": 1
- }
- ]
- },
- "unit": "none"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 3,
- "w": 4,
- "x": 16,
- "y": 1
- },
- "id": 51,
- "options": {
- "colorMode": "value",
- "graphMode": "area",
- "justifyMode": "auto",
- "orientation": "auto",
- "reduceOptions": {
- "calcs": [
- "lastNotNull"
- ],
- "fields": "",
- "values": false
- },
- "showPercentChange": false,
- "textMode": "auto",
- "wideLayout": true
- },
- "pluginVersion": "11.0.0",
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "PBFA97CFB590B2093"
- },
- "editorMode": "code",
- "exemplar": false,
- "expr": "sum(trivy_vulnerability_id{severity=\"Critical\", namespace=~\"$namespace\"})",
- "instant": true,
- "interval": "",
- "legendFormat": "",
- "refId": "A"
- }
- ],
- "title": "CRITICAL",
- "type": "stat"
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "PBFA97CFB590B2093"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "thresholds"
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "text",
- "value": 1
- }
- ]
- },
- "unit": "none"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 3,
- "w": 4,
- "x": 20,
- "y": 1
- },
- "id": 39,
- "options": {
- "colorMode": "value",
- "graphMode": "area",
- "justifyMode": "auto",
- "orientation": "auto",
- "reduceOptions": {
- "calcs": [
- "lastNotNull"
- ],
- "fields": "",
- "values": false
- },
- "showPercentChange": false,
- "textMode": "auto",
- "wideLayout": true
- },
- "pluginVersion": "11.0.0",
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "PBFA97CFB590B2093"
- },
- "editorMode": "code",
- "exemplar": false,
- "expr": "sum(trivy_vulnerability_id{namespace=~\"$namespace\"})",
- "instant": true,
- "interval": "",
- "legendFormat": "",
- "refId": "A"
- }
- ],
- "title": "TOTAL",
- "type": "stat"
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "PBFA97CFB590B2093"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "line",
- "fillOpacity": 15,
- "gradientMode": "opacity",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineStyle": {
- "fill": "solid"
- },
- "lineWidth": 2,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "never",
- "spanNulls": true,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "blue",
- "value": 1
- }
- ]
- },
- "unit": "none"
- },
- "overrides": [
- {
- "__systemRef": "hideSeriesFrom",
- "matcher": {
- "id": "byNames",
- "options": {
- "mode": "exclude",
- "names": [
- "kube-system"
- ],
- "prefix": "All except:",
- "readOnly": true
- }
- },
- "properties": [
- {
- "id": "custom.hideFrom",
- "value": {
- "legend": false,
- "tooltip": false,
- "viz": true
- }
- }
- ]
- }
- ]
- },
- "gridPos": {
- "h": 8,
- "w": 12,
- "x": 0,
- "y": 4
- },
- "id": 58,
- "options": {
- "legend": {
- "calcs": [],
- "displayMode": "table",
- "placement": "right",
- "showLegend": true
- },
- "tooltip": {
- "maxHeight": 600,
- "mode": "single",
- "sort": "none"
- }
- },
- "pluginVersion": "8.5.0",
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "PBFA97CFB590B2093"
- },
- "editorMode": "code",
- "exemplar": false,
- "expr": "sum(trivy_vulnerability_id{namespace=~\"$namespace\"}) by (namespace)",
- "instant": false,
- "interval": "",
- "legendFormat": "{{namespace}}",
- "range": true,
- "refId": "A"
- }
- ],
- "title": "Image Vulnerabilities by namespace",
- "type": "timeseries"
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "PBFA97CFB590B2093"
- },
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "line",
- "fillOpacity": 15,
- "gradientMode": "opacity",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 2,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "never",
- "spanNulls": true,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- },
- {
- "color": "blue",
- "value": 1
- }
- ]
- },
- "unit": "none"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 8,
- "w": 12,
- "x": 12,
- "y": 4
- },
- "id": 61,
- "options": {
- "legend": {
- "calcs": [],
- "displayMode": "table",
- "placement": "right",
- "showLegend": true
- },
- "tooltip": {
- "maxHeight": 600,
- "mode": "multi",
- "sort": "desc"
- }
- },
- "pluginVersion": "8.5.0",
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "PBFA97CFB590B2093"
- },
- "editorMode": "code",
- "exemplar": false,
- "expr": "sum(trivy_vulnerability_id{namespace=~\"$namespace\"}) by (severity)",
- "instant": false,
- "interval": "",
- "legendFormat": "{{severity}}",
- "range": true,
- "refId": "A"
- }
- ],
- "title": "Image Vulnerabilities by severity",
- "type": "timeseries"
- },
- {
- "datasource": {
- "type": "prometheus",
- "uid": "PBFA97CFB590B2093"
- },
- "description": "",
- "fieldConfig": {
- "defaults": {
- "color": {
- "fixedColor": "transparent",
- "mode": "fixed"
- },
- "custom": {
- "align": "left",
- "cellOptions": {
- "mode": "basic",
- "type": "color-background"
- },
- "filterable": true,
- "inspect": false
- },
- "links": [
- {
- "targetBlank": true,
- "title": "Go to CVE",
- "url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=${__data.fields.vuln_id}"
- }
- ],
- "mappings": [
- {
- "options": {
- "CRITICAL": {
- "color": "dark-red",
- "index": 0
- },
- "HIGH": {
- "color": "yellow",
- "index": 1
- },
- "LOW": {
- "color": "dark-blue",
- "index": 3
- },
- "MEDIUM": {
- "color": "dark-orange",
- "index": 2
- },
- "UNKNOWN": {
- "color": "super-light-blue",
- "index": 4
- }
- },
- "type": "value"
- }
- ],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "green",
- "value": null
- }
- ]
- },
- "unit": "short"
- },
- "overrides": [
- {
- "matcher": {
- "id": "byName",
- "options": "namespace"
- },
- "properties": [
- {
- "id": "custom.width"
- }
- ]
- },
- {
- "matcher": {
- "id": "byName",
- "options": "pod"
- },
- "properties": [
- {
- "id": "custom.width"
- }
- ]
- }
- ]
- },
- "gridPos": {
- "h": 10,
- "w": 24,
- "x": 0,
- "y": 12
- },
- "id": 67,
- "options": {
- "cellHeight": "sm",
- "footer": {
- "countRows": false,
- "fields": "",
- "reducer": [
- "sum"
- ],
- "show": false
- },
- "frameIndex": 2,
- "showHeader": true,
- "sortBy": [
- {
- "desc": false,
- "displayName": "severity"
- }
- ]
- },
- "pluginVersion": "11.0.0",
- "targets": [
- {
- "datasource": {
- "type": "prometheus",
- "uid": "PBFA97CFB590B2093"
- },
- "editorMode": "code",
- "exemplar": false,
- "expr": "sum(trivy_vulnerability_id{namespace=~\"$namespace\"}) without (namespace, last_modified_date, instance, job, endpoint, service, container, image_digest, resource, resource_name)",
- "format": "table",
- "instant": true,
- "interval": "",
- "legendFormat": "",
- "refId": "A"
- }
- ],
- "title": "Image by CVE",
- "transformations": [
- {
- "id": "organize",
- "options": {
- "excludeByName": {
- "Time": true,
- "Value": true,
- "instance": true,
- "job": true
- },
- "indexByName": {
- "Time": 10,
- "Value": 9,
- "image_digest": 7,
- "image_registry": 4,
- "image_repository": 5,
- "image_tag": 6,
- "name": 8,
- "namespace": 2,
- "pod": 3,
- "severity": 0,
- "vuln_id": 1
- },
- "renameByName": {
- "image_digest": "",
- "name": "source workload"
- }
- }
- }
- ],
- "type": "table"
- }
- ],
- "refresh": "30s",
- "schemaVersion": 39,
- "tags": [
- "Prometheus",
- "Addons",
- "Trivy"
- ],
- "templating": {
- "list": [
- {
- "current": {
- "selected": true,
- "text": [
- "kube-system"
- ],
- "value": [
- "kube-system"
- ]
- },
- "datasource": {
- "type": "prometheus",
- "uid": "PBFA97CFB590B2093"
- },
- "definition": "label_values(trivy_vulnerability_id{job=\"trivy-operator\"}, namespace)",
- "hide": 0,
- "includeAll": false,
- "label": "namespace",
- "multi": true,
- "name": "namespace",
- "options": [],
- "query": {
- "query": "label_values(trivy_vulnerability_id{job=\"trivy-operator\"}, namespace)",
- "refId": "StandardVariableQuery"
- },
- "refresh": 2,
- "regex": "",
- "skipUrlSync": false,
- "sort": 1,
- "type": "query"
- }
- ]
- },
- "time": {
- "from": "now-3h",
- "to": "now"
- },
- "timeRangeUpdatedDuringEditOrView": false,
- "timepicker": {},
- "timezone": "",
- "title": "Trivy Operator / Image Vulnerability",
- "uid": "trivy_starboard_operator",
- "version": 7,
- "weekStart": ""
- }
- traefik-loki:
- json: |
- {
- "annotations": {
- "list": [
- {
- "builtIn": 1,
- "datasource": {
- "type": "datasource",
- "uid": "grafana"
- },
- "enable": true,
- "hide": true,
- "iconColor": "rgba(0, 211, 255, 1)",
- "name": "Annotations & Alerts",
- "type": "dashboard"
- }
- ]
- },
- "description": "Loki version 2 showcase using JSON Traefik access logs.",
- "editable": true,
- "fiscalYearStartMonth": 0,
- "gnetId": 13713,
- "graphTooltip": 0,
- "links": [],
- "panels": [
- {
- "datasource": {
- "type": "loki",
- "uid": "loki"
- },
- "description": "",
- "gridPos": {
- "h": 2,
- "w": 24,
- "x": 0,
- "y": 0
- },
- "id": 32,
- "interval": "",
- "options": {
- "code": {
- "language": "plaintext",
- "showLineNumbers": false,
- "showMiniMap": false
- },
- "content": "\n

\n
Traefik Dashboard\n
",
- "mode": "html"
- },
- "pluginVersion": "11.0.0",
- "targets": [
- {
- "datasource": {
- "type": "loki",
- "uid": "loki"
- },
- "expr": "loki_build_info",
- "format": "table",
- "instant": false,
- "interval": "",
- "legendFormat": "",
- "refId": "A"
- }
- ],
- "transparent": true,
- "type": "text"
- },
- {
- "datasource": {
- "type": "loki",
- "uid": "loki"
- },
- "description": "",
- "fieldConfig": {
- "defaults": {
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "purple",
- "value": null
- }
- ]
- },
- "unit": "short"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 4,
- "w": 6,
- "x": 0,
- "y": 2
- },
- "id": 4,
- "interval": "1m",
- "options": {
- "colorMode": "background",
- "graphMode": "area",
- "justifyMode": "auto",
- "orientation": "auto",
- "reduceOptions": {
- "calcs": [
- "sum"
- ],
- "fields": "",
- "values": false
- },
- "showPercentChange": false,
- "textMode": "value",
- "wideLayout": true
- },
- "pluginVersion": "11.0.0",
- "targets": [
- {
- "datasource": {
- "type": "loki",
- "uid": "loki"
- },
- "editorMode": "code",
- "expr": "sum(count_over_time({namespace=\"traefik-system\"} |= \"RequestProtocol\" [$__interval]))",
- "legendFormat": "",
- "queryType": "range",
- "refId": "A"
- }
- ],
- "title": "Total requests ",
- "transparent": true,
- "type": "stat"
- },
- {
- "datasource": {
- "type": "loki",
- "uid": "loki"
- },
- "description": "",
- "fieldConfig": {
- "defaults": {
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "light-blue",
- "value": null
- }
- ]
- },
- "unit": "short"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 8,
- "w": 9,
- "x": 6,
- "y": 2
- },
- "id": 5,
- "interval": "30s",
- "options": {
- "colorMode": "background",
- "graphMode": "area",
- "justifyMode": "auto",
- "orientation": "auto",
- "reduceOptions": {
- "calcs": [
- "sum"
- ],
- "fields": "",
- "values": false
- },
- "showPercentChange": false,
- "textMode": "auto",
- "wideLayout": true
- },
- "pluginVersion": "11.0.0",
- "targets": [
- {
- "datasource": {
- "type": "loki",
- "uid": "loki"
- },
- "editorMode": "code",
- "expr": "sum by (OriginStatus) (count_over_time({namespace=\"traefik-system\"}|= \"RequestProtocol\" | json | __error__=\"\" [$__interval]))",
- "legendFormat": "HTTP Status: {{OriginStatus}}",
- "queryType": "range",
- "refId": "A"
- }
- ],
- "title": "Requests per status code",
- "transparent": true,
- "type": "stat"
- },
- {
- "datasource": {
- "type": "loki",
- "uid": "loki"
- },
- "description": "",
- "fieldConfig": {
- "defaults": {
- "mappings": [],
- "max": 100,
- "min": 0,
- "noValue": "0",
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "purple",
- "value": null
- },
- {
- "color": "red",
- "value": 80
- }
- ]
- },
- "unit": "percent"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 4,
- "w": 4,
- "x": 15,
- "y": 2
- },
- "id": 19,
- "interval": "5m",
- "maxDataPoints": 1,
- "options": {
- "colorMode": "background",
- "graphMode": "none",
- "justifyMode": "center",
- "orientation": "auto",
- "reduceOptions": {
- "calcs": [
- "mean"
- ],
- "fields": "",
- "values": false
- },
- "showPercentChange": false,
- "textMode": "value",
- "wideLayout": true
- },
- "pluginVersion": "11.0.0",
- "targets": [
- {
- "datasource": {
- "type": "loki",
- "uid": "loki"
- },
- "expr": " sum(rate({namespace=\"traefik-system\"} |~ \"RequestProtocol\" | json | OriginStatus >= 400 |__error__=\"\"[$__interval])) / (sum(rate({namespace=\"traefik-system\"} |~ \"RequestProtocol\" | json | __error__=\"\"[$__interval])) / 100)",
- "legendFormat": "",
- "refId": "A"
- }
- ],
- "title": "% of 4/5xx ",
- "transparent": true,
- "type": "stat"
- },
- {
- "datasource": {
- "type": "loki",
- "uid": "loki"
- },
- "description": "",
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "line",
- "fillOpacity": 10,
- "gradientMode": "none",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "never",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "off"
- }
- },
- "decimals": 0,
- "mappings": [],
- "min": 0,
- "noValue": "0",
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "purple",
- "value": null
- },
- {
- "color": "red",
- "value": 80
- }
- ]
- },
- "unit": "none"
- },
- "overrides": [
- {
- "matcher": {
- "id": "byValue",
- "options": {
- "op": "gte",
- "reducer": "allIsZero",
- "value": 0
- }
- },
- "properties": [
- {
- "id": "custom.hideFrom",
- "value": {
- "legend": true,
- "tooltip": true,
- "viz": false
- }
- }
- ]
- },
- {
- "matcher": {
- "id": "byValue",
- "options": {
- "op": "gte",
- "reducer": "allIsNull",
- "value": 0
- }
- },
- "properties": [
- {
- "id": "custom.hideFrom",
- "value": {
- "legend": true,
- "tooltip": true,
- "viz": false
- }
- }
- ]
- },
- {
- "matcher": {
- "id": "byType",
- "options": "time"
- },
- "properties": [
- {
- "id": "custom.axisPlacement",
- "value": "hidden"
- }
- ]
- }
- ]
- },
- "gridPos": {
- "h": 4,
- "w": 5,
- "x": 19,
- "y": 2
- },
- "id": 36,
- "interval": "1m",
- "options": {
- "legend": {
- "calcs": [],
- "displayMode": "list",
- "placement": "bottom",
- "showLegend": false
- },
- "tooltip": {
- "maxHeight": 600,
- "mode": "multi",
- "sort": "none"
- }
- },
- "pluginVersion": "7.3.6",
- "targets": [
- {
- "datasource": {
- "type": "loki",
- "uid": "loki"
- },
- "expr": " sum by (OriginStatus,ServiceName) (count_over_time({namespace=\"traefik-system\"} |~ \"RequestProtocol\" | json | OriginStatus >= 400 |__error__=\"\"[$__interval]))",
- "legendFormat": " {{ServiceName}} / {{OriginStatus}} ",
- "refId": "A"
- }
- ],
- "title": " 4/5xx Services",
- "transparent": true,
- "type": "timeseries"
- },
- {
- "datasource": {
- "type": "loki",
- "uid": "loki"
- },
- "description": "",
- "fieldConfig": {
- "defaults": {
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "purple",
- "value": null
- }
- ]
- }
- },
- "overrides": []
- },
- "gridPos": {
- "h": 4,
- "w": 6,
- "x": 0,
- "y": 6
- },
- "id": 22,
- "interval": "5m",
- "options": {
- "colorMode": "background",
- "graphMode": "none",
- "justifyMode": "auto",
- "orientation": "auto",
- "reduceOptions": {
- "calcs": [
- "mean"
- ],
- "fields": "",
- "values": false
- },
- "showPercentChange": false,
- "textMode": "value",
- "wideLayout": true
- },
- "pluginVersion": "11.0.0",
- "targets": [
- {
- "datasource": {
- "type": "loki",
- "uid": "loki"
- },
- "expr": "count(sum by (ClientHost) (count_over_time({namespace=\"traefik-system\"}|= \"RequestProtocol\" | json | __error__=\"\" [$__interval])))",
- "legendFormat": "",
- "refId": "A"
- }
- ],
- "title": "Users right now",
- "transparent": true,
- "type": "stat"
- },
- {
- "datasource": {
- "type": "loki",
- "uid": "loki"
- },
- "description": "",
- "fieldConfig": {
- "defaults": {
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "purple",
- "value": null
- }
- ]
- },
- "unit": "decbytes"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 4,
- "w": 9,
- "x": 15,
- "y": 6
- },
- "id": 8,
- "interval": "1m",
- "options": {
- "colorMode": "background",
- "graphMode": "none",
- "justifyMode": "center",
- "orientation": "auto",
- "reduceOptions": {
- "calcs": [
- "sum"
- ],
- "fields": "",
- "values": false
- },
- "showPercentChange": false,
- "textMode": "value",
- "wideLayout": true
- },
- "pluginVersion": "11.0.0",
- "targets": [
- {
- "datasource": {
- "type": "loki",
- "uid": "loki"
- },
- "expr": "sum_over_time({namespace=\"traefik-system\"}|= \"RequestProtocol\" | json | OriginStatus=200 | unwrap DownstreamContentSize | __error__=\"\" [$__interval])",
- "legendFormat": "Bytes sent",
- "refId": "A"
- }
- ],
- "title": "Total Bytes Sent",
- "transformations": [
- {
- "id": "reduce",
- "options": {
- "reducers": [
- "sum"
- ]
- }
- },
- {
- "id": "organize",
- "options": {
- "excludeByName": {},
- "indexByName": {},
- "renameByName": {
- "Total": "Bytes Sent"
- }
- }
- }
- ],
- "transparent": true,
- "type": "stat"
- },
- {
- "datasource": {
- "type": "loki",
- "uid": "loki"
- },
- "description": "",
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- }
- },
- "decimals": 0,
- "mappings": [],
- "unit": "short"
- },
- "overrides": []
- },
- "gridPos": {
- "h": 8,
- "w": 8,
- "x": 0,
- "y": 10
- },
- "id": 33,
- "interval": "5m",
- "maxDataPoints": 3,
- "options": {
- "legend": {
- "calcs": [],
- "displayMode": "table",
- "placement": "right",
- "showLegend": true,
- "values": [
- "value",
- "percent"
- ]
- },
- "pieType": "pie",
- "reduceOptions": {
- "calcs": [
- "lastNotNull"
- ],
- "fields": "",
- "values": false
- },
- "tooltip": {
- "maxHeight": 600,
- "mode": "single",
- "sort": "none"
- }
- },
- "pluginVersion": "7.3.4",
- "targets": [
- {
- "datasource": {
- "type": "loki",
- "uid": "loki"
- },
- "expr": "sum by (RouterName) (count_over_time({namespace=\"traefik-system\"}|= \"RequestProtocol\" | json | __error__=\"\" [$__interval]))",
- "legendFormat": "{{RouterName}}",
- "refId": "A"
- }
- ],
- "title": "Requests Route",
- "transparent": true,
- "type": "piechart"
- },
- {
- "datasource": {
- "type": "tempo",
- "uid": "tempo"
- },
- "gridPos": {
- "h": 17,
- "w": 16,
- "x": 8,
- "y": 10
- },
- "id": 37,
- "options": {
- "edges": {},
- "nodes": {}
- },
- "targets": [
- {
- "datasource": {
- "type": "tempo",
- "uid": "tempo"
- },
- "limit": 20,
- "queryType": "serviceMap",
- "refId": "A",
- "tableType": "traces"
- }
- ],
- "title": "Service graph",
- "type": "nodeGraph"
- },
- {
- "datasource": {
- "type": "loki",
- "uid": "loki"
- },
- "description": "",
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "line",
- "fillOpacity": 90,
- "gradientMode": "opacity",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "never",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "line+area"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "transparent",
- "value": null
- },
- {
- "color": "red",
- "value": 0.3
- }
- ]
- },
- "unit": "ns"
- },
- "overrides": [
- {
- "matcher": {
- "id": "byName",
- "options": "95th percentile"
- },
- "properties": [
- {
- "id": "color",
- "value": {
- "fixedColor": "blue",
- "mode": "fixed"
- }
- }
- ]
- },
- {
- "matcher": {
- "id": "byName",
- "options": "max latency"
- },
- "properties": [
- {
- "id": "color",
- "value": {
- "fixedColor": "super-light-blue",
- "mode": "fixed"
- }
- }
- ]
- },
- {
- "matcher": {
- "id": "byName",
- "options": "max latency"
- },
- "properties": [
- {
- "id": "custom.fillOpacity",
- "value": 30
- },
- {
- "id": "custom.lineStyle",
- "value": {
- "dash": [
- 10,
- 10
- ],
- "fill": "dash"
- }
- }
- ]
- }
- ]
- },
- "gridPos": {
- "h": 9,
- "w": 8,
- "x": 0,
- "y": 18
- },
- "id": 16,
- "interval": "30s",
- "options": {
- "legend": {
- "calcs": [
- "max"
- ],
- "displayMode": "list",
- "placement": "bottom",
- "showLegend": true
- },
- "tooltip": {
- "maxHeight": 600,
- "mode": "multi",
- "sort": "none"
- }
- },
- "pluginVersion": "7.3.6",
- "targets": [
- {
- "datasource": {
- "type": "loki",
- "uid": "loki"
- },
- "expr": "quantile_over_time(0.95,{namespace=\"traefik-system\"} |= \"RequestProtocol\"| json | unwrap Duration | __error__=\"\" [$__interval]) by (ServiceName)",
- "hide": false,
- "legendFormat": " {{ ServiceName }}",
- "refId": "C"
- }
- ],
- "title": "95th percentile of Request Time",
- "transparent": true,
- "type": "timeseries"
- },
- {
- "datasource": {
- "type": "loki",
- "uid": "loki"
- },
- "description": "",
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "line",
- "fillOpacity": 90,
- "gradientMode": "opacity",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "never",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "line+area"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "transparent",
- "value": null
- },
- {
- "color": "red",
- "value": 0.3
- }
- ]
- },
- "unit": "ns"
- },
- "overrides": [
- {
- "matcher": {
- "id": "byName",
- "options": "95th percentile"
- },
- "properties": [
- {
- "id": "color",
- "value": {
- "fixedColor": "blue",
- "mode": "fixed"
- }
- }
- ]
- },
- {
- "matcher": {
- "id": "byName",
- "options": "max latency"
- },
- "properties": [
- {
- "id": "color",
- "value": {
- "fixedColor": "super-light-blue",
- "mode": "fixed"
- }
- }
- ]
- },
- {
- "matcher": {
- "id": "byName",
- "options": "max latency"
- },
- "properties": [
- {
- "id": "custom.fillOpacity",
- "value": 30
- },
- {
- "id": "custom.lineStyle",
- "value": {
- "dash": [
- 10,
- 10
- ],
- "fill": "dash"
- }
- }
- ]
- }
- ]
- },
- "gridPos": {
- "h": 9,
- "w": 8,
- "x": 0,
- "y": 27
- },
- "id": 34,
- "interval": "30s",
- "options": {
- "legend": {
- "calcs": [],
- "displayMode": "list",
- "placement": "bottom",
- "showLegend": true
- },
- "tooltip": {
- "maxHeight": 600,
- "mode": "multi",
- "sort": "none"
- }
- },
- "pluginVersion": "7.3.6",
- "targets": [
- {
- "datasource": {
- "type": "loki",
- "uid": "loki"
- },
- "expr": "max by (ServiceName) (max_over_time({namespace=\"traefik-system\"} |= \"RequestProtocol\" |json | unwrap Duration | __error__=\"\" [$__interval]))",
- "hide": false,
- "legendFormat": "{{ ServiceName}}",
- "refId": "D"
- }
- ],
- "title": "Max Age of Request Time",
- "transparent": true,
- "type": "timeseries"
- },
- {
- "datasource": {
- "type": "loki",
- "uid": "loki"
- },
- "gridPos": {
- "h": 16,
- "w": 16,
- "x": 8,
- "y": 27
- },
- "id": 11,
- "interval": "",
- "options": {
- "dedupStrategy": "none",
- "enableLogDetails": true,
- "prettifyLogMessage": false,
- "showCommonLabels": false,
- "showLabels": false,
- "showTime": true,
- "sortOrder": "Descending",
- "wrapLogMessage": false
- },
- "targets": [
- {
- "datasource": {
- "type": "loki",
- "uid": "loki"
- },
- "expr": "{namespace=\"traefik-system\"} |= \"RequestProtocol\" | json | line_format \"{{.OriginStatus}} {{.RequestMethod}} {{.RequestAddr}}{{.RequestPath}} -> {{.ServiceAddr}}\"",
- "legendFormat": "",
- "refId": "A"
- }
- ],
- "title": "Logs",
- "transparent": true,
- "type": "logs"
- },
- {
- "datasource": {
- "type": "loki",
- "uid": "loki"
- },
- "description": "",
- "fieldConfig": {
- "defaults": {
- "color": {
- "mode": "palette-classic"
- },
- "custom": {
- "axisBorderShow": false,
- "axisCenteredZero": false,
- "axisColorMode": "text",
- "axisLabel": "",
- "axisPlacement": "auto",
- "barAlignment": 0,
- "drawStyle": "line",
- "fillOpacity": 90,
- "gradientMode": "opacity",
- "hideFrom": {
- "legend": false,
- "tooltip": false,
- "viz": false
- },
- "insertNulls": false,
- "lineInterpolation": "linear",
- "lineWidth": 1,
- "pointSize": 5,
- "scaleDistribution": {
- "type": "linear"
- },
- "showPoints": "never",
- "spanNulls": false,
- "stacking": {
- "group": "A",
- "mode": "none"
- },
- "thresholdsStyle": {
- "mode": "line+area"
- }
- },
- "mappings": [],
- "thresholds": {
- "mode": "absolute",
- "steps": [
- {
- "color": "transparent",
- "value": null
- },
- {
- "color": "red",
- "value": 0.3
- }
- ]
- },
- "unit": "decbytes"
- },
- "overrides": [
- {
- "matcher": {
- "id": "byName",
- "options": "95th percentile"
- },
- "properties": [
- {
- "id": "color",
- "value": {
- "fixedColor": "blue",
- "mode": "fixed"
- }
- }
- ]
- },
- {
- "matcher": {
- "id": "byName",
- "options": "max latency"
- },
- "properties": [
- {
- "id": "color",
- "value": {
- "fixedColor": "super-light-blue",
- "mode": "fixed"
- }
- }
- ]
- },
- {
- "matcher": {
- "id": "byName",
- "options": "max latency"
- },
- "properties": [
- {
- "id": "custom.fillOpacity",
- "value": 30
- },
- {
- "id": "custom.lineStyle",
- "value": {
- "dash": [
- 10,
- 10
- ],
- "fill": "dash"
- }
- }
- ]
- }
- ]
- },
- "gridPos": {
- "h": 9,
- "w": 8,
- "x": 0,
- "y": 36
- },
- "id": 35,
- "interval": "30s",
- "options": {
- "legend": {
- "calcs": [],
- "displayMode": "list",
- "placement": "bottom",
- "showLegend": true
- },
- "tooltip": {
- "maxHeight": 600,
- "mode": "multi",
- "sort": "none"
- }
- },
- "pluginVersion": "7.3.6",
- "targets": [
- {
- "datasource": {
- "type": "loki",
- "uid": "loki"
- },
- "expr": "sum by (ServiceName) (sum_over_time({namespace=\"traefik-system\"} |= \"RequestProtocol\" |json | unwrap RequestContentSize | __error__=\"\" [$__interval]))",
- "hide": false,
- "legendFormat": "{{ ServiceName}}",
- "refId": "D"
- }
- ],
- "title": "Requests Size",
- "transparent": true,
- "type": "timeseries"
- }
- ],
- "refresh": false,
- "schemaVersion": 39,
- "tags": [],
- "templating": {
- "list": []
- },
- "time": {
- "from": "now-12h",
- "to": "now"
- },
- "timeRangeUpdatedDuringEditOrView": false,
- "timepicker": {
- "refresh_intervals": [
- "10s",
- "30s",
- "1m",
- "5m",
- "15m",
- "30m",
- "1h",
- "2h",
- "1d"
- ]
- },
- "timezone": "",
- "title": "Traefik Via Loki",
- "uid": "fJarCeaGk",
- "version": 1,
- "weekStart": ""
- }
- dot-ai-logs:
- json: |
- {
- "annotations": { "list": [] },
- "editable": true,
- "fiscalYearStartMonth": 0,
- "graphTooltip": 0,
- "links": [],
- "panels": [
- {
- "title": "Log Volume",
- "type": "timeseries",
- "gridPos": { "h": 6, "w": 24, "x": 0, "y": 0 },
- "datasource": { "type": "loki", "uid": "loki" },
- "targets": [
- {
- "expr": "sum(count_over_time({namespace=\"dot-ai\"} [1m])) by (pod)",
- "legendFormat": "{{pod}}",
- "refId": "A"
- }
- ],
- "fieldConfig": {
- "defaults": {
- "custom": {
- "drawStyle": "bars",
- "fillOpacity": 50,
- "stacking": { "mode": "normal" }
- }
- },
- "overrides": []
- }
- },
- {
- "title": "Logs by Pod",
- "type": "logs",
- "gridPos": { "h": 16, "w": 24, "x": 0, "y": 6 },
- "datasource": { "type": "loki", "uid": "loki" },
- "targets": [
- {
- "expr": "{namespace=\"dot-ai\", pod=~\"$pod\"} | json log=\"log\", message=\"message\", msg=\"msg\", level=\"level\", stream=\"stream\" | label_format level=`{{if .level}}{{.level}}{{else if eq .stream \"stderr\"}}error{{else}}info{{end}}` | line_format `{{.pod}} |{{or .message .msg .log}}`",
- "refId": "A"
- }
- ],
- "options": {
- "showTime": true,
- "showLabels": false,
- "showCommonLabels": false,
- "wrapLogMessage": true,
- "prettifyLogMessage": false,
- "enableLogDetails": true,
- "sortOrder": "Descending",
- "dedupStrategy": "none",
- "displayedFields": ["pod", "level"]
- }
- },
- {
- "title": "Errors & Warnings",
- "type": "logs",
- "gridPos": { "h": 10, "w": 24, "x": 0, "y": 22 },
- "datasource": { "type": "loki", "uid": "loki" },
- "targets": [
- {
- "expr": "{namespace=\"dot-ai\", pod=~\"$pod\"} | json log=\"log\", message=\"message\", msg=\"msg\", level=\"level\", stream=\"stream\" | label_format level=`{{if .level}}{{.level}}{{else if eq .stream \"stderr\"}}error{{else}}info{{end}}` | level=~`error|warn|warning|fatal|panic` | line_format `{{.pod}} |{{or .message .msg .log}}`",
- "refId": "A"
- }
- ],
- "options": {
- "showTime": true,
- "showLabels": false,
- "showCommonLabels": false,
- "wrapLogMessage": true,
- "prettifyLogMessage": false,
- "enableLogDetails": true,
- "sortOrder": "Descending",
- "dedupStrategy": "none",
- "displayedFields": ["pod", "level"]
- }
- }
- ],
- "schemaVersion": 39,
- "tags": ["dot-ai", "logs", "loki"],
- "templating": {
- "list": [
- {
- "name": "pod",
- "type": "query",
- "datasource": { "type": "loki", "uid": "loki" },
- "query": { "label": "pod", "stream": "{namespace=\"dot-ai\"}", "type": 1 },
- "includeAll": true,
- "multi": true,
- "current": { "selected": true, "text": "All", "value": "$__all" }
- }
- ]
- },
- "time": { "from": "now-1h", "to": "now" },
- "title": "dot-ai Logs",
- "uid": "dot-ai-logs"
- }
- opencost:
- json: |
- {
- "annotations": {
- "list": [
- {
- "builtIn": 1,
- "datasource": { "type": "datasource", "uid": "grafana" },
- "enable": true,
- "hide": true,
- "iconColor": "rgba(0, 211, 255, 1)",
- "name": "Annotations & Alerts",
- "target": { "limit": 100, "matchAny": false, "tags": [], "type": "dashboard" },
- "type": "dashboard"
- }
- ]
- },
- "description": "UpCloud 4-node cluster cost monitoring powered by OpenCost with custom pricing.",
- "editable": true,
- "fiscalYearStartMonth": 0,
- "graphTooltip": 1,
- "links": [],
- "liveNow": false,
- "panels": [
- {
- "collapsed": false,
- "gridPos": { "h": 1, "w": 24, "x": 0, "y": 0 },
- "id": 100,
- "title": "Monthly Cost Overview",
- "type": "row"
- },
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "description": "Monthly CPU cost based on provisioned capacity and OpenCost custom pricing.",
- "fieldConfig": {
- "defaults": {
- "color": { "fixedColor": "green", "mode": "fixed" },
- "decimals": 2,
- "mappings": [],
- "thresholds": { "mode": "absolute", "steps": [{ "color": "green", "value": null }] },
- "unit": "currencyEUR"
- },
- "overrides": []
- },
- "gridPos": { "h": 4, "w": 6, "x": 0, "y": 1 },
- "id": 1,
- "options": { "colorMode": "value", "graphMode": "none", "justifyMode": "auto", "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], "fields": "", "values": false }, "textMode": "auto" },
- "title": "Monthly CPU Cost",
- "type": "stat",
- "targets": [
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "expr": "sum(avg(kube_node_status_capacity{resource=\"cpu\", unit=\"core\"}) by (node) * avg(node_cpu_hourly_cost) by (node) * 730 * (1-$useDiscount/100))",
- "legendFormat": "CPU Cost",
- "refId": "A"
- }
- ]
- },
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "description": "Monthly memory cost based on provisioned capacity and OpenCost custom pricing.",
- "fieldConfig": {
- "defaults": {
- "color": { "fixedColor": "green", "mode": "fixed" },
- "decimals": 2,
- "mappings": [],
- "thresholds": { "mode": "absolute", "steps": [{ "color": "green", "value": null }] },
- "unit": "currencyEUR"
- },
- "overrides": []
- },
- "gridPos": { "h": 4, "w": 6, "x": 6, "y": 1 },
- "id": 2,
- "options": { "colorMode": "value", "graphMode": "none", "justifyMode": "auto", "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], "fields": "", "values": false }, "textMode": "auto" },
- "title": "Monthly Memory Cost",
- "type": "stat",
- "targets": [
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "expr": "sum(avg(kube_node_status_capacity{resource=\"memory\", unit=\"byte\"}) by (node) / 1024/1024/1024 * avg(node_ram_hourly_cost) by (node) * 730 * (1-$useDiscount/100))",
- "legendFormat": "Memory Cost",
- "refId": "A"
- }
- ]
- },
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "description": "Monthly storage cost from PV hourly costs and local disk at $localStorageGBCost/GB.",
- "fieldConfig": {
- "defaults": {
- "color": { "fixedColor": "green", "mode": "fixed" },
- "decimals": 2,
- "mappings": [],
- "thresholds": { "mode": "absolute", "steps": [{ "color": "green", "value": null }] },
- "unit": "currencyEUR"
- },
- "overrides": []
- },
- "gridPos": { "h": 4, "w": 6, "x": 12, "y": 1 },
- "id": 3,
- "options": { "colorMode": "value", "graphMode": "none", "justifyMode": "auto", "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], "fields": "", "values": false }, "textMode": "auto" },
- "title": "Monthly Storage Cost",
- "type": "stat",
- "targets": [
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "expr": "sum(avg(pv_hourly_cost) by (persistentvolume) * 730 * avg(kube_persistentvolume_capacity_bytes) by (persistentvolume) / 1024/1024/1024) + (sum(sum(container_fs_limit_bytes{device!=\"tmpfs\", id=\"/\"}) by (instance) / 1024/1024/1024) * $localStorageGBCost OR on() vector(0))",
- "legendFormat": "Storage Cost",
- "refId": "A"
- }
- ]
- },
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "description": "Total monthly infrastructure cost (CPU + Memory + Storage).",
- "fieldConfig": {
- "defaults": {
- "color": { "fixedColor": "green", "mode": "fixed" },
- "decimals": 2,
- "mappings": [],
- "thresholds": { "mode": "absolute", "steps": [{ "color": "green", "value": null }] },
- "unit": "currencyEUR"
- },
- "overrides": []
- },
- "gridPos": { "h": 4, "w": 6, "x": 18, "y": 1 },
- "id": 4,
- "options": { "colorMode": "value", "graphMode": "none", "justifyMode": "auto", "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], "fields": "", "values": false }, "textMode": "auto" },
- "title": "Total Monthly Cost",
- "type": "stat",
- "targets": [
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "expr": "sum(avg(kube_node_status_capacity{resource=\"cpu\", unit=\"core\"}) by (node) * avg(node_cpu_hourly_cost) by (node) * 730 * (1-$useDiscount/100)) + sum(avg(kube_node_status_capacity{resource=\"memory\", unit=\"byte\"}) by (node) / 1024/1024/1024 * avg(node_ram_hourly_cost) by (node) * 730 * (1-$useDiscount/100)) + sum(avg(pv_hourly_cost) by (persistentvolume) * 730 * avg(kube_persistentvolume_capacity_bytes) by (persistentvolume) / 1024/1024/1024) + (sum(sum(container_fs_limit_bytes{device!=\"tmpfs\", id=\"/\"}) by (instance) / 1024/1024/1024) * $localStorageGBCost OR on() vector(0))",
- "legendFormat": "Total Cost",
- "refId": "A"
- }
- ]
- },
- {
- "collapsed": false,
- "gridPos": { "h": 1, "w": 24, "x": 0, "y": 5 },
- "id": 101,
- "title": "Resource Utilization",
- "type": "row"
- },
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "description": "Percentage of total CPU capacity currently in use.",
- "fieldConfig": {
- "defaults": {
- "color": { "mode": "thresholds" },
- "decimals": 1,
- "max": 100,
- "min": 0,
- "thresholds": { "mode": "absolute", "steps": [{ "color": "green", "value": null }, { "color": "yellow", "value": 60 }, { "color": "red", "value": 80 }] },
- "unit": "percent"
- },
- "overrides": []
- },
- "gridPos": { "h": 6, "w": 6, "x": 0, "y": 6 },
- "id": 5,
- "options": { "minVizHeight": 75, "minVizWidth": 75, "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], "fields": "", "values": false }, "showThresholdLabels": false, "showThresholdMarkers": true },
- "title": "CPU Utilization",
- "type": "gauge",
- "targets": [
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "expr": "sum(rate(container_cpu_usage_seconds_total{image!=\"\"}[5m])) / sum(kube_node_status_capacity{resource=\"cpu\", unit=\"core\"}) * 100",
- "legendFormat": "CPU Utilization",
- "refId": "A"
- }
- ]
- },
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "description": "Percentage of total CPU capacity reserved by resource requests.",
- "fieldConfig": {
- "defaults": {
- "color": { "mode": "thresholds" },
- "decimals": 1,
- "max": 100,
- "min": 0,
- "thresholds": { "mode": "absolute", "steps": [{ "color": "green", "value": null }, { "color": "yellow", "value": 60 }, { "color": "red", "value": 80 }] },
- "unit": "percent"
- },
- "overrides": []
- },
- "gridPos": { "h": 6, "w": 6, "x": 6, "y": 6 },
- "id": 6,
- "options": { "minVizHeight": 75, "minVizWidth": 75, "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], "fields": "", "values": false }, "showThresholdLabels": false, "showThresholdMarkers": true },
- "title": "CPU Requests",
- "type": "gauge",
- "targets": [
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "expr": "sum(kube_pod_container_resource_requests{resource=\"cpu\", unit=\"core\"}) / sum(kube_node_status_capacity{resource=\"cpu\", unit=\"core\"}) * 100",
- "legendFormat": "CPU Requests",
- "refId": "A"
- }
- ]
- },
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "description": "Percentage of total memory capacity currently in use.",
- "fieldConfig": {
- "defaults": {
- "color": { "mode": "thresholds" },
- "decimals": 1,
- "max": 100,
- "min": 0,
- "thresholds": { "mode": "absolute", "steps": [{ "color": "green", "value": null }, { "color": "yellow", "value": 60 }, { "color": "red", "value": 80 }] },
- "unit": "percent"
- },
- "overrides": []
- },
- "gridPos": { "h": 6, "w": 6, "x": 12, "y": 6 },
- "id": 7,
- "options": { "minVizHeight": 75, "minVizWidth": 75, "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], "fields": "", "values": false }, "showThresholdLabels": false, "showThresholdMarkers": true },
- "title": "RAM Utilization",
- "type": "gauge",
- "targets": [
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "expr": "sum(container_memory_working_set_bytes{image!=\"\"}) / sum(kube_node_status_capacity{resource=\"memory\", unit=\"byte\"}) * 100",
- "legendFormat": "RAM Utilization",
- "refId": "A"
- }
- ]
- },
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "description": "Percentage of total memory capacity reserved by resource requests.",
- "fieldConfig": {
- "defaults": {
- "color": { "mode": "thresholds" },
- "decimals": 1,
- "max": 100,
- "min": 0,
- "thresholds": { "mode": "absolute", "steps": [{ "color": "green", "value": null }, { "color": "yellow", "value": 60 }, { "color": "red", "value": 80 }] },
- "unit": "percent"
- },
- "overrides": []
- },
- "gridPos": { "h": 6, "w": 6, "x": 18, "y": 6 },
- "id": 8,
- "options": { "minVizHeight": 75, "minVizWidth": 75, "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], "fields": "", "values": false }, "showThresholdLabels": false, "showThresholdMarkers": true },
- "title": "RAM Requests",
- "type": "gauge",
- "targets": [
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "expr": "sum(kube_pod_container_resource_requests{resource=\"memory\", unit=\"byte\"}) / sum(kube_node_status_capacity{resource=\"memory\", unit=\"byte\"}) * 100",
- "legendFormat": "RAM Requests",
- "refId": "A"
- }
- ]
- },
- {
- "collapsed": true,
- "gridPos": { "h": 1, "w": 24, "x": 0, "y": 12 },
- "id": 102,
- "title": "Cost Trends",
- "type": "row",
- "panels": [
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "description": "Hourly cost trend stacked by resource type.",
- "fieldConfig": {
- "defaults": {
- "color": { "mode": "palette-classic" },
- "custom": { "axisBorderShow": false, "axisCenteredZero": false, "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, "drawStyle": "line", "fillOpacity": 30, "gradientMode": "none", "lineInterpolation": "smooth", "lineWidth": 2, "pointSize": 5, "showPoints": "never", "stacking": { "group": "A", "mode": "normal" } },
- "decimals": 2,
- "thresholds": { "mode": "absolute", "steps": [{ "color": "green", "value": null }] },
- "unit": "currencyEUR"
- },
- "overrides": []
- },
- "gridPos": { "h": 8, "w": 12, "x": 0, "y": 13 },
- "id": 9,
- "options": { "legend": { "calcs": ["mean", "lastNotNull"], "displayMode": "table", "placement": "bottom" }, "tooltip": { "mode": "multi", "sort": "desc" } },
- "title": "Total Cost Over Time",
- "type": "timeseries",
- "targets": [
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "expr": "sum(avg(kube_node_status_capacity{resource=\"cpu\", unit=\"core\"}) by (node) * avg(node_cpu_hourly_cost) by (node))",
- "legendFormat": "CPU",
- "refId": "A"
- },
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "expr": "sum(avg(kube_node_status_capacity{resource=\"memory\", unit=\"byte\"}) by (node) / 1024/1024/1024 * avg(node_ram_hourly_cost) by (node))",
- "legendFormat": "Memory",
- "refId": "B"
- },
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "expr": "sum(avg(pv_hourly_cost) by (persistentvolume) * avg(kube_persistentvolume_capacity_bytes) by (persistentvolume) / 1024/1024/1024) + (sum(sum(container_fs_limit_bytes{device!=\"tmpfs\", id=\"/\"}) by (instance) / 1024/1024/1024) * $localStorageGBCost / 730 OR on() vector(0))",
- "legendFormat": "Storage",
- "refId": "C"
- }
- ]
- },
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "description": "Hourly cost trend broken down by namespace.",
- "fieldConfig": {
- "defaults": {
- "color": { "mode": "palette-classic" },
- "custom": { "axisBorderShow": false, "axisCenteredZero": false, "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, "drawStyle": "line", "fillOpacity": 15, "gradientMode": "none", "lineInterpolation": "smooth", "lineWidth": 2, "pointSize": 5, "showPoints": "never", "stacking": { "group": "A", "mode": "normal" } },
- "decimals": 4,
- "thresholds": { "mode": "absolute", "steps": [{ "color": "green", "value": null }] },
- "unit": "currencyEUR"
- },
- "overrides": []
- },
- "gridPos": { "h": 8, "w": 12, "x": 12, "y": 13 },
- "id": 10,
- "options": { "legend": { "calcs": ["mean", "lastNotNull"], "displayMode": "table", "placement": "bottom" }, "tooltip": { "mode": "multi", "sort": "desc" } },
- "title": "Cost by Namespace Over Time",
- "type": "timeseries",
- "targets": [
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "expr": "sum(container_cpu_allocation{namespace=~\"$namespace\"} * on(node) group_left() node_cpu_hourly_cost + container_memory_allocation_bytes{namespace=~\"$namespace\"} / 1024/1024/1024 * on(node) group_left() node_ram_hourly_cost) by (namespace)",
- "legendFormat": "{{namespace}}",
- "refId": "A"
- }
- ]
- }
- ]
- },
- {
- "collapsed": true,
- "gridPos": { "h": 1, "w": 24, "x": 0, "y": 13 },
- "id": 103,
- "title": "Cost Breakdown",
- "type": "row",
- "panels": [
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "description": "Monthly cost breakdown per node showing CPU and memory costs.",
- "fieldConfig": {
- "defaults": {
- "color": { "mode": "thresholds" },
- "custom": { "align": "auto", "cellOptions": { "type": "auto" }, "inspect": false },
- "decimals": 2,
- "thresholds": { "mode": "absolute", "steps": [{ "color": "green", "value": null }] },
- "unit": "currencyEUR"
- },
- "overrides": [
- { "matcher": { "id": "byName", "options": "Node" }, "properties": [{ "id": "custom.width", "value": 250 }] }
- ]
- },
- "gridPos": { "h": 8, "w": 12, "x": 0, "y": 14 },
- "id": 11,
- "options": { "cellHeight": "sm", "footer": { "countRows": false, "enablePagination": false, "fields": "", "reducer": ["sum"], "show": true }, "showHeader": true, "sortBy": [{ "desc": true, "displayName": "CPU Cost" }] },
- "title": "Monthly Cost by Node",
- "type": "table",
- "transformations": [
- { "id": "seriesToColumns", "options": { "byField": "node" } },
- { "id": "organize", "options": { "excludeByName": { "Time 1": true, "Time 2": true }, "renameByName": { "Value #A": "CPU Cost", "Value #B": "Memory Cost", "node": "Node" } } }
- ],
- "targets": [
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "expr": "avg(kube_node_status_capacity{resource=\"cpu\", unit=\"core\"}) by (node) * avg(node_cpu_hourly_cost) by (node) * 730",
- "format": "table",
- "instant": true,
- "legendFormat": "CPU Cost",
- "refId": "A"
- },
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "expr": "avg(kube_node_status_capacity{resource=\"memory\", unit=\"byte\"}) by (node) / 1024/1024/1024 * avg(node_ram_hourly_cost) by (node) * 730",
- "format": "table",
- "instant": true,
- "legendFormat": "Memory Cost",
- "refId": "B"
- }
- ]
- },
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "description": "Monthly cost split by resource type.",
- "fieldConfig": {
- "defaults": {
- "color": { "mode": "palette-classic" },
- "decimals": 2,
- "thresholds": { "mode": "absolute", "steps": [{ "color": "green", "value": null }] },
- "unit": "currencyEUR"
- },
- "overrides": []
- },
- "gridPos": { "h": 8, "w": 12, "x": 12, "y": 14 },
- "id": 12,
- "options": { "displayMode": "gradient", "minVizHeight": 10, "minVizWidth": 0, "namePlacement": "auto", "orientation": "horizontal", "reduceOptions": { "calcs": ["lastNotNull"], "fields": "", "values": false }, "showUnfilled": true, "valueMode": "color" },
- "title": "Monthly Cost by Resource",
- "type": "bargauge",
- "targets": [
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "expr": "sum(avg(kube_node_status_capacity{resource=\"cpu\", unit=\"core\"}) by (node) * avg(node_cpu_hourly_cost) by (node) * 730)",
- "legendFormat": "CPU",
- "refId": "A"
- },
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "expr": "sum(avg(kube_node_status_capacity{resource=\"memory\", unit=\"byte\"}) by (node) / 1024/1024/1024 * avg(node_ram_hourly_cost) by (node) * 730)",
- "legendFormat": "Memory",
- "refId": "B"
- },
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "expr": "sum(avg(pv_hourly_cost) by (persistentvolume) * 730 * avg(kube_persistentvolume_capacity_bytes) by (persistentvolume) / 1024/1024/1024) + (sum(sum(container_fs_limit_bytes{device!=\"tmpfs\", id=\"/\"}) by (instance) / 1024/1024/1024) * $localStorageGBCost OR on() vector(0))",
- "legendFormat": "Storage",
- "refId": "C"
- }
- ]
- }
- ]
- },
- {
- "collapsed": true,
- "gridPos": { "h": 1, "w": 24, "x": 0, "y": 14 },
- "id": 104,
- "title": "Namespace & Container Costs",
- "type": "row",
- "panels": [
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "description": "Hourly cost distribution across namespaces.",
- "fieldConfig": {
- "defaults": {
- "color": { "mode": "palette-classic" },
- "decimals": 4,
- "thresholds": { "mode": "absolute", "steps": [{ "color": "green", "value": null }] },
- "unit": "currencyEUR"
- },
- "overrides": []
- },
- "gridPos": { "h": 8, "w": 12, "x": 0, "y": 15 },
- "id": 13,
- "options": { "displayLabels": ["name", "percent"], "legend": { "displayMode": "table", "placement": "right", "values": ["value", "percent"] }, "pieType": "donut", "reduceOptions": { "calcs": ["lastNotNull"], "fields": "", "values": false }, "tooltip": { "mode": "single", "sort": "none" } },
- "title": "Hourly Cost by Namespace",
- "type": "piechart",
- "targets": [
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "expr": "sum(container_cpu_allocation * on(node) group_left() node_cpu_hourly_cost + container_memory_allocation_bytes / 1024/1024/1024 * on(node) group_left() node_ram_hourly_cost) by (namespace)",
- "legendFormat": "{{namespace}}",
- "refId": "A"
- }
- ]
- },
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "description": "Hourly cost distribution across containers in the selected namespace(s).",
- "fieldConfig": {
- "defaults": {
- "color": { "mode": "palette-classic" },
- "decimals": 4,
- "thresholds": { "mode": "absolute", "steps": [{ "color": "green", "value": null }] },
- "unit": "currencyEUR"
- },
- "overrides": []
- },
- "gridPos": { "h": 8, "w": 12, "x": 12, "y": 15 },
- "id": 14,
- "options": { "displayLabels": ["name", "percent"], "legend": { "displayMode": "table", "placement": "right", "values": ["value", "percent"] }, "pieType": "donut", "reduceOptions": { "calcs": ["lastNotNull"], "fields": "", "values": false }, "tooltip": { "mode": "single", "sort": "none" } },
- "title": "Hourly Cost by Container",
- "type": "piechart",
- "targets": [
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "expr": "sum(container_cpu_allocation{namespace=~\"$namespace\"} * on(node) group_left() node_cpu_hourly_cost + container_memory_allocation_bytes{namespace=~\"$namespace\"} / 1024/1024/1024 * on(node) group_left() node_ram_hourly_cost) by (container)",
- "legendFormat": "{{container}}",
- "refId": "A"
- }
- ]
- }
- ]
- },
- {
- "collapsed": true,
- "gridPos": { "h": 1, "w": 24, "x": 0, "y": 15 },
- "id": 105,
- "title": "Cost Efficiency",
- "type": "row",
- "panels": [
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "description": "Compare CPU requests against actual usage to identify over-provisioning.",
- "fieldConfig": {
- "defaults": {
- "color": { "mode": "palette-classic" },
- "custom": { "axisBorderShow": false, "axisCenteredZero": false, "axisLabel": "CPU Cores", "axisPlacement": "auto", "barAlignment": 0, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "none", "lineInterpolation": "smooth", "lineWidth": 2, "pointSize": 5, "showPoints": "never", "stacking": { "group": "A", "mode": "none" } },
- "decimals": 2,
- "thresholds": { "mode": "absolute", "steps": [{ "color": "green", "value": null }] },
- "unit": "short"
- },
- "overrides": [
- {
- "matcher": { "id": "byRegexp", "options": "/Requested/" },
- "properties": [{ "id": "custom.lineStyle", "value": { "dash": [10, 10], "fill": "dash" } }, { "id": "custom.fillOpacity", "value": 0 }]
- }
- ]
- },
- "gridPos": { "h": 8, "w": 12, "x": 0, "y": 16 },
- "id": 15,
- "options": { "legend": { "calcs": ["mean", "lastNotNull"], "displayMode": "table", "placement": "bottom" }, "tooltip": { "mode": "multi", "sort": "desc" } },
- "title": "CPU Request vs Actual Usage by Namespace",
- "type": "timeseries",
- "targets": [
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "expr": "sum(kube_pod_container_resource_requests{resource=\"cpu\", unit=\"core\", namespace=~\"$namespace\"}) by (namespace)",
- "legendFormat": "{{namespace}} - Requested",
- "refId": "A"
- },
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "expr": "sum(rate(container_cpu_usage_seconds_total{namespace=~\"$namespace\", image!=\"\"}[5m])) by (namespace)",
- "legendFormat": "{{namespace}} - Actual",
- "refId": "B"
- }
- ]
- },
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "description": "Compare memory requests against actual usage to identify over-provisioning.",
- "fieldConfig": {
- "defaults": {
- "color": { "mode": "palette-classic" },
- "custom": { "axisBorderShow": false, "axisCenteredZero": false, "axisLabel": "Memory", "axisPlacement": "auto", "barAlignment": 0, "drawStyle": "line", "fillOpacity": 10, "gradientMode": "none", "lineInterpolation": "smooth", "lineWidth": 2, "pointSize": 5, "showPoints": "never", "stacking": { "group": "A", "mode": "none" } },
- "decimals": 2,
- "thresholds": { "mode": "absolute", "steps": [{ "color": "green", "value": null }] },
- "unit": "bytes"
- },
- "overrides": [
- {
- "matcher": { "id": "byRegexp", "options": "/Requested/" },
- "properties": [{ "id": "custom.lineStyle", "value": { "dash": [10, 10], "fill": "dash" } }, { "id": "custom.fillOpacity", "value": 0 }]
- }
- ]
- },
- "gridPos": { "h": 8, "w": 12, "x": 12, "y": 16 },
- "id": 16,
- "options": { "legend": { "calcs": ["mean", "lastNotNull"], "displayMode": "table", "placement": "bottom" }, "tooltip": { "mode": "multi", "sort": "desc" } },
- "title": "Memory Request vs Actual Usage by Namespace",
- "type": "timeseries",
- "targets": [
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "expr": "sum(kube_pod_container_resource_requests{resource=\"memory\", unit=\"byte\", namespace=~\"$namespace\"}) by (namespace)",
- "legendFormat": "{{namespace}} - Requested",
- "refId": "A"
- },
- {
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "expr": "sum(container_memory_working_set_bytes{namespace=~\"$namespace\", image!=\"\"}) by (namespace)",
- "legendFormat": "{{namespace}} - Actual",
- "refId": "B"
- }
- ]
- }
- ]
- }
- ],
- "refresh": "30s",
- "schemaVersion": 38,
- "tags": ["cost", "opencost", "upcloud"],
- "templating": {
- "list": [
- {
- "current": { "selected": false, "text": "Prometheus", "value": "Prometheus" },
- "hide": 0,
- "includeAll": false,
- "multi": false,
- "name": "datasource",
- "options": [],
- "query": "prometheus",
- "queryValue": "",
- "refresh": 1,
- "regex": "",
- "skipUrlSync": false,
- "type": "datasource"
- },
- {
- "allValue": ".*",
- "current": { "selected": true, "text": ["All"], "value": ["$__all"] },
- "datasource": { "type": "prometheus", "uid": "${datasource}" },
- "definition": "label_values(namespace)",
- "hide": 0,
- "includeAll": true,
- "multi": true,
- "name": "namespace",
- "options": [],
- "query": { "query": "label_values(namespace)", "refId": "StandardVariableQuery" },
- "refresh": 2,
- "regex": "",
- "skipUrlSync": false,
- "sort": 1,
- "type": "query"
- },
- {
- "current": { "selected": false, "text": "0", "value": "0" },
- "hide": 0,
- "label": "Sustained Use Discount %",
- "name": "useDiscount",
- "options": [{ "selected": true, "text": "0", "value": "0" }],
- "query": "0",
- "skipUrlSync": false,
- "type": "textbox"
- },
- {
- "current": { "selected": false, "text": "0.03", "value": "0.03" },
- "hide": 2,
- "label": "Local Storage GB Cost",
- "name": "localStorageGBCost",
- "options": [{ "selected": true, "text": "0.03", "value": "0.03" }],
- "query": "0.03",
- "skipUrlSync": false,
- "type": "constant"
- }
- ]
- },
- "time": { "from": "now-7d", "to": "now" },
- "timepicker": {
- "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h"],
- "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
- },
- "timezone": "",
- "title": "Cluster Cost Overview",
- "uid": "JOUdHGZZz",
- "version": 1,
- "weekStart": ""
- }