promethues.go 3.5 KB

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