promethues.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. package server
  2. import (
  3. "github.com/prometheus/client_golang/prometheus"
  4. "github.com/prometheus/client_golang/prometheus/promhttp"
  5. "net/http"
  6. )
  7. var rpcCallCnt = &Metric{
  8. ID: "rpcCallCnt",
  9. Name: "rpc_call_total",
  10. Description: "HOW MANY RPC CALL",
  11. Type: "counter_vec",
  12. Args: []string{"server", "host"},
  13. }
  14. var rpcCallDur = &Metric{
  15. ID: "rpc_call_duration",
  16. Name: "rpc_call_duration_seconds",
  17. Description: "rpc call duration seconds",
  18. Type: "histogram_vec",
  19. Args: []string{"client", "server", "method"},
  20. }
  21. var standardMetrics = []*Metric{
  22. rpcCallCnt,
  23. rpcCallDur,
  24. }
  25. type Metric struct {
  26. MetricCollector prometheus.Collector
  27. ID string
  28. Name string
  29. Description string
  30. Type string
  31. Args []string
  32. }
  33. type Prometheus struct {
  34. MetricsList []*Metric
  35. MetricsPath string
  36. CallCnt *prometheus.CounterVec
  37. CallDur *prometheus.HistogramVec
  38. }
  39. func NewPrometheus(subsystem string, customMetricsList ...*Metric) *Prometheus {
  40. var metricsList []*Metric
  41. for _, v := range customMetricsList {
  42. metricsList = append(metricsList, v)
  43. }
  44. for _, metric := range standardMetrics {
  45. metricsList = append(metricsList, metric)
  46. }
  47. p := &Prometheus{
  48. MetricsList: metricsList,
  49. MetricsPath: "/metrics",
  50. }
  51. p.registerMetrics(subsystem)
  52. return p
  53. }
  54. func (p *Prometheus) Start(addr string) error {
  55. http.Handle(p.MetricsPath, promhttp.Handler())
  56. return http.ListenAndServe(addr, nil)
  57. }
  58. func (p *Prometheus) RegisterMetrics(sub string, metrics ...*Metric) {
  59. for _, m := range metrics {
  60. metric := NewMetric(m, sub)
  61. if err := prometheus.Register(metric); err != nil {
  62. Log.Errorf("%s could not be registered in prometheus", m.Name)
  63. }
  64. }
  65. }
  66. // NewMetric associates prometheus.Collector based on Metric.Type
  67. func NewMetric(m *Metric, subsystem string) prometheus.Collector {
  68. var metric prometheus.Collector
  69. switch m.Type {
  70. case "counter_vec":
  71. metric = prometheus.NewCounterVec(
  72. prometheus.CounterOpts{
  73. Subsystem: subsystem,
  74. Name: m.Name,
  75. Help: m.Description,
  76. },
  77. m.Args,
  78. )
  79. case "counter":
  80. metric = prometheus.NewCounter(
  81. prometheus.CounterOpts{
  82. Subsystem: subsystem,
  83. Name: m.Name,
  84. Help: m.Description,
  85. },
  86. )
  87. case "gauge_vec":
  88. metric = prometheus.NewGaugeVec(
  89. prometheus.GaugeOpts{
  90. Subsystem: subsystem,
  91. Name: m.Name,
  92. Help: m.Description,
  93. },
  94. m.Args,
  95. )
  96. case "gauge":
  97. metric = prometheus.NewGauge(
  98. prometheus.GaugeOpts{
  99. Subsystem: subsystem,
  100. Name: m.Name,
  101. Help: m.Description,
  102. },
  103. )
  104. case "histogram_vec":
  105. metric = prometheus.NewHistogramVec(
  106. prometheus.HistogramOpts{
  107. Subsystem: subsystem,
  108. Name: m.Name,
  109. Help: m.Description,
  110. },
  111. m.Args,
  112. )
  113. case "histogram":
  114. metric = prometheus.NewHistogram(
  115. prometheus.HistogramOpts{
  116. Subsystem: subsystem,
  117. Name: m.Name,
  118. Help: m.Description,
  119. },
  120. )
  121. case "summary_vec":
  122. metric = prometheus.NewSummaryVec(
  123. prometheus.SummaryOpts{
  124. Subsystem: subsystem,
  125. Name: m.Name,
  126. Help: m.Description,
  127. },
  128. m.Args,
  129. )
  130. case "summary":
  131. metric = prometheus.NewSummary(
  132. prometheus.SummaryOpts{
  133. Subsystem: subsystem,
  134. Name: m.Name,
  135. Help: m.Description,
  136. },
  137. )
  138. }
  139. return metric
  140. }
  141. func (p *Prometheus) registerMetrics(sub string) {
  142. for _, metricDef := range p.MetricsList {
  143. metric := NewMetric(metricDef, sub)
  144. if err := prometheus.Register(metric); err != nil {
  145. Log.Errorf("%s could not be registered in prometheus", metricDef.Name)
  146. }
  147. switch metricDef {
  148. case rpcCallCnt:
  149. p.CallCnt = metric.(*prometheus.CounterVec)
  150. case rpcCallDur:
  151. p.CallDur = metric.(*prometheus.HistogramVec)
  152. }
  153. metricDef.MetricCollector = metric
  154. }
  155. }