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

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

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

Начать курс

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

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

Зачем нужен мониторинг Go-приложений?

Go-приложения часто используются для высоконагруженных микросервисов, API-шлюзов и фоновых обработчиков. Без мониторинга вы рискуете пропустить:

  • Утечки памяти и горутин;
  • Медленные запросы и блокировки;
  • Падение производительности под нагрузкой;
  • Ошибки подключения к базам данных и внешним сервисам.

1. 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:    "Duration of HTTP requests in seconds",
            Buckets: prometheus.DefBuckets,
        },
        []string{"method", "endpoint"},
    )
)

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

func middleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        start := time.Now()
        next.ServeHTTP(w, r)
        duration := time.Since(start).Seconds()
        requestCount.WithLabelValues(r.Method, r.URL.Path).Inc()
        requestDuration.WithLabelValues(r.Method, r.URL.Path).Observe(duration)
    })
}

func main() {
    mux := http.NewServeMux()
    mux.Handle("/metrics", promhttp.Handler())
    mux.Handle("/", middleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Hello, World!"))
    })))
    http.ListenAndServe(":8080", mux)
}

После запуска метрики будут доступны по адресу http://localhost:8080/metrics. Prometheus настроит сбор с этого эндпоинта.

2. expvar — встроенный экспорт метрик

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

Пример использования

package main

import (
    "expvar"
    "net/http"
)

var (
    requests = expvar.NewInt("requests_total")
    errors   = expvar.NewInt("errors_total")
)

func handler(w http.ResponseWriter, r *http.Request) {
    requests.Add(1)
    // Имитация ошибки
    if r.URL.Query().Get("error") == "1" {
        errors.Add(1)
        w.WriteHeader(http.StatusInternalServerError)
        return
    }
    w.Write([]byte("OK"))
}

func main() {
    http.HandleFunc("/debug/vars", expvar.Handler().ServeHTTP)
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

Метрики доступны по пути /debug/vars в формате JSON. Для интеграции с Prometheus можно использовать prometheus/expvar адаптер.

3. pprof — профилирование производительности

Пакет net/http/pprof позволяет получать профили CPU, памяти, блокировок и горутин в реальном времени.

Подключение

import _ "net/http/pprof"

func main() {
    http.ListenAndServe(":8080", nil)
}

После этого доступны эндпоинты:

  • /debug/pprof/ — список профилей;
  • /debug/pprof/heap — профиль памяти;
  • /debug/pprof/profile — CPU профиль (30 секунд);
  • /debug/pprof/goroutine — стек-трейсы всех горутин.

Для анализа можно использовать

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