prometheus.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. "net/http"
  6. "time"
  7. "github.com/prometheus/client_golang/prometheus"
  8. "github.com/prometheus/client_golang/prometheus/promhttp"
  9. )
  10. var (
  11. prometheusEnabled = false
  12. prometheusRequestsTotal prometheus.Counter
  13. prometheusErrorsTotal *prometheus.CounterVec
  14. prometheusRequestDuration prometheus.Histogram
  15. prometheusDownloadDuration prometheus.Histogram
  16. prometheusProcessingDuration prometheus.Histogram
  17. prometheusBufferSize *prometheus.HistogramVec
  18. prometheusBufferDefaultSize *prometheus.GaugeVec
  19. prometheusBufferMaxSize *prometheus.GaugeVec
  20. prometheusVipsMemory prometheus.GaugeFunc
  21. prometheusVipsMaxMemory prometheus.GaugeFunc
  22. prometheusVipsAllocs prometheus.GaugeFunc
  23. )
  24. func initPrometheus() {
  25. if len(conf.PrometheusBind) == 0 {
  26. return
  27. }
  28. prometheusRequestsTotal = prometheus.NewCounter(prometheus.CounterOpts{
  29. Namespace: conf.PrometheusNamespace,
  30. Name: "requests_total",
  31. Help: "A counter of the total number of HTTP requests imgproxy processed.",
  32. })
  33. prometheusErrorsTotal = prometheus.NewCounterVec(prometheus.CounterOpts{
  34. Namespace: conf.PrometheusNamespace,
  35. Name: "errors_total",
  36. Help: "A counter of the occurred errors separated by type.",
  37. }, []string{"type"})
  38. prometheusRequestDuration = prometheus.NewHistogram(prometheus.HistogramOpts{
  39. Namespace: conf.PrometheusNamespace,
  40. Name: "request_duration_seconds",
  41. Help: "A histogram of the response latency.",
  42. })
  43. prometheusDownloadDuration = prometheus.NewHistogram(prometheus.HistogramOpts{
  44. Namespace: conf.PrometheusNamespace,
  45. Name: "download_duration_seconds",
  46. Help: "A histogram of the source image downloading latency.",
  47. })
  48. prometheusProcessingDuration = prometheus.NewHistogram(prometheus.HistogramOpts{
  49. Namespace: conf.PrometheusNamespace,
  50. Name: "processing_duration_seconds",
  51. Help: "A histogram of the image processing latency.",
  52. })
  53. prometheusBufferSize = prometheus.NewHistogramVec(prometheus.HistogramOpts{
  54. Namespace: conf.PrometheusNamespace,
  55. Name: "buffer_size_bytes",
  56. Help: "A histogram of the buffer size in bytes.",
  57. Buckets: prometheus.ExponentialBuckets(1024, 2, 14),
  58. }, []string{"type"})
  59. prometheusBufferDefaultSize = prometheus.NewGaugeVec(prometheus.GaugeOpts{
  60. Namespace: conf.PrometheusNamespace,
  61. Name: "buffer_default_size_bytes",
  62. Help: "A gauge of the buffer default size in bytes.",
  63. }, []string{"type"})
  64. prometheusBufferMaxSize = prometheus.NewGaugeVec(prometheus.GaugeOpts{
  65. Namespace: conf.PrometheusNamespace,
  66. Name: "buffer_max_size_bytes",
  67. Help: "A gauge of the buffer max size in bytes.",
  68. }, []string{"type"})
  69. prometheusVipsMemory = prometheus.NewGaugeFunc(prometheus.GaugeOpts{
  70. Namespace: conf.PrometheusNamespace,
  71. Name: "vips_memory_bytes",
  72. Help: "A gauge of the vips tracked memory usage in bytes.",
  73. }, vipsGetMem)
  74. prometheusVipsMaxMemory = prometheus.NewGaugeFunc(prometheus.GaugeOpts{
  75. Namespace: conf.PrometheusNamespace,
  76. Name: "vips_max_memory_bytes",
  77. Help: "A gauge of the max vips tracked memory usage in bytes.",
  78. }, vipsGetMemHighwater)
  79. prometheusVipsAllocs = prometheus.NewGaugeFunc(prometheus.GaugeOpts{
  80. Namespace: conf.PrometheusNamespace,
  81. Name: "vips_allocs",
  82. Help: "A gauge of the number of active vips allocations.",
  83. }, vipsGetAllocs)
  84. prometheus.MustRegister(
  85. prometheusRequestsTotal,
  86. prometheusErrorsTotal,
  87. prometheusRequestDuration,
  88. prometheusDownloadDuration,
  89. prometheusProcessingDuration,
  90. prometheusBufferSize,
  91. prometheusBufferDefaultSize,
  92. prometheusBufferMaxSize,
  93. prometheusVipsMemory,
  94. prometheusVipsMaxMemory,
  95. prometheusVipsAllocs,
  96. )
  97. prometheusEnabled = true
  98. }
  99. func startPrometheusServer(cancel context.CancelFunc) error {
  100. s := http.Server{Handler: promhttp.Handler()}
  101. l, err := listenReuseport("tcp", conf.PrometheusBind)
  102. if err != nil {
  103. return fmt.Errorf("Can't start Prometheus metrics server: %s", err)
  104. }
  105. go func() {
  106. logNotice("Starting Prometheus server at %s", conf.PrometheusBind)
  107. if err := s.Serve(l); err != nil && err != http.ErrServerClosed {
  108. logError(err.Error())
  109. }
  110. cancel()
  111. }()
  112. return nil
  113. }
  114. func startPrometheusDuration(m prometheus.Histogram) func() {
  115. t := time.Now()
  116. return func() {
  117. m.Observe(time.Since(t).Seconds())
  118. }
  119. }
  120. func incrementPrometheusErrorsTotal(t string) {
  121. prometheusErrorsTotal.With(prometheus.Labels{"type": t}).Inc()
  122. }
  123. func observePrometheusBufferSize(t string, size int) {
  124. prometheusBufferSize.With(prometheus.Labels{"type": t}).Observe(float64(size))
  125. }
  126. func setPrometheusBufferDefaultSize(t string, size int) {
  127. prometheusBufferDefaultSize.With(prometheus.Labels{"type": t}).Set(float64(size))
  128. }
  129. func setPrometheusBufferMaxSize(t string, size int) {
  130. prometheusBufferMaxSize.With(prometheus.Labels{"type": t}).Set(float64(size))
  131. }