metric.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. // Copyright 2020 Frédéric Guillot. All rights reserved.
  2. // Use of this source code is governed by the Apache 2.0
  3. // license that can be found in the LICENSE file.
  4. package metric // import "miniflux.app/metric"
  5. import (
  6. "time"
  7. "miniflux.app/logger"
  8. "miniflux.app/storage"
  9. "github.com/prometheus/client_golang/prometheus"
  10. )
  11. // Prometheus Metrics.
  12. var (
  13. BackgroundFeedRefreshDuration = prometheus.NewHistogramVec(
  14. prometheus.HistogramOpts{
  15. Namespace: "miniflux",
  16. Name: "background_feed_refresh_duration",
  17. Help: "Processing time to refresh feeds from the background workers",
  18. Buckets: prometheus.LinearBuckets(1, 2, 15),
  19. },
  20. []string{"status"},
  21. )
  22. ScraperRequestDuration = prometheus.NewHistogramVec(
  23. prometheus.HistogramOpts{
  24. Namespace: "miniflux",
  25. Name: "scraper_request_duration",
  26. Help: "Web scraper request duration",
  27. Buckets: prometheus.LinearBuckets(1, 2, 25),
  28. },
  29. []string{"status"},
  30. )
  31. ArchiveEntriesDuration = prometheus.NewHistogramVec(
  32. prometheus.HistogramOpts{
  33. Namespace: "miniflux",
  34. Name: "archive_entries_duration",
  35. Help: "Archive entries duration",
  36. Buckets: prometheus.LinearBuckets(1, 2, 30),
  37. },
  38. []string{"status"},
  39. )
  40. usersGauge = prometheus.NewGauge(
  41. prometheus.GaugeOpts{
  42. Namespace: "miniflux",
  43. Name: "users",
  44. Help: "Number of users",
  45. },
  46. )
  47. feedsGauge = prometheus.NewGaugeVec(
  48. prometheus.GaugeOpts{
  49. Namespace: "miniflux",
  50. Name: "feeds",
  51. Help: "Number of feeds by status",
  52. },
  53. []string{"status"},
  54. )
  55. brokenFeedsGauge = prometheus.NewGauge(
  56. prometheus.GaugeOpts{
  57. Namespace: "miniflux",
  58. Name: "broken_feeds",
  59. Help: "Number of broken feeds",
  60. },
  61. )
  62. entriesGauge = prometheus.NewGaugeVec(
  63. prometheus.GaugeOpts{
  64. Namespace: "miniflux",
  65. Name: "entries",
  66. Help: "Number of entries by status",
  67. },
  68. []string{"status"},
  69. )
  70. dbOpenConnectionsGauge = prometheus.NewGauge(
  71. prometheus.GaugeOpts{
  72. Namespace: "miniflux",
  73. Name: "db_open_connections",
  74. Help: "The number of established connections both in use and idle",
  75. },
  76. )
  77. dbConnectionsInUseGauge = prometheus.NewGauge(
  78. prometheus.GaugeOpts{
  79. Namespace: "miniflux",
  80. Name: "db_connections_in_use",
  81. Help: "The number of connections currently in use",
  82. },
  83. )
  84. dbConnectionsIdleGauge = prometheus.NewGauge(
  85. prometheus.GaugeOpts{
  86. Namespace: "miniflux",
  87. Name: "db_connections_idle",
  88. Help: "The number of idle connections",
  89. },
  90. )
  91. dbConnectionsWaitCountGauge = prometheus.NewGauge(
  92. prometheus.GaugeOpts{
  93. Namespace: "miniflux",
  94. Name: "db_connections_wait_count",
  95. Help: "The total number of connections waited for",
  96. },
  97. )
  98. dbConnectionsMaxIdleClosedGauge = prometheus.NewGauge(
  99. prometheus.GaugeOpts{
  100. Namespace: "miniflux",
  101. Name: "db_connections_max_idle_closed",
  102. Help: "The total number of connections closed due to SetMaxIdleConns",
  103. },
  104. )
  105. dbConnectionsMaxIdleTimeClosedGauge = prometheus.NewGauge(
  106. prometheus.GaugeOpts{
  107. Namespace: "miniflux",
  108. Name: "db_connections_max_idle_time_closed",
  109. Help: "The total number of connections closed due to SetConnMaxIdleTime",
  110. },
  111. )
  112. dbConnectionsMaxLifetimeClosedGauge = prometheus.NewGauge(
  113. prometheus.GaugeOpts{
  114. Namespace: "miniflux",
  115. Name: "db_connections_max_lifetime_closed",
  116. Help: "The total number of connections closed due to SetConnMaxLifetime",
  117. },
  118. )
  119. )
  120. // Collector represents a metric collector.
  121. type Collector struct {
  122. store *storage.Storage
  123. refreshInterval int
  124. }
  125. // NewCollector initializes a new metric collector.
  126. func NewCollector(store *storage.Storage, refreshInterval int) *Collector {
  127. prometheus.MustRegister(BackgroundFeedRefreshDuration)
  128. prometheus.MustRegister(ScraperRequestDuration)
  129. prometheus.MustRegister(ArchiveEntriesDuration)
  130. prometheus.MustRegister(usersGauge)
  131. prometheus.MustRegister(feedsGauge)
  132. prometheus.MustRegister(brokenFeedsGauge)
  133. prometheus.MustRegister(entriesGauge)
  134. prometheus.MustRegister(dbOpenConnectionsGauge)
  135. prometheus.MustRegister(dbConnectionsInUseGauge)
  136. prometheus.MustRegister(dbConnectionsIdleGauge)
  137. prometheus.MustRegister(dbConnectionsWaitCountGauge)
  138. prometheus.MustRegister(dbConnectionsMaxIdleClosedGauge)
  139. prometheus.MustRegister(dbConnectionsMaxIdleTimeClosedGauge)
  140. prometheus.MustRegister(dbConnectionsMaxLifetimeClosedGauge)
  141. return &Collector{store, refreshInterval}
  142. }
  143. // GatherStorageMetrics polls the database to fetch metrics.
  144. func (c *Collector) GatherStorageMetrics() {
  145. for range time.Tick(time.Duration(c.refreshInterval) * time.Second) {
  146. logger.Debug("[Metric] Collecting database metrics")
  147. usersGauge.Set(float64(c.store.CountUsers()))
  148. brokenFeedsGauge.Set(float64(c.store.CountAllFeedsWithErrors()))
  149. feedsCount := c.store.CountAllFeeds()
  150. for status, count := range feedsCount {
  151. feedsGauge.WithLabelValues(status).Set(float64(count))
  152. }
  153. entriesCount := c.store.CountAllEntries()
  154. for status, count := range entriesCount {
  155. entriesGauge.WithLabelValues(status).Set(float64(count))
  156. }
  157. dbStats := c.store.DBStats()
  158. dbOpenConnectionsGauge.Set(float64(dbStats.OpenConnections))
  159. dbConnectionsInUseGauge.Set(float64(dbStats.InUse))
  160. dbConnectionsIdleGauge.Set(float64(dbStats.Idle))
  161. dbConnectionsWaitCountGauge.Set(float64(dbStats.WaitCount))
  162. dbConnectionsMaxIdleClosedGauge.Set(float64(dbStats.MaxIdleClosed))
  163. dbConnectionsMaxIdleTimeClosedGauge.Set(float64(dbStats.MaxIdleTimeClosed))
  164. dbConnectionsMaxLifetimeClosedGauge.Set(float64(dbStats.MaxLifetimeClosed))
  165. }
  166. }