promethues.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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{"service"},
  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. Name: m.Name,
  74. Help: m.Description,
  75. },
  76. m.Args,
  77. )
  78. case "counter":
  79. metric = prometheus.NewCounter(
  80. prometheus.CounterOpts{
  81. Name: m.Name,
  82. Help: m.Description,
  83. },
  84. )
  85. case "gauge_vec":
  86. metric = prometheus.NewGaugeVec(
  87. prometheus.GaugeOpts{
  88. Name: m.Name,
  89. Help: m.Description,
  90. },
  91. m.Args,
  92. )
  93. case "gauge":
  94. metric = prometheus.NewGauge(
  95. prometheus.GaugeOpts{
  96. Name: m.Name,
  97. Help: m.Description,
  98. },
  99. )
  100. case "histogram_vec":
  101. metric = prometheus.NewHistogramVec(
  102. prometheus.HistogramOpts{
  103. Name: m.Name,
  104. Help: m.Description,
  105. },
  106. m.Args,
  107. )
  108. case "histogram":
  109. metric = prometheus.NewHistogram(
  110. prometheus.HistogramOpts{
  111. Name: m.Name,
  112. Help: m.Description,
  113. },
  114. )
  115. case "summary_vec":
  116. metric = prometheus.NewSummaryVec(
  117. prometheus.SummaryOpts{
  118. Name: m.Name,
  119. Help: m.Description,
  120. },
  121. m.Args,
  122. )
  123. case "summary":
  124. metric = prometheus.NewSummary(
  125. prometheus.SummaryOpts{
  126. Name: m.Name,
  127. Help: m.Description,
  128. },
  129. )
  130. }
  131. return metric
  132. }
  133. func (p *Prometheus) registerMetrics(sub string) {
  134. for _, metricDef := range p.MetricsList {
  135. metric := NewMetric(metricDef, sub)
  136. if err := prometheus.Register(metric); err != nil {
  137. Log.Errorf("%s could not be registered in prometheus", metricDef.Name)
  138. }
  139. switch metricDef {
  140. case rpcCallCnt:
  141. p.CallCnt = metric.(*prometheus.CounterVec)
  142. case rpcCallDur:
  143. p.CallDur = metric.(*prometheus.HistogramVec)
  144. }
  145. metricDef.MetricCollector = metric
  146. }
  147. }