REPOSITORY / ScuroNeko

SNekLog

Код, история изменений и документация проекта.
ACTIVE PUBLIC SOURCE
ScuroNeko b7fa3f7606
Golang lint / lint (push) Successful in 47s
(chore): document and test new LogLevel APIs
- add godoc for SameLevel and Equal
- update package docs and READMEs with new helpers
- refresh unreleased release notes
- add tests for Printf, HTTP method levels, and level constructors
2026-04-27 17:04:41 +03:00
2026-04-27 15:42:24 +03:00
2026-04-24 15:43:14 +03:00
2026-04-27 09:56:46 +03:00
2026-04-24 15:43:14 +03:00
2026-01-29 11:56:48 +03:00
2026-04-24 15:43:14 +03:00
2026-04-27 15:42:24 +03:00

SNekLog (ScuroNeko Logger)

Small structured logger for Go with text and JSON output, multiple writers, and optional traceback metadata.

Russian version: README_ru.md

Features

  • Fan out the same record to multiple destinations.
  • Text and JSON writers.
  • stdout, files, and arbitrary external io.Writer values.
  • Optional timestamps for text output.
  • Compact traceback metadata for text writers and full traceback slices for JSON.
  • Message replacement for masking secrets or normalizing output.
  • Explicit ownership rules for writer closing.

Installation

go get git.scuroneko.dev/scuroneko/sneklog/v2

Quick start

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)
	}
}

Defaults

NewLogger() starts with:

  • Prefix("LOG")
  • Level(sneklog.FATAL)
  • JsonPretty(false)
  • text formatter: sneklog.DefaultTextFormatter
  • JSON formatter: sneklog.DefaultJsonFormatter

CreateLogger() is still available for backward compatibility.

Important: with the current level ordering, Level(sneklog.FATAL) allows INFO, WARN, ERROR, and FATAL, but not DEBUG. Use Level(sneklog.DEBUG) to enable every level.

Writers and ownership

Logger.Close() only closes writers created by the logger itself:

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

The following writers remain owned by the caller and are not closed by Logger.Close():

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

This makes it safe to plug in bytes.Buffer, network writers, and other externally managed resources.

Output formats

Text writers render records like:

2026-03-17T14:05:09+03:00 info API: service started

Use SetFormatter on a writer to customize timestamps, traceback fields, colors, and message layout.

JSON writers emit objects with this shape:

{
  "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"
    }
  ]
}

When JsonPretty(true) is enabled, JSON is indented.

Custom levels and colors

You can define your own levels and assign ANSI, 256-color, or RGB colors, plus text attributes such as Bold or 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)

Because LogLevel setters mutate the level in place, call them on a variable, not on a temporary value returned by NewLogLevel(...). Short forms such as SetFgColor and SetBgColor remain available for backward compatibility.

Common severities also have dedicated helpers:

access := sneklog.NewInfoLogLevelWithColors("access", sneklog.FgCyan, sneklog.BgNone)
audit := sneklog.NewWarnLogLevel("audit")

HTTP method-specific predefined levels are available out of the box:

level := sneklog.LogLevelForMethod(http.MethodPost)
logger.Print(level, "POST /users")

When comparing levels, use SameLevel if only the severity matters and Equal if the full configuration, including colors and attributes, must match.

Message replacement

AddReplacer(old, new) replaces matching text in every message before the record reaches any writer. Replacement rules are applied in the order they are added.

logger := sneklog.CreateLogger().
	Level(sneklog.DEBUG).
	AddReplacer("SOME_SECRET", "<redacted>").
	AddReplacer("user@example.com", "<email>")

logger.Infoln("login token:", "SOME_SECRET")

This writes <redacted> instead of SOME_SECRET in both text and JSON output. An empty old value is ignored.

API summary

  • Info, Warn, Error, Debug, and Fatal accept a list of values.
  • Infof, Warnf, Errorf, Debugf, and Fatalf use fmt.Sprintf.
  • Printf(level, format, args...) formats a message for an explicit LogLevel.
  • The *ln methods preserve newline semantics, which is useful for stdout, Docker, and line-based collectors.
  • Fatal, Fatalf, and Fatalln call os.Exit(1) after writing the message.
  • AddReplacer masks or rewrites message text before records are sent to writers.

Traceback behavior

  • Text writers use the nearest user stack frame.
  • JSON writers receive the full traceback slice.
  • Internal sneklog frames and runtime frames are filtered out.

Repository example

See examples/main.go.

License

This project is licensed under GNU GPLv3. See LICENSE.

S
Description
No description provided
Readme GPL-3.0
116 KiB
2.3.0
Latest
2026-04-28 14:36:03 +03:00
Languages
Go 100%