Помню день, когда наша производственная система вышла из строя в 2 часа ночи. Наш генеральный директор спросил: «Что случилось?», и у меня было три варианта: посмотреть на панели управления, которые не показывали ничего полезного, порыться в терабайтах логов с помощью grep или помолиться. Спойлер: я помолился. И тогда я понял, что мы всё делали неправильно.
Сейчас, спустя некоторое время, наблюдаемость стала Святым Граалем современной инженерии. Но вот грязный секрет, о котором вам не расскажут вендоры: вам не нужен годовой контракт на шестизначную сумму с SaaS-платформой, чтобы обеспечить достойную наблюдаемость. Вам нужны понимание, стратегия и немного усердной работы.
Эта статья — моё личное путешествие по построению прагматичной наблюдаемости при ограниченном бюджете. Независимо от того, являетесь ли вы стартапом, сжигающим венчурный капитал, или устоявшейся компанией, уставшей от усталости SaaS-подписок, это руководство покажет вам, как реализовать три столпа наблюдаемости — метрики, логи и трейсы — не продавая своего первенца.
Почему наблюдаемость важна (и почему традиционный мониторинг не работает)
Прежде чем мы углубимся в детали, давайте определимся, чем наблюдаемость отличается от традиционного мониторинга. Традиционный мониторинг — это как термостат: он показывает текущую температуру, не больше. Наблюдаемость — это как врач, который может задать вам вопросы и диагностировать проблему.
Метрики — это жизненные показатели вашего приложения. Использование ЦП, частота запросов, количество ошибок — это числовые измерения, агрегированные во времени. Они эффективны и идеально подходят для информационных панелей и оповещений.
Логи — это неизменяемые записи с меткой времени, показывающие, что на самом деле произошло. Они предоставляют детальный контекст об определённой ошибке или операции, сообщая вам подробности о том, что пошло не так в определённый момент.
Трейсы представляют собой полное, сквозное путешествие одного запроса по мере его распространения через ваши микросервисы. Они отвечают на важнейший вопрос о том, где возникла проблема в вашем сложном рабочем процессе.
Магия происходит, когда вы объединяете эти три сигнала. Специалист по надёжности системы может начать с оповещения о метрике высокого уровня, углубиться в конкретное сообщение об ошибке в логе и точно увидеть, какой нисходящий вызов службы failed. Это и есть наблюдаемость.
Проверка реальности бюджета
Давайте будем честными: платформы наблюдаемости для предприятий стоят дорого. Мы говорим о 10 000–100 000 долларов и более ежегодно в зависимости от объёма данных. Для многих организаций, особенно стартапов, это непозволительная роскошь.
Хорошая новость? Экосистема с открытым исходным кодом значительно продвинулась вперёд. Вы можете построить производственную стек наблюдаемости, используя:
- Prometheus для метрик (бесплатно, проверен в боях);
- Loki или ELK Stack для логов (бесплатно/дёшево);
- Jaeger или Zipkin для распределённого трейсинга (бесплатно);
- OpenTelemetry в качестве стандарта инструментирования (бесплатно).
Ваши единственные реальные затраты — это инфраструктура (которая у вас всё равно будет) и эксплуатационные усилия (которые научат вас большему, чем любое аутсорсинг-решение).
Понимание метрик: фундамент
Метрики — это ваш обзор на высоком уровне. Это агрегированные числа с тегами — например, «количество HTTP-запросов в секунду» или «использование пула соединений с базой данных».
Почему метрики важны
Метрики отлично подходят для:
- Обнаружения базовых аномалий («наш уровень ошибок только что подскочил на 10%»);
- Создания информационных панелей для руководителей («вот наш показатель времени безотказной работы за этот квартал»);
- Настройки оповещений («уведомляй меня, когда этот порог будет превышен»);
- Эффективного хранения (метрика занимает килобайты, а не гигабайты).
Практическая реализация с Prometheus
Prometheus — это стандарт де-факто для сбора метрик. Вот минимальная настройка:
# prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'my-app'
static_configs:
- targets: ['localhost:8080']
- job_name: 'node-exporter'
static_configs:
- targets: ['localhost:9100']
На стороне вашего приложения экспортируйте метрики, используя библиотеку, совместимую с вашим языком. Вот пример на Go с использованием клиента Prometheus:
package main
import (
"net/http"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
var (
requestCounter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "http_requests_total",
Help: "Общее количество HTTP-запросов",
},
[]string{"method", "endpoint", "status"},
)
requestDuration = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "http_request_duration_seconds",
Help: "Задержка HTTP-запроса",
Buckets: prometheus.DefBuckets,
},
[]string{"method", "endpoint"},
)
)
func init() {
prometheus.MustRegister(requestCounter)
prometheus.MustRegister(requestDuration)
}
func main() {
http.HandleFunc("/api/users", func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
// Ваша бизнес-логика здесь
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"status": "ok"}`))
// Запись метрик
requestCounter.WithLabelValues(
r.Method,
"/api/users",
"200",
).Inc()
requestDuration.WithLabelValues(
r.Method,
"/api/users",
).Observe(time.Since(start).Seconds())
})
http.Handle("/metrics", promhttp.Handler())
http.ListenAndServe(":8080", nil)
}
Ключевые метрики для отслеживания
Каждое приложение должно предоставлять эти базовые метрики:
- Частота запросов: количество запросов в секунду (с разбивкой по конечной точке и методу);
- Уровень ошибок: процент неудачных запросов;
- Задержка: p50, p95, p99 время ответа;
- Использование ресурсов: ЦП, память, дисковый ввод-вывод;
- Бизнес-метрики: регистрация пользователей, завершённые транзакции, выручка.
Запрос метрик с PromQL
Prometheus использует PromQL для запросов. Некоторые основные запросы:
# Частота запросов за последние 5 минут
rate(http_requests_total[5m])
# 95-й процентиль задержки
histogram_quantile(0.95, http_request_duration_seconds)
# Уровень ошибок
rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m])
# Использование памяти в МБ
node_memory_MemAvailable_bytes / 1024 / 1024
Понимание логов: подробная история
Пока метрики дают вам заголовок, логи дают вам полный отчёт расследования. Это текстовые записи, которые фиксируют, что произошло, почему это произошло и весь контекст.
Иерархия логов
Уровни логов существуют не просто так:
- DEBUG: Информация для разработки, подробный вывод;
- INFO: Нормальные операции, ключевые события;
- WARNING: Что-то неожиданное произошло, но мы восстановились;
- ERROR: Что-то failed, возможно, потребуется вмешательство вручную;
- CRITICAL: Система в плохом состоянии, требуется немедленное действие.
Структурированный логирование: игра меняется
Разница между хорошим и плохим логированием заключается в структуре. Сравните эти примеры:
Плохой: "Ошибка обработки запроса"
Хороший: {"timestamp": "2026-02-14T14:30:45Z", "level": "error", "service": "payment-service", "user_id": "usr_123", "error": "insufficient_funds", "amount": 99.99, "request_id": "req_456"}
Структурированное логирование (в формате JSON) позволяет вам без усилий искать, фильтровать и сопоставлять логи. Вот пример на Python:
import logging
import json
from pythonjsonlogger import jsonlogger
# Настройка JSON-логирования
logHandler = logging.StreamHandler()
formatter = jsonlogger.JsonFormatter()
logHandler.setFormatter(formatter)
logger = logging.getLogger()
logger.addHandler(logHandler)
logger.setLevel(logging.INFO)
# Использование
logger.info("payment_processed", extra={
"user
