> Есть ли у вас мониторинг и на каком стеке он работает (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_totalexternal_api_call_duration_seconds{provider}
Для алертов используем groups в Prometheus rules. Критичные алерты - on-call, некритичные - в дашборд.
Логи пишем через slog (стандартный пакет Go 1.21+) с JSON-хендлером. Trace ID прокидываем через контекст.
Пример кода
GOpackage mainimport ("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.ResponseWriterstatus int}func (r *statusRecorder) WriteHeader(code int) {r.status = coder.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
- Не упоминать, как мониторить сам мониторинг - это признак отсутствия реального опыта
> Похожие задачи по backend
Какие состояния могут быть у горутин в Go
Для чего нужен FOR UPDATE в PostgreSQL
Назови примеры метрик для алертов
Для чего используется профилирование pprof в Go
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью