diff --git a/terraform/grafana/dashboards.tf b/terraform/grafana/dashboards.tf new file mode 100644 index 0000000..9f5f20e --- /dev/null +++ b/terraform/grafana/dashboards.tf @@ -0,0 +1,16 @@ +resource "grafana_dashboard" "energy" { + config_json = file("${path.module}/dashboards/energy.json") +} + +resource "grafana_dashboard" "grafana_cloud_usage" { + config_json = file("${path.module}/dashboards/grafana_cloud_usage.json") +} + +resource "grafana_dashboard" "living_room_display" { + config_json = file("${path.module}/dashboards/living_room_display.json") +} + +resource "grafana_dashboard" "traffic_slo" { + org_id = 0 + config_json = file("${path.module}/dashboards/traffic_slo.json") +} diff --git a/terraform/grafana/dashboards/energy.json b/terraform/grafana/dashboards/energy.json new file mode 100644 index 0000000..153fd46 --- /dev/null +++ b/terraform/grafana/dashboards/energy.json @@ -0,0 +1,1140 @@ +{ + "apiVersion": "dashboard.grafana.app/v2", + "kind": "Dashboard", + "metadata": { + "name": "5101a7c4-e5cd-4178-8acf-320588a7a25e", + "namespace": "stacks-1621083", + "uid": "f58db8b6-0cc4-47dd-8f94-9c0a04f2074d", + "resourceVersion": "1777800808563412", + "generation": 4, + "creationTimestamp": "2026-05-02T22:02:27Z", + "labels": { + "grafana.app/deprecatedInternalID": "10" + }, + "annotations": { + "grafana.app/createdBy": "user:ffkviz5ugketce", + "grafana.app/folder": "", + "grafana.app/saved-from-ui": "Grafana Cloud", + "grafana.app/updatedBy": "user:ffkviz5ugketce", + "grafana.app/updatedTimestamp": "2026-05-03T09:33:28Z" + } + }, + "spec": { + "annotations": [ + { + "kind": "AnnotationQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "grafana", + "version": "v0", + "datasource": { + "name": "-- Grafana --" + }, + "spec": {} + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "builtIn": true + } + } + ], + "cursorSync": "Off", + "editable": true, + "elements": { + "panel-1": { + "kind": "Panel", + "spec": { + "id": 1, + "title": "Wattage", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "editorMode": "builder", + "expr": "octopus_electricity_demand_watts{instance=\"localhost:9359\"}", + "legendFormat": "Watts", + "range": true + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "13.1.0-25098815508", + "spec": { + "options": { + "annotations": { + "clustering": -1, + "multiLane": false + }, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "axisSoftMin": 0, + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] + } + } + } + } + }, + "panel-10": { + "kind": "Panel", + "spec": { + "id": 10, + "title": "Price", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "editorMode": "code", + "expr": "sum_over_time((octopus_electricity_consumption_kwh{instance=\"localhost:9359\"} * on() octopus_electricity_unit_rate_pence{instance=\"localhost:9359\"})[$__range:30m]) / 100", + "legendFormat": "__auto", + "range": true + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": { + "timeFrom": "30d" + } + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "13.1.0-25098815508", + "spec": { + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "inverted", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": true, + "textMode": "auto", + "wideLayout": true + }, + "fieldConfig": { + "defaults": { + "unit": "currencyGBP", + "decimals": 2, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + } + } + } + } + }, + "panel-2": { + "kind": "Panel", + "spec": { + "id": 2, + "title": "Current Watts", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "editorMode": "code", + "exemplar": false, + "expr": "octopus_electricity_demand_watts{job=\"octopus_exporter\", instance=\"localhost:9359\"}", + "instant": true, + "legendFormat": "__auto", + "range": false + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "13.1.0-25098815508", + "spec": { + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "fieldConfig": { + "defaults": { + "unit": "watt", + "min": 0, + "max": 5000, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 1000, + "color": "yellow" + }, + { + "value": 2000, + "color": "red" + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + } + } + } + } + }, + "panel-3": { + "kind": "Panel", + "spec": { + "id": 3, + "title": "Average (30 min)", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "editorMode": "code", + "expr": "avg_over_time(octopus_electricity_demand_watts{instance=\"localhost:9359\"}[30m])", + "legendFormat": "__auto", + "range": true + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": { + "timeFrom": "30m" + } + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "13.1.0-25098815508", + "spec": { + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "inverted", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": true, + "textMode": "auto", + "wideLayout": true + }, + "fieldConfig": { + "defaults": { + "unit": "watt", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 1000, + "color": "#EAB839" + }, + { + "value": 2000, + "color": "red" + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + } + } + } + } + }, + "panel-4": { + "kind": "Panel", + "spec": { + "id": 4, + "title": "Average (1 day)", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "editorMode": "code", + "expr": "avg_over_time(octopus_electricity_demand_watts{instance=\"localhost:9359\"}[24h])", + "legendFormat": "__auto", + "range": true + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": { + "timeFrom": "1d" + } + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "13.1.0-25098815508", + "spec": { + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "inverted", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": true, + "textMode": "auto", + "wideLayout": true + }, + "fieldConfig": { + "defaults": { + "unit": "watt", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 1000, + "color": "#EAB839" + }, + { + "value": 2000, + "color": "red" + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + } + } + } + } + }, + "panel-5": { + "kind": "Panel", + "spec": { + "id": 5, + "title": "Average (7 days)", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "editorMode": "code", + "expr": "avg_over_time(octopus_electricity_demand_watts{instance=\"localhost:9359\"}[7d])", + "legendFormat": "__auto", + "range": true + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": { + "timeFrom": "7d" + } + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "13.1.0-25098815508", + "spec": { + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "inverted", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": true, + "textMode": "auto", + "wideLayout": true + }, + "fieldConfig": { + "defaults": { + "unit": "watt", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 1000, + "color": "#EAB839" + }, + { + "value": 2000, + "color": "red" + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + } + } + } + } + }, + "panel-6": { + "kind": "Panel", + "spec": { + "id": 6, + "title": "Average (6 hours)", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "editorMode": "code", + "expr": "avg_over_time(octopus_electricity_demand_watts{instance=\"localhost:9359\"}[6h])", + "legendFormat": "__auto", + "range": true + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": { + "timeFrom": "6h" + } + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "13.1.0-25098815508", + "spec": { + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "inverted", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": true, + "textMode": "auto", + "wideLayout": true + }, + "fieldConfig": { + "defaults": { + "unit": "watt", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 1000, + "color": "#EAB839" + }, + { + "value": 2000, + "color": "red" + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + } + } + } + } + }, + "panel-7": { + "kind": "Panel", + "spec": { + "id": 7, + "title": "Price", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "editorMode": "code", + "expr": "sum_over_time((octopus_electricity_consumption_kwh{instance=\"localhost:9359\"} * on() octopus_electricity_unit_rate_pence{instance=\"localhost:9359\"})[$__range:30m]) / 100", + "legendFormat": "__auto", + "range": true + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": { + "timeFrom": "1h" + } + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "13.1.0-25098815508", + "spec": { + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "inverted", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": true, + "textMode": "auto", + "wideLayout": true + }, + "fieldConfig": { + "defaults": { + "unit": "currencyGBP", + "decimals": 2, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + } + } + } + } + }, + "panel-8": { + "kind": "Panel", + "spec": { + "id": 8, + "title": "Price", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "editorMode": "code", + "expr": "sum_over_time((octopus_electricity_consumption_kwh{instance=\"localhost:9359\"} * on() octopus_electricity_unit_rate_pence{instance=\"localhost:9359\"})[$__range:30m]) / 100", + "legendFormat": "__auto", + "range": true + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": { + "timeFrom": "1d" + } + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "13.1.0-25098815508", + "spec": { + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "inverted", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": true, + "textMode": "auto", + "wideLayout": true + }, + "fieldConfig": { + "defaults": { + "unit": "currencyGBP", + "decimals": 2, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + } + } + } + } + }, + "panel-9": { + "kind": "Panel", + "spec": { + "id": 9, + "title": "Price", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "editorMode": "code", + "expr": "sum_over_time((octopus_electricity_consumption_kwh{instance=\"localhost:9359\"} * on() octopus_electricity_unit_rate_pence{instance=\"localhost:9359\"})[$__range:30m]) / 100", + "legendFormat": "__auto", + "range": true + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": { + "timeFrom": "1w" + } + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "13.1.0-25098815508", + "spec": { + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "inverted", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": true, + "textMode": "auto", + "wideLayout": true + }, + "fieldConfig": { + "defaults": { + "unit": "currencyGBP", + "decimals": 2, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + } + } + } + } + } + }, + "layout": { + "kind": "GridLayout", + "spec": { + "items": [ + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 0, + "width": 6, + "height": 6, + "element": { + "kind": "ElementReference", + "name": "panel-3" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 6, + "y": 0, + "width": 6, + "height": 6, + "element": { + "kind": "ElementReference", + "name": "panel-6" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 12, + "y": 0, + "width": 6, + "height": 6, + "element": { + "kind": "ElementReference", + "name": "panel-4" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 18, + "y": 0, + "width": 6, + "height": 6, + "element": { + "kind": "ElementReference", + "name": "panel-5" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 6, + "width": 18, + "height": 7, + "element": { + "kind": "ElementReference", + "name": "panel-1" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 18, + "y": 6, + "width": 6, + "height": 7, + "element": { + "kind": "ElementReference", + "name": "panel-2" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 13, + "width": 6, + "height": 6, + "element": { + "kind": "ElementReference", + "name": "panel-7" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 6, + "y": 13, + "width": 6, + "height": 6, + "element": { + "kind": "ElementReference", + "name": "panel-8" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 12, + "y": 13, + "width": 6, + "height": 6, + "element": { + "kind": "ElementReference", + "name": "panel-9" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 18, + "y": 13, + "width": 6, + "height": 6, + "element": { + "kind": "ElementReference", + "name": "panel-10" + } + } + } + ] + } + }, + "links": [], + "liveNow": true, + "preload": false, + "tags": [], + "timeSettings": { + "timezone": "browser", + "from": "now-24h", + "to": "now", + "autoRefresh": "1m", + "autoRefreshIntervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "hideTimepicker": false, + "fiscalYearStartMonth": 0 + }, + "title": "Energy", + "variables": [] + } +} \ No newline at end of file diff --git a/terraform/grafana/dashboards/grafana_cloud_usage.json b/terraform/grafana/dashboards/grafana_cloud_usage.json new file mode 100644 index 0000000..44a51b1 --- /dev/null +++ b/terraform/grafana/dashboards/grafana_cloud_usage.json @@ -0,0 +1,231 @@ +{ + "apiVersion": "dashboard.grafana.app/v2", + "kind": "Dashboard", + "metadata": { + "name": "rwx88sh", + "namespace": "stacks-1621083", + "uid": "339a5668-ef0b-4d4d-ab4a-552787f13239", + "resourceVersion": "1777799491857762", + "generation": 2, + "creationTimestamp": "2026-05-03T09:04:14Z", + "labels": { + "grafana.app/deprecatedInternalID": "1726166845087744" + }, + "annotations": { + "grafana.app/createdBy": "user:ffkviz5ugketce", + "grafana.app/folder": "", + "grafana.app/saved-from-ui": "Grafana Cloud", + "grafana.app/updatedBy": "user:ffkviz5ugketce", + "grafana.app/updatedTimestamp": "2026-05-03T09:11:31Z" + } + }, + "spec": { + "annotations": [ + { + "kind": "AnnotationQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "grafana", + "version": "v0", + "datasource": { + "name": "-- Grafana --" + }, + "spec": {} + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "builtIn": true + } + } + ], + "cursorSync": "Off", + "editable": true, + "elements": { + "panel-1": { + "kind": "Panel", + "spec": { + "id": 1, + "title": "Active Series", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-usage" + }, + "spec": { + "editorMode": "builder", + "expr": "grafanacloud_instance_active_series", + "legendFormat": "Active Series", + "range": true + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "13.1.0-25098815508", + "spec": { + "options": { + "annotations": { + "clustering": -1, + "multiLane": false + }, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "percentage", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 40, + "color": "#EAB839" + }, + { + "value": 60, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic", + "seriesBy": "last" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 27, + "gradientMode": "opacity", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineStyle": { + "fill": "solid" + }, + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] + } + } + } + } + } + }, + "layout": { + "kind": "AutoGridLayout", + "spec": { + "maxColumnCount": 3, + "columnWidthMode": "standard", + "rowHeightMode": "standard", + "items": [ + { + "kind": "AutoGridLayoutItem", + "spec": { + "element": { + "kind": "ElementReference", + "name": "panel-1" + } + } + } + ] + } + }, + "links": [], + "liveNow": false, + "preload": false, + "tags": [], + "timeSettings": { + "timezone": "browser", + "from": "now-6h", + "to": "now", + "autoRefresh": "", + "autoRefreshIntervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "hideTimepicker": false, + "fiscalYearStartMonth": 0 + }, + "title": "Grafana Cloud Usage", + "variables": [], + "preferences": { + "layout": { + "kind": "AutoGridLayout", + "spec": { + "maxColumnCount": 3, + "columnWidthMode": "standard", + "rowHeightMode": "standard", + "items": [] + } + } + } + } +} \ No newline at end of file diff --git a/terraform/grafana/dashboards/living_room_display.json b/terraform/grafana/dashboards/living_room_display.json new file mode 100644 index 0000000..f70caec --- /dev/null +++ b/terraform/grafana/dashboards/living_room_display.json @@ -0,0 +1,1401 @@ +{ + "apiVersion": "dashboard.grafana.app/v2", + "kind": "Dashboard", + "metadata": { + "name": "a68bd259-c836-4fad-b33e-98f1a52a5eb9", + "namespace": "stacks-1621083", + "uid": "b54f9c7b-7a8a-42cd-81d7-843b23f69137", + "resourceVersion": "1777805928919206", + "generation": 7, + "creationTimestamp": "2026-05-02T21:18:29Z", + "labels": { + "grafana.app/deprecatedInternalID": "1548558891634688" + }, + "annotations": { + "grafana.app/createdBy": "user:ffkviz5ugketce", + "grafana.app/folder": "", + "grafana.app/saved-from-ui": "Grafana Cloud", + "grafana.app/updatedBy": "user:ffkviz5ugketce", + "grafana.app/updatedTimestamp": "2026-05-03T10:58:48Z" + } + }, + "spec": { + "annotations": [ + { + "kind": "AnnotationQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "grafana", + "version": "v0", + "datasource": { + "name": "-- Grafana --" + }, + "spec": {} + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "builtIn": true + } + } + ], + "cursorSync": "Off", + "editable": true, + "elements": { + "panel-1": { + "kind": "Panel", + "spec": { + "id": 1, + "title": "CPU", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "editorMode": "code", + "expr": "100 * (1 - avg(rate(node_cpu_seconds_total{instance=\"london-b\", mode=\"idle\"}[$__rate_interval])))", + "legendFormat": "__auto", + "range": true + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "13.1.0-25153870157", + "spec": { + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "fieldConfig": { + "defaults": { + "unit": "percent", + "decimals": 1, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + } + } + } + } + }, + "panel-12": { + "kind": "Panel", + "spec": { + "id": 12, + "title": "Current Activity", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "disableTextWrap": false, + "editorMode": "builder", + "exemplar": false, + "expr": "plays_total{user!=\"Rasmus\"}", + "format": "table", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": true, + "legendFormat": "User", + "range": false, + "useBackend": false + } + }, + "refId": "A", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "editorMode": "code", + "exemplar": false, + "expr": "sum(plays_total) by (title)", + "format": "table", + "instant": true, + "legendFormat": "Title", + "range": false + } + }, + "refId": "B", + "hidden": true + } + } + ], + "transformations": [ + { + "kind": "Transformation", + "group": "filterFieldsByName", + "spec": { + "options": { + "include": { + "names": [ + "child_title", + "stream_resolution", + "stream_type", + "title", + "user", + "grandchild_title" + ] + } + } + } + }, + { + "kind": "Transformation", + "group": "organize", + "spec": { + "options": { + "excludeByName": {}, + "includeByName": {}, + "indexByName": { + "child_title": 2, + "grandchild_title": 3, + "stream_resolution": 5, + "stream_type": 4, + "title": 1, + "user": 0 + }, + "renameByName": { + "child_title": "Season", + "grandchild_title": "Episode Title", + "stream_resolution": "Resolution", + "stream_type": "Stream", + "title": "Title", + "user": "User" + } + } + } + } + ], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "table", + "version": "13.1.0-25153870157", + "spec": { + "options": { + "cellHeight": "sm", + "showHeader": true + }, + "fieldConfig": { + "defaults": { + "mappings": [ + { + "type": "value", + "options": { + "Mak999": { + "text": "Amar", + "index": 4 + }, + "Malene Wejlgaard Knudsen": { + "text": "Malene", + "index": 5 + }, + "d.han81": { + "text": "Han", + "index": 2 + }, + "er1227": { + "text": "Erik", + "index": 1 + }, + "guykeren437": { + "text": "Guy", + "index": 15 + }, + "isab579": { + "text": "Scoulers Daughter", + "index": 3 + }, + "naveen.629": { + "text": "Naveen", + "index": 6 + }, + "pe423": { + "text": "Living Room", + "index": 13 + }, + "praczyk.": { + "text": "Trevor", + "index": 7 + }, + "pravee63": { + "text": "Praveen", + "index": 8 + }, + "scou210": { + "text": "Scouler", + "index": 9 + }, + "sorghumc": { + "text": "Anton", + "index": 10 + }, + "theonet5": { + "text": "Trevor", + "index": 11 + }, + "theonetb": { + "text": "Trevor", + "index": 12 + }, + "wooley_82": { + "text": "Wooly", + "index": 0 + }, + "yp2xc": { + "text": "Trevor", + "index": 14 + } + } + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "filterable": false, + "footer": { + "reducers": [] + }, + "inspect": false + } + }, + "overrides": [] + } + } + } + } + }, + "panel-13": { + "kind": "Panel", + "spec": { + "id": 13, + "title": "Active Streams", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "disableTextWrap": false, + "editorMode": "code", + "exemplar": false, + "expr": "count(plays_total{user!=\"Rasmus\"})", + "format": "table", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": true, + "legendFormat": "__auto", + "range": false, + "useBackend": false + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "13.1.0-25153870157", + "spec": { + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "fieldConfig": { + "defaults": { + "min": 0, + "mappings": [ + { + "type": "value", + "options": { + "wooley_82": { + "text": "Wooly", + "index": 0 + } + } + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "thresholds" + }, + "noValue": "0", + "fieldMinMax": false + }, + "overrides": [] + } + } + } + } + }, + "panel-14": { + "kind": "Panel", + "spec": { + "id": 14, + "title": "Watts", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "editorMode": "code", + "expr": "octopus_electricity_demand_watts{instance=\"localhost:9359\"}", + "legendFormat": "__auto", + "range": true + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "13.1.0-25153870157", + "spec": { + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "fieldConfig": { + "defaults": { + "unit": "watt", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 1000, + "color": "yellow" + }, + { + "value": 2000, + "color": "red" + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + } + } + } + } + }, + "panel-15": { + "kind": "Panel", + "spec": { + "id": 15, + "title": "Octopus Account Bill", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "editorMode": "code", + "expr": "octopus_account_balance_pence{instance=\"localhost:9359\"} / 100 * -1", + "legendFormat": "__auto", + "range": true + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "13.1.0-25153870157", + "spec": { + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "fieldConfig": { + "defaults": { + "unit": "currencyGBP", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + } + } + } + } + }, + "panel-2": { + "kind": "Panel", + "spec": { + "id": 2, + "title": "HDD State", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "editorMode": "code", + "exemplar": false, + "expr": "node_zfs_zpool_state{instance=\"london-b\",zpool=\"hdd\", state=\"online\"} > 0", + "instant": true, + "legendFormat": "Online", + "range": false + } + }, + "refId": "A", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "editorMode": "code", + "exemplar": false, + "expr": "node_zfs_zpool_state{instance=\"london-b\",zpool=\"hdd\", state=\"degraded\"} > 0", + "instant": true, + "legendFormat": "Degraded", + "range": false + } + }, + "refId": "B", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "editorMode": "code", + "exemplar": false, + "expr": "node_zfs_zpool_state{instance=\"london-b\",zpool=\"hdd\", state=\"faulted\"} > 0", + "instant": true, + "legendFormat": "Faulted", + "range": false + } + }, + "refId": "C", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "editorMode": "code", + "exemplar": false, + "expr": "node_zfs_zpool_state{instance=\"london-b\",zpool=\"hdd\", state=\"offline\"} > 0", + "instant": true, + "legendFormat": "Offline", + "range": false + } + }, + "refId": "D", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "editorMode": "code", + "exemplar": false, + "expr": "node_zfs_zpool_state{instance=\"london-b\",zpool=\"hdd\", state=\"removed\"} > 0", + "instant": true, + "legendFormat": "Removed", + "range": false + } + }, + "refId": "E", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "editorMode": "code", + "exemplar": false, + "expr": "node_zfs_zpool_state{instance=\"london-b\",zpool=\"hdd\", state=\"suspended\"} > 0", + "instant": true, + "legendFormat": "Suspended", + "range": false + } + }, + "refId": "F", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "editorMode": "code", + "exemplar": false, + "expr": "node_zfs_zpool_state{instance=\"london-b\",zpool=\"hdd\", state=\"unavail\"} > 0", + "instant": true, + "legendFormat": "Unavailable", + "range": false + } + }, + "refId": "G", + "hidden": false + } + } + ], + "transformations": [ + { + "kind": "Transformation", + "group": "filterFieldsByName", + "spec": { + "options": { + "include": { + "names": [ + "Online" + ] + } + } + } + } + ], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "13.1.0-25153870157", + "spec": { + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/.*/", + "values": false + }, + "showPercentChange": false, + "textMode": "name", + "wideLayout": true + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + } + } + } + } + }, + "panel-3": { + "kind": "Panel", + "spec": { + "id": 3, + "title": "Memory", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "editorMode": "code", + "expr": "clamp_min((1 - (node_memory_MemAvailable_bytes{instance=\"london-b\"} / node_memory_MemTotal_bytes{instance=\"london-b\"})) * 100, 0)", + "legendFormat": "__auto", + "range": true + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "13.1.0-25153870157", + "spec": { + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "fieldConfig": { + "defaults": { + "unit": "percent", + "decimals": 1, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "#EAB839" + }, + { + "value": 90, + "color": "red" + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + } + } + } + } + }, + "panel-4": { + "kind": "Panel", + "spec": { + "id": 4, + "title": "HDD Space", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "editorMode": "code", + "expr": "node_filesystem_avail_bytes{instance=\"london-b\",mountpoint=\"/hdd\"}", + "legendFormat": "Available", + "range": true + } + }, + "refId": "A", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "editorMode": "code", + "expr": "node_filesystem_size_bytes{instance=\"london-b\",mountpoint=\"/hdd\"} - node_filesystem_avail_bytes{instance=\"london-b\",mountpoint=\"/hdd\"}", + "legendFormat": "Used", + "range": true + } + }, + "refId": "B", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "piechart", + "version": "13.1.0-25153870157", + "spec": { + "options": { + "displayLabels": [], + "legend": { + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "pieType": "donut", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "sort": "desc", + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "unit": "bytes", + "color": { + "mode": "palette-classic", + "fixedColor": "#73BF69" + }, + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + } + } + }, + "overrides": [] + } + } + } + } + }, + "panel-5": { + "kind": "Panel", + "spec": { + "id": 5, + "title": "Available Space", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "editorMode": "code", + "expr": "node_filesystem_avail_bytes{instance=\"london-b\",mountpoint=\"/hdd\"}", + "legendFormat": "__auto", + "range": true + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "13.1.0-25153870157", + "spec": { + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "fieldConfig": { + "defaults": { + "unit": "bytes", + "decimals": 1, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + } + } + } + } + }, + "panel-6": { + "kind": "Panel", + "spec": { + "id": 6, + "title": "Used Space", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "editorMode": "code", + "expr": "node_filesystem_size_bytes{instance=\"london-b\",mountpoint=\"/hdd\"} - node_filesystem_avail_bytes{instance=\"london-b\",mountpoint=\"/hdd\"}", + "legendFormat": "__auto", + "range": true + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "13.1.0-25153870157", + "spec": { + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "fieldConfig": { + "defaults": { + "unit": "bytes", + "decimals": 1, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + } + } + } + } + } + }, + "layout": { + "kind": "GridLayout", + "spec": { + "items": [ + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 0, + "width": 5, + "height": 5, + "element": { + "kind": "ElementReference", + "name": "panel-1" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 5, + "y": 0, + "width": 6, + "height": 5, + "element": { + "kind": "ElementReference", + "name": "panel-14" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 11, + "y": 0, + "width": 7, + "height": 10, + "element": { + "kind": "ElementReference", + "name": "panel-4" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 18, + "y": 0, + "width": 6, + "height": 5, + "element": { + "kind": "ElementReference", + "name": "panel-2" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 5, + "width": 5, + "height": 5, + "element": { + "kind": "ElementReference", + "name": "panel-3" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 5, + "y": 5, + "width": 6, + "height": 5, + "element": { + "kind": "ElementReference", + "name": "panel-15" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 18, + "y": 5, + "width": 3, + "height": 5, + "element": { + "kind": "ElementReference", + "name": "panel-5" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 21, + "y": 5, + "width": 3, + "height": 5, + "element": { + "kind": "ElementReference", + "name": "panel-6" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 10, + "width": 20, + "height": 9, + "element": { + "kind": "ElementReference", + "name": "panel-12" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 20, + "y": 10, + "width": 4, + "height": 9, + "element": { + "kind": "ElementReference", + "name": "panel-13" + } + } + } + ] + } + }, + "links": [], + "liveNow": true, + "preload": false, + "tags": [], + "timeSettings": { + "timezone": "browser", + "from": "now-24h", + "to": "now", + "autoRefresh": "30s", + "autoRefreshIntervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "hideTimepicker": false, + "fiscalYearStartMonth": 0, + "nowDelay": "0m" + }, + "title": "Living Room Display", + "variables": [] + } +} \ No newline at end of file diff --git a/terraform/grafana/dashboards/traffic_slo.json b/terraform/grafana/dashboards/traffic_slo.json new file mode 100644 index 0000000..ae2d5ba --- /dev/null +++ b/terraform/grafana/dashboards/traffic_slo.json @@ -0,0 +1,826 @@ +{ + "apiVersion": "dashboard.grafana.app/v2", + "kind": "Dashboard", + "metadata": { + "name": "384f28fe-2435-480f-a0f0-723ccdcf8b3b", + "namespace": "stacks-1621083", + "uid": "aef74b06-a1af-4a8e-ad1d-88d1208aeb6d", + "resourceVersion": "1777831196986612", + "generation": 2, + "creationTimestamp": "2026-05-03T17:57:39Z", + "labels": { + "grafana.app/deprecatedInternalID": "1860405031632896" + }, + "annotations": { + "grafana.app/createdBy": "user:ffkviz5ugketce", + "grafana.app/folder": "", + "grafana.app/saved-from-ui": "Grafana Cloud", + "grafana.app/updatedBy": "user:ffkviz5ugketce", + "grafana.app/updatedTimestamp": "2026-05-03T17:59:56Z" + } + }, + "spec": { + "annotations": [ + { + "kind": "AnnotationQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "grafana", + "version": "v0", + "datasource": { + "name": "-- Grafana --" + }, + "spec": {} + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "builtIn": true + } + } + ], + "cursorSync": "Off", + "editable": true, + "elements": { + "panel-1": { + "kind": "Panel", + "spec": { + "id": 1, + "title": "Traffic Rate by Service", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "disableTextWrap": false, + "editorMode": "code", + "expr": "sum(\n label_replace(\n rate(caddy_http_request_duration_seconds_count{handler!=\"metrics\", host=~\".*(pez.solutions|pez.sh)\"}[$__rate_interval]),\n \"host_prefix\",\n \"$1\",\n \"host\",\n \"([^.]+)\\\\..*\"\n )\n) by (host_prefix)", + "fullMetaSearch": false, + "includeNullMetadata": false, + "legendFormat": "{{host}}", + "range": true, + "useBackend": false + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "13.1.0-25153870157", + "spec": { + "options": { + "annotations": { + "clustering": -1, + "multiLane": false + }, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "unit": "reqps", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] + } + } + } + } + }, + "panel-2": { + "kind": "Panel", + "spec": { + "id": 2, + "title": "Response Codes (Good)", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "disableTextWrap": false, + "editorMode": "code", + "expr": "sum(rate(caddy_http_request_duration_seconds_count{code!~\"5.*\"}[$__rate_interval]))", + "fullMetaSearch": false, + "includeNullMetadata": false, + "legendFormat": "Good", + "range": true, + "useBackend": false + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "13.1.0-25153870157", + "spec": { + "options": { + "annotations": { + "clustering": -1, + "multiLane": false + }, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "unit": "reqps", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] + } + } + } + } + }, + "panel-3": { + "kind": "Panel", + "spec": { + "id": 3, + "title": "SLI", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "disableTextWrap": false, + "editorMode": "code", + "expr": "clamp_max(\n (sum(caddy_http_request_duration_seconds_count{host=~\".*(pez.solutions|pez.sh)\", code!~\"5.*\"}) / (sum(caddy_http_request_duration_seconds_count{host=~\".*(pez.solutions|pez.sh)\"}))) * 100,\n 99.999\n)", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "__auto", + "range": true, + "useBackend": false + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "13.1.0-25153870157", + "spec": { + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "fieldConfig": { + "defaults": { + "unit": "percent", + "decimals": 3, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "red" + }, + { + "value": 99.9, + "color": "yellow" + }, + { + "value": 99.99, + "color": "green" + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + } + } + } + } + }, + "panel-4": { + "kind": "Panel", + "spec": { + "id": 4, + "title": "SLI by Host", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "disableTextWrap": false, + "editorMode": "code", + "expr": "clamp_max(\n (\n sum(\n label_replace(\n caddy_http_request_duration_seconds_count{host=~\".*(pez.solutions|pez.sh)\", host!~\"(pez.sh|pez.solutions)\", code!~\"5.*\"},\n \"host_prefix\",\n \"$1\",\n \"host\",\n \"([^.]+)\\\\..*\"\n )\n ) by (host_prefix)\n /\n sum(\n label_replace(\n caddy_http_request_duration_seconds_count{host=~\".*(pez.solutions|pez.sh)\", host!~\"(pez.sh|pez.solutions)\"},\n \"host_prefix\",\n \"$1\",\n \"host\",\n \"([^.]+)\\\\..*\"\n )\n ) by (host_prefix)\n ) * 100,\n 99.999\n)", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "__auto", + "range": true, + "useBackend": false + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "13.1.0-25153870157", + "spec": { + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "center", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "fieldConfig": { + "defaults": { + "unit": "percent", + "decimals": 3, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "red" + }, + { + "value": 99.9, + "color": "yellow" + }, + { + "value": 99.99, + "color": "green" + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + } + } + } + } + }, + "panel-5": { + "kind": "Panel", + "spec": { + "id": 5, + "title": "Response Codes (Bad)", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "disableTextWrap": false, + "editorMode": "code", + "expr": "(sum(rate(caddy_http_request_duration_seconds_count{code=~\"5.*\"}[$__rate_interval])) by (code, host) > 0) or vector(0)", + "fullMetaSearch": false, + "includeNullMetadata": false, + "legendFormat": "{{code}} - {{host}}", + "range": true, + "useBackend": false + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "13.1.0-25153870157", + "spec": { + "options": { + "annotations": { + "clustering": -1, + "multiLane": false + }, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "unit": "reqps", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "axisSoftMin": 0, + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] + } + } + } + } + }, + "panel-6": { + "kind": "Panel", + "spec": { + "id": 6, + "title": "Active Services", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "grafanacloud-prom" + }, + "spec": { + "editorMode": "code", + "exemplar": false, + "expr": "sum(\n label_replace(\n rate(caddy_http_request_duration_seconds_count{handler!=\"metrics\", host=~\".*(pez.solutions|pez.sh)\", host!~\"(pez.sh|pez.solutions)\"}[$__rate_interval]),\n \"host_prefix\",\n \"$1\",\n \"host\",\n \"([^.]+)\\\\..*\"\n )\n) by (host_prefix) > 0", + "format": "table", + "instant": true, + "legendFormat": "__auto", + "range": false + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [ + { + "kind": "Transformation", + "group": "organize", + "spec": { + "options": { + "excludeByName": { + "Time": true + }, + "includeByName": {}, + "indexByName": {}, + "renameByName": { + "Value": "req/s", + "host_prefix": "Service" + } + } + } + } + ], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "table", + "version": "13.1.0-25153870157", + "spec": { + "options": { + "cellHeight": "sm", + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "req/s" + } + ] + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "footer": { + "reducers": [] + }, + "inspect": false + } + }, + "overrides": [] + } + } + } + } + } + }, + "layout": { + "kind": "GridLayout", + "spec": { + "items": [ + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 0, + "width": 4, + "height": 10, + "element": { + "kind": "ElementReference", + "name": "panel-3" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 4, + "y": 0, + "width": 20, + "height": 10, + "element": { + "kind": "ElementReference", + "name": "panel-4" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 10, + "width": 19, + "height": 11, + "element": { + "kind": "ElementReference", + "name": "panel-1" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 19, + "y": 10, + "width": 5, + "height": 11, + "element": { + "kind": "ElementReference", + "name": "panel-6" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 21, + "width": 12, + "height": 11, + "element": { + "kind": "ElementReference", + "name": "panel-2" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 12, + "y": 21, + "width": 12, + "height": 11, + "element": { + "kind": "ElementReference", + "name": "panel-5" + } + } + } + ] + } + }, + "links": [], + "liveNow": false, + "preload": false, + "tags": [], + "timeSettings": { + "timezone": "browser", + "from": "now-24h", + "to": "now", + "autoRefresh": "5s", + "autoRefreshIntervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "hideTimepicker": false, + "fiscalYearStartMonth": 0 + }, + "title": "Traffic / SLO", + "variables": [] + } +} \ No newline at end of file diff --git a/terraform/grafana/fleet_collectors.tf b/terraform/grafana/fleet_collectors.tf new file mode 100644 index 0000000..471f8bd --- /dev/null +++ b/terraform/grafana/fleet_collectors.tf @@ -0,0 +1,48 @@ +resource "grafana_fleet_management_collector" "london_a" { + id = "london-a" + remote_attributes = { + location = "london" + } +} + +resource "grafana_fleet_management_collector" "london_b" { + id = "london-b" + remote_attributes = { + location = "london" + } +} + +resource "grafana_fleet_management_collector" "london_c" { + id = "london-c" + remote_attributes = { + location = "london" + } +} + +resource "grafana_fleet_management_collector" "copenhagen_a" { + id = "copenhagen-a" + remote_attributes = { + location = "copenhagen" + } +} + +resource "grafana_fleet_management_collector" "copenhagen_c" { + id = "copenhagen-c" + remote_attributes = { + location = "copenhagen" + } +} + +resource "grafana_fleet_management_collector" "helsinki_a" { + id = "helsinki-a" + remote_attributes = { + location = "cloud" + } +} + +resource "grafana_fleet_management_collector" "nuremberg_a" { + id = "nuremberg-a" + remote_attributes = { + location = "cloud" + } +} diff --git a/terraform/grafana/fleet_pipelines.tf b/terraform/grafana/fleet_pipelines.tf new file mode 100644 index 0000000..ee96fd5 --- /dev/null +++ b/terraform/grafana/fleet_pipelines.tf @@ -0,0 +1,29 @@ +resource "grafana_fleet_management_pipeline" "linux_node_linux" { + name = "linux_node_linux" + matchers = ["collector.os=\"linux\""] + contents = file("${path.module}/fleet_pipelines/linux_node_linux.alloy") +} + +resource "grafana_fleet_management_pipeline" "octopus_exporter" { + name = "octopus_exporter" + matchers = ["collector.ID=\"london-c\""] + contents = file("${path.module}/fleet_pipelines/octopus_exporter.alloy") +} + +resource "grafana_fleet_management_pipeline" "plex" { + name = "plex" + matchers = ["collector.ID=\"london-b\""] + contents = file("${path.module}/fleet_pipelines/plex.alloy") +} + +resource "grafana_fleet_management_pipeline" "caddy_linux" { + name = "caddy_linux" + matchers = ["collector.ID=\"helsinki-a\""] + contents = file("${path.module}/fleet_pipelines/caddy_linux.alloy") +} + +resource "grafana_fleet_management_pipeline" "docker_linux" { + name = "docker_linux" + matchers = ["collector.os=\"linux\""] + contents = file("${path.module}/fleet_pipelines/docker_linux.alloy") +} diff --git a/terraform/grafana/fleet_pipelines/caddy_linux.alloy b/terraform/grafana/fleet_pipelines/caddy_linux.alloy new file mode 100644 index 0000000..65a89a9 --- /dev/null +++ b/terraform/grafana/fleet_pipelines/caddy_linux.alloy @@ -0,0 +1,37 @@ +discovery.relabel "metrics_integrations_integrations_caddy" { + targets = [{ + __address__ = "localhost:2019", + }] + + rule { + target_label = "instance" + replacement = constants.hostname + } +} + +prometheus.scrape "metrics_integrations_integrations_caddy" { + targets = discovery.relabel.metrics_integrations_integrations_caddy.output + forward_to = [prometheus.relabel.metrics_integrations_integrations_caddy.receiver] + job_name = "integrations/caddy" +} + +prometheus.relabel "metrics_integrations_integrations_caddy" { + forward_to = [prometheus.remote_write.metrics_service.receiver] + + rule { + source_labels = ["__name__"] + regex = "up|caddy_http_request_duration_seconds_bucket|caddy_http_request_duration_seconds_count|caddy_http_requests_in_flight|caddy_http_requests_total" + action = "keep" + } +} + +prometheus.remote_write "metrics_service" { + endpoint { + url = "https://prometheus-prod-55-prod-gb-south-1.grafana.net/api/prom/push" + + basic_auth { + username = "3166394" + password = sys.env("GCLOUD_RW_API_KEY") + } + } +} diff --git a/terraform/grafana/fleet_pipelines/docker_linux.alloy b/terraform/grafana/fleet_pipelines/docker_linux.alloy new file mode 100644 index 0000000..2067191 --- /dev/null +++ b/terraform/grafana/fleet_pipelines/docker_linux.alloy @@ -0,0 +1,92 @@ +prometheus.exporter.cadvisor "integrations_cadvisor" { + docker_only = true +} + +discovery.relabel "integrations_cadvisor" { + targets = prometheus.exporter.cadvisor.integrations_cadvisor.targets + + rule { + target_label = "job" + replacement = "integrations/docker" + } + + rule { + target_label = "instance" + replacement = constants.hostname + } +} + +prometheus.relabel "integrations_cadvisor" { + forward_to = [prometheus.remote_write.metrics_service.receiver] + + rule { + source_labels = ["__name__"] + regex = "container_cpu_usage_seconds_total|container_fs_reads_total|container_fs_usage_bytes|container_fs_writes_total|container_last_seen|container_memory_usage_bytes|container_network_receive_bytes_total|container_network_receive_errors_total|container_network_receive_packets_dropped_total|container_network_transmit_bytes_total|container_network_transmit_errors_total|container_network_transmit_packets_dropped_total|container_spec_memory_reservation_limit_bytes|machine_memory_bytes|machine_scrape_error|up" + action = "keep" + } +} + +prometheus.scrape "integrations_cadvisor" { + targets = discovery.relabel.integrations_cadvisor.output + forward_to = [prometheus.relabel.integrations_cadvisor.receiver] +} + +prometheus.remote_write "metrics_service" { + endpoint { + url = "https://prometheus-prod-55-prod-gb-south-1.grafana.net/api/prom/push" + + basic_auth { + username = "3166394" + password = sys.env("GCLOUD_RW_API_KEY") + } + } +} + +discovery.docker "logs_integrations_docker" { + host = "unix:///var/run/docker.sock" + refresh_interval = "5s" +} + +discovery.relabel "logs_integrations_docker" { + targets = [] + + rule { + target_label = "job" + replacement = "integrations/docker" + } + + rule { + target_label = "instance" + replacement = constants.hostname + } + + rule { + source_labels = ["__meta_docker_container_name"] + regex = "/(.*)" + target_label = "container" + } + + rule { + source_labels = ["__meta_docker_container_log_stream"] + target_label = "stream" + } +} + +loki.source.docker "logs_integrations_docker" { + host = "unix:///var/run/docker.sock" + targets = discovery.docker.logs_integrations_docker.targets + forward_to = [loki.write.grafana_cloud_loki.receiver] + relabel_rules = discovery.relabel.logs_integrations_docker.rules + refresh_interval = "5s" +} + +loki.write "grafana_cloud_loki" { + endpoint { + url = "https://logs-prod-035.grafana.net/loki/api/v1/push" + + basic_auth { + username = "1578872" + password = sys.env("GCLOUD_RW_API_KEY") + } + } +} \ No newline at end of file diff --git a/terraform/grafana/fleet_pipelines/linux_node_linux.alloy b/terraform/grafana/fleet_pipelines/linux_node_linux.alloy new file mode 100644 index 0000000..d5feb30 --- /dev/null +++ b/terraform/grafana/fleet_pipelines/linux_node_linux.alloy @@ -0,0 +1,126 @@ +discovery.relabel "integrations_node_exporter" { + targets = prometheus.exporter.unix.integrations_node_exporter.targets + + rule { + target_label = "instance" + replacement = constants.hostname + } + + rule { + target_label = "job" + replacement = "integrations/node_exporter" + } +} + +prometheus.exporter.unix "integrations_node_exporter" { + disable_collectors = ["ipvs", "btrfs", "infiniband", "xfs"] + + filesystem { + fs_types_exclude = "^(autofs|binfmt_misc|bpf|cgroup2?|configfs|debugfs|devpts|devtmpfs|tmpfs|fusectl|hugetlbfs|iso9660|mqueue|nsfs|overlay|proc|procfs|pstore|rpc_pipefs|securityfs|selinuxfs|squashfs|sysfs|tracefs)$" + mount_points_exclude = "^/(dev|proc|run/credentials/.+|sys|var/lib/docker/.+)($|/)" + mount_timeout = "5s" + } + + netclass { + ignored_devices = "^(veth.*|cali.*|[a-f0-9]{15})$" + } + + netdev { + device_exclude = "^(veth.*|cali.*|[a-f0-9]{15})$" + } +} + +prometheus.scrape "integrations_node_exporter" { + targets = discovery.relabel.integrations_node_exporter.output + forward_to = [prometheus.relabel.integrations_node_exporter.receiver] +} + +prometheus.relabel "integrations_node_exporter" { + forward_to = [prometheus.remote_write.metrics_service.receiver] + + rule { + source_labels = ["__name__"] + regex = "up|node_arp_entries|node_boot_time_seconds|node_context_switches_total|node_cpu_seconds_total|node_disk_io_time_seconds_total|node_disk_io_time_weighted_seconds_total|node_disk_read_bytes_total|node_disk_read_time_seconds_total|node_disk_reads_completed_total|node_disk_write_time_seconds_total|node_disk_writes_completed_total|node_disk_written_bytes_total|node_filefd_allocated|node_filefd_maximum|node_filesystem_avail_bytes|node_filesystem_device_error|node_filesystem_files|node_filesystem_files_free|node_filesystem_readonly|node_filesystem_size_bytes|node_intr_total|node_load1|node_load15|node_load5|node_md_disks|node_md_disks_required|node_memory_Active_anon_bytes|node_memory_Active_bytes|node_memory_Active_file_bytes|node_memory_AnonHugePages_bytes|node_memory_AnonPages_bytes|node_memory_Bounce_bytes|node_memory_Buffers_bytes|node_memory_Cached_bytes|node_memory_CommitLimit_bytes|node_memory_Committed_AS_bytes|node_memory_DirectMap1G_bytes|node_memory_DirectMap2M_bytes|node_memory_DirectMap4k_bytes|node_memory_Dirty_bytes|node_memory_HugePages_Free|node_memory_HugePages_Rsvd|node_memory_HugePages_Surp|node_memory_HugePages_Total|node_memory_Hugepagesize_bytes|node_memory_Inactive_anon_bytes|node_memory_Inactive_bytes|node_memory_Inactive_file_bytes|node_memory_Mapped_bytes|node_memory_MemAvailable_bytes|node_memory_MemFree_bytes|node_memory_MemTotal_bytes|node_memory_SReclaimable_bytes|node_memory_SUnreclaim_bytes|node_memory_ShmemHugePages_bytes|node_memory_ShmemPmdMapped_bytes|node_memory_Shmem_bytes|node_memory_Slab_bytes|node_memory_SwapTotal_bytes|node_memory_VmallocChunk_bytes|node_memory_VmallocTotal_bytes|node_memory_VmallocUsed_bytes|node_memory_WritebackTmp_bytes|node_memory_Writeback_bytes|node_netstat_Icmp6_InErrors|node_netstat_Icmp6_InMsgs|node_netstat_Icmp6_OutMsgs|node_netstat_Icmp_InErrors|node_netstat_Icmp_InMsgs|node_netstat_Icmp_OutMsgs|node_netstat_IpExt_InOctets|node_netstat_IpExt_OutOctets|node_netstat_TcpExt_ListenDrops|node_netstat_TcpExt_ListenOverflows|node_netstat_TcpExt_TCPSynRetrans|node_netstat_Tcp_InErrs|node_netstat_Tcp_InSegs|node_netstat_Tcp_OutRsts|node_netstat_Tcp_OutSegs|node_netstat_Tcp_RetransSegs|node_netstat_Udp6_InDatagrams|node_netstat_Udp6_InErrors|node_netstat_Udp6_NoPorts|node_netstat_Udp6_OutDatagrams|node_netstat_Udp6_RcvbufErrors|node_netstat_Udp6_SndbufErrors|node_netstat_UdpLite_InErrors|node_netstat_Udp_InDatagrams|node_netstat_Udp_InErrors|node_netstat_Udp_NoPorts|node_netstat_Udp_OutDatagrams|node_netstat_Udp_RcvbufErrors|node_netstat_Udp_SndbufErrors|node_network_carrier|node_network_info|node_network_mtu_bytes|node_network_receive_bytes_total|node_network_receive_compressed_total|node_network_receive_drop_total|node_network_receive_errs_total|node_network_receive_fifo_total|node_network_receive_multicast_total|node_network_receive_packets_total|node_network_speed_bytes|node_network_transmit_bytes_total|node_network_transmit_compressed_total|node_network_transmit_drop_total|node_network_transmit_errs_total|node_network_transmit_fifo_total|node_network_transmit_multicast_total|node_network_transmit_packets_total|node_network_transmit_queue_length|node_network_up|node_nf_conntrack_entries|node_nf_conntrack_entries_limit|node_os_info|node_sockstat_FRAG6_inuse|node_sockstat_FRAG_inuse|node_sockstat_RAW6_inuse|node_sockstat_RAW_inuse|node_sockstat_TCP6_inuse|node_sockstat_TCP_alloc|node_sockstat_TCP_inuse|node_sockstat_TCP_mem|node_sockstat_TCP_mem_bytes|node_sockstat_TCP_orphan|node_sockstat_TCP_tw|node_sockstat_UDP6_inuse|node_sockstat_UDPLITE6_inuse|node_sockstat_UDPLITE_inuse|node_sockstat_UDP_inuse|node_sockstat_UDP_mem|node_sockstat_UDP_mem_bytes|node_sockstat_sockets_used|node_softnet_dropped_total|node_softnet_processed_total|node_softnet_times_squeezed_total|node_systemd_unit_state|node_textfile_scrape_error|node_time_zone_offset_seconds|node_timex_estimated_error_seconds|node_timex_maxerror_seconds|node_timex_offset_seconds|node_timex_sync_status|node_uname_info|node_vmstat_oom_kill|node_vmstat_pgfault|node_vmstat_pgmajfault|node_vmstat_pgpgin|node_vmstat_pgpgout|node_vmstat_pswpin|node_vmstat_pswpout|process_max_fds|process_open_fds|node_zfs_zpool_state" + action = "keep" + } +} + +prometheus.remote_write "metrics_service" { + endpoint { + url = "https://prometheus-prod-55-prod-gb-south-1.grafana.net/api/prom/push" + + basic_auth { + username = "3166394" + password = sys.env("GCLOUD_RW_API_KEY") + } + } +} + +loki.relabel "integrations_node_exporter" { + forward_to = [loki.write.grafana_cloud_loki.receiver] + + rule { + target_label = "job" + replacement = "integrations/node_exporter" + } + + rule { + target_label = "instance" + replacement = constants.hostname + } +} + +journal_module "integrations_node_exporter" { + forward_to = [loki.relabel.integrations_node_exporter.receiver] +} + +//JOURNAL +declare "journal_module" { + argument "forward_to" { + optional = false + } + + loki.source.journal "default" { + max_age = "12h0m0s" + forward_to = [loki.process.default.receiver] + relabel_rules = loki.relabel.default.rules + } + + loki.relabel "default" { + rule { + source_labels = ["__journal__systemd_unit"] + target_label = "unit" + } + + rule { + source_labels = ["__journal__boot_id"] + target_label = "boot_id" + } + + rule { + source_labels = ["__journal__transport"] + target_label = "transport" + } + + rule { + source_labels = ["__journal_priority_keyword"] + target_label = "level" + } + forward_to = [] + } + + loki.process "default" { + forward_to = argument.forward_to.value + } +} + +loki.write "grafana_cloud_loki" { + endpoint { + url = "https://logs-prod-035.grafana.net/loki/api/v1/push" + + basic_auth { + username = "1578872" + password = sys.env("GCLOUD_RW_API_KEY") + } + } +} \ No newline at end of file diff --git a/terraform/grafana/fleet_pipelines/octopus_exporter.alloy b/terraform/grafana/fleet_pipelines/octopus_exporter.alloy new file mode 100644 index 0000000..12028bd --- /dev/null +++ b/terraform/grafana/fleet_pipelines/octopus_exporter.alloy @@ -0,0 +1,20 @@ +prometheus.remote_write "grafana_cloud" { + endpoint { + url = "https://prometheus-prod-55-prod-gb-south-1.grafana.net/api/prom/push" + + basic_auth { + username = "3166394" + password = sys.env("GCLOUD_RW_API_KEY") + } + } +} + +prometheus.scrape "octopus_exporter" { + targets = [ + { + "__address__" = "localhost:9359", + "job" = "octopus_exporter", + }, + ] + forward_to = [prometheus.remote_write.grafana_cloud.receiver] +} \ No newline at end of file diff --git a/terraform/grafana/fleet_pipelines/plex.alloy b/terraform/grafana/fleet_pipelines/plex.alloy new file mode 100644 index 0000000..de78427 --- /dev/null +++ b/terraform/grafana/fleet_pipelines/plex.alloy @@ -0,0 +1,20 @@ +prometheus.remote_write "grafana_cloud" { + endpoint { + url = "https://prometheus-prod-55-prod-gb-south-1.grafana.net/api/prom/push" + + basic_auth { + username = "3166394" + password = sys.env("GCLOUD_RW_API_KEY") + } + } +} + +prometheus.scrape "plex" { + targets = [ + { + "__address__" = "localhost:9000", + "job" = "plex", + }, + ] + forward_to = [prometheus.remote_write.grafana_cloud.receiver] +} \ No newline at end of file diff --git a/terraform/grafana/providers.tf b/terraform/grafana/providers.tf new file mode 100644 index 0000000..2d4ed20 --- /dev/null +++ b/terraform/grafana/providers.tf @@ -0,0 +1,8 @@ +terraform { + required_providers { + grafana = { + source = "grafana/grafana" + version = "~> 4.35" + } + } +} diff --git a/terraform/grafana/stack.tf b/terraform/grafana/stack.tf new file mode 100644 index 0000000..ed00085 --- /dev/null +++ b/terraform/grafana/stack.tf @@ -0,0 +1,5 @@ +resource "grafana_cloud_stack" "pez" { + name = "pez.grafana.net" + slug = "pez" + region_slug = "prod-gb-south-1" +} diff --git a/terraform/grafana/synthetic_check_alerts.tf b/terraform/grafana/synthetic_check_alerts.tf new file mode 100644 index 0000000..cbd7ffa --- /dev/null +++ b/terraform/grafana/synthetic_check_alerts.tf @@ -0,0 +1,72 @@ +resource "grafana_synthetic_monitoring_check_alerts" "pez_sh" { + check_id = grafana_synthetic_monitoring_check.pez_sh.id + alerts = [ + { + name = "ProbeFailedExecutionsTooHigh" + threshold = 3 + period = "30m" + runbook_url = "" + } + ] +} + +resource "grafana_synthetic_monitoring_check_alerts" "pez_solutions" { + check_id = grafana_synthetic_monitoring_check.pez_solutions.id + alerts = [ + { + name = "ProbeFailedExecutionsTooHigh" + threshold = 3 + period = "30m" + runbook_url = "" + } + ] +} + +resource "grafana_synthetic_monitoring_check_alerts" "jellyfin" { + check_id = grafana_synthetic_monitoring_check.jellyfin.id + alerts = [ + { + name = "ProbeFailedExecutionsTooHigh" + threshold = 3 + period = "30m" + runbook_url = "" + } + ] +} + +resource "grafana_synthetic_monitoring_check_alerts" "plex" { + check_id = grafana_synthetic_monitoring_check.plex.id + alerts = [ + { + name = "ProbeFailedExecutionsTooHigh" + threshold = 3 + period = "30m" + runbook_url = "" + } + ] +} + +resource "grafana_synthetic_monitoring_check_alerts" "request" { + check_id = grafana_synthetic_monitoring_check.request.id + alerts = [ + { + name = "ProbeFailedExecutionsTooHigh" + threshold = 3 + period = "30m" + runbook_url = "" + } + ] +} + +resource "grafana_synthetic_monitoring_check_alerts" "jellyfin-requests" { + check_id = grafana_synthetic_monitoring_check.jellyfin-requests.id + alerts = [ + { + name = "ProbeFailedExecutionsTooHigh" + threshold = 3 + period = "30m" + runbook_url = "" + } + ] +} + diff --git a/terraform/grafana/synthetic_checks.tf b/terraform/grafana/synthetic_checks.tf new file mode 100644 index 0000000..d46e224 --- /dev/null +++ b/terraform/grafana/synthetic_checks.tf @@ -0,0 +1,132 @@ +resource "grafana_synthetic_monitoring_check" "pez_sh" { + job = "pez.sh" + target = "https://pez.sh" + enabled = true + probes = [14] # 14 = London, UK + settings { + http { + method = "GET" + compression = "none" + fail_if_not_ssl = true + ip_version = "V4" + valid_http_versions = ["HTTP/2.0", "HTTP/1.1", "HTTP/1.0"] + valid_status_codes = ["200"] + } + } + frequency = 600000 + timeout = 3000 + lifecycle { + ignore_changes = [settings] + } +} + +resource "grafana_synthetic_monitoring_check" "pez_solutions" { + job = "pez.solutions" + target = "https://pez.solutions" + enabled = true + probes = [14] # 14 = London, UK + settings { + http { + method = "GET" + compression = "none" + fail_if_not_ssl = true + ip_version = "V4" + valid_http_versions = ["HTTP/2.0", "HTTP/1.1", "HTTP/1.0"] + valid_status_codes = ["200"] + } + } + frequency = 600000 + timeout = 3000 + lifecycle { + ignore_changes = [settings] + } +} + +resource "grafana_synthetic_monitoring_check" "jellyfin" { + job = "jellyfin.pez.sh" + target = "https://jellyfin.pez.sh" + enabled = true + probes = [14] # 14 = London, UK + settings { + http { + method = "GET" + compression = "none" + fail_if_not_ssl = true + ip_version = "V4" + valid_http_versions = ["HTTP/2.0", "HTTP/1.1", "HTTP/1.0"] + valid_status_codes = ["200"] + } + } + frequency = 600000 + timeout = 3000 + lifecycle { + ignore_changes = [settings] + } +} + +resource "grafana_synthetic_monitoring_check" "plex" { + job = "plex.pez.sh" + target = "https://plex.pez.sh" + enabled = true + probes = [14] # 14 = London, UK + settings { + http { + method = "GET" + headers = ["X-Plex-Token:${var.plex_token}"] + compression = "none" + fail_if_not_ssl = true + ip_version = "V4" + valid_http_versions = ["HTTP/2.0", "HTTP/1.1", "HTTP/1.0"] + valid_status_codes = ["200"] + } + } + frequency = 600000 + timeout = 3000 + lifecycle { + ignore_changes = [settings] + } +} + +resource "grafana_synthetic_monitoring_check" "request" { + job = "request.pez.sh" + target = "https://request.pez.sh" + enabled = true + probes = [14] # 14 = London, UK + settings { + http { + method = "GET" + compression = "none" + fail_if_not_ssl = true + ip_version = "V4" + valid_http_versions = ["HTTP/2.0", "HTTP/1.1", "HTTP/1.0"] + valid_status_codes = ["200"] + } + } + frequency = 600000 + timeout = 3000 + lifecycle { + ignore_changes = [settings] + } +} + +resource "grafana_synthetic_monitoring_check" "jellyfin-requests" { + job = "jellyfin-requests.pez.sh" + target = "https://jellyfin-requests.pez.sh" + enabled = true + probes = [14] # 14 = London, UK + settings { + http { + method = "GET" + compression = "none" + fail_if_not_ssl = true + ip_version = "V4" + valid_http_versions = ["HTTP/2.0", "HTTP/1.1", "HTTP/1.0"] + valid_status_codes = ["200"] + } + } + frequency = 600000 + timeout = 3000 + lifecycle { + ignore_changes = [settings] + } +} diff --git a/terraform/grafana/vars.tf b/terraform/grafana/vars.tf new file mode 100644 index 0000000..3cd8803 --- /dev/null +++ b/terraform/grafana/vars.tf @@ -0,0 +1,4 @@ +variable "plex_token" { + type = string + sensitive = true +}