Bladeren bron

refactor(storage): return errors from count functions used by metrics

Return errors instead of zero values or nil from CountUsers,
CountAllFeeds, CountAllFeedsWithErrors, and CountAllEntries so the
metric collector can log failures and preserve previous gauge values.
Frédéric Guillot 2 weken geleden
bovenliggende
commit
76452fab99
4 gewijzigde bestanden met toevoegingen van 35 en 20 verwijderingen
  1. 23 8
      internal/metric/metric.go
  2. 3 3
      internal/storage/entry.go
  3. 6 6
      internal/storage/feed.go
  4. 3 3
      internal/storage/user.go

+ 23 - 8
internal/metric/metric.go

@@ -182,17 +182,32 @@ func (c *collector) GatherStorageMetrics(ctx context.Context) {
 		}
 		slog.Debug("Collecting metrics from the database")
 
-		usersGauge.Set(float64(c.store.CountUsers()))
-		brokenFeedsGauge.Set(float64(c.store.CountAllFeedsWithErrors()))
+		if usersCount, err := c.store.CountUsers(); err != nil {
+			slog.Warn("Unable to collect users metric", slog.Any("error", err))
+		} else {
+			usersGauge.Set(float64(usersCount))
+		}
+
+		if brokenFeedsCount, err := c.store.CountAllFeedsWithErrors(); err != nil {
+			slog.Warn("Unable to collect broken feeds metric", slog.Any("error", err))
+		} else {
+			brokenFeedsGauge.Set(float64(brokenFeedsCount))
+		}
 
-		feedsCount := c.store.CountAllFeeds()
-		for status, count := range feedsCount {
-			feedsGauge.WithLabelValues(status).Set(float64(count))
+		if feedsCount, err := c.store.CountAllFeeds(); err != nil {
+			slog.Warn("Unable to collect feeds metric", slog.Any("error", err))
+		} else {
+			for status, count := range feedsCount {
+				feedsGauge.WithLabelValues(status).Set(float64(count))
+			}
 		}
 
-		entriesCount := c.store.CountAllEntries()
-		for status, count := range entriesCount {
-			entriesGauge.WithLabelValues(status).Set(float64(count))
+		if entriesCount, err := c.store.CountAllEntries(); err != nil {
+			slog.Warn("Unable to collect entries metric", slog.Any("error", err))
+		} else {
+			for status, count := range entriesCount {
+				entriesGauge.WithLabelValues(status).Set(float64(count))
+			}
 		}
 
 		dbStats := c.store.DBStats()

+ 3 - 3
internal/storage/entry.go

@@ -17,10 +17,10 @@ import (
 )
 
 // CountAllEntries returns the number of entries for each status in the database.
-func (s *Storage) CountAllEntries() map[string]int64 {
+func (s *Storage) CountAllEntries() (map[string]int64, error) {
 	rows, err := s.db.Query(`SELECT status, count(*) FROM entries GROUP BY status`)
 	if err != nil {
-		return nil
+		return nil, fmt.Errorf("storage: unable to count entries: %w", err)
 	}
 	defer rows.Close()
 
@@ -41,7 +41,7 @@ func (s *Storage) CountAllEntries() map[string]int64 {
 	}
 
 	results["total"] = results[model.EntryStatusUnread] + results[model.EntryStatusRead] + results[model.EntryStatusRemoved]
-	return results
+	return results, nil
 }
 
 // CountUnreadEntries returns the number of unread entries.

+ 6 - 6
internal/storage/feed.go

@@ -77,10 +77,10 @@ func (s *Storage) AnotherFeedURLExists(userID, feedID int64, feedURL string) boo
 }
 
 // CountAllFeeds returns the number of feeds in the database.
-func (s *Storage) CountAllFeeds() map[string]int64 {
+func (s *Storage) CountAllFeeds() (map[string]int64, error) {
 	rows, err := s.db.Query(`SELECT disabled, count(*) FROM feeds GROUP BY disabled`)
 	if err != nil {
-		return nil
+		return nil, fmt.Errorf("storage: unable to count feeds: %w", err)
 	}
 	defer rows.Close()
 
@@ -106,7 +106,7 @@ func (s *Storage) CountAllFeeds() map[string]int64 {
 	}
 
 	results["total"] = results["disabled"] + results["enabled"]
-	return results
+	return results, nil
 }
 
 // CountUserFeedsWithErrors returns the number of feeds with parsing errors that belong to the given user.
@@ -126,7 +126,7 @@ func (s *Storage) CountUserFeedsWithErrors(userID int64) int {
 }
 
 // CountAllFeedsWithErrors returns the number of feeds with parsing errors.
-func (s *Storage) CountAllFeedsWithErrors() int {
+func (s *Storage) CountAllFeedsWithErrors() (int, error) {
 	pollingParsingErrorLimit := config.Opts.PollingParsingErrorLimit()
 	if pollingParsingErrorLimit <= 0 {
 		pollingParsingErrorLimit = 1
@@ -135,10 +135,10 @@ func (s *Storage) CountAllFeedsWithErrors() int {
 	var result int
 	err := s.db.QueryRow(query, pollingParsingErrorLimit).Scan(&result)
 	if err != nil {
-		return 0
+		return 0, fmt.Errorf("storage: unable to count feeds with errors: %w", err)
 	}
 
-	return result
+	return result, nil
 }
 
 // Feeds returns all feeds that belongs to the given user.

+ 3 - 3
internal/storage/user.go

@@ -18,14 +18,14 @@ import (
 )
 
 // CountUsers returns the total number of users.
-func (s *Storage) CountUsers() int {
+func (s *Storage) CountUsers() (int, error) {
 	var result int
 	err := s.db.QueryRow(`SELECT count(*) FROM users`).Scan(&result)
 	if err != nil {
-		return 0
+		return 0, fmt.Errorf("storage: unable to count users: %w", err)
 	}
 
-	return result
+	return result, nil
 }
 
 // SetLastLogin updates the last login date of a user.