github.com/netdata/go.d.plugin@v0.58.1/modules/weblog/weblog.go (about) 1 // SPDX-License-Identifier: GPL-3.0-or-later 2 3 package weblog 4 5 import ( 6 _ "embed" 7 8 "github.com/netdata/go.d.plugin/agent/module" 9 "github.com/netdata/go.d.plugin/pkg/logs" 10 ) 11 12 //go:embed "config_schema.json" 13 var configSchema string 14 15 func init() { 16 module.Register("web_log", module.Creator{ 17 JobConfigSchema: configSchema, 18 Create: func() module.Module { return New() }, 19 }) 20 } 21 22 func New() *WebLog { 23 return &WebLog{ 24 Config: Config{ 25 ExcludePath: "*.gz", 26 GroupRespCodes: true, 27 Parser: logs.ParserConfig{ 28 LogType: typeAuto, 29 CSV: logs.CSVConfig{ 30 FieldsPerRecord: -1, 31 Delimiter: " ", 32 TrimLeadingSpace: false, 33 CheckField: checkCSVFormatField, 34 }, 35 LTSV: logs.LTSVConfig{ 36 FieldDelimiter: "\t", 37 ValueDelimiter: ":", 38 }, 39 RegExp: logs.RegExpConfig{}, 40 JSON: logs.JSONConfig{}, 41 }, 42 }, 43 } 44 } 45 46 type ( 47 Config struct { 48 Parser logs.ParserConfig `yaml:",inline"` 49 Path string `yaml:"path"` 50 ExcludePath string `yaml:"exclude_path"` 51 URLPatterns []userPattern `yaml:"url_patterns"` 52 CustomFields []customField `yaml:"custom_fields"` 53 CustomTimeFields []customTimeField `yaml:"custom_time_fields"` 54 CustomNumericFields []customNumericField `yaml:"custom_numeric_fields"` 55 Histogram []float64 `yaml:"histogram"` 56 GroupRespCodes bool `yaml:"group_response_codes"` 57 } 58 userPattern struct { 59 Name string `yaml:"name"` 60 Match string `yaml:"match"` 61 } 62 customField struct { 63 Name string `yaml:"name"` 64 Patterns []userPattern `yaml:"patterns"` 65 } 66 customTimeField struct { 67 Name string `yaml:"name"` 68 Histogram []float64 `yaml:"histogram"` 69 } 70 customNumericField struct { 71 Name string `yaml:"name"` 72 Units string `yaml:"units"` 73 Multiplier int `yaml:"multiplier"` 74 Divisor int `yaml:"divisor"` 75 } 76 ) 77 78 type WebLog struct { 79 module.Base 80 Config `yaml:",inline"` 81 82 file *logs.Reader 83 parser logs.Parser 84 line *logLine 85 urlPatterns []*pattern 86 87 customFields map[string][]*pattern 88 customTimeFields map[string][]float64 89 customNumericFields map[string]bool 90 91 charts *module.Charts 92 mx *metricsData 93 } 94 95 func (w *WebLog) Init() bool { 96 if err := w.createURLPatterns(); err != nil { 97 w.Errorf("init failed: %v", err) 98 return false 99 } 100 101 if err := w.createCustomFields(); err != nil { 102 w.Errorf("init failed: %v", err) 103 return false 104 } 105 106 if err := w.createCustomTimeFields(); err != nil { 107 w.Errorf("init failed: %v", err) 108 return false 109 } 110 111 if err := w.createCustomNumericFields(); err != nil { 112 w.Errorf("init failed: %v", err) 113 } 114 115 w.createLogLine() 116 w.mx = newMetricsData(w.Config) 117 118 return true 119 } 120 121 func (w *WebLog) Check() bool { 122 // Note: these inits are here to make auto-detection retry working 123 if err := w.createLogReader(); err != nil { 124 w.Warning("check failed: ", err) 125 return false 126 } 127 128 if err := w.createParser(); err != nil { 129 w.Warning("check failed: ", err) 130 return false 131 } 132 133 if err := w.createCharts(w.line); err != nil { 134 w.Warning("check failed: ", err) 135 return false 136 } 137 return true 138 } 139 140 func (w *WebLog) Charts() *module.Charts { 141 return w.charts 142 } 143 144 func (w *WebLog) Collect() map[string]int64 { 145 mx, err := w.collect() 146 if err != nil { 147 w.Error(err) 148 } 149 150 if len(mx) == 0 { 151 return nil 152 } 153 return mx 154 } 155 156 func (w *WebLog) Cleanup() { 157 if w.file != nil { 158 _ = w.file.Close() 159 } 160 }