// app/metrics/gauge_updater.go // Периодическое обновление gauge-метрик (количество очередей и сообщений per tenant). // Запускается как горутина из main, обновляет каждые 15 секунд. // Не блокирует SQS-запросы — читает через RLock. // Created: 2026-04-12 package metrics import ( "strings" "time" "shared-sqs/app/models" log "github.com/sirupsen/logrus" ) // StartGaugeUpdater — запускает горутину, которая каждые interval секунд // пересчитывает количество очередей и сообщений по тенантам для Prometheus gauge. // Останавливается при закрытии канала quit. func StartGaugeUpdater(interval time.Duration, quit <-chan bool) { go func() { ticker := time.NewTicker(interval) defer ticker.Stop() for { select { case <-ticker.C: updateGauges() case <-quit: log.Debug("metrics: gauge updater stopped") return } } }() log.Infof("metrics: gauge updater started, interval=%s", interval) } // updateGauges — пересчитывает sqs_queues_count и sqs_messages_count per tenant. // Формат ключа очереди: "{accessKey}:{queueName}" — берём часть до первого ":". func updateGauges() { // Собираем данные под RLock — не блокируем запись models.SyncQueues.RLock() tenantQueues := make(map[string]int) tenantMessages := make(map[string]int) for key, queue := range models.SyncQueues.Queues { // Ключ формата "accessKey:queueName" — tenant определяется по accessKey parts := strings.SplitN(key, ":", 2) tenantKey := parts[0] tenantQueues[tenantKey]++ tenantMessages[tenantKey] += len(queue.Messages) } models.SyncQueues.RUnlock() // Сбрасываем старые значения и записываем новые QueuesGauge.Reset() MessagesGauge.Reset() for tenant, count := range tenantQueues { QueuesGauge.WithLabelValues(tenant).Set(float64(count)) } for tenant, count := range tenantMessages { MessagesGauge.WithLabelValues(tenant).Set(float64(count)) } }