Мы рекомендуем использовать инструменты мониторинга, такие как Prometheus, для отслеживания процессов выполнения заданий и очередей в производственной среде.

Метрики очереди

Если вы используете веб-интерфейс, вы можете включить интеграцию с Prometheus, предоставив два параметра:

  • --enable-metrics-exporter: Включает сбор метрик очереди и экспортирует их в конечную точку /metrics.
  • --prometheus-addr: Включает визуализацию метрик очереди в рамках веб-интерфейса.

Страница метрик очереди выглядит следующим образом:

Screen Shot 2021-12-19 at 4 37 19 PM

Если вы не используете веб-интерфейс, Asynq поставляется с исполняемым файлом, который можно запустить для экспорта метрик очереди. Также имеется пакет x/metrics для сбора метрик очереди.

Метрики процесса задания

Интерфейс Handler и ServeMux в Asynq может быть инструментирован с помощью метрик для возможности отслеживания.

Приведем пример экспорта метрик процесса задания с использованием Prometheus. Мы можем инструментировать наш код в рамках приложения для отслеживания дополнительных метрик, специфичных для приложения, а также метрик по умолчанию (таких как память и ЦП), отслеживаемых Prometheus.

Вот список специфичных для приложения метрик, отслеживаемых в приведенном примере кода:

  • Общее количество задач, обработанных процессом выполнения задания (включая как успешные, так и неудавшиеся задачи).
  • Количество неудавшихся задач, обработанных процессом выполнения задания.
  • Текущее количество задач, обрабатываемых процессом выполнения задания.
package main

import (
    "context"
    "log"
    "net/http"
    "os"
    "os/signal"
    "runtime"

    "github.com/hibiken/asynq"
    "github.com/hibiken/asynq/examples/tasks"
    "github.com/prometheus/client_golang/prometheus"
    "github.com/prometheus/client_golang/prometheus/promauto"
    "github.com/prometheus/client_golang/prometheus/promhttp"
    "golang.org/x/sys/unix"
)

// Переменные для метрик.
var (
    processedCounter = promauto.NewCounterVec(
        prometheus.CounterOpts{
            Name: "processed_tasks_total",
            Help: "Общее количество обработанных задач",
        },
        []string{"task_type"},
    )

    failedCounter = promauto.NewCounterVec(
        prometheus.CounterOpts{
            Name: "failed_tasks_total",
            Help: "Общее количество неудавшихся обработанных задач",
        },
        []string{"task_type"},
    )

    inProgressGauge = promauto.NewGaugeVec(
        prometheus.GaugeOpts{
            Name: "in_progress_tasks",
            Help: "Текущее количество обрабатываемых задач",
        },
        []string{"task_type"},
    )
)

func metricsMiddleware(next asynq.Handler) asynq.Handler {
    return asynq.HandlerFunc(func(ctx context.Context, t *asynq.Task) error {
        inProgressGauge.WithLabelValues(t.Type()).Inc()
        err := next.ProcessTask(ctx, t)
        inProgressGauge.WithLabelValues(t.Type()).Dec()
        if err != nil {
            failedCounter.WithLabelValues(t.Type()).Inc()
        }
        processedCounter.WithLabelValues(t.Type()).Inc()
        return err
    })
}

func main(){
   // Код не изменен
}