Какие метрики 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.

Ответ 18+ 🔞

Да ты посмотри, какие у нас в Го инструменты для слежки за приложением, просто овердохуища! Прям как в больнице — тебе и пульс, и давление, и что в голове творится, всё покажут. Главное, не перепутать, где метрики, а где уже агония начинается.

Ну вот, смотри, есть три основных подхода, как свою прогу на просушку взять.

Во-первых, пакет runtime. Это как заглянуть под капот, пока движок работает. Там про память и горутины всё узнаешь.

var m runtime.MemStats
runtime.ReadMemStats(&m)

// m.Alloc      // Сколько байт выделил и ещё не выкинул
// m.TotalAlloc // А это сколько всего навыделял за свою жизнь, расточитель
// m.HeapAlloc  // Сколько в куче болтается
// m.NumGC      // Сколько раз мусорщик приходил
// m.PauseTotalNs // И сколько наносекунд все эти уборки тормозили жизнь

А горутин посчитать — вообще раз плюнуть:

// Сколько этих мелких трудяг сейчас носятся
numGoroutines := runtime.NumGoroutine()

Во-вторых, пакет expvar. Это уже для цивилизованных людей, которые любят JSON. Он автоматом заведёт эндпоинт /debug/vars и будет там в красивом виде твои метрики выкладывать.

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) // Щёлк — ещё один запрос припёрся
    // ...
}

// И всё, блядь, готово. Заходи на localhost:8080/debug/vars и смотри.

Ну и в-третьих, тяжёлая артиллерия — net/http/pprof. Вот это, сука, настоящая магия! Импортируешь его, и у тебя сразу целая клиника для профилирования открывается.

import _ "net/http/pprof" // Просто импорт, и всё — волшебство!

И поехали эндпоинты:

  • /debug/pprof/goroutine — тут тебе все горутины, как на ладони, кто где завис.
  • /debug/pprof/heap — смотри, чем твоя куча дышит, кто память жрёт.
  • /debug/pprof/profile — CPU-профиль на 30 секунд, узнаешь, на что процессор время тратит.
  • /debug/pprof/trace — трассировка, чтоб вообще по шагам воспроизвести, что происходило.

А для продакшена, где всё серьёзно, обычно подключают Prometheus. Берёшь библиотечку prometheus/client_golang, накручиваешь свои метрики, и они у тебя на /metrics в правильном, понятном прометею виде лежат. Красота, ёпта!