FILE / ScuroNeko/SNekLog

README_ru.md

Исходный файл и его история в репозитории.
FILE v2.3.0
Files
SNekLog/README_ru.md
T
ScuroNeko e6d15b530f
Golang lint / lint (push) Successful in 1m36s
(new): add threshold-based log level filtering and docs
- 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
2026-04-28 09:45:40 +03:00

8.1 KiB
Raw Permalink Blame History

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=10
  • WARN: th=20
  • ERROR: th=30
  • FATAL: th=40
  • DEBUG: 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.