10 вопросов
Prometheus - метрики в формате ключ-значение, pull-модель. В Go: client_golang (prometheus/prometheus). Регистрируют Counter, Gauge, Histogram, Summary; метрики обновляют в коде. Endpoint /metrics отдает текст в формате Prometheus (promhttp.Handler()). Метки (labels) для разбиения (handler, method, code).
var reqTotal = prometheus.NewCounterVec(
prometheus.CounterOpts{Name: "http_requests_total"},
[]string{"method", "path", "code"},
)
prometheus.MustRegister(reqTotal)
reqTotal.WithLabelValues("GET", "/", "200").Inc()
http.Handle("/metrics", promhttp.Handler())Grafana - визуализация метрик и логов. Источник данных - Prometheus (и другие). Дашборды строят из запросов PromQL к метрикам Go-приложения (запросы в секунду, латентность, ошибки). В Go достаточно экспортировать метрики в формате Prometheus; Grafana подключается к Prometheus и строит графики. Алерты настраивают в Grafana или Alertmanager.
OpenTelemetry - единый API для трейсов, метрик и логов. В Go: opentelemetry-go, экспортеры (Jaeger, Prometheus, OTLP). Трейсинг: создание span, пропигация контекста, экспорт в бэкенд. Метрики: Meter, Counter/Histogram. Инструментация вручную или через автоинструментацию (HTTP, gRPC). Контекст передают через request и в между сервисами (заголовки W3C Trace Context).
ctx, span := tracer.Start(ctx, "handleRequest")
defer span.End()
span.SetAttributes(attribute.Int("user_id", id))Логи - дискретные события (slog, zap, zerolog); уровни, структурированные поля. Метрики - числовые агрегаты (счетчики, гистограммы) для графиков и алертов. Трейсы - цепочка операций по запросу (span, parent/child). В Go логи пишут в stdout или в систему сбора; метрики в Prometheus; трейсы в Jaeger/Tempo через OpenTelemetry. Логи и трейсы связывают по trace_id.
Перцентили показывают латентность: p99 - 99% запросов быстрее этого значения. В Prometheus Histogram дает buckets и автоматически квантили (histogram_quantile в PromQL). В Go регистрируют Histogram с разумными buckets (например, 5ms, 10ms, 25ms, 50ms, 100ms, 250ms, 500ms, 1s), вызывают Observe(duration). Summary дает квантили на стороне приложения, но менее гибкий в PromQL.
hist := prometheus.NewHistogramVec(
prometheus.HistogramOpts{Name: "http_duration_seconds", Buckets: prometheus.DefBuckets},
[]string{"path"},
)
hist.WithLabelValues("/api").Observe(elapsed.Seconds())Логи из Go отправляют в Elasticsearch (напрямую или через Logstash/Filebeat). В Go: структурированные логи (slog JSON), вывод в stdout; коллектор (Fluentd, Filebeat) забирает и отправляет в ELK. Альтернативы: Loki (как Prometheus для логов), облачные сервисы (Datadog, CloudWatch). Важно единый формат (JSON) и поля trace_id, level, message.
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
logger.Info("request", "path", r.URL.Path, "trace_id", traceID)Трейс - цепочка span по запросу; при переходе между сервисами передают trace_id и span_id в заголовках (W3C Trace Context: traceparent, tracestate). В Go контекст с span пробрасывают в вызовы; при HTTP-вызове к другому сервису инжектируют заголовки из контекста. OpenTelemetry делает это автоматически с правильной инструментацией.
carrier := propagation.MapCarrier{}
propagator.Inject(ctx, carrier)
req.Header.Set("traceparent", carrier["traceparent"])slog - стандартная библиотека (Go 1.21): структурированные логи, уровни, группы, заменяемый handler (JSON, text). zap - быстрый, структурированный, популярен в проектах. zerolog - минимальный аллокации, цепочка вызовов. Выбор: slog для нового кода (стандарт, достаточная производительность), zap/zerolog при жестких требованиях к скорости и объему логов.
logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))
logger.Info("msg", "user_id", 123, "path", r.URL.Path)Алерты настраивают в Prometheus (Alertmanager) или в Grafana. Правила на PromQL: например, высокая доля ошибок (rate(errors_total)/rate(requests_total) > 0.05), недоступность (up == 0), высокая латентность. В Go приложение только отдает метрики; пороги и уведомления - в мониторинге. Критичные сценарии: ошибки, недоступность, деградация SLA. Избегать шума: группировка, подавление дублей.
SLI - метрика доступности/качества (например, доля успешных запросов, p99 латентности). SLO - целевой уровень SLI (99.9% доступности). SLA - договор с штрафами. В Go считают метрики под SLO: счетчик успешных и неуспешных запросов, гистограмма латентности. В Prometheus запросы для SLI (например, availability = sum(success)/sum(total)); алерты при нарушении SLO (error budget).