Skip to content
This repository has been archived by the owner on Feb 11, 2024. It is now read-only.

Commit

Permalink
feat: add layout lib for Grafana dashboard (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
Xavier Basty authored Mar 31, 2023
1 parent 3f5fc8f commit 794b350
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 83 deletions.
11 changes: 11 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
root = true

[*]
charset = utf-8
end_of_line = lf
indent_size = 2
tab_width = 2
indent_style = space
insert_final_newline = true
max_line_length = 80
trim_trailing_whitespace = true
143 changes: 64 additions & 79 deletions terraform/monitoring/dashboard.jsonnet
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
local lib = import 'lib.libsonnet';
local layout = import 'layout.libsonnet';
local full_width = layout.full_width;
local half_width = layout.half_width;
local height = 8;

local grafana = import 'grafonnet/grafana.libsonnet';
local dashboard = grafana.dashboard;
Expand All @@ -7,8 +10,8 @@ local statPanel = grafana.statPanel;
local prometheus = grafana.prometheus;

local ds_prometheus = {
type: 'prometheus',
uid: std.extVar('prometheus_uid'),
type: 'prometheus',
uid: std.extVar('prometheus_uid'),
};

dashboard.new(
Expand All @@ -19,98 +22,80 @@ dashboard.new(
graphTooltip = 'shared_crosshair',
)
.addAnnotation(
annotation.default +
{
iconColor: 'rgba(0, 211, 255, 1)',
}
annotation.default {
iconColor: 'rgba(0, 211, 255, 1)',
}
)
.addPanel(
.addPanels(
layout.generate_grid([
statPanel.new(
title = 'Received Items per Hour',
description = 'The number of items received from relay',
datasource = ds_prometheus,
reducerFunction = 'lastNotNull',
title = 'Received Items per Hour',
description = 'The number of items received from relay',
datasource = ds_prometheus,
reducerFunction = 'lastNotNull',
)
.addTarget(prometheus.target(
expr = 'sum(rate(received_items{}[1h]))',
legendFormat = 'Received Items',
datasource = ds_prometheus,
)),
gridPos = {
x: 0, y: 0,
w: 10, h: 8
},
)
.addPanel(
expr = 'sum(rate(received_items{}[1h]))',
legendFormat = 'Received Items',
datasource = ds_prometheus,
))
{ gridPos: { w: half_width, h: height } },

statPanel.new(
title = 'Stored Items per Hour',
description = 'The number of items actually stored in the database',
datasource = ds_prometheus,
reducerFunction = 'lastNotNull',
title = 'Stored Items per Hour',
description = 'The number of items actually stored in the database',
datasource = ds_prometheus,
reducerFunction = 'lastNotNull',
)
.addTarget(prometheus.target(
expr = 'sum(rate(stored_items{}[1h]))',
legendFormat = 'Stored Items',
datasource = ds_prometheus,
)),
gridPos = {
x: 10, y: 0,
w: 10, h: 8
},
)
.addPanel(
expr = 'sum(rate(stored_items{}[1h]))',
legendFormat = 'Stored Items',
datasource = ds_prometheus,
))
{ gridPos: { w: half_width, h: height } },

statPanel.new(
title = 'Get Queries per Hour',
description = 'The number of items retrieval queries',
datasource = ds_prometheus,
reducerFunction = 'lastNotNull',
title = 'Get Queries per Hour',
description = 'The number of items retrieval queries',
datasource = ds_prometheus,
reducerFunction = 'lastNotNull',
)
.addTarget(prometheus.target(
expr = 'sum(rate(get_queries{}[1h]))',
legendFormat = '"Get" Queries',
datasource = ds_prometheus,
)),
gridPos = {
x: 0, y: 8,
w: 10, h: 8
},
)
.addPanel(
expr = 'sum(rate(get_queries{}[1h]))',
legendFormat = '"Get" Queries',
datasource = ds_prometheus,
))
{ gridPos: { w: half_width, h: height } },

statPanel.new(
title = 'Served Items per Hour',
description = 'The number of messages served to clients',
datasource = ds_prometheus,
reducerFunction = 'lastNotNull',
title = 'Served Items per Hour',
description = 'The number of messages served to clients',
datasource = ds_prometheus,
reducerFunction = 'lastNotNull',
)
.addTarget(prometheus.target(
expr = 'sum(rate(served_items{}[1h]))',
legendFormat = '"Get" Queries',
datasource = ds_prometheus,
)),
gridPos = {
x: 10, y: 8,
w: 10, h: 8
},
)
.addPanel(
expr = 'sum(rate(served_items{}[1h]))',
legendFormat = '"Get" Queries',
datasource = ds_prometheus,
))
{ gridPos: { w: half_width, h: height } },

