slog
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 externalio.Writervalues.- Optional timestamps for text output.
- Compact traceback metadata for text writers and full traceback slices for JSON.
- Explicit ownership rules for writer closing.
Installation
go get git.nix13.pw/scuroneko/slog
Quick start
package main
import (
"log"
"git.nix13.pw/scuroneko/slog"
)
func main() {
logger := slog.CreateLogger().
Prefix("API").
Level(slog.DEBUG).
PrintTraceback(true).
JsonPretty(true)
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")
if err := logger.Close(); err != nil {
log.Fatal(err)
}
}
Defaults
CreateLogger() starts with:
Prefix("LOG")Level(slog.FATAL)PrintTime(true)PrintTraceback(false)JsonPretty(false)
Important: with the current level ordering, Level(slog.FATAL) allows INFO, WARN, ERROR, and FATAL, but not DEBUG. Use Level(slog.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:
[API] [INFO] [main.go:main:27] [17.03.26 14:05:09] service started
The traceback field is included only when PrintTraceback(true) is enabled.
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.
API summary
Info,Warn,Error,Debug, andFatalaccept a list of values.Infof,Warnf,Errorf,Debugf, andFatalfusefmt.Sprintf.- The
*lnmethods preserve newline semantics, which is useful forstdout, Docker, and line-based collectors. Fatal,Fatalf, andFatallncallos.Exit(1)after writing the message.
Traceback behavior
- Text writers use the nearest user stack frame.
- JSON writers receive the full traceback slice.
- Internal
slogframes andruntimeframes are filtered out.
Repository example
See examples/main.go.
License
This project is licensed under GNU GPLv3. See LICENSE.