Skip to content

Commit cb72d73

Browse files
authored
Merge pull request #961 from adberger/master
feat: Add join label functionality to alerts
2 parents dac6d03 + 8bdf68b commit cb72d73

File tree

3 files changed

+55
-1
lines changed

3 files changed

+55
-1
lines changed

alerts/apps_alerts.libsonnet

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
local utils = import '../lib/utils.libsonnet';
2+
13
{
24
_config+:: {
35
kubeStateMetricsSelector: error 'must provide selector for kube-state-metrics',
@@ -10,7 +12,8 @@
1012
groups+: [
1113
{
1214
name: 'kubernetes-apps',
13-
rules: [
15+
rules: [utils.wrap_rule_for_labels(rule, $._config) for rule in self.rules_],
16+
rules_:: [
1417
{
1518
expr: |||
1619
max_over_time(kube_pod_container_status_waiting_reason{reason="CrashLoopBackOff", %(prefixedNamespaceSelector)s%(kubeStateMetricsSelector)s}[5m]) >= 1

config.libsonnet

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,16 @@
3232
windowsExporterSelector: 'job="kubernetes-windows-exporter"',
3333
containerfsSelector: 'container!=""',
3434

35+
// List of labels to join for different type of metrics
36+
// Only works if your environment has the labels kube_%s_labels (e.g. kube_pod_labels) available.
37+
common_join_labels: [],
38+
pods_join_labels: $._config.common_join_labels,
39+
statefulsets_join_labels: $._config.common_join_labels,
40+
deployments_join_labels: $._config.common_join_labels,
41+
daemonsets_join_labels: $._config.common_join_labels,
42+
horizontalpodautoscalers_join_labels: $._config.common_join_labels,
43+
jobs_join_labels: $._config.common_join_labels,
44+
3545
// Grafana dashboard IDs are necessary for stable links for dashboards
3646
grafanaDashboardIDs: {
3747
'apiserver.json': std.md5('apiserver.json'),

lib/utils.libsonnet

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,45 @@
1515
if s > 60 * 60 * 24
1616
then '%.1f days' % (s / 60 / 60 / 24)
1717
else '%.1f hours' % (s / 60 / 60),
18+
19+
// Handle adding `group left` to join labels into rule by wrapping the rule in () * on(xxx) group_left(xxx) kube_xxx_labels
20+
// If kind of rule is not defined try to detect rule type by alert name
21+
wrap_rule_for_labels(rule, config):
22+
// Detect Kind of rule from name unless hidden `kind field is passed in the rule`
23+
local kind =
24+
if 'kind' in rule then rule.kind
25+
// Handle Alerts
26+
else if std.objectHas(rule, 'alert') then
27+
if std.startsWith(rule.alert, 'KubePod') then 'pod'
28+
else if std.startsWith(rule.alert, 'KubeContainer') then 'pod'
29+
else if std.startsWith(rule.alert, 'KubeStateful') then 'statefulset'
30+
else if std.startsWith(rule.alert, 'KubeDeploy') then 'deployment'
31+
else if std.startsWith(rule.alert, 'KubeDaemon') then 'daemonset'
32+
else if std.startsWith(rule.alert, 'KubeHpa') then 'horizontalpodautoscaler'
33+
else if std.startsWith(rule.alert, 'KubeJob') then 'job'
34+
else 'none'
35+
else 'none';
36+
37+
local labels = {
38+
join_labels: config['%ss_join_labels' % kind],
39+
// since the label 'job' is reserved, the resource with kind Job uses the label 'job_name' instead
40+
on_labels: ['%s' % (if kind == 'job' then 'job_name' else kind), '%s' % config.namespaceLabel, '%s' % config.clusterLabel],
41+
metric: 'kube_%s_labels' % kind,
42+
};
43+
44+
// Failed to identify kind - return raw rule
45+
if kind == 'none' then rule
46+
// No join labels passed in the config - return raw rule
47+
else if std.length(labels.join_labels) == 0 then rule
48+
// Wrap expr with join group left
49+
else
50+
rule {
51+
local expr = super.expr,
52+
expr: '(%(expr)s) * on (%(on)s) group_left(%(join)s) %(metric)s' % {
53+
expr: expr,
54+
on: std.join(',', labels.on_labels),
55+
join: std.join(',', labels.join_labels),
56+
metric: labels.metric,
57+
},
58+
},
1859
}

0 commit comments

Comments
 (0)