-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconfig.go
173 lines (156 loc) · 6.09 KB
/
config.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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
package datalayersgrpcexporter
import (
"fmt"
"strings"
"go.opentelemetry.io/collector/config/configretry"
"go.opentelemetry.io/collector/exporter/exporterhelper"
"golang.org/x/exp/maps"
)
type Trace struct {
Table string `mapstructure:"table"`
// SpanDimensions are span attributes to be used as line protocol tags.
// These are always included as tags:
// - trace ID
// - span ID
// The default values are strongly recommended for use with Jaeger:
// - service.name
// - span.name
// Other common attributes can be found here:
// - https://opentelemetry.io/docs/specs/semconv/
SpanDimensions []string `mapstructure:"span_dimensions"`
// SpanFields are span attributes to be used as line protocol fields.
// SpanFields can be empty.
SpanFields []string `mapstructure:"span_fields"`
CustomKeyScope string `mapstructure:"custom_key_scope"`
Custom []CustomTrace `mapstructure:"custom"`
}
type CustomTrace struct {
Key []string `mapstructure:"key"`
Table string `mapstructure:"table"`
SpanDimensions []string `mapstructure:"span_dimensions"`
SpanFields []string `mapstructure:"span_fields"`
}
// Config defines configuration for the InfluxDB exporter.
type Config struct {
// confighttp.ClientConfig `mapstructure:",squash"`
QueueSettings exporterhelper.QueueSettings `mapstructure:"sending_queue"`
configretry.BackOffConfig `mapstructure:"retry_on_failure"`
// // Org is the InfluxDB organization name of the destination bucket.
// Org string `mapstructure:"org"`
// // Bucket is the InfluxDB bucket name that telemetry will be written to.
// Bucket string `mapstructure:"bucket"`
// // Token is used to identify InfluxDB permissions within the organization.
// Token configopaque.String `mapstructure:"token"`
// Endpoint is the InfluxDB server URL.
Host string `mapstructure:"host"`
// Port is the InfluxDB server port.
Port uint32 `mapstructure:"port"`
// TlsCertPath is the path to the TLS certificate to use for HTTPS requests.
TlsCertPath string `mapstructure:"tls_cert_path"`
// DB is used to specify the name of the V1 InfluxDB database that telemetry will be written to.
DB string `mapstructure:"db"`
// Table is the name of the Datalayers table that telemetry will be written to.
Table string `mapstructure:"table"`
// PartitionNum is the number of partitions to use for partitioning.
PartitionNum int `mapstructure:"partition_num"`
// Username is used to optionally specify the basic auth username
Username string `mapstructure:"username"`
// Password is used to optionally specify the basic auth password
Password string `mapstructure:"password"`
Trace Trace `mapstructure:"trace"`
// PayloadMaxLines is the maximum number of line protocol lines to POST in a single request.
PayloadMaxLines int `mapstructure:"payload_max_lines"`
// PayloadMaxBytes is the maximum number of line protocol bytes to POST in a single request.
PayloadMaxBytes int `mapstructure:"payload_max_bytes"`
// MetricsSchema indicates the metrics schema to emit to line protocol.
// Options:
// - telegraf-prometheus-v1
// - telegraf-prometheus-v2
MetricsSchema string `mapstructure:"metrics_schema"`
}
func (cfg *Config) Validate() error {
globalSpanTags := make(map[string]struct{}, len(cfg.Trace.SpanDimensions))
globalSpanFields := make(map[string]struct{}, len(cfg.Trace.SpanDimensions))
duplicateTags := make(map[string]struct{})
for _, k := range cfg.Trace.SpanDimensions {
if _, found := globalSpanTags[k]; found {
duplicateTags[k] = struct{}{}
} else {
globalSpanTags[k] = struct{}{}
}
}
if len(duplicateTags) > 0 {
return fmt.Errorf("duplicate span dimension(s) configured: %s",
strings.Join(maps.Keys(duplicateTags), ","))
}
duplicateFields := make(map[string]struct{})
for _, k := range cfg.Trace.SpanFields {
if _, found := globalSpanFields[k]; found {
duplicateTags[k] = struct{}{}
} else {
globalSpanFields[k] = struct{}{}
}
}
if len(duplicateFields) > 0 {
return fmt.Errorf("duplicate span fields(s) configured: %s",
strings.Join(maps.Keys(duplicateFields), ","))
}
if len(cfg.Trace.Custom) > 0 {
// validate custom_key_scope
// valid values: name, kind, parent_span_id, status_code, context.trace_id, context.span_id, attributes.xxx
keyScope := cfg.Trace.CustomKeyScope
switch keyScope {
case "name", "kind", "parent_span_id", "status_code", "context.trace_id", "context.span_id":
default:
if !strings.HasPrefix(keyScope, "attributes.") {
return fmt.Errorf("invalid custom key scope %s, valid scope values are: name, kind, parent_span_id, status_code, context.trace_id, context.span_id, attributes.xxx", keyScope)
}
}
// validate tags & fields
customKeys := make(map[string]struct{})
duplicateKeys := make(map[string]struct{})
for _, custom := range cfg.Trace.Custom {
keyArray := custom.Key
for _, k := range keyArray {
if _, found := customKeys[k]; found {
duplicateKeys[k] = struct{}{}
} else {
customKeys[k] = struct{}{}
}
}
customSpanTags := make(map[string]struct{}, len(cfg.Trace.SpanDimensions))
customSpanFields := make(map[string]struct{})
duplicateTags = make(map[string]struct{})
for _, k := range custom.SpanDimensions {
if _, found := customSpanTags[k]; found {
duplicateTags[k] = struct{}{}
} else {
customSpanTags[k] = struct{}{}
}
}
if len(duplicateTags) > 0 {
return fmt.Errorf("duplicate custom span dimension(s) configured: %s",
strings.Join(maps.Keys(duplicateTags), ","))
}
duplicateFields := make(map[string]struct{})
for _, k := range custom.SpanFields {
if _, found := customSpanFields[k]; found {
duplicateFields[k] = struct{}{}
} else {
customSpanFields[k] = struct{}{}
}
}
if len(duplicateFields) > 0 {
return fmt.Errorf("duplicate custom span fields(s) configured: %s",
strings.Join(maps.Keys(duplicateFields), ","))
}
}
if len(duplicateKeys) > 0 {
return fmt.Errorf("duplicate custom key configured: %s",
strings.Join(maps.Keys(duplicateKeys), ","))
}
}
return nil
}