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

Add GetProcessedMetrics method to Prometheus helper #6916

Merged
merged 4 commits into from
Apr 25, 2018
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 4 additions & 0 deletions CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ https://github.com/elastic/beats/compare/v6.0.0-beta2...master[Check the HEAD di
- Add config option for windows/perfmon metricset to ignore non existent counters. {pull}6432[6432]
- Refactor docker CPU calculations to be more consistent with `docker stats`. {pull}6608[6608]
- Update logstash.node_stats metricset to write data under `logstash.node.stats.*`. {pull}6714[6714]
- Fixed typo in values for `state_container` `status.phase`, from `terminate` to `terminated`. {pull}6916[6916]

*Packetbeat*

Expand Down Expand Up @@ -223,6 +224,9 @@ https://github.com/elastic/beats/compare/v6.0.0-beta2...master[Check the HEAD di

*Metricbeat*

- Kubernetes `state_container` `cpu.limit.nanocores` and `cpu.request.nanocores` have been
deprecated in favor of `cpu.*.cores`. {pull}6916[6916]

*Packetbeat*

*Winlogbeat*
Expand Down
20 changes: 20 additions & 0 deletions metricbeat/docs/fields.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -7307,6 +7307,26 @@ Container restarts count
--


*`kubernetes.container.cpu.limit.cores`*::
+
--
type: long

Container CPU cores limit


--

*`kubernetes.container.cpu.request.cores`*::
+
--
type: long

Container CPU requested cores


--

*`kubernetes.container.cpu.limit.nanocores`*::
+
--
Expand Down
59 changes: 0 additions & 59 deletions metricbeat/helper/prometheus.go

This file was deleted.

42 changes: 42 additions & 0 deletions metricbeat/helper/prometheus/label.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package prometheus

// LabelMap defines the mapping from Prometheus label to a Metricbeat field
type LabelMap interface {
// GetField returns the resulting field name
GetField() string

// IsKey returns true if the label is a key label
IsKey() bool
}

// Label maps a Prometheus label to a Metricbeat field
func Label(field string) LabelMap {
return &commonLabel{
field: field,
key: false,
}
}

// KeyLabel maps a Prometheus label to a Metricbeat field. The label is flagged as key.
// Metrics with the same tuple of key labels will be grouped in the same event.
func KeyLabel(field string) LabelMap {
return &commonLabel{
field: field,
key: true,
}
}

type commonLabel struct {
field string
key bool
}

// GetField returns the resulting field name
func (l *commonLabel) GetField() string {
return l.field
}

// IsKey returns true if the label is a key label
func (l *commonLabel) IsKey() bool {
return l.key
}
126 changes: 126 additions & 0 deletions metricbeat/helper/prometheus/metric.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package prometheus

import (
"strings"

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

// MetricMap defines the mapping from Prometheus metric to a Metricbeat field
type MetricMap interface {
// GetField returns the resulting field name
GetField() string

// GetValue returns the resulting value
GetValue(m *dto.Metric) interface{}
}

// Metric directly maps a Prometheus metric to a Metricbeat field
func Metric(field string) MetricMap {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we make a difference between float and int?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Uhm that's a good question, so far I think that mapping should take care of that?

Copy link
Contributor

Choose a reason for hiding this comment

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

It indeed does for the define fields. Coming from the schema package I kind of expected to have both.

return &commonMetric{
field: field,
}
}

// KeywordMetric maps a Prometheus metric to a Metricbeat field, stores the
// given keyword when source metric value is 1
func KeywordMetric(field, keyword string) MetricMap {
return &keywordMetric{
commonMetric{
field: field,
},
keyword,
}
}

// BooleanMetric maps a Prometheus metric to a Metricbeat field of bool type
func BooleanMetric(field string) MetricMap {
return &booleanMetric{
commonMetric{
field: field,
},
}
}

// LabelMetric maps a Prometheus metric to a Metricbeat field, stores the value
// of a given label on it if the gauge value is 1
func LabelMetric(field, label string) MetricMap {
return &labelMetric{
commonMetric{
field: field,
},
label,
}
}

type commonMetric struct {
field string
}

// GetField returns the resulting field name
func (m *commonMetric) GetField() string {
return m.field
}

// GetValue returns the resulting value
func (m *commonMetric) GetValue(metric *dto.Metric) interface{} {
counter := metric.GetCounter()
if counter != nil {
return int64(counter.GetValue())
}

gauge := metric.GetGauge()
if gauge != nil {
return gauge.GetValue()
}

// Other types are not supported here
return nil
}

type keywordMetric struct {
commonMetric
keyword string
}

// GetValue returns the resulting value
func (m *keywordMetric) GetValue(metric *dto.Metric) interface{} {
if gauge := metric.GetGauge(); gauge != nil && gauge.GetValue() == 1 {
return m.keyword
}
return nil
}

type booleanMetric struct {
commonMetric
}

// GetValue returns the resulting value
func (m *booleanMetric) GetValue(metric *dto.Metric) interface{} {
if gauge := metric.GetGauge(); gauge != nil {
return gauge.GetValue() == 1
}
return nil
}

type labelMetric struct {
commonMetric
label string
}

// GetValue returns the resulting value
func (m *labelMetric) GetValue(metric *dto.Metric) interface{} {
if gauge := metric.GetGauge(); gauge != nil && gauge.GetValue() == 1 {
return strings.ToLower(getLabel(metric, m.label))
}
return nil
}

func getLabel(metric *dto.Metric, name string) string {
for _, label := range metric.GetLabel() {
if label.GetName() == name {
return label.GetValue()
}
}
return ""
}
Loading