Skip to content

Commit 3ff3c72

Browse files
committed
feat: add netflow-mixin
This mixin is intended to be used with tools like [ktranslate](https://github.com/kentik/ktranslate) but will also work with other tooling, as long as the metrics conform to the [networking semantic conventions](https://opentelemetry.io/docs/specs/semconv/registry/attributes/network/).
1 parent c014522 commit 3ff3c72

File tree

12 files changed

+2109
-0
lines changed

12 files changed

+2109
-0
lines changed

netflow-mixin/.lint

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
exclusions:
2+
target-instance-rule:
3+
reason: "Instance based filtering does not make sense here. Using device_name as reported by ktranslate instead"
4+
template-instance-rule:
5+
reason: "Instance based filtering does not make sense here. Using device_name as reported by ktranslate instead"
6+
panel-datasource-rule:
7+
reason: "newer grafonnet versions use -- Mixed -- data sources and specify the template at the query level"
8+
panel-title-description-rule:
9+
reason: "no title on purpose"
10+
entries:
11+
- id: 2
12+
- id: 15
13+
- id: 17
14+
target-job-rule:
15+
reason: "Status panel queries require exact match and not regex match"
16+
entries:
17+
- panel: "Metrics"
18+
- panel: "Latest metrics received"
19+
- panel: "Logs"
20+
- panel: "Latest logs received"
21+
- panel: "Collector logs"
22+
panel-no-targets-rule:
23+
reason: "Fixed static value - no target required"
24+
entries:
25+
- panel: "Integration version"

netflow-mixin/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
include ../Makefile_mixin

netflow-mixin/README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Netflow Mixin
2+
3+
The Netflow mixin is a set of configurable Grafana dashboards for visualizing network flows.
4+
It is based on the [OpenTelemetry semantic conventions for networking](https://opentelemetry.io/docs/specs/semconv/registry/attributes/network/).
5+
6+
The Netflow mixin contains the following dashboards:
7+
- Netflow Overview
8+
9+
## Netflow Overview
10+
11+
12+
![First screenshot of the overview dashboard](https://storage.googleapis.com/grafanalabs-integration-assets/ktranslate-netflow/netflow-overview.png)
13+
![Second screenshot of the overview dashboard](https://storage.googleapis.com/grafanalabs-integration-assets/ktranslate-netflow/netflow-overview-2.png)
14+
15+
16+
## Install tools
17+
18+
```bash
19+
go install github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb@latest
20+
go install github.com/monitoring-mixins/mixtool/cmd/mixtool@latest
21+
```
22+
23+
For linting and formatting, you would also need and `jsonnetfmt` installed. If you
24+
have a working Go development environment, it's easiest to run the following:
25+
26+
```bash
27+
go install github.com/google/go-jsonnet/cmd/jsonnetfmt@latest
28+
```
29+
30+
The files in `dashboards_out` need to be imported
31+
into your Grafana server. The exact details will be depending on your environment.
32+
33+
## Generate dashboards
34+
35+
Edit `config.libsonnet` if required and then build JSON dashboard files for Grafana:
36+
37+
```bash
38+
make
39+
```
40+
41+
For more advanced uses of mixins, see
42+
https://github.com/monitoring-mixins/docs.

netflow-mixin/config.libsonnet

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
_config+:: {
3+
dashboardTags: ['neflow-mixin'],
4+
dashboardPeriod: 'now-1h',
5+
dashboardTimezone: 'default',
6+
dashboardRefresh: '1m',
7+
},
8+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
(import 'netflow-overview.libsonnet')
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
local g = import 'github.com/grafana/grafonnet/gen/grafonnet-latest/main.libsonnet';
2+
local var = g.dashboard.variable;
3+
4+
local panels = import 'panels.libsonnet';
5+
6+
7+
local labelVar = function(label, title=label) var.query.new(label, 'network_io_bytes')
8+
+ var.query.refresh.onTime()
9+
+ var.query.generalOptions.withLabel(title)
10+
+ var.query.queryTypes.withLabelValues(
11+
label,
12+
)
13+
+ var.query.withDatasource(
14+
type='prometheus',
15+
uid='$prometheus_datasource',
16+
)
17+
+ var.query.selectionOptions.withMulti()
18+
+ var.query.selectionOptions.withIncludeAll(customAllValue='.+');
19+
local withPos(x, y, h, w) = { gridPos+: { x: x, y: y, h: h, w: w } };
20+
21+
local dashboardUid = 'netflow-overview';
22+
23+
{
24+
grafanaDashboards+:: {
25+
'netflow-overview.json':
26+
g.dashboard.new('Netflow overview')
27+
+ g.dashboard.withUid(dashboardUid)
28+
+ g.dashboard.withTags($._config.dashboardTags)
29+
+ g.dashboard.time.withFrom($._config.dashboardPeriod)
30+
+ g.dashboard.withRefresh($._config.dashboardRefresh)
31+
+ g.dashboard.withTimezone($._config.dashboardTimezone)
32+
+ g.dashboard.withVariables([
33+
var.datasource.new('prometheus_datasource', 'prometheus')
34+
+ var.datasource.withRegex('(ops|dev)-cortex')
35+
+ var.query.generalOptions.withLabel('Prometheus data source'),
36+
var.datasource.new('loki_datasource', 'loki')
37+
+ var.query.generalOptions.withLabel('Loki data source'),
38+
labelVar('job', 'Job')
39+
+ var.query.generalOptions.showOnDashboard.withNothing(),
40+
labelVar('device_name', 'Device name'),
41+
labelVar('network_local_address', 'Source'),
42+
labelVar('network_peer_address', 'Destination'),
43+
])
44+
+ g.dashboard.withPanels([
45+
panels.totalTraffic
46+
+ withPos(0, 1, 5, 15),
47+
panels.stats
48+
+ withPos(15, 1, 5, 9),
49+
panels.topSources
50+
+ withPos(0, 6, 8, 12),
51+
panels.topDestinations
52+
+ withPos(12, 6, 8, 12),
53+
g.panel.row.new('Conversations')
54+
+ withPos(0, 14, 1, 24),
55+
panels.conversationTotalBytes
56+
+ withPos(0, 15, 15, 15),
57+
panels.conversationTraffic
58+
+ withPos(15, 15, 7, 9),
59+
panels.conversationByPair
60+
+ withPos(15, 22, 8, 9),
61+
g.panel.row.new('Protocols')
62+
+ withPos(0, 30, 1, 24),
63+
panels.protocolTotalBytes
64+
+ withPos(0, 31, 15, 15),
65+
panels.protocolDistribution
66+
+ withPos(15, 31, 7, 9),
67+
panels.protocolOverTime
68+
+ withPos(15, 38, 8, 9),
69+
g.panel.row.new('Geographic data')
70+
+ withPos(0, 46, 1, 24),
71+
panels.topDestinationMap
72+
+ withPos(0, 47, 13, 8),
73+
panels.destinationsLegend
74+
+ withPos(8, 47, 13, 4),
75+
panels.topSourcesMap
76+
+ withPos(12, 47, 13, 8),
77+
panels.sourcesLegend
78+
+ withPos(20, 47, 13, 4),
79+
g.panel.row.new('Collector details')
80+
+ withPos(0, 60, 1, 24),
81+
panels.collectorLogs
82+
+ withPos(0, 61, 8, 17),
83+
panels.deviceStats
84+
+ withPos(17, 61, 8, 7),
85+
]),
86+
87+
},
88+
}

0 commit comments

Comments
 (0)