Skip to content
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

[Metricbeat][Kubernetes] Add metricset for state_namespace #36406

Merged
merged 21 commits into from
Oct 4, 2023
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG-developer.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ The list below covers the major changes between 7.0.0-rc2 and main only.

==== Added

- Add new metricset in Kubernetes module, `namespace_state`. {pull}36406[36406]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this comment #36406 (comment) was related only to the field name, where metrics are store kubernetes.state_namespace.* - > kubernetes.namespace_state.* , not to the name of the metricset itself.

I think that the state_* in the metricset name is a reference to the metrics source - that they are scraped from the kube_state_metrics, if it is correct module name should be state_namespace for consistency. @MichaelKatsoulis @ChrsMark is my assumption regarding naming correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @tetianakravchenko, you are right, I misunderstood. So now the document looks like this:

{
    "@timestamp": "2019-03-01T08:05:34.853Z",
    "event": {
        "dataset": "kubernetes.namespace_state",
        ...
    },
    "kubernetes": {
        "namespace": "kube-node-lease",
        "namespace_state": {
            ...
        }
    },
    "metricset": {
        "name": "state_namespace",
        ...
    },
    ...
}

I could not change the event.dataset, I am not sure what this field means and elastic docs are not very clear either. I am guessing it is the "family" of fields that caused the metrics on the document.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think event.dataset should be kubernetes.namespace. I explain this at #36406 (comment). I'm not sure if that line there also has impact in other places but event.namespace should be kubernetes.namespace if we want to be more accurate.

- Add configuration for APM instrumentation and expose the tracer trough the Beat object. {pull}17938[17938]
- Make the behavior of clientWorker and netClientWorker consistent when error is returned from publisher pipeline
- Metricset generator generates beta modules by default now. {pull}10657[10657]
Expand Down
36 changes: 36 additions & 0 deletions metricbeat/docs/fields.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -44375,6 +44375,42 @@ type: keyword

--

[float]
=== namespace_state

Kubernetes namespace metrics.



*`kubernetes.namespace_state.created.sec`*::
+
--
Unix creation timestamp.


type: double

--


*`kubernetes.namespace_state.status.active`*::
+
--
Whether the namespace is active (true or false).

type: boolean

--

*`kubernetes.namespace_state.status.terminating`*::
+
--
Whether the namespace is terminating (true or false).

type: boolean

--

[float]
=== node

