-
Notifications
You must be signed in to change notification settings - Fork 2.1k
/
config.go
160 lines (131 loc) · 5.16 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
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
package fileexporter // import "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/fileexporter"
import (
"errors"
"fmt"
"strings"
"time"
"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/confmap"
)
const (
rotationFieldName = "rotation"
backupsFieldName = "max_backups"
)
// Config defines configuration for file exporter.
type Config struct {
// Path of the file to write to. Path is relative to current directory.
Path string `mapstructure:"path"`
// Mode defines whether the exporter should append to the file.
// Options:
// - false[default]: truncates the file
// - true: appends to the file.
Append bool `mapstructure:"append"`
// Rotation defines an option about rotation of telemetry files. Ignored
// when GroupByAttribute is used.
Rotation *Rotation `mapstructure:"rotation"`
// FormatType define the data format of encoded telemetry data
// Options:
// - json[default]: OTLP json bytes.
// - proto: OTLP binary protobuf bytes.
FormatType string `mapstructure:"format"`
// Encoding defines the encoding of the telemetry data.
// If specified, it overrides `FormatType` and applies an encoding extension.
Encoding *component.ID `mapstructure:"encoding"`
// Compression Codec used to export telemetry data
// Supported compression algorithms:`zstd`
Compression string `mapstructure:"compression"`
// FlushInterval is the duration between flushes.
// See time.ParseDuration for valid values.
FlushInterval time.Duration `mapstructure:"flush_interval"`
// GroupBy enables writing to separate files based on a resource attribute.
GroupBy *GroupBy `mapstructure:"group_by"`
}
// Rotation an option to rolling log files
type Rotation struct {
// MaxMegabytes is the maximum size in megabytes of the file before it gets
// rotated. It defaults to 100 megabytes.
MaxMegabytes int `mapstructure:"max_megabytes"`
// MaxDays is the maximum number of days to retain old log files based on the
// timestamp encoded in their filename. Note that a day is defined as 24
// hours and may not exactly correspond to calendar days due to daylight
// savings, leap seconds, etc. The default is not to remove old log files
// based on age.
MaxDays int `mapstructure:"max_days" `
// MaxBackups is the maximum number of old log files to retain. The default
// is to 100 files.
MaxBackups int `mapstructure:"max_backups" `
// LocalTime determines if the time used for formatting the timestamps in
// backup files is the computer's local time. The default is to use UTC
// time.
LocalTime bool `mapstructure:"localtime"`
}
type GroupBy struct {
// Enables group_by. When group_by is enabled, rotation setting is ignored. Default is false.
Enabled bool `mapstructure:"enabled"`
// ResourceAttribute specifies the name of the resource attribute that
// contains the path segment of the file to write to. The final path will be
// the Path config value, with the * replaced with the value of this resource
// attribute. Default is "fileexporter.path_segment".
ResourceAttribute string `mapstructure:"resource_attribute"`
// MaxOpenFiles specifies the maximum number of open file descriptors for the output files.
// The default is 100.
MaxOpenFiles int `mapstructure:"max_open_files"`
}
var _ component.Config = (*Config)(nil)
// Validate checks if the exporter configuration is valid
func (cfg *Config) Validate() error {
if cfg.Path == "" {
return errors.New("path must be non-empty")
}
if cfg.Append && cfg.Compression != "" {
return fmt.Errorf("append and compression enabled at the same time is not supported")
}
if cfg.Append && cfg.Rotation != nil {
return fmt.Errorf("append and rotation enabled at the same time is not supported")
}
if cfg.FormatType != formatTypeJSON && cfg.FormatType != formatTypeProto {
return errors.New("format type is not supported")
}
if cfg.Compression != "" && cfg.Compression != compressionZSTD {
return errors.New("compression is not supported")
}
if cfg.FlushInterval < 0 {
return errors.New("flush_interval must be larger than zero")
}
if cfg.GroupBy != nil && cfg.GroupBy.Enabled {
pathParts := strings.Split(cfg.Path, "*")
if len(pathParts) != 2 {
return errors.New("path must contain exatcly one * when group_by is enabled")
}
if len(pathParts[0]) == 0 {
return errors.New("path must not start with * when group_by is enabled")
}
if cfg.GroupBy.ResourceAttribute == "" {
return errors.New("resource_attribute must not be empty when group_by is enabled")
}
}
return nil
}
// Unmarshal a confmap.Conf into the config struct.
func (cfg *Config) Unmarshal(componentParser *confmap.Conf) error {
if componentParser == nil {
return errors.New("empty config for file exporter")
}
// first load the config normally
err := componentParser.Unmarshal(cfg)
if err != nil {
return err
}
// next manually search for protocols in the confmap.Conf,
// if rotation is not present it means it is disabled.
if !componentParser.IsSet(rotationFieldName) {
cfg.Rotation = nil
}
// set flush interval to 1 second if not set.
if cfg.FlushInterval == 0 {
cfg.FlushInterval = time.Second
}
return nil
}