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 6 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, `state_namespace`. {pull}36406[36406]
- 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 @@ -46035,6 +46035,42 @@ type: keyword

--

[float]
=== state_namespace

Kubernetes namespace metrics.



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


type: double

--


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

type: boolean

--

*`kubernetes.state_namespace.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 state_namespace, as field kubernetes.namespace already exists, and we need to create a new object
// for the state_namespace 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
- state_namespace
Copy link
Contributor

Choose a reason for hiding this comment

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

seems you pushed local changes for this file, could you please revert?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. Is it ok now with just state_namespace added?

- 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/state_namespace/_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.state_namespace",
"duration": 115000,
"module": "kubernetes"
},
"kubernetes": {
"namespace": "default",
"state_namespace": {
"created": {
"sec": 1691566338
},
"status": {
"active": true,
"terminating": false
}
}
},
"metricset": {
"name": "state_namespace",
"period": 10000
},
"service": {
"address": "127.0.0.1:55555",
"type": "kubernetes"
}
}
19 changes: 19 additions & 0 deletions metricbeat/module/kubernetes/state_namespace/_meta/fields.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
- name: state_namespace
Copy link
Member

Choose a reason for hiding this comment

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

I would prefer a name like namespace_state which reflects that this section gives information related to the namespace's state. state_* is quite an internal/elastic terminology and might not be so accurate/specific.

Note that I'm only referring to the fields' prefix and not the name of the metricset. The name of the metricset is just fine as is. But maybe we can improve the field's naming with what I mention.

@mlunadia do you have any preference here? state_namespace.* VS namespace_state.*?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@gizas since you were the one suggesting this name, what do you think?

Copy link
Contributor

Choose a reason for hiding this comment

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

I am also +1 for using namespace_state as the object field name.

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.state_namespace",
"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.state_namespace",
"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.state_namespace",
"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.state_namespace",
"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.state_namespace",
"Timestamp": "0001-01-01T00:00:00Z",
"Error": null,
"Host": "",
"Service": "",
"Took": 0,
"Period": 0,
"DisableTimeSeries": false
}
]
Loading
Loading