Перейти к содержимому
ГоМастер

Поиск по урокам

Найдите урок, курс, термин или раздел

zap или zerolog: какой логгер Go выбрать для сервиса

zap — структурный логгер от Uber: два API (быстрый Logger и удобный SugaredLogger), ядро zapcore для кастомных энкодеров и секции. zerolog — минимализм: чистый JSON без аллокаций и цепочный API в одну строку. Гибкость против простоты.

zapкурсzerolog

Подбор под ваши приоритеты

Двигайте ползунки — насколько для вас важен каждый критерий (0 — не важен, 5 — критично). Счёт пересчитывается на лету: это взвешенное среднее оценок библиотек по критериям, а не бенчмарк.

Цена записи под нагрузкой

Ежедневный код логирования

Энкодеры, секции, sampling, уровни

Интеграции, вакансии, готовые middleware

Время до первого структурного лога

Взвешенный счёт

  • zapваш матч80
  • zerolog76

Под ваши веса лидирует zap: сервисам, чьи логи едут в elk или loki и требуют тонкой настройки формата.

Пара «zap или zerolog» — классическая дилемма, когда fmt.Println в проде сменился структурными логами: JSON-строки, уровни, поля, корреляция запросов. Оба логгера из топа бенчмарков и обоими гордятся команды, но ежедневная работа с ними ощущается по-разному. zap — это экосистема: ядро zapcore, где энкодеры, выводы и уровни собираются как конструктор, и два API на выбор. zerolog — это одна цепочка вызовов, которая пишется быстрее читается. Здесь разберём оба по одним критериям, покажем одну и ту же запись лога рядом и соберём рекомендацию ползунками под ваши приоритеты.

zap силён там, где логи — часть инфраструктуры. zapcore позволяет собрать произвольный конвейер: JSON для сбора, console для локальной разработки, секция sampling, чтобы под нагрузкой не утонуть в повторах, динамические уровни через AtomicLevel без перезапуска. Отдельный SugaredLogger жертвует частью скорости за удобство: printf-стиль и any-поля. Из этого следует практический вывод: zap выбирают сервисы, у которых логи едут в ELK или Loki и нужна тонкая настройка формата, ротации и уровней по окружениям. Расплата — церемоний больше: конфигурация ядра verbose, а два API в одном коде путают новичков.

zerolog отвечает минимализмом: лог — цепочка .Info().Str("path", p).Int("ms", ms).Msg("done"), JSON собирается без рефлексии и почти без аллокаций. Бинарник не раздувается, конфигурация умещается в три строки, а суб-логгеры с полями (логгер запроса с request_id) создаются на лету. Цена принципиальна: кастомизация скромнее — энкодер один, расширение формата и секции либо не нужны, либо пишутся руками. Комьюнити и число интеграций у zerolog меньше, чем у zap, хотя базовые middleware для популярных фреймворков существуют для обоих.

Как читать итог ниже: оценки — усреднение практики, а не лабораторные цифры; ползунки подставляют ваши приоритеты. В нашем курсе zap разобран полностью: от полей и уровней до zapcore, сэмплинга, динамических уровней и интеграций с gin, gRPC и GORM — этот материал даёт контекст даже для стороннего логгера. Одна и та же запись «запрос обработан» в обеих библиотеках — ниже.

Одна и та же задача в каждой библиотеке

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

Структурные логи от Uber: конструктор zapcore и два API на выбор

package main

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

func main() {
  cfg := zap.NewProductionConfig()
  cfg.Encoding = "json"
  logger, _ := cfg.Build()
  defer logger.Sync()

  logger.Info("request finished",
    zap.String("path", "/api/users"),
    zap.Int("ms", 12),
  )
}

Сильные и слабые стороны

zap

Структурные логи от Uber: конструктор zapcore и два API на выбор

  • zapcore: JSON и console-энкодеры, секции, sampling — конвейер под любое окружение
  • Динамические уровни AtomicLevel без перезапуска сервиса
  • Крупная экосистема: интеграции с фреймворками, мониторингом и вакансии
  • Конфигурация ядра verbose: прод-логгер — это 20-30 строк
  • Два API (Logger и SugaredLogger) путают новичков в одном проекте

Берите, если: сервисам, чьи логи едут в elk или loki и требуют тонкой настройки формата.

zerolog

Чистый JSON без аллокаций: цепочный API и умещающийся в три строки конфиг

  • Минимум аллокаций: JSON собирается на лету, лидер по цене записи
  • Цепочка .Str().Int().Msg() читается и пишется без церемоний
  • Суб-логгеры с полями: logger.With().Str("request_id", id) на каждый запрос
  • Один энкодер: кастомные форматы и секции пишутся руками
  • Экосистема интеграций скромнее, чем у zap

Берите, если: сервисам, которым нужен быстрый json-лог без настройки конвейера.

Оценки по критериям

Шкала 1-5: экспертная оценка команды проекта по практике, а не синтетика.

Сравнение zap, zerolog по критериям
Критерийzapzerolog
Скорость и аллокацииЦена записи под нагрузкой
Удобство APIЕжедневный код логирования
Гибкость конфигурацииЭнкодеры, секции, sampling, уровни
ЭкосистемаИнтеграции, вакансии, готовые middleware
Порог входаВремя до первого структурного лога

Вердикт: когда что выбирать

Оба логгера быстры настолько, что выбор редко о производительности: разница — в модели владения конфигурацией. zap даёт конвейер: форматы, секции, сэмплинг и уровни как конфигурация инфраструктуры. zerolog даёт простоту: одна цепочка вызовов и ноль церемоний при подключении. Сервисы с centralized-логами чаще оседают в zap, утилиты и небольшие сервисы — в zerolog.

Логи едут в ELK, Loki или облачный сборщик с строгим форматомzapzapcore настраивает энкодеры и секции под схему индекса
Нужен лог «здесь и сейчас» без настройкиzerologТри строки конфигурации и цепочка вызовов вместо сборки ядра
Пиковые нагрузки с повторяющимися записямиzapВстроенный sampling режет повторы до настройки уровней
Кросс-сервисные стандарты: единый формат у нескольких командzapОбщий конфиг-пакет с zapcore тиражируется между сервисами

А что выбрали вы?

Кликните по своему выбору — голос сохранится только в вашем браузере (персональные данные никуда не отправляются).

Частые вопросы

Что быстрее — zap или zerolog?

В бенчмарках zerolog чаще впереди по аллокациям, zap — рядом: оба на порядки быстрее стандартного log и fmt.Println. На реальном сервисе цена записи тонет в работе приложения: выбирать логгер по процентам в синтетике — ошибка. Смотрите на конфигурацию и экосистему, которые нужны вашему сборщику логов.

Стоит ли использовать SugaredLogger?

Если команда ценит printf-стиль и удобство any-полей — да: SugaredLogger отдаёт немного скорости за читаемость. Быстрый путь — обычный Logger с типизированными полями zap.String и zap.Int. Правило простое: один API на проект, смешение обоих в одном пакете — источник путаницы; как они устроены внутри, разобрано в курсе zap.

Как мигрировать со стандартного log на структурный логгер?

По шагам: замените глобальный логгер на обёртку (фасад) своего пакета, чтобы вызовы log.Printf ушли в одно место; добавьте уровни и поля точечно, начиная с обработчиков запросов; включите request_id через middleware. У zerolog роль фасада играет суб-логгер с полями, у zap — logger.With. Наш курс zap показывает эту миграцию на живом сервисе.

Почему бы просто не писать в slog из стандартной библиотеки?

slog закрывает базовые структурные потребности и отлично подходит новым небольшим проектам. zap и zerolog всё ещё дают более низкую цену записи и больше настроек: sampling, кастомные энкодеры, динамические уровни. Разбор slog рядом с zap собран на отдельной странице сравнения логгеров — это частая третья опция в этом выборе.

Другие сравнения