Ответ
Для обеспечения наблюдаемости (observability) системы я использую стандартный в индустрии подход, основанный на трех столпах: метрики, логи и трейсы.
1. Метрики (Metrics):
- Стек:
Prometheus
+Grafana
. - Реализация в Go: Использовал библиотеку
prometheus/client_golang
для создания и экспорта кастомных метрик. Основные метрики, которые мы отслеживали:requests_total
(Counter): общее число запросов с лейблами (эндпоинт, метод, статус-код).request_duration_seconds
(Histogram): распределение времени ответа на запросы.database_query_duration_seconds
(Histogram): время выполнения запросов к БД.goroutines_count
(Gauge): количество активных горутин.
import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)
var (
httpRequestsTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
Name: "myapp_http_requests_total",
Help: "Total number of HTTP requests.",
},
[]string{"path", "method", "code"},
)
)
// В middleware для HTTP-сервера:
// httpRequestsTotal.WithLabelValues(path, method, code).Inc()
2. Логи (Logging):
- Стек:
Fluentd
для сбора логов и отправки вElasticsearch
илиLoki
. - Реализация в Go: Использовал библиотеки для структурированного логирования, такие как
slog
(стандартная библиотека с Go 1.21) илиZap
/Zerolog
. Структурированные логи (например, в формате JSON) критически важны для эффективного парсинга, поиска и анализа в системах агрегации.
3. Трейсинг (Tracing):
- Стек:
Jaeger
илиZipkin
для визуализации трейсов. - Реализация в Go: Использовал стандарт де-факто —
OpenTelemetry
. Трейсинг незаменим в микросервисной архитектуре, так как позволяет отследить путь запроса через несколько сервисов, найти узкие места и выявить причину ошибки в распределенной системе.