{ pkgs, lib }: let prom = { type = "prometheus"; uid = "prometheus"; }; loki = { type = "loki"; uid = "loki"; }; autoLayout = panels: let step = acc: panel: let w = panel.gridPos.w; h = panel.gridPos.h; wrap = acc.x + w > 24; x = if wrap then 0 else acc.x; y = if wrap then acc.y + acc.rowH else acc.y; rowH = if wrap then h else lib.max acc.rowH h; in { x = x + w; inherit y rowH; result = acc.result ++ [ ( panel // { gridPos = panel.gridPos // { inherit x y; }; } ) ]; }; in (lib.foldl' step { x = 0; y = 0; rowH = 0; result = [ ]; } panels).result; T = expr: legendFormat: { datasource = prom; inherit expr legendFormat; }; mkRow = title: { inherit title; type = "row"; collapsed = false; panels = [ ]; gridPos = { w = 24; h = 1; }; }; mkStat = { title, w ? 4, h ? 4, expr, unit ? "short", decimals ? 2, }: { inherit title; type = "stat"; datasource = prom; gridPos = { inherit w h; }; fieldConfig.defaults = { inherit unit decimals; color.mode = "thresholds"; thresholds = { mode = "absolute"; steps = [ { color = "blue"; value = null; } ]; }; }; options = { reduceOptions.calcs = [ "lastNotNull" ]; colorMode = "value"; textMode = "value"; }; targets = [ { datasource = prom; inherit expr; instant = true; legendFormat = ""; } ]; }; mkGauge = { title, w ? 4, h ? 4, expr, unit ? "percent", min ? 0, max ? 100, }: { inherit title; type = "gauge"; datasource = prom; gridPos = { inherit w h; }; fieldConfig.defaults = { inherit unit min max; thresholds = { mode = "absolute"; steps = [ { color = "green"; value = null; } { color = "yellow"; value = 70; } { color = "red"; value = 90; } ]; }; }; options = { reduceOptions.calcs = [ "lastNotNull" ]; orientation = "auto"; showThresholdLabels = false; showThresholdMarkers = true; }; targets = [ { datasource = prom; inherit expr; instant = true; legendFormat = ""; } ]; }; mkTs = { title, w ? 24, h ? 8, unit ? "short", targets, }: { inherit title targets; type = "timeseries"; datasource = prom; gridPos = { inherit w h; }; fieldConfig.defaults = { inherit unit; custom = { lineWidth = 1; fillOpacity = 5; }; color.mode = "palette-classic"; }; options = { tooltip.mode = "multi"; legend = { displayMode = "table"; placement = "bottom"; calcs = [ "mean" "max" "lastNotNull" ]; }; }; }; mkDashboard = { name, title, uid, from ? "now-1h", panels, templating ? [ ], }: pkgs.writeText name ( builtins.toJSON ( { inherit title uid; schemaVersion = 37; refresh = "30s"; time = { inherit from; to = "now"; }; panels = lib.imap1 (id: p: p // { inherit id; }) (autoLayout panels); } // lib.optionalAttrs (templating != [ ]) { templating.list = templating; } ) ); in { inherit prom loki autoLayout T mkRow mkStat mkGauge mkTs mkDashboard ; }