Skip to content

Commit

Permalink
Add Kubernetes StatefulSet metricset (#6236)
Browse files Browse the repository at this point in the history
metricbeat: add support for StatefulSet reporting in Kubernetes module
  • Loading branch information
fassisrosa authored and exekias committed Feb 2, 2018
1 parent 5782e81 commit 4cbb1de
Show file tree
Hide file tree
Showing 16 changed files with 431 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ https://github.com/elastic/beats/compare/v6.0.0-beta2...master[Check the HEAD di
- Add experimental uwsgi module. {pull}6006[6006]
- Docker and Kubernetes modules are now GA, instead of Beta. {pull}6105[6105]
- Add pct calculated fields for Pod and container CPU and memory usages. {pull}6158[6158]
- Add statefulset support to Kubernetes module. {pull}6236[6236]

*Packetbeat*

Expand Down
69 changes: 69 additions & 0 deletions metricbeat/docs/fields.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -6151,6 +6151,75 @@ type: long
The number of fully labeled replicas per ReplicaSet
[float]
== statefulset fields
kubernetes stateful set metrics
[float]
=== `kubernetes.statefulset.name`
type: keyword
Kubernetes stateful set name
[float]
=== `kubernetes.statefulset.created`
type: long
The creation timestamp (epoch) for StatefulSet
[float]
== replicas fields
Kubernetes stateful set replicas status
[float]
=== `kubernetes.statefulset.replicas.observed`
type: long
The number of observed replicas per StatefulSet
[float]
=== `kubernetes.statefulset.replicas.desired`
type: long
The number of desired replicas per StatefulSet
[float]
== generation fields
Kubernetes stateful set generation information
[float]
=== `kubernetes.statefulset.generation.observed`
type: long
The observed generation per StatefulSet
[float]
=== `kubernetes.statefulset.generation.desired`
type: long
The desired generation per StatefulSet
[float]
== system fields
Expand Down
5 changes: 5 additions & 0 deletions metricbeat/docs/modules/kubernetes.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ metricbeat.modules:
- state_node
- state_deployment
- state_replicaset
- state_statefulset
- state_pod
- state_container
period: 10s
Expand Down Expand Up @@ -77,6 +78,8 @@ The following metricsets are available:

* <<metricbeat-metricset-kubernetes-state_replicaset,state_replicaset>>

* <<metricbeat-metricset-kubernetes-state_statefulset,state_statefulset>>

* <<metricbeat-metricset-kubernetes-system,system>>

* <<metricbeat-metricset-kubernetes-volume,volume>>
Expand All @@ -99,6 +102,8 @@ include::kubernetes/state_pod.asciidoc[]

include::kubernetes/state_replicaset.asciidoc[]

include::kubernetes/state_statefulset.asciidoc[]

include::kubernetes/system.asciidoc[]

include::kubernetes/volume.asciidoc[]
Expand Down
21 changes: 21 additions & 0 deletions metricbeat/docs/modules/kubernetes/state_statefulset.asciidoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
////
This file is generated! See scripts/docs_collector.py
////

[[metricbeat-metricset-kubernetes-state_statefulset]]
=== Kubernetes state_statefulset metricset

include::../../../module/kubernetes/state_statefulset/_meta/docs.asciidoc[]


==== Fields

For a description of each field in the metricset, see the
<<exported-fields-kubernetes,exported fields>> section.

Here is an example document generated by this metricset:

[source,json]
----
include::../../../module/kubernetes/state_statefulset/_meta/data.json[]
----
3 changes: 2 additions & 1 deletion metricbeat/docs/modules_list.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ This file is generated! See scripts/docs_collector.py
|<<metricbeat-module-kibana,Kibana>> beta[] |
.1+| |<<metricbeat-metricset-kibana-status,status>> beta[]
|<<metricbeat-module-kubernetes,Kubernetes>> |
.11+| |<<metricbeat-metricset-kubernetes-container,container>>
.12+| |<<metricbeat-metricset-kubernetes-container,container>>
|<<metricbeat-metricset-kubernetes-event,event>> experimental[]
|<<metricbeat-metricset-kubernetes-node,node>>
|<<metricbeat-metricset-kubernetes-pod,pod>>
Expand All @@ -67,6 +67,7 @@ This file is generated! See scripts/docs_collector.py
|<<metricbeat-metricset-kubernetes-state_node,state_node>>
|<<metricbeat-metricset-kubernetes-state_pod,state_pod>>
|<<metricbeat-metricset-kubernetes-state_replicaset,state_replicaset>>
|<<metricbeat-metricset-kubernetes-state_statefulset,state_statefulset>>
|<<metricbeat-metricset-kubernetes-system,system>>
|<<metricbeat-metricset-kubernetes-volume,volume>>
|<<metricbeat-module-logstash,Logstash>> experimental[] |
Expand Down
1 change: 1 addition & 0 deletions metricbeat/include/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ import (
_ "github.com/elastic/beats/metricbeat/module/kubernetes/state_node"
_ "github.com/elastic/beats/metricbeat/module/kubernetes/state_pod"
_ "github.com/elastic/beats/metricbeat/module/kubernetes/state_replicaset"
_ "github.com/elastic/beats/metricbeat/module/kubernetes/state_statefulset"
_ "github.com/elastic/beats/metricbeat/module/kubernetes/system"
_ "github.com/elastic/beats/metricbeat/module/kubernetes/util"
_ "github.com/elastic/beats/metricbeat/module/kubernetes/volume"
Expand Down
1 change: 1 addition & 0 deletions metricbeat/metricbeat.reference.yml
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ metricbeat.modules:
- state_node
- state_deployment
- state_replicaset
- state_statefulset
- state_pod
- state_container
period: 10s
Expand Down
1 change: 1 addition & 0 deletions metricbeat/module/kubernetes/_meta/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
- state_node
- state_deployment
- state_replicaset
- state_statefulset
- state_pod
- state_container
period: 10s
Expand Down
31 changes: 31 additions & 0 deletions metricbeat/module/kubernetes/_meta/test/kube-state-metrics
Original file line number Diff line number Diff line change
Expand Up @@ -386,3 +386,34 @@ process_start_time_seconds 1.4939719827e+09
# HELP process_virtual_memory_bytes Virtual memory size in bytes.
# TYPE process_virtual_memory_bytes gauge
process_virtual_memory_bytes 5.2932608e+07
# HELP kube_statefulset_created Unix creation timestamp
# TYPE kube_statefulset_created gauge
kube_statefulset_created{namespace="default",statefulset="elasticsearch"} 1.511973651e+09
kube_statefulset_created{namespace="default",statefulset="mysql"} 1.511989697e+09
kube_statefulset_created{namespace="custom",statefulset="mysql"} 1.511999697e+09
# HELP kube_statefulset_labels Kubernetes labels converted to Prometheus labels.
# TYPE kube_statefulset_labels gauge
kube_statefulset_labels{label_app="oci",label_io_kompose_service="elasticsearch",namespace="default",statefulset="elasticsearch"} 1
kube_statefulset_labels{label_app="oci",label_custom_pod="true",label_io_kompose_service="s-mysql",namespace="default",statefulset="mysql"} 1
kube_statefulset_labels{label_app="oci",label_custom_pod="true",label_io_kompose_service="s-mysql",namespace="custom",statefulset="mysql"} 1
# HELP kube_statefulset_metadata_generation Sequence number representing a specific generation of the desired state for the StatefulSet.
# TYPE kube_statefulset_metadata_generation gauge
kube_statefulset_metadata_generation{namespace="default",statefulset="elasticsearch"} 3
kube_statefulset_metadata_generation{namespace="default",statefulset="mysql"} 4
kube_statefulset_metadata_generation{namespace="custom",statefulset="mysql"} 5
# HELP kube_statefulset_replicas Number of desired pods for a StatefulSet.
# TYPE kube_statefulset_replicas gauge
kube_statefulset_replicas{namespace="default",statefulset="elasticsearch"} 4
kube_statefulset_replicas{namespace="default",statefulset="mysql"} 5
kube_statefulset_replicas{namespace="custom",statefulset="mysql"} 6
# HELP kube_statefulset_status_observed_generation The generation observed by the StatefulSet controller.
# TYPE kube_statefulset_status_observed_generation gauge
kube_statefulset_status_observed_generation{namespace="default",statefulset="elasticsearch"} 1
kube_statefulset_status_observed_generation{namespace="default",statefulset="mysql"} 2
kube_statefulset_status_observed_generation{namespace="custom",statefulset="mysql"} 3
# HELP kube_statefulset_status_replicas The number of replicas per StatefulSet.
# TYPE kube_statefulset_status_replicas gauge
kube_statefulset_status_replicas{namespace="default",statefulset="elasticsearch"} 1
kube_statefulset_status_replicas{namespace="default",statefulset="mysql"} 2
kube_statefulset_status_replicas{namespace="custom",statefulset="mysql"} 3

30 changes: 30 additions & 0 deletions metricbeat/module/kubernetes/state_statefulset/_meta/data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"@timestamp": "2017-05-10T16:46:37.821Z",
"beat": {
"hostname": "X1",
"name": "X1",
"version": "6.0.0-alpha1"
},
"kubernetes": {
"namespace": "jenkins",
"statefulset": {
"name": "wise-lynx-jenkins-1616735317",
"created": 123454,
"replicas": {
"desired": 1,
"observed": 1,
},
"generation": {
"desired": 1,
"observed": 1,
}
}
},
"metricset": {
"host": "192.168.99.100:18080",
"module": "kubernetes",
"name": "state_statefulset",
"namespace": "statefulset",
"rtt": 6719
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This is the `state_statefulset` metricset of the Kubernetes module.
40 changes: 40 additions & 0 deletions metricbeat/module/kubernetes/state_statefulset/_meta/fields.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
- name: statefulset
type: group
description: >
kubernetes stateful set metrics
release: ga
fields:
- name: name
type: keyword
description: >
Kubernetes stateful set name
- name: created
type: long
description: >
The creation timestamp (epoch) for StatefulSet
- name: replicas
type: group
description: >
Kubernetes stateful set replicas status
fields:
- name: observed
type: long
description: >
The number of observed replicas per StatefulSet
- name: desired
type: long
description: >
The number of desired replicas per StatefulSet
- name: generation
type: group
description: >
Kubernetes stateful set generation information
fields:
- name: observed
type: long
description: >
The observed generation per StatefulSet
- name: desired
type: long
description: >
The desired generation per StatefulSet
53 changes: 53 additions & 0 deletions metricbeat/module/kubernetes/state_statefulset/data.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package state_statefulset

import (
"github.com/elastic/beats/libbeat/common"
"github.com/elastic/beats/metricbeat/mb"
"github.com/elastic/beats/metricbeat/module/kubernetes/util"

dto "github.com/prometheus/client_model/go"
)

func eventMapping(families []*dto.MetricFamily) ([]common.MapStr, error) {
eventsMap := map[string]common.MapStr{}
for _, family := range families {
for _, metric := range family.GetMetric() {
statefulset := util.GetLabel(metric, "statefulset")
if statefulset == "" {
continue
}
namespace := util.GetLabel(metric, "namespace")
statefulsetKey := namespace + "::" + statefulset
event, ok := eventsMap[statefulsetKey]
if !ok {
event = common.MapStr{}
eventsMap[statefulsetKey] = event
}
switch family.GetName() {
case "kube_statefulset_metadata_generation":
event.Put(mb.ModuleDataKey+".namespace", util.GetLabel(metric, "namespace"))
event.Put(mb.NamespaceKey, "statefulset")
event.Put("name", util.GetLabel(metric, "statefulset"))
event.Put("generation.desired", metric.GetGauge().GetValue())
case "kube_statefulset_status_observed_generation":
event.Put("generation.observed", metric.GetGauge().GetValue())
case "kube_statefulset_created":
event.Put("created", metric.GetGauge().GetValue())
case "kube_statefulset_replicas":
event.Put("replicas.desired", metric.GetGauge().GetValue())
case "kube_statefulset_status_replicas":
event.Put("replicas.observed", metric.GetGauge().GetValue())
default:
// Ignore unknown metric
continue
}
}
}

// initialize, populate events array from values in eventsMap
events := make([]common.MapStr, 0, len(eventsMap))
for _, event := range eventsMap {
events = append(events, event)
}
return events, nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package state_statefulset

import (
"github.com/elastic/beats/libbeat/common"
"github.com/elastic/beats/metricbeat/helper"
"github.com/elastic/beats/metricbeat/mb"
"github.com/elastic/beats/metricbeat/mb/parse"
)

const (
defaultScheme = "http"
defaultPath = "/metrics"
)

var (
hostParser = parse.URLHostParserBuilder{
DefaultScheme: defaultScheme,
DefaultPath: defaultPath,
}.Build()
)

// init registers the MetricSet with the central registry.
// The New method will be called after the setup of the module and before starting to fetch data
func init() {
if err := mb.Registry.AddMetricSet("kubernetes", "state_statefulset", New, hostParser); err != nil {
panic(err)
}
}

// MetricSet type defines all fields of the MetricSet
// As a minimum it must inherit the mb.BaseMetricSet fields, but can be extended with
// additional entries. These variables can be used to persist data or configuration between
// multiple fetch calls.
type MetricSet struct {
mb.BaseMetricSet
prometheus *helper.Prometheus
}

// New create a new instance of the MetricSet
// Part of new is also setting up the configuration by processing additional
// configuration entries if needed.
func New(base mb.BaseMetricSet) (mb.MetricSet, error) {
prometheus, err := helper.NewPrometheusClient(base)
if err != nil {
return nil, err
}
return &MetricSet{
BaseMetricSet: base,
prometheus: prometheus,
}, nil
}

// Fetch methods implements the data gathering and data conversion to the right format
// It returns the event which is then forward to the output. In case of an error, a
// descriptive error must be returned.
func (m *MetricSet) Fetch() ([]common.MapStr, error) {
families, err := m.prometheus.GetFamilies()
if err != nil {
return nil, err
}

return eventMapping(families)
}
Loading

0 comments on commit 4cbb1de

Please sign in to comment.