# slog Small structured logger for Go with text and JSON output, multiple writers, and optional traceback metadata. Russian version: [README_ru.md](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. - Explicit ownership rules for writer closing. ## Installation ```bash go get git.nix13.pw/scuroneko/slog ``` ## Quick start ```go 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: ```text [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: ```json { "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`, and `Fatal` accept a list of values. - `Infof`, `Warnf`, `Errorf`, `Debugf`, and `Fatalf` use `fmt.Sprintf`. - 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. ## Traceback behavior - Text writers use the nearest user stack frame. - JSON writers receive the full traceback slice. - Internal `slog` frames and `runtime` frames are filtered out. ## Repository example See [examples/main.go](examples/main.go). ## License This project is licensed under GNU GPLv3. See [LICENSE](LICENSE).