Какие метрики Go-приложения можно получить из рантайма и как это сделать?

Ответ

В Go есть встроенные механизмы для сбора метрик производительности и состояния приложения. Основные подходы — использование пакетов runtime, expvar и net/http/pprof.

1. Пакет runtime

Позволяет получить низкоуровневые метрики о состоянии рантайма Go.

  • Метрики памяти:

    var m runtime.MemStats
    runtime.ReadMemStats(&m)
    
    // m.Alloc      // Байт выделено и до сих пор используется
    // m.TotalAlloc // Всего байт выделено за время жизни программы
    // m.HeapAlloc  // Байт выделено в куче
    // m.NumGC      // Количество сборок мусора
    // m.PauseTotalNs // Общее время пауз GC в наносекундах
  • Метрики горутин:

    // Текущее количество активных горутин
    numGoroutines := runtime.NumGoroutine()

2. Пакет expvar

expvar предоставляет стандартизированный способ для публикации кастомных метрик приложения через HTTP-эндпоинт /debug/vars в формате JSON.

import (
    "expvar"
    "net/http"
)

// Создаем кастомные метрики
var (
    httpRequests = expvar.NewInt("http_requests_total")
    activeUsers  = expvar.NewInt("active_users")
)

func myHandler(w http.ResponseWriter, r *http.Request) {
    httpRequests.Add(1) // Увеличиваем счетчик
    // ...
}

// Метрики будут доступны по http://localhost:8080/debug/vars
// http.ListenAndServe(":8080", nil)

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

Этот пакет регистрирует обработчики для отладки и профилирования. Он является наиболее мощным инструментом для анализа производительности.

Для его активации достаточно импортировать пакет:

import _ "net/http/pprof"

После этого становятся доступны эндпоинты для профилирования:

  • /debug/pprof/goroutine: стек трейсы всех текущих горутин.
  • /debug/pprof/heap: семпл использования памяти в куче.
  • /debug/pprof/profile: CPU-профиль (по умолчанию 30 секунд).
  • /debug/pprof/trace: трассировка выполнения приложения.

Рекомендация: Для production-систем стандартные средства часто интегрируют с системами мониторинга, такими как Prometheus. Для этого используется клиентская библиотека (prometheus/client_golang), которая позволяет собирать метрики в формате Prometheus и предоставлять их по эндпоинту /metrics.