diff options
Diffstat (limited to 'src/go/plugin/go.d/modules/weblog/weblog.go')
-rw-r--r-- | src/go/plugin/go.d/modules/weblog/weblog.go | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/src/go/plugin/go.d/modules/weblog/weblog.go b/src/go/plugin/go.d/modules/weblog/weblog.go new file mode 100644 index 000000000..242999e68 --- /dev/null +++ b/src/go/plugin/go.d/modules/weblog/weblog.go @@ -0,0 +1,168 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +package weblog + +import ( + _ "embed" + + "github.com/netdata/netdata/go/plugins/plugin/go.d/agent/module" + "github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/logs" +) + +//go:embed "config_schema.json" +var configSchema string + +func init() { + module.Register("web_log", module.Creator{ + JobConfigSchema: configSchema, + Create: func() module.Module { return New() }, + Config: func() any { return &Config{} }, + }) +} + +func New() *WebLog { + return &WebLog{ + Config: Config{ + ExcludePath: "*.gz", + GroupRespCodes: true, + ParserConfig: logs.ParserConfig{ + LogType: typeAuto, + CSV: logs.CSVConfig{ + FieldsPerRecord: -1, + Delimiter: " ", + TrimLeadingSpace: false, + CheckField: checkCSVFormatField, + }, + LTSV: logs.LTSVConfig{ + FieldDelimiter: "\t", + ValueDelimiter: ":", + }, + RegExp: logs.RegExpConfig{}, + JSON: logs.JSONConfig{}, + }, + }, + } +} + +type ( + Config struct { + UpdateEvery int `yaml:"update_every,omitempty" json:"update_every"` + Path string `yaml:"path" json:"path"` + ExcludePath string `yaml:"exclude_path,omitempty" json:"exclude_path"` + logs.ParserConfig `yaml:",inline" json:""` + URLPatterns []userPattern `yaml:"url_patterns,omitempty" json:"url_patterns"` + CustomFields []customField `yaml:"custom_fields,omitempty" json:"custom_fields"` + CustomTimeFields []customTimeField `yaml:"custom_time_fields,omitempty" json:"custom_time_fields"` + CustomNumericFields []customNumericField `yaml:"custom_numeric_fields,omitempty" json:"custom_numeric_fields"` + Histogram []float64 `yaml:"histogram,omitempty" json:"histogram"` + GroupRespCodes bool `yaml:"group_response_codes" json:"group_response_codes"` + } + userPattern struct { + Name string `yaml:"name" json:"name"` + Match string `yaml:"match" json:"match"` + } + customField struct { + Name string `yaml:"name" json:"name"` + Patterns []userPattern `yaml:"patterns" json:"patterns"` + } + customTimeField struct { + Name string `yaml:"name" json:"name"` + Histogram []float64 `yaml:"histogram" json:"histogram"` + } + customNumericField struct { + Name string `yaml:"name" json:"name"` + Units string `yaml:"units" json:"units"` + Multiplier int `yaml:"multiplier,omitempty" json:"multiplier"` + Divisor int `yaml:"divisor,omitempty" json:"divisor"` + } +) + +type WebLog struct { + module.Base + Config `yaml:",inline" json:""` + + charts *module.Charts + + file *logs.Reader + parser logs.Parser + line *logLine + + urlPatterns []*pattern + customFields map[string][]*pattern + customTimeFields map[string][]float64 + customNumericFields map[string]bool + + mx *metricsData +} + +func (w *WebLog) Configuration() any { + return w.Config +} + +func (w *WebLog) Init() error { + if err := w.createURLPatterns(); err != nil { + w.Errorf("init failed: %v", err) + return err + } + + if err := w.createCustomFields(); err != nil { + w.Errorf("init failed: %v", err) + return err + } + + if err := w.createCustomTimeFields(); err != nil { + w.Errorf("init failed: %v", err) + return err + } + + if err := w.createCustomNumericFields(); err != nil { + w.Errorf("init failed: %v", err) + } + + w.createLogLine() + w.mx = newMetricsData(w.Config) + + return nil +} + +func (w *WebLog) Check() error { + // Note: these inits are here to make auto-detection retry working + if err := w.createLogReader(); err != nil { + w.Warning("check failed: ", err) + return err + } + + if err := w.createParser(); err != nil { + w.Warning("check failed: ", err) + return err + } + + if err := w.createCharts(w.line); err != nil { + w.Warning("check failed: ", err) + return err + } + + return nil +} + +func (w *WebLog) Charts() *module.Charts { + return w.charts +} + +func (w *WebLog) Collect() map[string]int64 { + mx, err := w.collect() + if err != nil { + w.Error(err) + } + + if len(mx) == 0 { + return nil + } + return mx +} + +func (w *WebLog) Cleanup() { + if w.file != nil { + _ = w.file.Close() + } +} |