Как отправить метрики с приложения в Grafana?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Конечно, как опытный Go-разработчик, я подробно расскажу об отправке метрик из Go-приложения в экосистему Grafana. Важно понимать, что Grafana — это в первую очередь платформа для визуализации и анализа данных, а не система их сбора или хранения. Поэтому отправка метрик происходит не напрямую в Grafana, а в систему хранения временных рядов (TSDB), которую затем подключают к Grafana в качестве источника данных.
Основной принцип работы
Типичный пайплайн выглядит так:
- Приложение (Instrumentation): Генерирует метрики (счётчики, гистограммы и т.д.).
- Сборщик/Агент (Optional): Собирает метрики (например, Prometheus
node_exporterили Pushgateway). - База данных временных рядов (Storage): Хранит метрики (Prometheus, InfluxDB, Graphite, VictoriaMetrics).
- Grafana (Visualization): Запрашивает данные из базы и строит дашборды.
Рассмотрим самые популярные способы отправки метрик из Go-приложения.
Способ 1: Prometheus (Pull-модель) — Самый распространённый подход
Prometheus работает по pull-модели: он периодически "опрашивает" (scrapes) ваше приложение по HTTP-эндпоинту (обычно /metrics), чтобы получить текущие значения метрик.
Шаги для реализации:
-
Установите клиентскую библиотеку:
go get github.com/prometheus/client_golang -
Инструментируйте ваше приложение. Создайте и зарегистрируйте метрики:
package main import ( "net/http" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/client_golang/prometheus/promhttp" ) // Определяем метрики var ( httpRequestsTotal = promauto.NewCounterVec( prometheus.CounterOpts{ Name: "http_requests_total", Help: "Total number of HTTP requests", }, []string{"method", "path", "status"}, ) requestDuration = promauto.NewHistogramVec( prometheus.HistogramOpts{ Name: "http_request_duration_seconds", Help: "Duration of HTTP requests.", Buckets: prometheus.DefBuckets, // Предопределённые корзины для гистограммы }, []string{"method", "path"}, ) ) func main() { // Регистрируем стандартные метрики Go и процесса (GC, горутины, память) prometheus.MustRegister(prometheus.NewBuildInfoCollector()) // Экспортируем метрики по адресу /metrics http.Handle("/metrics", promhttp.Handler()) // Пример обработчика, который инкрементит метрики http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { timer := prometheus.NewTimer(requestDuration.WithLabelValues(r.Method, r.URL.Path)) defer timer.ObserveDuration() // Логика обработки запроса... w.WriteHeader(http.StatusOK) w.Write([]byte("Hello World")) // Увеличиваем счётчик запросов httpRequestsTotal.WithLabelValues(r.Method, r.URL.Path, "200").Inc() }) http.ListenAndServe(":8080", nil) } -
Настройте Prometheus на сбор метрик с вашего приложения, добавив задание (job) в
prometheus.yml:scrape_configs: - job_name: 'my_go_app' static_configs: - targets: ['localhost:8080'] -
В Grafana добавьте Prometheus как источник данных, указав его адрес (например,
http://prometheus:9090). После этого вы сможете создавать дашборды, используя запросы на языке PromQL (например,rate(http_requests_total[5m])).
Преимущества Pull-модели (Prometheus):
- Простота отладки: можно вручную зайти на
/metricsи увидеть все данные. - Централизованное управление сбором с одной стороны.
- Сложнее "потерять" данные при кратковременных сбоях приложения.
Способ 2: Push-модель (Graphite, InfluxDB)
Иногда pull-модель невозможна (например, для кратковременных задач или в serverless-средах). Тогда используют push-подход, где приложение само отправляет метрики.
Пример с InfluxDB 2.x (используя официальный клиент):
package main
import (
"context"
"fmt"
"time"
influxdb2 "github.com/influxdata/influxdb-client-go/v2"
)
func main() {
// Создаём клиент
client := influxdb2.NewClient("http://localhost:8086", "your-auth-token")
defer client.Close()
// Получаем API для записи
writeAPI := client.WriteAPI("your-org", "your-bucket")
// Создаём точку (point) — запись метрики
p := influxdb2.NewPointWithMeasurement("http_requests").
AddTag("method", "GET").
AddTag("path", "/api/v1/users").
AddField("duration_ms", 152.5).
AddField("count", 1).
SetTime(time.Now())
// Асинхронная запись
writeAPI.WritePoint(p)
// Для синхронной записи
// err := writeAPI.WritePoint(context.Background(), p)
// Гарантируем отправку всех ожидающих записей
writeAPI.Flush()
}
Для работы с Grafana вам нужно будет добавить InfluxDB (или Graphite) как источник данных, указав соответствующие параметры подключения.
Способ 3: Использование Pushgateway (для задач в Prometheus)
Pushgateway в экосистеме Prometheus служит буфером для метрик от short-lived jobs (например, Cron-задач).
package main
import (
"fmt"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/push"
)
func main() {
// Создаём метрику
completionTime := prometheus.NewGauge(prometheus.GaugeOpts{
Name: "batch_job_last_completion_timestamp_seconds",
Help: "The timestamp of the last successful batch job completion.",
})
completionTime.SetToCurrentTime()
// Пушим метрику в Pushgateway
err := push.New("http://pushgateway:9091", "my_batch_job").
Collector(completionTime).
Grouping("instance", "my_hostname").
Push()
if err != nil {
fmt.Println("Could not push to Pushgateway:", err)
}
}
Ключевые рекомендации
- Выбор инструмента: Для долгоживущих сервисов (микросервисов, API) используйте Prometheus (Pull). Для задач, живущих меньше периода сбора Prometheus, или для legacy-систем — Pushgateway или прямой push в TSDB.
- Библиотеки: Для Prometheus всегда используйте официальный
client_golang. Он потокобезопасен, эффективен и предоставляет все типы метрик (Counter, Gauge, Histogram, Summary). - Лейблы (labels): Используйте их разумно. Лейблы должны иметь ограниченный набор значений (как
status=200,method=GET). Не используйте в качестве лейбла уникальные ID (например,user_id), это создаст кардинальность метрик и убьёт производительность системы. - Экспорт стандартных метрик: Всегда включайте сбор стандартных метрик Go (
go_*) и процесса (process_*) с помощьюpromhttp.Handler(). - Сервис-открытие (Service Discovery): В продакшене настройте автоматическое обнаружение целей для Prometheus (через Kubernetes, Consul, файлы и т.д.), а не хардкодьте адреса.
Таким образом, отправка метрик из Go-приложения в Grafana — это процесс инструментирования кода, выбора и настройки подходящей системы хранения (Prometheus, InfluxDB и др.) и последующего подключения этой системы к Grafana для построения наглядных дашбордов.