promethues.go 3.7 KB

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