diff options
Diffstat (limited to 'src/go/collectors/go.d.plugin/modules/weblog/metrics.go')
-rw-r--r-- | src/go/collectors/go.d.plugin/modules/weblog/metrics.go | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/src/go/collectors/go.d.plugin/modules/weblog/metrics.go b/src/go/collectors/go.d.plugin/modules/weblog/metrics.go new file mode 100644 index 000000000..651221a99 --- /dev/null +++ b/src/go/collectors/go.d.plugin/modules/weblog/metrics.go @@ -0,0 +1,188 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +package weblog + +import ( + "github.com/netdata/netdata/go/go.d.plugin/pkg/metrics" +) + +func newWebLogSummary() metrics.Summary { + return &weblogSummary{metrics.NewSummary()} +} + +type weblogSummary struct { + metrics.Summary +} + +// WriteTo redefines metrics.Summary.WriteTo +// TODO: temporary workaround? +func (s weblogSummary) WriteTo(rv map[string]int64, key string, mul, div int) { + s.Summary.WriteTo(rv, key, mul, div) + if _, ok := rv[key+"_min"]; !ok { + rv[key+"_min"] = 0 + rv[key+"_max"] = 0 + rv[key+"_avg"] = 0 + } +} + +type ( + metricsData struct { + Requests metrics.Counter `stm:"requests"` + ReqUnmatched metrics.Counter `stm:"req_unmatched"` + + RespCode metrics.CounterVec `stm:"resp_code"` + Resp1xx metrics.Counter `stm:"resp_1xx"` + Resp2xx metrics.Counter `stm:"resp_2xx"` + Resp3xx metrics.Counter `stm:"resp_3xx"` + Resp4xx metrics.Counter `stm:"resp_4xx"` + Resp5xx metrics.Counter `stm:"resp_5xx"` + + ReqSuccess metrics.Counter `stm:"req_type_success"` + ReqRedirect metrics.Counter `stm:"req_type_redirect"` + ReqBad metrics.Counter `stm:"req_type_bad"` + ReqError metrics.Counter `stm:"req_type_error"` + + UniqueIPv4 metrics.UniqueCounter `stm:"uniq_ipv4"` + UniqueIPv6 metrics.UniqueCounter `stm:"uniq_ipv6"` + BytesSent metrics.Counter `stm:"bytes_sent"` + BytesReceived metrics.Counter `stm:"bytes_received"` + ReqProcTime metrics.Summary `stm:"req_proc_time"` + ReqProcTimeHist metrics.Histogram `stm:"req_proc_time_hist"` + UpsRespTime metrics.Summary `stm:"upstream_resp_time"` + UpsRespTimeHist metrics.Histogram `stm:"upstream_resp_time_hist"` + + ReqVhost metrics.CounterVec `stm:"req_vhost"` + ReqPort metrics.CounterVec `stm:"req_port"` + ReqMethod metrics.CounterVec `stm:"req_method"` + ReqURLPattern metrics.CounterVec `stm:"req_url_ptn"` + ReqVersion metrics.CounterVec `stm:"req_version"` + ReqSSLProto metrics.CounterVec `stm:"req_ssl_proto"` + ReqSSLCipherSuite metrics.CounterVec `stm:"req_ssl_cipher_suite"` + ReqHTTPScheme metrics.Counter `stm:"req_http_scheme"` + ReqHTTPSScheme metrics.Counter `stm:"req_https_scheme"` + ReqIPv4 metrics.Counter `stm:"req_ipv4"` + ReqIPv6 metrics.Counter `stm:"req_ipv6"` + + ReqCustomField map[string]metrics.CounterVec `stm:"custom_field"` + URLPatternStats map[string]*patternMetrics `stm:"url_ptn"` + + ReqCustomTimeField map[string]*customTimeFieldMetrics `stm:"custom_time_field"` + ReqCustomNumericField map[string]*customNumericFieldMetrics `stm:"custom_numeric_field"` + } + customTimeFieldMetrics struct { + Time metrics.Summary `stm:"time"` + TimeHist metrics.Histogram `stm:"time_hist"` + } + customNumericFieldMetrics struct { + Summary metrics.Summary `stm:"summary"` + + multiplier int + divisor int + } + patternMetrics struct { + RespCode metrics.CounterVec `stm:"resp_code"` + ReqMethod metrics.CounterVec `stm:"req_method"` + BytesSent metrics.Counter `stm:"bytes_sent"` + BytesReceived metrics.Counter `stm:"bytes_received"` + ReqProcTime metrics.Summary `stm:"req_proc_time"` + } +) + +func newMetricsData(config Config) *metricsData { + return &metricsData{ + ReqVhost: metrics.NewCounterVec(), + ReqPort: metrics.NewCounterVec(), + ReqMethod: metrics.NewCounterVec(), + ReqVersion: metrics.NewCounterVec(), + RespCode: metrics.NewCounterVec(), + ReqSSLProto: metrics.NewCounterVec(), + ReqSSLCipherSuite: metrics.NewCounterVec(), + ReqProcTime: newWebLogSummary(), + ReqProcTimeHist: metrics.NewHistogram(convHistOptionsToMicroseconds(config.Histogram)), + UpsRespTime: newWebLogSummary(), + UpsRespTimeHist: metrics.NewHistogram(convHistOptionsToMicroseconds(config.Histogram)), + UniqueIPv4: metrics.NewUniqueCounter(true), + UniqueIPv6: metrics.NewUniqueCounter(true), + ReqURLPattern: newCounterVecFromPatterns(config.URLPatterns), + ReqCustomField: newReqCustomField(config.CustomFields), + URLPatternStats: newURLPatternStats(config.URLPatterns), + ReqCustomTimeField: newReqCustomTimeField(config.CustomTimeFields), + ReqCustomNumericField: newReqCustomNumericField(config.CustomNumericFields), + } +} + +func (m *metricsData) reset() { + m.UniqueIPv4.Reset() + m.UniqueIPv6.Reset() + m.ReqProcTime.Reset() + m.UpsRespTime.Reset() + for _, v := range m.URLPatternStats { + v.ReqProcTime.Reset() + } + for _, v := range m.ReqCustomTimeField { + v.Time.Reset() + } + for _, v := range m.ReqCustomNumericField { + v.Summary.Reset() + } +} + +func newCounterVecFromPatterns(patterns []userPattern) metrics.CounterVec { + c := metrics.NewCounterVec() + for _, p := range patterns { + _, _ = c.GetP(p.Name) + } + return c +} + +func newURLPatternStats(patterns []userPattern) map[string]*patternMetrics { + stats := make(map[string]*patternMetrics) + for _, p := range patterns { + stats[p.Name] = &patternMetrics{ + RespCode: metrics.NewCounterVec(), + ReqMethod: metrics.NewCounterVec(), + ReqProcTime: newWebLogSummary(), + } + } + return stats +} + +func newReqCustomField(fields []customField) map[string]metrics.CounterVec { + cf := make(map[string]metrics.CounterVec) + for _, f := range fields { + cf[f.Name] = newCounterVecFromPatterns(f.Patterns) + } + return cf +} + +func newReqCustomTimeField(fields []customTimeField) map[string]*customTimeFieldMetrics { + cf := make(map[string]*customTimeFieldMetrics) + for _, f := range fields { + cf[f.Name] = &customTimeFieldMetrics{ + Time: newWebLogSummary(), + TimeHist: metrics.NewHistogram(convHistOptionsToMicroseconds(f.Histogram)), + } + } + return cf +} + +func newReqCustomNumericField(fields []customNumericField) map[string]*customNumericFieldMetrics { + rv := make(map[string]*customNumericFieldMetrics) + for _, f := range fields { + rv[f.Name] = &customNumericFieldMetrics{ + Summary: newWebLogSummary(), + multiplier: f.Multiplier, + divisor: f.Divisor, + } + } + return rv +} + +// convert histogram options to microseconds (second => us) +func convHistOptionsToMicroseconds(histogram []float64) []float64 { + var buckets []float64 + for _, value := range histogram { + buckets = append(buckets, value*1e6) + } + return buckets +} |