categraf/config/logs/integration_config.go

158 lines
4.8 KiB
Go

// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2016-present Datadog, Inc.
package logs
import (
"fmt"
"strings"
)
// Logs source types
const (
TCPType = "tcp"
UDPType = "udp"
FileType = "file"
DockerType = "docker"
JournaldType = "journald"
WindowsEventType = "windows_event"
SnmpTrapsType = "snmp_traps"
StringChannelType = "string_channel"
// UTF16BE for UTF-16 Big endian encoding
UTF16BE string = "utf-16-be"
// UTF16LE for UTF-16 Little Endian encoding
UTF16LE string = "utf-16-le"
)
// LogsConfig represents a log source config, which can be for instance
// a file to tail or a port to listen to.
type (
LogsConfig struct {
Type string
Port int // Network
IdleTimeout string `mapstructure:"idle_timeout" json:"idle_timeout"` // Network
Path string // File, Journald
Encoding string `mapstructure:"encoding" json:"encoding"` // File
ExcludePaths []string `mapstructure:"exclude_paths" json:"exclude_paths"` // File
TailingMode string `mapstructure:"start_position" json:"start_position"` // File
IncludeUnits []string `mapstructure:"include_units" json:"include_units"` // Journald
ExcludeUnits []string `mapstructure:"exclude_units" json:"exclude_units"` // Journald
ContainerMode bool `mapstructure:"container_mode" json:"container_mode"` // Journald
Image string // Docker
Label string // Docker
// Name contains the container name
Name string // Docker
// Identifier contains the container ID
Identifier string // Docker
ChannelPath string `mapstructure:"channel_path" json:"channel_path"` // Windows Event
Query string // Windows Event
// used as input only by the Channel tailer.
// could have been unidirectional but the tailer could not close it in this case.
Channel chan *ChannelMessage `json:"-"`
Service string
Source string
SourceCategory string
Tags []string
ProcessingRules []*ProcessingRule `mapstructure:"log_processing_rules" json:"log_processing_rules"`
AutoMultiLine bool `mapstructure:"auto_multi_line_detection" json:"auto_multi_line_detection"`
AutoMultiLineSampleSize int `mapstructure:"auto_multi_line_sample_size" json:"auto_multi_line_sample_size"`
AutoMultiLineMatchThreshold float64 `mapstructure:"auto_multi_line_match_threshold" json:"auto_multi_line_match_threshold"`
}
)
// TailingMode type
type TailingMode uint8
// Tailing Modes
const (
ForceBeginning = iota
ForceEnd
Beginning
End
)
var tailingModeTuples = []struct {
s string
m TailingMode
}{
{"forceBeginning", ForceBeginning},
{"forceEnd", ForceEnd},
{"beginning", Beginning},
{"end", End},
}
// TailingModeFromString parses a string and returns a corresponding tailing mode, default to End if not found
func TailingModeFromString(mode string) (TailingMode, bool) {
for _, t := range tailingModeTuples {
if t.s == mode {
return t.m, true
}
}
return End, false
}
// TailingModeToString returns seelog string representation for a specified tailing mode. Returns "" for invalid tailing mode.
func (mode TailingMode) String() string {
for _, t := range tailingModeTuples {
if t.m == mode {
return t.s
}
}
return ""
}
// Validate returns an error if the config is misconfigured
func (c *LogsConfig) Validate() error {
switch {
case c.Type == "":
// user don't have to specify a logs-config type when defining
// an autodiscovery label because so we must override it at some point,
// this check is mostly used for sanity purposed to detect an override miss.
return fmt.Errorf("a config must have a type")
case c.Type == FileType:
if c.Path == "" {
return fmt.Errorf("file source must have a path")
}
err := c.validateTailingMode()
if err != nil {
return err
}
case c.Type == TCPType && c.Port == 0:
return fmt.Errorf("tcp source must have a port")
case c.Type == UDPType && c.Port == 0:
return fmt.Errorf("udp source must have a port")
}
err := ValidateProcessingRules(c.ProcessingRules)
if err != nil {
return err
}
return CompileProcessingRules(c.ProcessingRules)
}
func (c *LogsConfig) validateTailingMode() error {
mode, found := TailingModeFromString(c.TailingMode)
if !found && c.TailingMode != "" {
return fmt.Errorf("invalid tailing mode '%v' for %v", c.TailingMode, c.Path)
}
if ContainsWildcard(c.Path) && (mode == Beginning || mode == ForceBeginning) {
return fmt.Errorf("tailing from the beginning is not supported for wildcard path %v", c.Path)
}
return nil
}
// ContainsWildcard returns true if the path contains any wildcard character
func ContainsWildcard(path string) bool {
return strings.ContainsAny(path, "*?[")
}