Expand Down
24 changes: 19 additions & 5 deletions metricbeat/helper/kubernetes/state_metricset.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ var lock sync.RWMutex
// 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(name string, mapping *prometheus.MetricsMapping) {
name = prefix + name
if name != util.NamespaceResource {
name = prefix + name
}
lock.Lock()
mappings[name] = mapping
lock.Unlock()
Expand Down Expand Up @@ -77,11 +79,16 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) {
mapping := mappings[base.Name()]
lock.Unlock()

resourceName := base.Name()
if resourceName != util.NamespaceResource {
resourceName = strings.ReplaceAll(resourceName, prefix, "")
}

return &MetricSet{
BaseMetricSet: base,
prometheusClient: prometheusClient,
prometheusMapping: mapping,
enricher: util.NewResourceMetadataEnricher(base, strings.ReplaceAll(base.Name(), prefix, ""), mod.GetMetricsRepo(), false),
enricher: util.NewResourceMetadataEnricher(base, resourceName, mod.GetMetricsRepo(), false),
mod: mod,
}, nil
}
Expand All @@ -90,6 +97,15 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) {
// format. It publishes the event which is then forwarded to the output. In case
// of an error set the Error field of mb.Event or simply call report.Error().
func (m *MetricSet) Fetch(reporter mb.ReporterV2) {
// The name of the metric state can be obtained by using m.BaseMetricSet.Name(). However, names that start with state_* (e.g. state_cronjob)
// need to have that prefix removed. So, for example, strings.ReplaceAll("state_cronjob", "state_", "") would result in just cronjob.
// Exception is namespace_state, as field kubernetes.namespace already exists, and we need to create a new object
// for the namespace_state metricset.
resourceName := m.BaseMetricSet.Name()
if resourceName != util.NamespaceResource {
resourceName = strings.ReplaceAll(resourceName, prefix, "")
}

m.enricher.Start()

families, err := m.mod.GetStateMetricsFamilies(m.prometheusClient)
Expand All @@ -107,9 +123,7 @@ func (m *MetricSet) Fetch(reporter mb.ReporterV2) {

m.enricher.Enrich(events)
for _, event := range events {
// The name of the metric state can be obtained by using m.BaseMetricSet.Name(). However, names that start with state_* (e.g. state_cronjob)
// need to have that prefix removed. So, for example, strings.ReplaceAll("state_cronjob", "state_", "") would result in just cronjob.
e, err := util.CreateEvent(event, "kubernetes."+strings.ReplaceAll(m.BaseMetricSet.Name(), "state_", ""))
e, err := util.CreateEvent(event, "kubernetes."+resourceName)
if err != nil {
m.Logger().Error(err)
}
Expand Down
1 change: 1 addition & 0 deletions metricbeat/include/list_docker.go

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

Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ data:
- state_persistentvolume
- state_persistentvolumeclaim
- state_storageclass
- namespace_state
- module: kubernetes
metricsets:
- apiserver
Expand Down
2 changes: 1 addition & 1 deletion metricbeat/module/kubernetes/fields.go

Large diffs are not rendered by default.

28 changes: 28 additions & 0 deletions metricbeat/module/kubernetes/namespace_state/_meta/data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"@timestamp": "2019-03-01T08:05:34.853Z",
"event": {
"dataset": "kubernetes.namespace_state",
"duration": 115000,
"module": "kubernetes"
},
"kubernetes": {
"namespace": "kube-system",
"namespace_state": {
"created": {
"sec": 1691566337
},
"status": {
"active": true,
"terminating": false
}
}
},
"metricset": {
"name": "namespace_state",
"period": 10000
},
"service": {
"address": "127.0.0.1:55555",
"type": "kubernetes"
}
}
19 changes: 19 additions & 0 deletions metricbeat/module/kubernetes/namespace_state/_meta/fields.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
- name: namespace_state
type: group
release: ga
description: >
Kubernetes namespace metrics.
fields:
- name: created.sec
type: double
description: >
Unix creation timestamp.
- name: status
type: group
fields:
- name: active
type: boolean
description: Whether the namespace is active (true or false).
- name: terminating
type: boolean
description: Whether the namespace is terminating (true or false).
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
[
{
"RootFields": null,
"ModuleFields": {
"namespace": "kube-node-lease"
},
"MetricSetFields": {
"created": {
"sec": 1673879559
},
"status": {
"active": true,
"terminating": false
}
},
"Index": "",
"ID": "",
"Namespace": "kubernetes.namespace_state",
"Timestamp": "0001-01-01T00:00:00Z",
"Error": null,
"Host": "",
"Service": "",
"Took": 0,
"Period": 0,
"DisableTimeSeries": false
},
{
"RootFields": null,
"ModuleFields": {
"namespace": "default"
},
"MetricSetFields": {
"created": {
"sec": 1673879561
},
"status": {
"active": true,
"terminating": false
}
},
"Index": "",
"ID": "",
"Namespace": "kubernetes.namespace_state",
"Timestamp": "0001-01-01T00:00:00Z",
"Error": null,
"Host": "",
"Service": "",
"Took": 0,
"Period": 0,
"DisableTimeSeries": false
},
{
"RootFields": null,
"ModuleFields": {
"namespace": "local-path-storage"
},
"MetricSetFields": {
"created": {
"sec": 1673879567
},
"status": {
"active": true,
"terminating": false
}
},
"Index": "",
"ID": "",
"Namespace": "kubernetes.namespace_state",
"Timestamp": "0001-01-01T00:00:00Z",
"Error": null,
"Host": "",
"Service": "",
"Took": 0,
"Period": 0,
"DisableTimeSeries": false
},
{
"RootFields": null,
"ModuleFields": {
"namespace": "kube-public"
},
"MetricSetFields": {
"created": {
"sec": 1673879559
},
"status": {
"active": true,
"terminating": false
}
},
"Index": "",
"ID": "",
"Namespace": "kubernetes.namespace_state",
"Timestamp": "0001-01-01T00:00:00Z",
"Error": null,
"Host": "",
"Service": "",
"Took": 0,
"Period": 0,
"DisableTimeSeries": false
},
{
"RootFields": null,
"ModuleFields": {
"namespace": "kube-system"
},
"MetricSetFields": {
"created": {
"sec": 1673879559
},
"status": {
"active": true,
"terminating": false
}
},
"Index": "",
"ID": "",
"Namespace": "kubernetes.namespace_state",
"Timestamp": "0001-01-01T00:00:00Z",
"Error": null,
"Host": "",
"Service": "",
"Took": 0,
"Period": 0,
"DisableTimeSeries": false
}
]
Loading
Loading