FILE / ScuroNeko/SNekLog

README_ru.md

Исходный файл и его история в репозитории.
FILE 9268e222ab817945dcffab143bd71ea4de1ae7f7
Files
SNekLog/README_ru.md
T
ScuroNeko 9268e222ab feat: add message replacement for log records
Add Logger.AddReplacer to mask or normalize message text before records reach writers.
Document replacement behavior in README and package GoDoc, and update the example.

Also fix JSON writer edge cases:
- avoid panic on empty message lists
- preserve newline semantics when the last message already ends with n
- keep original message argument types for custom writers when no replacers are configured

Update dependencies and add release notes for the next release.
2026-04-20 18:00:11 +03:00

5.2 KiB

slog

Небольшой структурированный логгер для Go с текстовым и JSON-выводом, несколькими writer'ами и настраиваемыми traceback-метаданными.

English version: README.md

Возможности

  • Одновременная запись в несколько destinations.
  • Текстовый и JSON-форматы.
  • stdout, файлы и любые внешние io.Writer.
  • Опциональные timestamp'ы для текстового вывода.
  • Компактный traceback для текстовых writer'ов и полный traceback для JSON.
  • Замена текста в сообщениях для маскирования секретов или нормализации вывода.
  • Явные правила владения writer'ами при Close().

Установка

go get git.nix13.pw/scuroneko/slog

Быстрый старт

package main

import (
	"log"

	"git.nix13.pw/scuroneko/slog"
)

func main() {
	logger := slog.CreateLogger().
		Prefix("API").
		Level(slog.DEBUG).
		PrintTraceback(true).
		JsonPretty(true).
		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)
	}
}

Значения по умолчанию

CreateLogger() создает логгер со следующими настройками:

  • Prefix("LOG")
  • Level(slog.FATAL)
  • PrintTime(true)
  • PrintTraceback(false)
  • JsonPretty(false)

Важно: в текущей модели уровней Level(slog.FATAL) пропускает INFO, WARN, ERROR и FATAL, но не DEBUG. Чтобы включить все сообщения, используйте Level(slog.DEBUG).

Writer'ы и владение

Logger.Close() закрывает только writer'ы, которые логгер создал сам:

  • CreateTextFileWriter(...)
  • CreateJsonFileWriter(...)

Внешние writer'ы не закрываются:

  • CreateTextWriter(existingWriter)
  • CreateJsonWriter(existingWriter)
  • CreateTextStdoutWriter()
  • CreateJsonStdoutWriter()

Это позволяет безопасно подключать bytes.Buffer, сетевые writer'ы и другие уже управляемые ресурсы.

Форматы вывода

Текстовый writer формирует записи вида:

[API] [INFO] [main.go:main:27] [17.03.26 14:05:09] service started

Поле traceback появляется только если включен PrintTraceback(true).

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 выводится с отступами.

Замена сообщений

AddReplacer(old, new) заменяет найденный текст в каждом сообщении до того, как запись попадет в writer'ы. Правила замены применяются в порядке добавления.

logger := slog.CreateLogger().
	Level(slog.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.
  • Методы *ln добавляют семантику перевода строки, что удобно для stdout, Docker и line-based collectors.
  • Fatal, Fatalf и Fatalln вызывают os.Exit(1) после записи сообщения.
  • AddReplacer маскирует или переписывает текст сообщений перед отправкой в writer'ы.

Поведение traceback

  • Текстовые writer'ы используют ближайший пользовательский stack frame.
  • JSON writer'ы получают полный traceback.
  • Внутренние frame'ы slog и runtime фильтруются из traceback.

Пример из репозитория

См. examples/main.go.

Лицензия

Проект распространяется под GNU GPLv3. См. LICENSE.