Пользовательские обработчики
Создавайте собственный вывод журналов
«Пользовательские обработчики» — бесплатный урок Go Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Go Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Go Academy содержит 4 уроков всего.
Когда встроенных обработчиков недостаточно
Текстовые обработчики и обработчики JSON покрывают большинство потребностей, но иногда требуется специальный вывод: цветные терминалы, отправка в систему метрик или удаление секретов. В таком случае создаётся custom Handler.
Интерфейс Handler
Обработчик реализует четыре метода:
Enabled(ctx, level) boolHandle(ctx, record) errorWithAttrs(attrs) HandlerWithGroup(name) Handler
type Handler interface {
Enabled(context.Context, slog.Level) bool
Handle(context.Context, slog.Record) error
WithAttrs(attrs []slog.Attr) slog.Handler
WithGroup(name string) slog.Handler
}Enabled управляет фильтрацией
Enabled вызывается до создания записи. Возврат значения false позволяет slog полностью пропустить работу, поэтому используйте этот метод для проверки уровня.
func (h *MyHandler) Enabled(_ context.Context, l slog.Level) bool {
return l >= slog.LevelInfo
}Handle выполняет работу
Handle получает объект slog.Record со временем, уровнем, сообщением и атрибутами. Вы можете форматировать и записывать его как угодно.
func (h *MyHandler) Handle(_ context.Context, r slog.Record) error {
fmt.Printf("[%s] %s\n", r.Level, r.Message)
return nil
}Перебор атрибутов
Запись предоставляет доступ к атрибутам через r.Attrs, который вызывает Вашу функцию для каждого атрибута.
r.Attrs(func(a slog.Attr) bool {
fmt.Printf(" %s=%v\n", a.Key, a.Value)
return true // keep going
})WithAttrs и WithGroup
Эти методы возвращают копию Вашего обработчика с заранее заданными атрибутами или префиксом группы. Они поддерживают logger.With и slog.Group. Минимальный обработчик может сохранять и повторно обрабатывать эти данные или, в учебных целях, возвращать самого себя.
Обёртка вместо создания
Часто не требуется создавать полноценный обработчик: можно обернуть существующий и переопределить только нужное поведение, например добавить постоянный атрибут или скрыть ключи.
type RedactHandler struct{ slog.Handler }
func (h RedactHandler) Handle(ctx context.Context, r slog.Record) error {
// mutate r here, then delegate
return h.Handler.Handle(ctx, r)
}Пример использования: удаление данных
Обработчик с удалением данных может просматривать атрибуты в поисках конфиденциальных ключей, таких как password или token, и заменять значение перед передачей данных обработчику JSON.
Пример использования: маршрутизация
Пользовательский обработчик может распределять записи по уровню: отправлять журналы Error в stderr и веб-перехватчик оповещений, а Info — в stdout. Это избавляет каждый участок вызова от логики маршрутизации.
Замечания о производительности
Handle может выполняться на часто используемых участках. Избегайте выделения памяти, проверяйте уровень в Enabled и повторно используйте буферы. Именно поэтому стандартные обработчики внутри используют буфер из пула.
Выполняемая программа: минимальный пользовательский обработчик
Эта автономная программа определяет небольшой обработчик, который выводит уровень, сообщение и атрибуты, а затем записывает через него журналы.
package main
import (
"context"
"fmt"
"log/slog"
)
type Mini struct{}
func (Mini) Enabled(context.Context, slog.Level) bool { return true }
func (Mini) WithAttrs(a []slog.Attr) slog.Handler { return Mini{} }
func (Mini) WithGroup(string) slog.Handler { return Mini{} }
func (Mini) Handle(_ context.Context, r slog.Record) error {
fmt.Printf("%s: %s", r.Level, r.Message)
r.Attrs(func(a slog.Attr) bool {
fmt.Printf(" %s=%v", a.Key, a.Value)
return true
})
fmt.Println()
return nil
}
func main() {
l := slog.New(Mini{})
l.Info("hello", "user", "ada", "id", 7)
}Быстрая проверка
Проверьте, насколько хорошо Вы поняли пользовательские обработчики.
Итоги
Вы научились создавать пользовательские обработчики:
- Реализуйте
Enabled,Handle,WithAttrs,WithGroup - Для производительности выполняйте проверки уровня в
Enabled - Перебирайте атрибуты с помощью
r.Attrs - Часто проще обернуть существующий обработчик, чем создавать всё с нуля
Изучай Go с ИИ-репетитором — бесплатно
Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.
- Курсы
- 51
- Уроки
- 203
Часто задаваемые вопросы
Урок «Пользовательские обработчики» бесплатный?
Да — полный текст урока «Пользовательские обработчики» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Go Academy, подпишись на CoddyKit PRO. Курс Go Academy содержит 4 уроков всего.
Чему я научусь в уроке «Пользовательские обработчики»?
Создавайте собственный вывод журналов Ты практикуешь Go Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Go Academy?
Предыдущий опыт не требуется. Go Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Пользовательские обработчики»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Go Academy?
Да. Каждый урок Go Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Зачем нужны структурированные журналы
- Обработчики slog
- Уровни журналирования и атрибуты
- Пользовательские обработчики