> Есть ли у вас мониторинг и на каком стеке он работает (Go)

Уровень: senior · Роль: backend · Категория: Технические вопросы

Компании: Wildberries

Стек: Go

> Пример ответа

Короткий ответ

Да, мониторинг есть. Основной стек: Prometheus для сбора метрик, Grafana для визуализации, Alertmanager для алертинга, Loki для логов и OpenTelemetry для трейсинга. В Go-сервисах используем официальные клиентские библиотеки Prometheus и middleware для HTTP/gRPC. Плюс стандартные метрики runtime (GOMEMLIMIT, goroutines, GC) и RED-метрики для каждого эндпоинта.

Подробное объяснение

Мониторинг построен по классической трёхосевой модели: метрики, логи, трейсы.

Метрики: Prometheus с pull-моделью. Каждый Go-сервис экспортирует /metrics на отдельном порту. Собираем:

  • RED-метрики (Rate, Errors, Duration) для каждого HTTP-роута и gRPC-метода
  • метрики бизнес-уровня (количество обработанных заказов, размер очереди, latency внешних вызовов)
  • runtime-метрики Go: go_goroutines, go_gc_duration_seconds, process_resident_memory_bytes

Алертинг: Alertmanager с правилами на основе SLO. Например, p99 latency > 500ms в течение 5 минут или error rate > 1% за 10 минут. Уведомления в Telegram и PagerDuty, эскалация по уровням.

Логи: Loki + Promtail. Структурированные логи в JSON, обязательные поля: level, service, trace_id, request_id. Хранение 30 дней, поиск по label.

Трейсинг: OpenTelemetry SDK, экспорт в Jaeger или Tempo. Каждый HTTP-запрос создаёт span, внутренние вызовы - дочерние spans. Для Go используем go.opentelemetry.io/otel с автоматической инструментацией net/http и gRPC.

Инфраструктура мониторинга развёрнута в Kubernetes через Helm-чарты (kube-prometheus-stack). Сам мониторинг тоже мониторится: uptime Prometheus, диск, перезапуски.

На практике

В Go-сервисах подключаем стандартную библиотеку prometheus/client_golang. Для HTTP-сервера используем middleware, который автоматически создаёт метрики по паттерну роута - важно, чтобы кардинальность была ограничена, иначе Prometheus раздуется.

Пример типового набора метрик для сервиса:

  • http_requests_total{method, route, status}
  • http_request_duration_seconds{method, route}
  • business_orders_created_total
  • external_api_call_duration_seconds{provider}

Для алертов используем groups в Prometheus rules. Критичные алерты - on-call, некритичные - в дашборд.

Логи пишем через slog (стандартный пакет Go 1.21+) с JSON-хендлером. Trace ID прокидываем через контекст.

Пример кода

GO
package main
import (
"net/http"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
var (
httpRequests = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "http_requests_total",
Help: "Total HTTP requests",
},
[]string{"method", "route", "status"},
)
httpDuration = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "http_request_duration_seconds",
Help: "HTTP request duration",
Buckets: prometheus.DefBuckets,
},
[]string{"method", "route"},
)
)
func init() {
prometheus.MustRegister(httpRequests, httpDuration)
}
func metricsMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
rec := &statusRecorder{ResponseWriter: w, status: http.StatusOK}
next.ServeHTTP(rec, r)
route := r.URL.Path // в реальности - паттерн роута, не полный путь
httpRequests.WithLabelValues(r.Method, route, http.StatusText(rec.status)).Inc()
httpDuration.WithLabelValues(r.Method, route).Observe(time.Since(start).Seconds())
})
}
type statusRecorder struct {
http.ResponseWriter
status int
}
func (r *statusRecorder) WriteHeader(code int) {
r.status = code
r.ResponseWriter.WriteHeader(code)
}
func main() {
mux := http.NewServeMux()
mux.Handle("/metrics", promhttp.Handler())
mux.Handle("/api/orders", metricsMiddleware(http.HandlerFunc(ordersHandler)))
http.ListenAndServe(":8080", mux)
}

Как отвечать на собеседовании

Начни с краткого перечисления стека, затем переходи к деталям. Обязательно упомяни, что мониторинг - это не только метрики, но и логи, и трейсинг. Покажи понимание trade-off: например, почему Prometheus, а не InfluxDB (pull vs push, интеграция с K8s). Расскажи про кардинальность метрик и как её контролируешь. Упомяни SLO и алертинг на основе SLO, а не на основе "все упало".

Если спросят про конкретные метрики - перечисли RED для HTTP и USE для ресурсов (Utilization, Saturation, Errors). Для Go добавь специфику: GOMAXPROCS, GOMEMLIMIT, runtime.NumGoroutine().

Что проверяет интервьюер

  • Понимание трёх осей observability: метрики, логи, трейсы
  • Практический опыт с Prometheus и Grafana, а не только теорию
  • Умение проектировать метрики с учётом кардинальности и стоимости хранения
  • Знание Go-специфики: runtime-метрики, middleware, контекст для trace ID
  • Понимание алертинга: как избежать alert fatigue, как привязать алерты к SLO
  • Умение объяснить, что делать, когда метрики показывают проблему - как дебажить через трейсы и логи

Типичные ошибки

  • Называть только Grafana и не упоминать Prometheus - это сразу выдаёт поверхностное знание
  • Говорить "мониторинг на Grafana" - Grafana это визуализация, а не сбор
  • Не упоминать логи и трейсы - мониторинг без них неполный
  • Использовать полный URL как label в метриках - кардинальность взорвётся
  • Не знать разницу между Counter, Gauge, Histogram и Summary
  • Говорить "алерты на всё" - интервьюер ждёт SLO-based подход
  • Путать pull и push модели, не понимать, почему Prometheus использует pull
  • Не упоминать, как мониторить сам мониторинг - это признак отсутствия реального опыта

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью