логотип PurpleSchool
логотип PurpleSchool

Логирование в Golang. Zap, Logrus, Loki, Grafana

Автор

Александр Гольцман

Логирование — важный инструмент для мониторинга и отладки приложений, особенно в продакшене. В Go доступны несколько мощных библиотек для работы с логами, таких как Zap и Logrus. В этой статье я покажу, как использовать их для логирования в Go-приложениях, а также как интегрировать логи с Grafana для удобного анализа.

Почему логирование важно?

Логирование — это не просто вывод сообщений в консоль. Оно помогает:

  • Отслеживать ошибки и предупреждения в коде.
  • Анализировать поведение приложения.
  • Собирать метрики для диагностики.
  • Интегрировать логи с системами мониторинга (Grafana, Loki и др.).

В Go стандартная библиотека предоставляет пакет log, но для продакшен-приложений он слишком простой. Смотрите, для расширенных возможностей используются сторонние библиотеки, такие как Zap и Logrus.

Библиотека Zap

Zap — это одна из самых быстрых библиотек для логирования в Go. Она оптимизирована для работы в высоконагруженных приложениях.

Установка Zap

go get go.uber.org/zap

Базовое использование

Смотрите, вот простой пример логирования с Zap:

package main

import (
    "go.uber.org/zap"
)

func main() {
    logger, _ := zap.NewProduction()
    defer logger.Sync()

    logger.Info("Запуск приложения",
        zap.String("версия", "1.0.0"),
        zap.Int("порт", 8080),
    )
}

Здесь я создал продакшен-логгер, который форматирует сообщения в JSON, что удобно для обработки в системах мониторинга.

Настройка уровней логирования

Zap поддерживает разные уровни логов:

  • Debug — отладочная информация.
  • Info — общие сообщения.
  • Warn — предупреждения.
  • Error — ошибки, требующие внимания.
  • Fatal — критические ошибки (после которых программа завершает работу).

Пример использования:

logger.Debug("Отладочное сообщение")
logger.Warn("Предупреждение о возможной проблеме")
logger.Error("Ошибка в работе сервиса")

Библиотека Logrus

Logrus — ещё одна популярная библиотека для логирования, поддерживающая кастомные форматтеры и хуки.

Установка Logrus

go get github.com/sirupsen/logrus

Базовое использование

Вот пример простого логирования с Logrus:

package main

import (
    "github.com/sirupsen/logrus"
)

func main() {
    logger := logrus.New()
    logger.SetFormatter(&logrus.JSONFormatter{})

    logger.WithFields(logrus.Fields{
        "версия": "1.0.0",
        "порт":   8080,
    }).Info("Запуск приложения")
}

Здесь я использую JSON-форматтер, чтобы логировать данные в удобном для парсинга виде.

Настройка уровней логирования

Logrus также поддерживает уровни логов:

logger.Debug("Отладочная информация")
logger.Info("Общая информация")
logger.Warn("Предупреждение")
logger.Error("Ошибка")
logger.Fatal("Фатальная ошибка")

Интеграция логов с Grafana через Loki

Grafana — мощный инструмент для визуализации данных, а для логирования можно использовать её связку с Loki.

Установка Loki и Promtail

Для сбора и хранения логов понадобится Loki и Promtail. Установить их можно через Docker:

docker run -d --name=loki -p 3100:3100 grafana/loki
docker run -d --name=promtail -v /var/log:/var/log grafana/promtail

Promtail собирает логи с сервера и отправляет их в Loki, откуда Grafana может их визуализировать.

Настройка отправки логов в Loki

Для отправки логов в Loki можно использовать библиотеку loki-logrus или настроить отправку через Promtail.

Пример отправки логов в Loki с Logrus:

hook, err := logrus_loki.NewBatchLokiHook("http://localhost:3100/api/prom/push", nil, logrus.DebugLevel, &logrus.JSONFormatter{})
if err == nil {
    logger.AddHook(hook)
}

После этого все логи из Go-приложения можно просматривать в Grafana.

Заключение

Логирование — важная часть работы с Go-приложениями. В этой статье я показал, как использовать Zap и Logrus, а также как интегрировать логи с Grafana через Loki.

Если вы работаете с высоконагруженными системами, Zap подойдёт лучше. Если важна гибкость и кастомизация, Logrus — хороший выбор. А интеграция с Grafana позволит удобно анализировать логи в реальном времени.

Работа с Docker-контейнерами в GoСтрелочка вправо

Все гайды по Golang

Преобразование типов в GolangРабота с YAML в GolangКонвертация структур в JSON в GolangStrconv в GolangИспользование пакета SQLx для работы с базами данных в GolangРазбираемся с SQL в GolangРазделение строк с помощью функции split в GolangSort в GoПоиск и замена строк в Go - GolangИспользование пакета reflect в GolangРабота с PostgreSQL в GoPointers в GolangПарсинг в GoРабота со списками (list) в GolangПреобразование int в string в GolangРабота с числами с плавающей точкой в GolangРабота с полями в GolangИспользование enum в GolangОбработка JSON в GoЧтение и запись CSV-файлов в GolangРабота с cookie в GolangРегистры в GoКэширование данных в GolangПреобразование byte в string в GolangByte в GoИспользование bufio для работы с потоками данных в GolangДобавление данных и элементов (add) в Go
Логирование в Golang. Zap, Logrus, Loki, GrafanaРабота с Docker-контейнерами в GoИспользование pprof в GolangМеханизмы синхронизации в GolangРабота с пакетом S3 в GolangМониторинг Golang приложений с помощью PrometheusОптимизация проектов на GoПаттерны проектирования в GolangМиграции базы данных в GolangОркестрация контейнеров Go с Kubernetes + DockerGjGo Playground и компилятор GolangИспользование go mod init для создания модулей GolangРабота с переменными окружения (env) в GolangКоманда go build в GolangАвтоматизация Golang проектов — CI/CD с GitLab CI и JenkinsОтладка кода в GolangЧтение и использование конфигурации в приложениях на GolangКомпиляция в GolangКак развернуть Go-приложение на облаке AWSАутентификация в Golang
Сетевые протоколы в GoПеременные в GolangДженерик %T и его применение в GolangЗначения в GolangТипы данных в GolangИспользование tls в GolangИспользование tag в структурах GolangSwitch в GoСтроки в GolangРабота с потоками (stream) в GolangSelect в GoРуны в GoРабота с пакетом params в GolangКонвертация строк в числа в GolangNull, Nil, None, 0 в GoНаименования переменных, функций и структур в GoInt в GolangУстановка GolangЧтение и установка HTTP заголовков в GolangMethods в GolangGoLand — IDE для разработки на Golang от JetBrainsОбработка «not found» в GolangFloat в GolangФлаги командной строки в Go (Golang)Запуск внешних команд в GolangОбработка ошибок в GoИспользование defer в GolangЗначения default в GolangГенерация кода в GoФорматирование кода в GolangЧистая архитектура в GolangКаналы (channels) в GolangПолучение body из HTTP запроса в Golang
Открыть базу знаний