Skip to content

Commit

Permalink
[Metricbeat][Kubernetes] Extend state_node with conditions (#23905)
Browse files Browse the repository at this point in the history
Signed-off-by: Ioannis Androulidakis <[email protected]>
  • Loading branch information
ioandr committed Feb 16, 2021
1 parent ba42321 commit 33d7406
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 21 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d
- kubernetes.container.cpu.limit.cores and kubernetes.container.cpu.requests.cores are now floats. {issue}11975[11975]
- Change types of numeric metrics from Kubelet summary api to double so as to cover big numbers. {pull}23335[23335]
- Add container.image.name and containe.name ECS fields for state_container. {pull}23802[23802]
- Add support for the MemoryPressure, DiskPressure, OutOfDisk and PIDPressure status conditions in state_node. {pull}[23905]

*Packetbeat*

Expand Down
40 changes: 40 additions & 0 deletions metricbeat/docs/fields.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -29807,6 +29807,46 @@ type: keyword
Node unschedulable status


type: boolean

--

*`kubernetes.node.status.memorypressure`*::
+
--
Node MemoryPressure status


type: boolean

--

*`kubernetes.node.status.diskpressure`*::
+
--
Node DiskPressure status


type: boolean

--

*`kubernetes.node.status.outofdisk`*::
+
--
Node OutOfDisk status


type: boolean

--

*`kubernetes.node.status.pidpressure`*::
+
--
Node PIDPressure status


type: boolean

--
Expand Down
29 changes: 17 additions & 12 deletions metricbeat/helper/prometheus/metric.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,11 @@ type MetricOption interface {
Process(field string, value interface{}, labels common.MapStr) (string, interface{}, common.MapStr)
}

// OpFilter only processes metrics matching the given filter
func OpFilter(filter map[string]string) MetricOption {
return opFilter{
labels: filter,
// OpFilterMap only processes metrics matching the given filter
func OpFilterMap(label string, filterMap map[string]string) MetricOption {
return opFilterMap{
label: label,
filterMap: filterMap,
}
}

Expand Down Expand Up @@ -331,18 +332,22 @@ func (m *infoMetric) GetField() string {
return ""
}

type opFilter struct {
labels map[string]string
type opFilterMap struct {
label string
filterMap map[string]string
}

// Process will return nil if labels don't match the filter
func (o opFilter) Process(field string, value interface{}, labels common.MapStr) (string, interface{}, common.MapStr) {
for k, v := range o.labels {
if labels[k] != v {
return "", nil, nil
// Called by the Prometheus helper to apply extra options on retrieved metrics
// Check whether the value of the specified label is allowed and, if yes, return the metric via the specified mapped field
// Else, if the specified label does not match the filter, return nil
// This is useful in cases where multiple Metricbeat fields need to be defined per Prometheus metric, based on label values
func (o opFilterMap) Process(field string, value interface{}, labels common.MapStr) (string, interface{}, common.MapStr) {
for k, v := range o.filterMap {
if labels[o.label] == k {
return fmt.Sprintf("%v.%v", field, v), value, labels
}
}
return field, value, labels
return "", nil, nil
}

type opLowercaseValue struct{}
Expand Down
33 changes: 30 additions & 3 deletions metricbeat/helper/prometheus/prometheus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -397,9 +397,36 @@ func TestPrometheus(t *testing.T) {
msg: "Label metrics, filter",
mapping: &MetricsMapping{
Metrics: map[string]MetricMap{
"first_metric": LabelMetric("first.metric", "label4", OpLowercaseValue(), OpFilter(map[string]string{
"foo": "filtered",
})),
"first_metric": LabelMetric("first.metric", "label4", OpFilterMap(
"label1",
map[string]string{"value1": "foo"},
)),
},
Labels: map[string]LabelMap{
"label1": Label("labels.label1"),
},
},
expected: []common.MapStr{
common.MapStr{
"first": common.MapStr{
"metric": common.MapStr{
"foo": "FOO",
},
},
"labels": common.MapStr{
"label1": "value1",
},
},
},
},
{
msg: "Label metrics, filter",
mapping: &MetricsMapping{
Metrics: map[string]MetricMap{
"first_metric": LabelMetric("first.metric", "label4", OpLowercaseValue(), OpFilterMap(
"foo",
map[string]string{"Filtered": "filtered"},
)),
},
Labels: map[string]LabelMap{
"label1": Label("labels.label1"),
Expand Down
2 changes: 1 addition & 1 deletion metricbeat/module/kubernetes/fields.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions metricbeat/module/kubernetes/state_node/_meta/fields.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,22 @@
type: boolean
description: >
Node unschedulable status
- name: memorypressure
type: boolean
description: >
Node MemoryPressure status
- name: diskpressure
type: boolean
description: >
Node DiskPressure status
- name: outofdisk
type: boolean
description: >
Node OutOfDisk status
- name: pidpressure
type: boolean
description: >
Node PIDPressure status
- name: cpu
type: group
fields:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
}
},
"status": {
"diskpressure": "false",
"memorypressure": "false",
"outofdisk": "false",
"ready": "true",
"unschedulable": false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
}
},
"status": {
"diskpressure": "false",
"memorypressure": "false",
"pidpressure": "false",
"ready": "true",
"unschedulable": false
}
Expand Down
14 changes: 9 additions & 5 deletions metricbeat/module/kubernetes/state_node/state_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,16 @@ var (
"kube_node_status_allocatable_cpu_cores": p.Metric("cpu.allocatable.cores"),
"kube_node_spec_unschedulable": p.BooleanMetric("status.unschedulable"),
"kube_node_status_ready": p.LabelMetric("status.ready", "condition"),
"kube_node_status_condition": p.LabelMetric("status.ready", "status",
p.OpFilter(map[string]string{
"condition": "Ready",
})),
"kube_node_status_condition": p.LabelMetric("status", "status", p.OpFilterMap(
"condition", map[string]string{
"Ready": "ready",
"MemoryPressure": "memorypressure",
"DiskPressure": "diskpressure",
"OutOfDisk": "outofdisk",
"PIDPressure": "pidpressure",
},
)),
},

Labels: map[string]p.LabelMap{
"node": p.KeyLabel("name"),
},
Expand Down

0 comments on commit 33d7406

Please sign in to comment.