-
Notifications
You must be signed in to change notification settings - Fork 162
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Integrations common lib #1028
Integrations common lib #1028
Changes from all commits
3430ad1
5b574af
aac4467
6e6a921
baf69ab
e42c21b
d7c45aa
148a906
5e93a5f
947e73d
a775ca1
2f4d4df
853b407
7fcb5f1
ec9c420
3e4b5d0
a2edc2e
7e9f32f
5d48a2e
b533802
7966cdf
b1d644a
781c316
28b1fa9
e6a73d5
1a95561
07c9360
cc295d5
d4083ad
53493ed
90739d9
bf5ac34
12e239e
73d7cc0
e0d04c3
c54fa7b
52a4583
d8203a1
7570070
88a38dd
883e6f5
e18b1f6
643747a
ad669a8
0e23766
382d45d
974ff27
fe90390
5a6d0b2
dd0e353
fb90335
d1f4cc7
f695413
994137f
f6758a1
6d3a42d
7247c57
2c9bbf5
bc0fa62
ef263c4
83b36a8
cb1fb97
dede26b
869f93d
b9aa2f1
6d776a3
e1aa770
cb079c6
cfc250f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
|
||
## Panels overview | ||
|
||
All panels in this lib should implement one of the following methods: | ||
|
||
- `panel.new(title,targets,description)` - creates new panel. List of arguments could vary; | ||
- `panel.stylize(allLayers=true)` - directly applies this panel style to existing panel. By default includes all layers of styles. To apply only top layer, set allLayers=false. This mode is useful to cherry-pick style layers to create new style combination. | ||
|
||
Some other methods could be found such as: | ||
- `panel.stylizeByRegexp(regexp)` - attaches style as panel overrides (by regexp); | ||
- `panel.stylizeByName(name)` - attaches style as panel overrides (by name). | ||
|
||
## Panels common groups | ||
|
||
This library consists of multiple common groups of panels for widely used resources such as CPU, memory, disks and so on. | ||
|
||
All of those groups inherit `generic` group as their base. | ||
|
||
All panels inherit `generic/base.libsonnet` via `generic/<paneltype>/base.libsonnet`. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
JSONNET_FMT := jsonnetfmt -n 2 --max-blank-lines 1 --string-style s --comment-style s | ||
|
||
.PHONY: all | ||
all: build | ||
|
||
vendor: jsonnetfile.json | ||
jb install | ||
|
||
.PHONY: build | ||
build: vendor | ||
|
||
.PHONY: fmt | ||
fmt: | ||
find . -name 'vendor' -prune -o -name '*.libsonnet' -print -o -name '*.jsonnet' -print | \ | ||
xargs -n 1 -- $(JSONNET_FMT) -i | ||
|
||
.PHONY: lint | ||
lint: build | ||
find . -name 'vendor' -prune -o -name '*.libsonnet' -print -o -name '*.jsonnet' -print | \ | ||
while read f; do \ | ||
$(JSONNET_FMT) "$$f" | diff -u "$$f" -; \ | ||
done | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# Grafana integrations common lib | ||
|
||
This common library can be used to quickly create dashboards' `panels` and `annotations`. | ||
|
||
By using this common library we can 'enforce' common style choices across multiple dashboards and mixins. | ||
|
||
## Import | ||
|
||
```sh | ||
jb init | ||
jb install https://github.com/grafana/jsonnet-libs/common-lib | ||
``` | ||
|
||
## Use | ||
|
||
### Create new panel | ||
|
||
```jsonnet | ||
|
||
local commonlib = import 'github.com/grafana/jsonnet-libs/common-lib/common/main.libsonnet'; | ||
local cpuUsage = commonlib.panels.cpu.timeSeries.utilization.new(targets=[targets.cpuUsage]); | ||
|
||
``` | ||
|
||
### Mutate exisiting panel with style options | ||
|
||
```jsonnet | ||
|
||
local commonlib = import 'github.com/grafana/jsonnet-libs/common-lib/common/main.libsonnet'; | ||
local cpuPanel = oldPanel + commonlib.panels.cpu.timeSeries.utilization.stylize(); | ||
``` | ||
|
||
See [windows-observ-lib](./windows-observ-lib) for full example. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
local g = import '../g.libsonnet'; | ||
local annotation = g.dashboard.annotation; | ||
{ | ||
new( | ||
title, | ||
target, | ||
): | ||
annotation.withEnable(true) | ||
+ annotation.withName(title) | ||
+ annotation.withDatasourceMixin(target.datasource) | ||
{ | ||
titleFormat: title, | ||
expr: target.expr, | ||
|
||
} | ||
+ (if std.objectHas(target, 'interval') then { step: target.interval } else {}), | ||
|
||
withTagKeys(value): | ||
{ | ||
tagKeys: value, | ||
}, | ||
withValueForTime(value=false): | ||
{ | ||
useValueForTime: value, | ||
}, | ||
withTextFormat(value=''): | ||
{ | ||
textFormat: value, | ||
}, | ||
|
||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
local g = import '../g.libsonnet'; | ||
local annotation = g.dashboard.annotation; | ||
local base = import './base.libsonnet'; | ||
|
||
// Show fatal or critical events as annotations | ||
base { | ||
new( | ||
title, | ||
target, | ||
): | ||
super.new(title, target) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's no built-in logic for identifying fatal/critical events, which I believe is intentional. A user would define this by providing a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, you got it right. We just provide this annotation.fatal as prototype, where color choice is enforced for now. |
||
+ annotation.withIconColor('light-purple') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm a fan of purple... But.. Wouldn't fatal or critical events be red/orange? I haven't gotten through the other panels yet, but perhaps this is part of the embedded design language that's used throughout the library? If so, this is another good opportunity for expanded documentation. I.E. A table of colors, and where/why they're used. Also examples on how to override those values if you wish. Again, this is probably appropriate for a followup PR, with an issue to track. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just following colors used in grafana itself for autocoloring loki logs: https://github.com/grafana/grafana/blob/fe9f52097bb4717a7ebfac17a62f399a2ce0ba1b/docs/sources/explore/index.md#log-level There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ahh perfect! Still worth documenting it (again, in a future PR). I have a bias with purple. It's my favorite color, so I don't immediately associate it with "bad things". But I'm always reminded that it's "darker" than red, and thus more severe. :) |
||
+ annotation.withHide(true), | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
base: import './base.libsonnet', | ||
reboot: import './reboot.libsonnet', | ||
serviceFailed: import './service_failed.libsonnet', | ||
fatal: import './fatal.libsonnet', | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
local g = import '../g.libsonnet'; | ||
local annotation = g.dashboard.annotation; | ||
local base = import './base.libsonnet'; | ||
|
||
base { | ||
new( | ||
title, | ||
target, | ||
instanceLabels, | ||
): | ||
super.new(title, target) | ||
rgeyer marked this conversation as resolved.
Show resolved
Hide resolved
|
||
+ annotation.withIconColor('light-yellow') | ||
+ annotation.withHide(true) | ||
+ { useValueForTime: 'on' } | ||
+ base.withTagKeys(instanceLabels), | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
local g = import '../g.libsonnet'; | ||
local annotation = g.dashboard.annotation; | ||
local base = import './base.libsonnet'; | ||
|
||
base { | ||
new( | ||
title, | ||
target, | ||
): | ||
super.new(title, target) | ||
+ annotation.withIconColor('light-orange') | ||
+ annotation.withHide(true), | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
import 'github.com/grafana/grafonnet/gen/grafonnet-v10.0.0/main.libsonnet' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
annotations: import './annotations/main.libsonnet', | ||
panels: import './panels.libsonnet', | ||
utils: import './utils.libsonnet', | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
local g = import './g.libsonnet'; | ||
|
||
{ | ||
generic: { | ||
stat: import './panels/generic/stat/main.libsonnet', | ||
timeSeries: import './panels/generic/timeSeries/main.libsonnet', | ||
table: import './panels/generic/table/main.libsonnet', | ||
statusHistory: import './panels/generic/statusHistory/main.libsonnet', | ||
}, | ||
network: { | ||
timeSeries: import './panels/network/timeSeries/main.libsonnet', | ||
}, | ||
system: { | ||
stat: import './panels/system/stat/main.libsonnet', | ||
table: import './panels/system/table/main.libsonnet', | ||
statusHistory: import './panels/system/statusHistory/main.libsonnet', | ||
}, | ||
cpu: { | ||
stat: import './panels/cpu/stat/main.libsonnet', | ||
timeSeries: import './panels/cpu/timeSeries/main.libsonnet', | ||
}, | ||
memory: { | ||
stat: import './panels/memory/stat/main.libsonnet', | ||
timeSeries: import './panels/memory/timeSeries/main.libsonnet', | ||
}, | ||
disk: { | ||
timeSeries: import './panels/disk/timeSeries/main.libsonnet', | ||
table: import './panels/disk/table/main.libsonnet', | ||
stat: import './panels/disk/stat/main.libsonnet', | ||
}, | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
local g = import '../../../g.libsonnet'; | ||
local stat = g.panel.stat; | ||
local base = import '../../generic/stat/base.libsonnet'; | ||
|
||
base { | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
local g = import '../../../g.libsonnet'; | ||
local generic = import '../../generic/stat/main.libsonnet'; | ||
local base = import './base.libsonnet'; | ||
local stat = g.panel.stat; | ||
|
||
base { | ||
new( | ||
title='CPU count', | ||
targets, | ||
description=||| | ||
CPU count is the number of processor cores or central processing units (CPUs) in a computer, | ||
determining its processing capability and ability to handle tasks concurrently. | ||
||| | ||
): | ||
super.new(title, targets, description), | ||
|
||
stylize(allLayers=true): | ||
(if allLayers then super.stylize() else {}) | ||
+ generic.info.stylize(allLayers=false), | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
base: import './base.libsonnet', | ||
usage: import './usage.libsonnet', | ||
count: import './count.libsonnet', | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
local g = import '../../../g.libsonnet'; | ||
local generic = import '../../generic/stat/main.libsonnet'; | ||
local base = import './base.libsonnet'; | ||
local stat = g.panel.stat; | ||
|
||
base { | ||
new( | ||
title='CPU usage', | ||
targets, | ||
description=||| | ||
Total CPU utilization percent is a metric that indicates the overall level of central processing unit (CPU) usage in a computer system. | ||
It represents the combined load placed on all CPU cores or processors. | ||
|
||
For instance, if the total CPU utilization percent is 50%, it means that, | ||
on average, half of the CPU's processing capacity is being used to execute tasks. A higher percentage indicates that the CPU is working more intensively, potentially leading to system slowdowns if it remains consistently high. | ||
||| | ||
): | ||
super.new(title, targets, description), | ||
stylize(allLayers=true): | ||
(if allLayers then super.stylize() else {}) | ||
+ generic.percentage.stylize(allLayers=false), | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
local g = import '../../../g.libsonnet'; | ||
local base = import '../../generic/timeSeries/base.libsonnet'; | ||
|
||
base { | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
base: import './base.libsonnet', | ||
utilization: import './utilization.libsonnet', | ||
utilizationByMode: import './utilization_by_mode.libsonnet', | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
local g = import '../../../g.libsonnet'; | ||
local generic = import '../../generic/timeSeries/main.libsonnet'; | ||
local base = import './base.libsonnet'; | ||
base { | ||
new( | ||
title='CPU usage', | ||
targets, | ||
description=||| | ||
Total CPU utilization percent is a metric that indicates the overall level of central processing unit (CPU) usage in a computer system. | ||
It represents the combined load placed on all CPU cores or processors. | ||
|
||
For instance, if the total CPU utilization percent is 50%, it means that, | ||
on average, half of the CPU's processing capacity is being used to execute tasks. A higher percentage indicates that the CPU is working more intensively, potentially leading to system slowdowns if it remains consistently high. | ||
||| | ||
): | ||
super.new(title, targets, description) | ||
+ self.stylize(), | ||
|
||
stylize(allLayers=true): | ||
(if allLayers then super.stylize() else {}) | ||
+ generic.percentage.stylize(allLayers=false), | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
local g = import '../../../g.libsonnet'; | ||
local base = import './base.libsonnet'; | ||
base { | ||
new( | ||
title='CPU usage by modes', | ||
targets, | ||
description='CPU usage by different modes.' | ||
): | ||
super.new(title, targets, description) | ||
+ self.stylize(), | ||
|
||
stylize(allLayers=true): | ||
local timeSeries = g.panel.timeSeries; | ||
local fieldOverride = g.panel.timeSeries.fieldOverride; | ||
|
||
(if allLayers then super.stylize() else {}) | ||
|
||
+ timeSeries.standardOptions.withUnit('percent') | ||
+ timeSeries.fieldConfig.defaults.custom.withFillOpacity(80) | ||
+ timeSeries.fieldConfig.defaults.custom.withStacking({ mode: 'normal' }) | ||
+ timeSeries.standardOptions.withOverrides( | ||
[ | ||
fieldOverride.byName.new('idle') | ||
+ fieldOverride.byName.withPropertiesFromOptions( | ||
timeSeries.standardOptions.color.withMode('fixed') | ||
+ timeSeries.standardOptions.color.withFixedColor('light-blue'), | ||
), | ||
fieldOverride.byName.new('interrupt') | ||
+ fieldOverride.byName.withPropertiesFromOptions( | ||
timeSeries.standardOptions.color.withMode('fixed') | ||
+ timeSeries.standardOptions.color.withFixedColor('light-purple'), | ||
), | ||
fieldOverride.byName.new('user') | ||
+ fieldOverride.byName.withPropertiesFromOptions( | ||
timeSeries.standardOptions.color.withMode('fixed') | ||
+ timeSeries.standardOptions.color.withFixedColor('light-orange'), | ||
), | ||
fieldOverride.byRegexp.new('system|privileged') | ||
+ fieldOverride.byRegexp.withPropertiesFromOptions( | ||
timeSeries.standardOptions.color.withMode('fixed') | ||
+ timeSeries.standardOptions.color.withFixedColor('light-red'), | ||
), | ||
] | ||
), | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
local g = import '../../../g.libsonnet'; | ||
local stat = g.panel.stat; | ||
local base = import '../../generic/stat/base.libsonnet'; | ||
|
||
base { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
base: import './base.libsonnet', | ||
total: import './total.libsonnet', | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
local g = import '../../../g.libsonnet'; | ||
local generic = import '../../generic/stat/main.libsonnet'; | ||
local base = import './base.libsonnet'; | ||
local stat = g.panel.stat; | ||
|
||
base { | ||
new( | ||
title, | ||
targets, | ||
description='' | ||
): | ||
super.new(title=title, targets=targets, description=description), | ||
|
||
stylize(allLayers=true): | ||
|
||
(if allLayers then super.stylize() else {}) | ||
|
||
+ generic.info.stylize(allLayers=false) | ||
+ stat.standardOptions.withUnit('bytes'), | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
local g = import '../../../g.libsonnet'; | ||
local base = import '../../generic/table/base.libsonnet'; | ||
local table = g.panel.table; | ||
local fieldOverride = g.panel.table.fieldOverride; | ||
local custom = table.fieldConfig.defaults.custom; | ||
local defaults = table.fieldConfig.defaults; | ||
local options = table.options; | ||
base { | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
base: import './base.libsonnet', | ||
usage: import './usage.libsonnet', | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we document the concept of "layers" here a bit more thoroughly? The concept is not immediately apparent from the
CONTRIB.md
orREADME.md
.It looks like what is meant is if you, for example, apply stylize from
panels/network/timeseries/packets/
, withallLayers
you will effectively apply not only the styles specific to a network packets timeseries (ingress above 0, egress below 0), but also the default style frompanels/generic/timeseries
?Possibly an architecture diagram of the layout of this lib would be useful.
Also, I would advise that this get added to a follow-up PR, and we create an issue to track. No need to hold the merging of this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
correct. I'll try to expand documentation once we came to terms.