forked from open-telemetry/opentelemetry-collector-contrib
-
Notifications
You must be signed in to change notification settings - Fork 2
/
utils.go
122 lines (103 loc) · 3.89 KB
/
utils.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http:https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package metrics // import "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/datadogexporter/internal/metrics"
import (
"fmt"
"strings"
"go.opentelemetry.io/collector/component"
"gopkg.in/zorkian/go-datadog-api.v2"
)
type MetricDataType string
const (
// Gauge is the Datadog Gauge metric type
Gauge MetricDataType = "gauge"
// Count is the Datadog Count metric type
Count MetricDataType = "count"
otelNamespacePrefix string = "otel"
)
// newMetric creates a new Datadog metric given a name, a Unix nanoseconds timestamp
// a value and a slice of tags
func newMetric(name string, ts uint64, value float64, tags []string) datadog.Metric {
// Transform UnixNano timestamp into Unix timestamp
// 1 second = 1e9 ns
timestamp := float64(ts / 1e9)
metric := datadog.Metric{
Points: []datadog.DataPoint{[2]*float64{×tamp, &value}},
Tags: tags,
}
metric.SetMetric(name)
return metric
}
// NewMetric creates a new Datadog metric given a name, a type, a Unix nanoseconds timestamp
// a value and a slice of tags
func NewMetric(name string, dt MetricDataType, ts uint64, value float64, tags []string) datadog.Metric {
metric := newMetric(name, ts, value, tags)
metric.SetType(string(dt))
return metric
}
// NewGauge creates a new Datadog Gauge metric given a name, a Unix nanoseconds timestamp
// a value and a slice of tags
func NewGauge(name string, ts uint64, value float64, tags []string) datadog.Metric {
return NewMetric(name, Gauge, ts, value, tags)
}
// NewCount creates a new Datadog count metric given a name, a Unix nanoseconds timestamp
// a value and a slice of tags
func NewCount(name string, ts uint64, value float64, tags []string) datadog.Metric {
return NewMetric(name, Count, ts, value, tags)
}
// DefaultMetrics creates built-in metrics to report that an exporter is running
func DefaultMetrics(exporterType string, hostname string, timestamp uint64, buildInfo component.BuildInfo) []datadog.Metric {
var tags []string
if buildInfo.Version != "" {
tags = append(tags, "version:"+buildInfo.Version)
}
if buildInfo.Command != "" {
tags = append(tags, "command:"+buildInfo.Command)
}
metrics := []datadog.Metric{
NewGauge(fmt.Sprintf("otel.datadog_exporter.%s.running", exporterType), timestamp, 1.0, tags),
}
for i := range metrics {
metrics[i].SetHost(hostname)
}
return metrics
}
// ProcessMetrics adds the hostname to the metric and prefixes it with the "otel"
// namespace as the Datadog backend expects
func ProcessMetrics(ms []datadog.Metric) {
addNamespace(ms, otelNamespacePrefix)
}
// shouldPrepend decides if a given metric name should be prepended by `otel.`.
// By default, this happens for
// - hostmetrics receiver metrics (since they clash with Datadog Agent system check) and
// - running metrics
func shouldPrepend(name string) bool {
namespaces := [...]string{"system.", "process."}
for _, ns := range namespaces {
if strings.HasPrefix(name, ns) {
return true
}
}
return false
}
// addNamespace prepends some metric names with a given namespace.
// This is used to namespace metrics that clash with the Datadog Agent
func addNamespace(metrics []datadog.Metric, namespace string) {
for i := range metrics {
if shouldPrepend(*metrics[i].Metric) {
newName := namespace + "." + *metrics[i].Metric
metrics[i].Metric = &newName
}
}
}