← Назад к вопросам

Как посмотреть данные метрик?

2.2 Middle🔥 152 комментариев
#Observability#Контейнеризация и DevOps

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Получение метрик в Go-приложениях

В Go для работы с метриками существует несколько основных подходов и библиотек, которые позволяют собирать, агрегировать и экспортировать метрики производительности приложений.

1. Стандартные метрики Go (runtime)

Go предоставляет встроенные метрики о работе рантайма, которые можно получить через пакет runtime и специальный HTTP-эндпоинт:

import (
    "net/http"
    _ "net/http/pprof"
    "runtime"
)

func main() {
    // Запуск сервера для сбора метрик pprof
    go func() {
        http.ListenAndServe("localhost:6060", nil)
    }()
    
    // Получение статистики памяти
    var m runtime.MemStats
    runtime.ReadMemStats(&m)
    
    // Метрики горутин
    numGoroutines := runtime.NumGoroutine()
}

Доступные метрики через /debug/pprof:

  • /debug/pprof/heap - профиль памяти
  • /debug/pprof/goroutine - информация о горутинах
  • /debug/pprof/profile - CPU профиль

2. Prometheus клиент-библиотека

Наиболее популярное решение для сбора метрик в Go-экосистеме - Prometheus. Использую библиотеку github.com/prometheus/client_golang:

import (
    "github.com/prometheus/client_golang/prometheus"
    "github.com/prometheus/client_golang/prometheus/promhttp"
    "net/http"
)

func main() {
    // Создание кастомных метрик
    requestsCounter := prometheus.NewCounterVec(
        prometheus.CounterOpts{
            Name: "http_requests_total",
            Help: "Total HTTP requests",
        },
        []string{"method", "endpoint", "status"},
    )
    
    requestDuration := prometheus.NewHistogramVec(
        prometheus.HistogramOpts{
            Name: "http_request_duration_seconds",
            Help: "HTTP request duration",
        },
        []string{"method", "endpoint"},
    )
    
    // Регистрация метрик
    prometheus.MustRegister(requestsCounter, requestDuration)
    
    // Экспорт метрик на /metrics
    http.Handle("/metrics", promhttp.Handler())
    http.ListenAndServe(":2112", nil)
}

3. Экспорт метрик для различных систем

В зависимости от вашего стека мониторинга, можно использовать различные экспортеры:

Для Prometheus:

// Метрики автоматически доступны на /metrics
// Prometheus будет скрейпить этот эндпоинт

Для OpenTelemetry:

import (
    "go.opentelemetry.io/otel/exporters/prometheus"
    "go.opentelemetry.io/otel/sdk/metric"
)

func setupMetrics() {
    exporter, _ := prometheus.New()
    provider := metric.NewMeterProvider(metric.WithReader(exporter))
    
    // Создание метрик через OpenTelemetry API
    meter := provider.Meter("myapp")
    requestCounter, _ := meter.Int64Counter(
        "requests.total",
        metric.WithDescription("Total requests"),
    )
}

Push-модель для Graphite, StatsD:

import "github.com/cactus/go-statsd-client/v5/statsd"

func pushToStatsD() {
    client, _ := statsd.NewClient("127.0.0.1:8125", "myapp")
    defer client.Close()
    
    client.Inc("requests", 1, 1.0)
    client.Timing("request_time", 150, 1.0)
}

4. Просмотр метрик в реальном времени

Для разработки и отладки полезны следующие инструменты:

Prometheus UI:

  • Локальный запуск: docker run -p 9090:9090 prom/prometheus
  • Настройка скрейпинга вашего приложения
  • Запросы через PromQL: rate(http_requests_total[5m])

Grafana:

  • Визуализация метрик из Prometheus
  • Создание дашбордов с графиками
  • Алертинг на основе метрик

Консольные утилиты:

# Просмотр метрик через curl
curl http://localhost:2112/metrics

# Фильтрация определенных метрик
curl http://localhost:2112/metrics | grep "http_requests"

# Использование инструментов Prometheus
promtool query instant http://localhost:9090 'up{job="myapp"}'

5. Метрики инфраструктуры и бизнес-логики

Кроме системных метрик, важно собирать:

// Бизнес-метрики
var (
    ordersProcessed = prometheus.NewCounter(
        prometheus.CounterOpts{
            Name: "orders_processed_total",
            Help: "Total processed orders",
        },
    )
    
    activeUsers = prometheus.NewGauge(
        prometheus.GaugeOpts{
            Name: "active_users_current",
            Help: "Current active users",
        },
    )
)

// Метрики базы данных
dbQueryDuration := prometheus.NewHistogramVec(
    prometheus.HistogramOpts{
        Name: "db_query_duration_seconds",
        Help: "Database query duration",
        Buckets: prometheus.DefBuckets,
    },
    []string{"query", "database"},
)

6. Best Practices для работы с метриками

  1. Нейминг метрик: используйте соглашения Prometheus (snake_case, суффиксы _total, _seconds)
  2. Лейблы: используйте для многомерного анализа, но не злоупотребляйте (кардинальность!)
  3. Типы метрик:
    • Counter - для монотонно возрастающих значений (запросы, ошибки)
    • Gauge - для значений, которые могут увеличиваться и уменьшаться (память, активные соединения)
    • Histogram/Summary - для распределений (время ответа, размеры запросов)
  4. Документирование: всегда заполняйте поле Help для понятного описания
  5. Производительность: не создавайте метрики в горячих путях, используйте предварительно созданные экземпляры

7. Пример комплексного решения

package main

import (
    "net/http"
    "time"
    
    "github.com/prometheus/client_golang/prometheus"
    "github.com/prometheus/client_golang/prometheus/promauto"
    "github.com/prometheus/client_golang/prometheus/promhttp"
)

var (
    httpRequests = promauto.NewCounterVec(
        prometheus.CounterOpts{
            Name: "myapp_http_requests_total",
            Help: "Total HTTP requests by method, path and status",
        },
        []string{"method", "path", "status"},
    )
    
    httpDuration = promauto.NewHistogramVec(
        prometheus.HistogramOpts{
            Name: "myapp_http_duration_seconds",
            Help: "HTTP request duration in seconds",
            Buckets: []float64{0.1, 0.5, 1, 2, 5},
        },
        []string{"method", "path"},
    )
)

func metricsMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        start := time.Now()
        rw := &responseWriter{w, http.StatusOK}
        
        next.ServeHTTP(rw, r)
        
        duration := time.Since(start).Seconds()
        httpDuration.WithLabelValues(r.Method, r.URL.Path).Observe(duration)
        httpRequests.WithLabelValues(r.Method, r.URL.Path, http.StatusText(rw.status)).Inc()
    })
}

func main() {
    mux := http.NewServeMux()
    mux.Handle("/metrics", promhttp.Handler())
    mux.HandleFunc("/api", apiHandler)
    
    http.ListenAndServe(":8080", metricsMiddleware(mux))
}

Для эффективного мониторинга Go-приложений рекомендую использовать Prometheus как стандарт де-факто, дополняя его бизнес-метриками и интегрируя с Grafana для визуализации. Начинайте с базовых метрик (память, горутины, HTTP-запросы), постепенно добавляя специфичные для вашего приложения.