statPanel.new(
title = 'Registrations per Hour',
description = 'The number of registrations retrievals',
datasource = ds_prometheus,
reducerFunction = 'lastNotNull',
title = 'Registrations per Hour',
description = 'The number of registrations retrievals',
datasource = ds_prometheus,
reducerFunction = 'lastNotNull',
)
.addTarget(prometheus.target(
expr = 'sum(rate(cached_registrations{}[1h]))',
legendFormat = 'Cache hits',
datasource = ds_prometheus,
expr = 'sum(rate(cached_registrations{}[1h]))',
legendFormat = 'Cache hits',
datasource = ds_prometheus,
))
.addTarget(prometheus.target(
expr = 'sum(rate(fetched_registrations{}[1h]))',
legendFormat = 'Cache misses',
datasource = ds_prometheus,
)),
gridPos = {
x: 0, y: 16,
w: 20, h: 8
},
expr = 'sum(rate(fetched_registrations{}[1h]))',
legendFormat = 'Cache misses',
datasource = ds_prometheus,
))
{ gridPos: { w: full_width, h: height } },
])
)
93 changes: 93 additions & 0 deletions terraform/monitoring/layout.libsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
local grid_width = 24;

{
full_width: grid_width,
half_width: grid_width / 2,
quarter_width: grid_width / 4,
heighth_width: grid_width / 8,

/**
* @name utils.generate_grid
*
* Generate Grafana grid, based on panels size.
* Should be called only once with the list of all panels that will be added.
* It puts panels from left to right, until there is a free space, and then uses new line.
* Line step on a new line break is the height of the last panel in a previous line.
* You can use rows as line breaks.
* For complex structures you can insert panels with pre-set position,
* but you must be careful to not introduce conflicts.
* If there are conflicts in grid, Grafana will solve them on import.
* Grafana's negative gravity will also be applied on import, it is not computed here.
* You should be careful with using both this and dynamic repeating with variables:
* static generator do not know about dynamic repeating,
* so Grafana conflict solver will be applied on import.
*
* @param panels List of panels (their width and height must be set in gridPos)
*
* @return List of panels with computed grid positions
*/
generate_grid(panels):: [
el {
gridPos: {
x: el.gridPos.x,
y: el.gridPos.y,
h: el.gridPos.h,
w: el.gridPos.w,
},
}
for el in std.foldl(function(_panels, p) (
local i = std.length(_panels);
local prev = (if i == 0 then null else _panels[i - 1]);

if i == 0 then
_panels + [p { gridPos: {
x: 0,
y: 0,
h: p.gridPos.h,
w: p.gridPos.w,
x_cursor: p.gridPos.w,
y_cursor: 0,
} }]
else
local line_break = prev.gridPos.x_cursor + p.gridPos.w > grid_width;

_panels + [p { gridPos: {
x:
if std.objectHas(p.gridPos, 'x') then
p.gridPos.x
else if line_break then
0
else
prev.gridPos.x_cursor,

y:
if std.objectHas(p.gridPos, 'y') then
p.gridPos.y
else if line_break then
prev.gridPos.y_cursor + prev.gridPos.h
else
prev.gridPos.y_cursor,

h: p.gridPos.h,

w: p.gridPos.w,

x_cursor:
if std.objectHas(p.gridPos, 'x') then
p.gridPos.x + p.gridPos.w
else if line_break then
p.gridPos.w
else
prev.gridPos.x_cursor + p.gridPos.w,

y_cursor:
if std.objectHas(p.gridPos, 'y') then
p.gridPos.y
else if line_break then
prev.gridPos.y_cursor + prev.gridPos.h
else
prev.gridPos.y_cursor,
} }]
), panels, [])
],
}
3 changes: 0 additions & 3 deletions terraform/monitoring/lib/lib.libsonnet

This file was deleted.

2 changes: 1 addition & 1 deletion terraform/monitoring/terraform.tf
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ terraform {
}

provider "jsonnet" {
jsonnet_path = "./lib/,./grafonnet"
jsonnet_path = "./grafonnet"
}

0 comments on commit 794b350

Please sign in to comment.