github.com/netdata/go.d.plugin@v0.58.1/modules/weblog/metrics.go (about) 1 // SPDX-License-Identifier: GPL-3.0-or-later 2 3 package weblog 4 5 import ( 6 "github.com/netdata/go.d.plugin/pkg/metrics" 7 ) 8 9 func newWebLogSummary() metrics.Summary { 10 return &weblogSummary{metrics.NewSummary()} 11 } 12 13 type weblogSummary struct { 14 metrics.Summary 15 } 16 17 // WriteTo redefines metrics.Summary.WriteTo 18 // TODO: temporary workaround? 19 func (s weblogSummary) WriteTo(rv map[string]int64, key string, mul, div int) { 20 s.Summary.WriteTo(rv, key, mul, div) 21 if _, ok := rv[key+"_min"]; !ok { 22 rv[key+"_min"] = 0 23 rv[key+"_max"] = 0 24 rv[key+"_avg"] = 0 25 } 26 } 27 28 type ( 29 metricsData struct { 30 Requests metrics.Counter `stm:"requests"` 31 ReqUnmatched metrics.Counter `stm:"req_unmatched"` 32 33 RespCode metrics.CounterVec `stm:"resp_code"` 34 Resp1xx metrics.Counter `stm:"resp_1xx"` 35 Resp2xx metrics.Counter `stm:"resp_2xx"` 36 Resp3xx metrics.Counter `stm:"resp_3xx"` 37 Resp4xx metrics.Counter `stm:"resp_4xx"` 38 Resp5xx metrics.Counter `stm:"resp_5xx"` 39 40 ReqSuccess metrics.Counter `stm:"req_type_success"` 41 ReqRedirect metrics.Counter `stm:"req_type_redirect"` 42 ReqBad metrics.Counter `stm:"req_type_bad"` 43 ReqError metrics.Counter `stm:"req_type_error"` 44 45 UniqueIPv4 metrics.UniqueCounter `stm:"uniq_ipv4"` 46 UniqueIPv6 metrics.UniqueCounter `stm:"uniq_ipv6"` 47 BytesSent metrics.Counter `stm:"bytes_sent"` 48 BytesReceived metrics.Counter `stm:"bytes_received"` 49 ReqProcTime metrics.Summary `stm:"req_proc_time"` 50 ReqProcTimeHist metrics.Histogram `stm:"req_proc_time_hist"` 51 UpsRespTime metrics.Summary `stm:"upstream_resp_time"` 52 UpsRespTimeHist metrics.Histogram `stm:"upstream_resp_time_hist"` 53 54 ReqVhost metrics.CounterVec `stm:"req_vhost"` 55 ReqPort metrics.CounterVec `stm:"req_port"` 56 ReqMethod metrics.CounterVec `stm:"req_method"` 57 ReqURLPattern metrics.CounterVec `stm:"req_url_ptn"` 58 ReqVersion metrics.CounterVec `stm:"req_version"` 59 ReqSSLProto metrics.CounterVec `stm:"req_ssl_proto"` 60 ReqSSLCipherSuite metrics.CounterVec `stm:"req_ssl_cipher_suite"` 61 ReqHTTPScheme metrics.Counter `stm:"req_http_scheme"` 62 ReqHTTPSScheme metrics.Counter `stm:"req_https_scheme"` 63 ReqIPv4 metrics.Counter `stm:"req_ipv4"` 64 ReqIPv6 metrics.Counter `stm:"req_ipv6"` 65 66 ReqCustomField map[string]metrics.CounterVec `stm:"custom_field"` 67 URLPatternStats map[string]*patternMetrics `stm:"url_ptn"` 68 69 ReqCustomTimeField map[string]*customTimeFieldMetrics `stm:"custom_time_field"` 70 ReqCustomNumericField map[string]*customNumericFieldMetrics `stm:"custom_numeric_field"` 71 } 72 customTimeFieldMetrics struct { 73 Time metrics.Summary `stm:"time"` 74 TimeHist metrics.Histogram `stm:"time_hist"` 75 } 76 customNumericFieldMetrics struct { 77 Summary metrics.Summary `stm:"summary"` 78 79 multiplier int 80 divisor int 81 } 82 patternMetrics struct { 83 RespCode metrics.CounterVec `stm:"resp_code"` 84 ReqMethod metrics.CounterVec `stm:"req_method"` 85 BytesSent metrics.Counter `stm:"bytes_sent"` 86 BytesReceived metrics.Counter `stm:"bytes_received"` 87 ReqProcTime metrics.Summary `stm:"req_proc_time"` 88 } 89 ) 90 91 func newMetricsData(config Config) *metricsData { 92 return &metricsData{ 93 ReqVhost: metrics.NewCounterVec(), 94 ReqPort: metrics.NewCounterVec(), 95 ReqMethod: metrics.NewCounterVec(), 96 ReqVersion: metrics.NewCounterVec(), 97 RespCode: metrics.NewCounterVec(), 98 ReqSSLProto: metrics.NewCounterVec(), 99 ReqSSLCipherSuite: metrics.NewCounterVec(), 100 ReqProcTime: newWebLogSummary(), 101 ReqProcTimeHist: metrics.NewHistogram(convHistOptionsToMicroseconds(config.Histogram)), 102 UpsRespTime: newWebLogSummary(), 103 UpsRespTimeHist: metrics.NewHistogram(convHistOptionsToMicroseconds(config.Histogram)), 104 UniqueIPv4: metrics.NewUniqueCounter(true), 105 UniqueIPv6: metrics.NewUniqueCounter(true), 106 ReqURLPattern: newCounterVecFromPatterns(config.URLPatterns), 107 ReqCustomField: newReqCustomField(config.CustomFields), 108 URLPatternStats: newURLPatternStats(config.URLPatterns), 109 ReqCustomTimeField: newReqCustomTimeField(config.CustomTimeFields), 110 ReqCustomNumericField: newReqCustomNumericField(config.CustomNumericFields), 111 } 112 } 113 114 func (m *metricsData) reset() { 115 m.UniqueIPv4.Reset() 116 m.UniqueIPv6.Reset() 117 m.ReqProcTime.Reset() 118 m.UpsRespTime.Reset() 119 for _, v := range m.URLPatternStats { 120 v.ReqProcTime.Reset() 121 } 122 for _, v := range m.ReqCustomTimeField { 123 v.Time.Reset() 124 } 125 for _, v := range m.ReqCustomNumericField { 126 v.Summary.Reset() 127 } 128 } 129 130 func newCounterVecFromPatterns(patterns []userPattern) metrics.CounterVec { 131 c := metrics.NewCounterVec() 132 for _, p := range patterns { 133 _, _ = c.GetP(p.Name) 134 } 135 return c 136 } 137 138 func newURLPatternStats(patterns []userPattern) map[string]*patternMetrics { 139 stats := make(map[string]*patternMetrics) 140 for _, p := range patterns { 141 stats[p.Name] = &patternMetrics{ 142 RespCode: metrics.NewCounterVec(), 143 ReqMethod: metrics.NewCounterVec(), 144 ReqProcTime: newWebLogSummary(), 145 } 146 } 147 return stats 148 } 149 150 func newReqCustomField(fields []customField) map[string]metrics.CounterVec { 151 cf := make(map[string]metrics.CounterVec) 152 for _, f := range fields { 153 cf[f.Name] = newCounterVecFromPatterns(f.Patterns) 154 } 155 return cf 156 } 157 158 func newReqCustomTimeField(fields []customTimeField) map[string]*customTimeFieldMetrics { 159 cf := make(map[string]*customTimeFieldMetrics) 160 for _, f := range fields { 161 cf[f.Name] = &customTimeFieldMetrics{ 162 Time: newWebLogSummary(), 163 TimeHist: metrics.NewHistogram(convHistOptionsToMicroseconds(f.Histogram)), 164 } 165 } 166 return cf 167 } 168 169 func newReqCustomNumericField(fields []customNumericField) map[string]*customNumericFieldMetrics { 170 rv := make(map[string]*customNumericFieldMetrics) 171 for _, f := range fields { 172 rv[f.Name] = &customNumericFieldMetrics{ 173 Summary: newWebLogSummary(), 174 multiplier: f.Multiplier, 175 divisor: f.Divisor, 176 } 177 } 178 return rv 179 } 180 181 // convert histogram options to microseconds (second => us) 182 func convHistOptionsToMicroseconds(histogram []float64) []float64 { 183 var buckets []float64 184 for _, value := range histogram { 185 buckets = append(buckets, value*1e6) 186 } 187 return buckets 188 }