...

Source file src/github.com/penglongli/gin-metrics/ginmetrics/types.go

Documentation: github.com/penglongli/gin-metrics/ginmetrics

     1  package ginmetrics
     2  
     3  import (
     4  	"github.com/pkg/errors"
     5  	"github.com/prometheus/client_golang/prometheus"
     6  )
     7  
     8  type MetricType int
     9  
    10  const (
    11  	None MetricType = iota
    12  	Counter
    13  	Gauge
    14  	Histogram
    15  	Summary
    16  
    17  	defaultMetricPath = "/debug/metrics"
    18  	defaultSlowTime   = int32(5)
    19  )
    20  
    21  var (
    22  	defaultDuration = []float64{0.1, 0.3, 1.2, 5, 10}
    23  	monitor         *Monitor
    24  
    25  	promTypeHandler = map[MetricType]func(metric *Metric) error{
    26  		Counter:   counterHandler,
    27  		Gauge:     gaugeHandler,
    28  		Histogram: histogramHandler,
    29  		Summary:   summaryHandler,
    30  	}
    31  )
    32  
    33  // Monitor is an object that uses to set gin server monitor.
    34  type Monitor struct {
    35  	slowTime    int32
    36  	metricPath  string
    37  	reqDuration []float64
    38  	metrics     map[string]*Metric
    39  }
    40  
    41  // GetMonitor used to get global Monitor object,
    42  // this function returns a singleton object.
    43  func GetMonitor() *Monitor {
    44  	if monitor == nil {
    45  		monitor = &Monitor{
    46  			metricPath:  defaultMetricPath,
    47  			slowTime:    defaultSlowTime,
    48  			reqDuration: defaultDuration,
    49  			metrics:     make(map[string]*Metric),
    50  		}
    51  	}
    52  	return monitor
    53  }
    54  
    55  // GetMetric used to get metric object by metric_name.
    56  func (m *Monitor) GetMetric(name string) *Metric {
    57  	if metric, ok := m.metrics[name]; ok {
    58  		return metric
    59  	}
    60  	return &Metric{}
    61  }
    62  
    63  // SetMetricPath set metricPath property. metricPath is used for Prometheus
    64  // to get gin server monitoring data.
    65  func (m *Monitor) SetMetricPath(path string) {
    66  	m.metricPath = path
    67  }
    68  
    69  // SetSlowTime set slowTime property. slowTime is used to determine whether
    70  // the request is slow. For "gin_slow_request_total" metric.
    71  func (m *Monitor) SetSlowTime(slowTime int32) {
    72  	m.slowTime = slowTime
    73  }
    74  
    75  // SetDuration set reqDuration property. reqDuration is used to ginRequestDuration
    76  // metric buckets.
    77  func (m *Monitor) SetDuration(duration []float64) {
    78  	m.reqDuration = duration
    79  }
    80  
    81  func (m *Monitor) SetMetricPrefix(prefix string) {
    82  	metricRequestTotal = prefix + metricRequestTotal
    83  	metricRequestUVTotal = prefix + metricRequestUVTotal
    84  	metricURIRequestTotal = prefix + metricURIRequestTotal
    85  	metricRequestBody = prefix + metricRequestBody
    86  	metricResponseBody = prefix + metricResponseBody
    87  	metricRequestDuration = prefix + metricRequestDuration
    88  	metricSlowRequest = prefix + metricSlowRequest
    89  }
    90  
    91  func (m *Monitor) SetMetricSuffix(suffix string) {
    92  	metricRequestTotal += suffix
    93  	metricRequestUVTotal += suffix
    94  	metricURIRequestTotal += suffix
    95  	metricRequestBody += suffix
    96  	metricResponseBody += suffix
    97  	metricRequestDuration += suffix
    98  	metricSlowRequest += suffix
    99  }
   100  
   101  // AddMetric add custom monitor metric.
   102  func (m *Monitor) AddMetric(metric *Metric) error {
   103  	if _, ok := m.metrics[metric.Name]; ok {
   104  		return errors.Errorf("metric '%s' is existed", metric.Name)
   105  	}
   106  
   107  	if metric.Name == "" {
   108  		return errors.Errorf("metric name cannot be empty.")
   109  	}
   110  	if f, ok := promTypeHandler[metric.Type]; ok {
   111  		if err := f(metric); err == nil {
   112  			prometheus.MustRegister(metric.vec)
   113  			m.metrics[metric.Name] = metric
   114  			return nil
   115  		}
   116  	}
   117  	return errors.Errorf("metric type '%d' not existed.", metric.Type)
   118  }
   119  
   120  func counterHandler(metric *Metric) error {
   121  	metric.vec = prometheus.NewCounterVec(
   122  		prometheus.CounterOpts{Name: metric.Name, Help: metric.Description},
   123  		metric.Labels,
   124  	)
   125  	return nil
   126  }
   127  
   128  func gaugeHandler(metric *Metric) error {
   129  	metric.vec = prometheus.NewGaugeVec(
   130  		prometheus.GaugeOpts{Name: metric.Name, Help: metric.Description},
   131  		metric.Labels,
   132  	)
   133  	return nil
   134  }
   135  
   136  func histogramHandler(metric *Metric) error {
   137  	if len(metric.Buckets) == 0 {
   138  		return errors.Errorf("metric '%s' is histogram type, cannot lose bucket param.", metric.Name)
   139  	}
   140  	metric.vec = prometheus.NewHistogramVec(
   141  		prometheus.HistogramOpts{Name: metric.Name, Help: metric.Description, Buckets: metric.Buckets},
   142  		metric.Labels,
   143  	)
   144  	return nil
   145  }
   146  
   147  func summaryHandler(metric *Metric) error {
   148  	if len(metric.Objectives) == 0 {
   149  		return errors.Errorf("metric '%s' is summary type, cannot lose objectives param.", metric.Name)
   150  	}
   151  	prometheus.NewSummaryVec(
   152  		prometheus.SummaryOpts{Name: metric.Name, Help: metric.Description, Objectives: metric.Objectives},
   153  		metric.Labels,
   154  	)
   155  	return nil
   156  }
   157  

View as plain text