Go: почему без Observability ты отлаживаешь систему вслепую
Сетка - живи!!! Пожелаем сервису здоровья. А мы продолжаем!
Представим, что у нас есть Go-сервис, который обрабатывает заказы.
Пользователь нажимает кнопку, запрос уходит на бэк, а ответ приходит через 5 секунд вместо обычных 100 мс.
Что делать?
Можно открыть логи и искать ошибку. Но если ошибка не возникла, а сервис просто тормозит? Как понять, где именно проблема: в обработчике, базе данных или внешнем апи?
Для этого нужна Observability, ну то есть простыми словами - наблюдаемость.
Обычно выделяют три основных компонента: Logs - что произошло. Metrics - как часто и насколько хорошо это происходит. Traces - где именно теряется время при обработке запроса.
Покажу на простом примере, как минимум можно сделать уже сейчас.
Практика: измеряем время обработки HTTP-запросов
В Go можно начать с middleware, который измеряет длительность запроса и записывает её в лог.
package main
import ( “log” “net/http” “time” )
func observability(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { start := time.Now()
next.ServeHTTP(w, r)
duration := time.Since(start)
log.Printf( “method=%s path=%s duration=%s”, r.Method, r.URL.Path, duration, ) }) }
func main() { mux := http.NewServeMux()
mux.HandleFunc(“/orders”, func(w http.ResponseWriter, r *http.Request) { time.Sleep(300 * time.Millisecond) w.Write([]byte(“orders”)) })
log.Println(“server started on :8080”)
err := http.ListenAndServe(“:8080”, observability(mux)) if err != nil { log.Fatal(err) } }
Запускаем сервис и отправляем запрос: curl http://localhost:8080/orders
В логах увидим примерно следующее: method=GET path=/orders duration=300.4ms
Теперь у нас есть хотя бы одна полезная зацепка. Если обработка занимает 300 мс, можно двигаться дальше и измерять отдельные этапы: запрос к БД, обращение к внешнему сервису, сериализацию ответа.
Но одного лога недостаточно
В production я бы развивал эту схему дальше: Prometheus - собирать метрики количества запросов, ошибок и задержек, смотреть p95 и p99. OpenTelemetry - создавать трассировки запросов и связывать между собой вызовы разных сервисов. Grafana - строить дашборды и наблюдать за состоянием приложения.
Например, p99 в 2 секунды при среднем времени ответа в 100 мс означает, что для части запросов ситуация намного хуже, чем кажется по среднему значению. И ещё важный момент: в реальном middleware стоит записывать HTTP-статус и размер ответа. Для этого понадобится ResponseWriter-обёртка. А в production-логах лучше использовать структурированный логгер, например log/slog, и не записывать чувствительные данные.
Главная мысль: Observability нужна не только тогда, когда сервис уже упал. Она позволяет понять, что происходит внутри работающей системы, обнаружить деградацию и найти узкое место до того, как проблема станет заметна всем пользователям.
Чем больше сервисов и зависимостей, тем дороже обходится работа вслепую. А что вы используете в Go-проектах: только логи или уже связку метрик и распределённых трассировок?