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  }