From 644970f36a64f412576550ed2b7707cdde364efa Mon Sep 17 00:00:00 2001 From: Philip Norman Date: Fri, 4 Jan 2019 19:10:06 -0800 Subject: [PATCH] Account for prometheus app metrics (#35) * Account for prometheus app metrics Mesos tasks may expose metrics via prometheus as an alternative to transmitting metrics via statsd (see https://jira.mesosphere.com/browse/DCOS_OSS-3717). This commit allows the dcos_metrics output plugin to expose prometheus task metrics via the /v0/containers//app endpoint. * Fix unittests for new year (#5213) * Update comment; combine case statements --- plugins/inputs/logparser/grok/grok_test.go | 7 +-- plugins/outputs/dcos_metrics/translator.go | 9 ++-- .../outputs/dcos_metrics/translator_test.go | 46 +++++++++++++++++++ 3 files changed, 55 insertions(+), 7 deletions(-) diff --git a/plugins/inputs/logparser/grok/grok_test.go b/plugins/inputs/logparser/grok/grok_test.go index 837e750a9569d..ad5fa0aa1cd08 100644 --- a/plugins/inputs/logparser/grok/grok_test.go +++ b/plugins/inputs/logparser/grok/grok_test.go @@ -972,6 +972,7 @@ func TestNewlineInPatterns(t *testing.T) { } func TestSyslogTimestamp(t *testing.T) { + currentYear := time.Now().Year() tests := []struct { name string line string @@ -980,17 +981,17 @@ func TestSyslogTimestamp(t *testing.T) { { name: "two digit day of month", line: "Sep 25 09:01:55 value=42", - expected: time.Date(2018, time.September, 25, 9, 1, 55, 0, time.UTC), + expected: time.Date(currentYear, time.September, 25, 9, 1, 55, 0, time.UTC), }, { name: "one digit day of month single space", line: "Sep 2 09:01:55 value=42", - expected: time.Date(2018, time.September, 2, 9, 1, 55, 0, time.UTC), + expected: time.Date(currentYear, time.September, 2, 9, 1, 55, 0, time.UTC), }, { name: "one digit day of month double space", line: "Sep 2 09:01:55 value=42", - expected: time.Date(2018, time.September, 2, 9, 1, 55, 0, time.UTC), + expected: time.Date(currentYear, time.September, 2, 9, 1, 55, 0, time.UTC), }, } for _, tt := range tests { diff --git a/plugins/outputs/dcos_metrics/translator.go b/plugins/outputs/dcos_metrics/translator.go index d75e4461da7bc..17b7ff67e5fb6 100644 --- a/plugins/outputs/dcos_metrics/translator.go +++ b/plugins/outputs/dcos_metrics/translator.go @@ -39,15 +39,16 @@ func (t *producerTranslator) Translate(metric telegraf.Metric) (msg producers.Me ok = true switch { // Container metrics - // We assume any metric with a container_id tag but without a metric_type tag is a container metric from the - // dcos_containers input. - case hasAllKeys(tags, []string{"container_id"}) && !hasAnyKeys(tags, []string{"metric_type"}): + // We assume any metric with a container_id tag but without a metric_type tag or a url tag is a container metric from + // the dcos_containers input. + case hasAllKeys(tags, []string{"container_id"}) && !hasAnyKeys(tags, []string{"metric_type", "url"}): msg = t.containerMetricsMessage(metric) // App metrics // We assume any metric with both a container_id tag and a metric_type tag is an app metric from the dcos_statsd // input. - case hasAllKeys(tags, []string{"container_id", "metric_type"}): + // We assume any metric with both a container_id tag and a url tag is an app metric from the prometheus input. + case hasAllKeys(tags, []string{"container_id"}) && hasAnyKeys(tags, []string{"metric_type", "url"}): msg = t.appMetricsMessage(metric) // Node metrics diff --git a/plugins/outputs/dcos_metrics/translator_test.go b/plugins/outputs/dcos_metrics/translator_test.go index b49668a36bad5..8d10a4e3d71d0 100644 --- a/plugins/outputs/dcos_metrics/translator_test.go +++ b/plugins/outputs/dcos_metrics/translator_test.go @@ -706,6 +706,52 @@ func TestTranslate(t *testing.T) { }, }, }, + + // Custom metrics from tasks collected by the Prometheus input should appear as app metrics. + testCase{ + name: "prom app metric", + input: metricParams{ + name: "prefix.prom.foo", + tags: map[string]string{ + "container_id": "cid", + "service_name": "sname", + "task_name": "tname", + "url": "http://example.com", + "label_name": "label_value", + }, + fields: map[string]interface{}{ + "metric1": uint64(0), + "metric2": uint64(1), + }, + tm: tm, + tp: telegraf.Untyped, + }, + output: producers.MetricsMessage{ + Name: "dcos.metrics.app", + Dimensions: producers.Dimensions{ + MesosID: translator.MesosID, + ClusterID: translator.DCOSClusterID, + Hostname: translator.DCOSNodePrivateIP, + ContainerID: "cid", + FrameworkName: "sname", + TaskName: "tname", + }, + Datapoints: []producers.Datapoint{ + producers.Datapoint{ + Name: "prefix.prom.foo.metric1", + Value: uint64(0), + Timestamp: timestamp, + Tags: map[string]string{"label_name": "label_value", "url": "http://example.com"}, + }, + producers.Datapoint{ + Name: "prefix.prom.foo.metric2", + Value: uint64(1), + Timestamp: timestamp, + Tags: map[string]string{"label_name": "label_value", "url": "http://example.com"}, + }, + }, + }, + }, } for _, tc := range testCases {