Мониторинг Go-приложений: библиотеки и инструменты

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Мониторинг приложений Go (Golang): инструменты и библиотеки

Мониторинг — неотъемлемая часть production-эксплуатации любого сервиса. Для приложений на Go (Golang) экосистема предлагает как встроенные решения, так и мощные внешние инструменты. В этой статье мы разберём основные подходы: от базового профилирования до сбора метрик и трейсинга.

1. Встроенные средства: пакет expvar

Пакет expvar предоставляет простейший HTTP-эндпоинт для публикации переменных состояния приложения. Он не требует внешних зависимостей и идеально подходит для быстрой диагностики.

Подключение и использование

package main

import (
    "expvar"
    "net/http"
)

var requestsCount = expvar.NewInt("total_requests")

func handler(w http.ResponseWriter, r *http.Request) {
    requestsCount.Add(1)
    w.Write([]byte("OK"))
}

func main() {
    http.HandleFunc("/api", handler)
    // Эндпоинт /debug/vars будет доступен автоматически
    http.ListenAndServe(":8080", nil)
}

После запуска перейдите на /debug/vars — вы увидите JSON с метриками, включая счётчик запросов, данные GC и память.

2. Prometheus — де-факто стандарт метрик

Prometheus — самая популярная система мониторинга для Go. Библиотека prometheus/client_golang позволяет экспортировать метрики в формате, понятном Prometheus-серверу.

Установка

go get github.com/prometheus/client_golang/prometheus
go get github.com/prometheus/client_golang/prometheus/promhttp

Пример: счётчик и гистограмма

package main

import (
    "net/http"
    "time"

    "github.com/prometheus/client_golang/prometheus"
    "github.com/prometheus/client_golang/prometheus/promhttp"
)

var (
    requestCount = prometheus.NewCounterVec(
        prometheus.CounterOpts{
            Name: "http_requests_total",
            Help: "Total number of HTTP requests",
        },
        []string{"method", "endpoint"},
    )
    requestDuration = prometheus.NewHistogramVec(
        prometheus.HistogramOpts{
            Name:    "http_request_duration_seconds",
            Help:    "Histogram of request durations",
            Buckets: prometheus.DefBuckets,
        },
        []string{"method"},
    )
)

func init() {
    prometheus.MustRegister(requestCount, requestDuration)
}

func handler(w http.ResponseWriter, r *http.Request) {
    start := time.Now()
    requestCount.WithLabelValues(r.Method, r.URL.Path).Inc()
    w.Write([]byte("Hello"))
    requestDuration.WithLabelValues(r.Method).Observe(time.Since(start).Seconds())
}

func main() {
    http.Handle("/metrics", promhttp.Handler())
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

Prometheus будет собирать метрики с эндпоинта /metrics. Вы можете добавить алерты в Alertmanager на основе этих данных.

3. Профилирование с pprof

Пакет net/http/pprof добавляет в приложение эндпоинты для профилирования CPU, памяти, горутин и блокировок. Это незаменимый инструмент для поиска узких мест.

Быстрый старт

package main

import (
    "log"
    "net/http"
    _ "net/http/pprof" // регистрирует обработчики
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Hello, pprof!"))
    })
    log.Fatal(http.ListenAndServe(":6060", nil))
}

Теперь доступны эндпоинты:

  • /debug/pprof/ — список профилей
  • /debug/pprof/profile — CPU-профиль
  • /debug/pprof/heap — профиль памяти
  • /debug/pprof/goroutine — стеки горутин

Анализируйте профили командой go tool pprof или визуализируйте через go tool pprof -http=:8081.

4. OpenTelemetry — универсальный трейсинг

OpenTelemetry (OTel) — это фреймворк для сбора трейсов, метрик и логов. В Go используется SDK go.opentelemetry.io/otel. Он позволяет отправлять данные в Jaeger, Zipkin, Prometheus и другие бэкенды.

Пример: распределённый трейсинг

package main

import (
    "context"
    "log"
    "net/http"

    "go.opentelemetry.io/otel"
    "go.op                    

Рекомендаций