metric.go 5.5 KB

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