README_ru.md
- add threshold-aware LogLevel constructors - add Logger.SetThresholdMode and SameThreshold - preserve legacy SameLevel behavior for compatibility - extend tests for threshold mode and compatibility - update README and release notes for v2.2.0
8.1 KiB
SNekLog (ScuroNeko Logger)
Небольшой структурированный логгер для Go с текстовым и JSON-выводом, несколькими writer'ами и настраиваемыми traceback-метаданными.
English version: README.md
Возможности
- Одновременная запись в несколько destinations.
- Текстовый и JSON-форматы.
stdout, файлы и любые внешниеio.Writer.- Опциональные timestamp'ы для текстового вывода.
- Компактный traceback для текстовых writer'ов и полный traceback для JSON.
- Замена текста в сообщениях для маскирования секретов или нормализации вывода.
- Явные правила владения writer'ами при
Close().
Установка
go get git.scuroneko.dev/scuroneko/sneklog/v2
Быстрый старт
package main
import (
"log"
"git.scuroneko.dev/scuroneko/sneklog/v2"
)
func main() {
logger := sneklog.NewLogger().
SetName("API").
SetLevel(sneklog.DEBUG).
AddReplacer("SOME_SECRET", "<redacted>")
text := logger.CreateTextStdoutWriter()
jsonFile, err := logger.CreateJsonFileWriter("logs/app.json")
if err != nil {
log.Fatal(err)
}
logger.AddWriters(text, jsonFile)
logger.Infoln("service started")
logger.Warnln("cache miss")
logger.Errorln("request failed")
logger.Debugln("debug details")
logger.Infoln("token", "SOME_SECRET")
if err := logger.Close(); err != nil {
log.Fatal(err)
}
}
Значения по умолчанию
NewLogger() создает логгер со следующими настройками:
Prefix("LOG")Level(sneklog.FATAL)JsonPretty(false)- текстовый formatter:
sneklog.DefaultTextFormatter - JSON formatter:
sneklog.DefaultJsonFormatter
CreateLogger() по-прежнему доступен для обратной совместимости.
Важно: в текущей модели уровней Level(sneklog.FATAL) пропускает INFO, WARN, ERROR и FATAL, но не DEBUG. Чтобы включить все сообщения, используйте Level(sneklog.DEBUG).
Если нужна классическая threshold-фильтрация, включите SetThresholdMode(true) и
задавайте уровни через NewThresholdLogLevel(...) или
NewThresholdLogLevelWithColors(...).
Writer'ы и владение
Logger.Close() закрывает только writer'ы, которые логгер создал сам:
CreateTextFileWriter(...)CreateJsonFileWriter(...)
Внешние writer'ы не закрываются:
CreateTextWriter(existingWriter)CreateJsonWriter(existingWriter)CreateTextStdoutWriter()CreateJsonStdoutWriter()
Это позволяет безопасно подключать bytes.Buffer, сетевые writer'ы и другие уже управляемые ресурсы.
Форматы вывода
Текстовый writer формирует записи вида:
2026-03-17T14:05:09+03:00 info API: service started
Используйте SetFormatter у writer'а, чтобы настроить timestamp'ы, traceback-поля, цвета и шаблон сообщения.
JSON writer записывает объект со следующими полями:
{
"time": "2026-03-17T14:05:09.123456789+03:00",
"level": "info",
"prefix": "API",
"message": "service started",
"traceback": [
{
"method": "main",
"filename": "main.go",
"line": 27,
"signature": "main.main",
"fullPath": "/path/to/main.go"
}
]
}
Если включен JsonPretty(true), JSON выводится с отступами.
Кастомные уровни и цвета
Можно создавать собственные уровни и назначать им ANSI, 256-color или RGB-цвета, а также текстовые атрибуты вроде Bold и Italic.
httpDelete := sneklog.NewLogLevel(0, "delete")
httpDelete.SetBackgroundRGB(128, 0, 0)
httpDelete.AddAttribute(sneklog.Italic).AddAttribute(sneklog.Bold)
httpCache := sneklog.NewLogLevel(0, "cache")
httpCache.SetForeground256Color(214)
Так как setter'ы LogLevel изменяют уровень на месте, их нужно вызывать на переменной, а не на временном результате NewLogLevel(...).
Короткие формы вроде SetFgColor и SetBgColor сохранены для обратной совместимости.
Для стандартных severity также есть отдельные helper'ы:
access := sneklog.NewInfoLogLevelWithColors("access", sneklog.FgCyan, sneklog.BgNone)
audit := sneklog.NewWarnLogLevel("audit")
Эти helper'ы сохраняют legacy severity index для обратной совместимости и одновременно выставляют значения threshold по умолчанию:
INFO:th=10WARN:th=20ERROR:th=30FATAL:th=40DEBUG:th=0
Чтобы явно создавать уровни для threshold-режима:
trace := sneklog.NewThresholdLogLevelWithColors(4, 5, "trace", sneklog.FgHiBlack, sneklog.BgNone)
audit := sneklog.NewThresholdLogLevel(1, 25, "audit")
logger := sneklog.NewLogger().
SetLevel(audit).
SetThresholdMode(true)
logger.Print(trace, "verbose trace") // будет отфильтровано
logger.Print(audit, "audit event") // будет записано
Для HTTP-методов доступны готовые уровни:
level := sneklog.LogLevelForMethod(http.MethodPost)
logger.Print(level, "POST /users")
При сравнении уровней:
- используйте
SameLevel, если важен только legacy severity index; - используйте
SameThreshold, если важна только threshold-фильтрация; - используйте
Equal, если нужно полное совпадение конфигурации, включая threshold, цвета и атрибуты.
Замена сообщений
AddReplacer(old, new) заменяет найденный текст в каждом сообщении до того,
как запись попадет в writer'ы. Правила замены применяются в порядке добавления.
logger := sneklog.CreateLogger().
Level(sneklog.DEBUG).
AddReplacer("SOME_SECRET", "<redacted>").
AddReplacer("user@example.com", "<email>")
logger.Infoln("login token:", "SOME_SECRET")
В текстовом и JSON-выводе вместо SOME_SECRET будет записано <redacted>.
Пустое значение old игнорируется.
API кратко
Info,Warn,Error,Debug,Fatalпринимают список значений.Infof,Warnf,Errorf,Debugf,Fatalfиспользуютfmt.Sprintf.Printf(level, format, args...)форматирует сообщение для явногоLogLevel.- Методы
*lnдобавляют семантику перевода строки, что удобно дляstdout, Docker и line-based collectors. Fatal,FatalfиFatallnвызываютos.Exit(1)после записи сообщения.AddReplacerмаскирует или переписывает текст сообщений перед отправкой в writer'ы.
Поведение traceback
- Текстовые writer'ы используют ближайший пользовательский stack frame.
- JSON writer'ы получают полный traceback.
- Внутренние frame'ы
sneklogиruntimeфильтруются из traceback.
Пример из репозитория
См. examples/main.go.
Лицензия
Проект распространяется под GNU GPLv3. См. LICENSE.