Log
A minimal, colorful Go logging library 🪵
Install / Use
/learn @charmbracelet/LogREADME
Log
<p> <picture> <source media="(prefers-color-scheme: light)" srcset="https://user-images.githubusercontent.com/25087/219742757-c8afe0d9-608a-4845-a555-ef59c0af9ebc.png" width="359"> <source media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/25087/219743408-3d7bef51-1409-40c0-8159-acc6e52f078e.png" width="359"> <img src="https://user-images.githubusercontent.com/25087/219742757-c8afe0d9-608a-4845-a555-ef59c0af9ebc.png" width="359" /> </picture> <br> <a href="https://github.com/charmbracelet/log/releases"><img src="https://img.shields.io/github/release/charmbracelet/log.svg" alt="Latest Release"></a> <a href="https://pkg.go.dev/github.com/charmbracelet/log?tab=doc"><img src="https://godoc.org/github.com/golang/gddo?status.svg" alt="Go Docs"></a> <a href="https://github.com/charmbracelet/log/actions"><img src="https://github.com/charmbracelet/log/workflows/build/badge.svg" alt="Build Status"></a> <a href="https://codecov.io/gh/charmbracelet/log"><img alt="Codecov branch" src="https://img.shields.io/codecov/c/github/charmbracelet/log/main.svg"></a> <a href="https://goreportcard.com/report/github.com/charmbracelet/log"><img alt="Go Report Card" src="https://goreportcard.com/badge/github.com/charmbracelet/log"></a> </p>A minimal and colorful Go logging library. 🪵
<picture> <source media="(prefers-color-scheme: dark)" srcset="https://vhs.charm.sh/vhs-1wBImk2iSIuiiD7Ib9rufi.gif"> <source media="(prefers-color-scheme: light)" srcset="https://vhs.charm.sh/vhs-1wBImk2iSIuiiD7Ib9rufi.gif"> <!-- <source media="(prefers-color-scheme: light)" srcset="https://vhs.charm.sh/vhs-2NvOYS29AauVRgRRPmquXx.gif"> --> <img src="https://vhs.charm.sh/vhs-1wBImk2iSIuiiD7Ib9rufi.gif" alt="Made with VHS" /> </picture>It provides a leveled structured human readable logger with a small API. Unlike
[standard log][stdlog], the Charm logger provides customizable colorful human
readable logging with batteries included.
- Uses [Lip Gloss][lipgloss] to style and colorize the output.
- Colorful, human readable format.
- Ability to customize the time stamp format.
- Skips caller frames and marks function as helpers.
- Leveled logging.
- Text, JSON, and Logfmt formatters.
- Store and retrieve logger in and from context.
- Slog handler.
- Standard log adapter.
Usage
Use go get to download the dependency.
go get github.com/charmbracelet/log@latest
Then, import it in your Go files:
import "github.com/charmbracelet/log"
The Charm logger comes with a global package-wise logger with timestamps turned
on, and the logging level set to info.
log.Debug("Cookie 🍪") // won't print anything
log.Info("Hello World!")
<picture>
<source media="(prefers-color-scheme: dark)" width="400" srcset="https://vhs.charm.sh/vhs-cKiS8OuRrF1VVVpscM9e3.gif">
<source media="(prefers-color-scheme: light)" width="400" srcset="https://vhs.charm.sh/vhs-cKiS8OuRrF1VVVpscM9e3.gif">
<!-- <source media="(prefers-color-scheme: light)" width="400" srcset="https://vhs.charm.sh/vhs-4AeLaEuO3tDbECR1qe9Jvp.gif"> -->
<img width="400" src="https://vhs.charm.sh/vhs-4AeLaEuO3tDbECR1qe9Jvp.gif" alt="Made with VHS" />
</picture>
All logging levels accept optional key/value pairs to be printed along with a message.
err := fmt.Errorf("too much sugar")
log.Error("failed to bake cookies", "err", err)
<picture>
<source media="(prefers-color-scheme: dark)" width="600" srcset="https://vhs.charm.sh/vhs-65KIpGw4FTESK0IzkDB9VQ.gif" >
<source media="(prefers-color-scheme: light)" width="600" srcset="https://vhs.charm.sh/vhs-65KIpGw4FTESK0IzkDB9VQ.gif" >
<!-- <source media="(prefers-color-scheme: light)" width="600" srcset="https://vhs.charm.sh/vhs-7rk8wALXRDoFw8SLFwn9rW.gif"> -->
<img width="600" src="https://vhs.charm.sh/vhs-65KIpGw4FTESK0IzkDB9VQ.gif" alt="Made with VHS">
</picture>
You can use log.Print() to print messages without a level prefix.
log.Print("Baking 101")
// 2023/01/04 10:04:06 Baking 101
New loggers
Use New() to create new loggers.
logger := log.New(os.Stderr)
if butter {
logger.Warn("chewy!", "butter", true)
}
<picture>
<source media="(prefers-color-scheme: dark)" width="300" srcset="https://vhs.charm.sh/vhs-3QQdzOW4Zc0bN2tOhAest9.gif">
<source media="(prefers-color-scheme: light)" width="300" srcset="https://vhs.charm.sh/vhs-3QQdzOW4Zc0bN2tOhAest9.gif">
<!-- <source media="(prefers-color-scheme: light)" width="300" srcset="https://vhs.charm.sh/vhs-1nrhNSuFnQkxWD4RoMlE4O.gif"> -->
<img width="300" src="https://vhs.charm.sh/vhs-3QQdzOW4Zc0bN2tOhAest9.gif">
</picture>
Levels
Log offers multiple levels to filter your logs on. Available levels are:
log.DebugLevel
log.InfoLevel
log.WarnLevel
log.ErrorLevel
log.FatalLevel
Use log.SetLevel() to set the log level. You can also create a new logger with
a specific log level using log.Options{Level: }.
Use the corresponding function to log a message:
err := errors.New("Baking error 101")
log.Debug(err)
log.Info(err)
log.Warn(err)
log.Error(err)
log.Fatal(err) // this calls os.Exit(1)
log.Print(err) // prints regardless of log level
Or use the formatter variant:
format := "%s %d"
log.Debugf(format, "chocolate", 10)
log.Warnf(format, "adding more", 5)
log.Errorf(format, "increasing temp", 420)
log.Fatalf(format, "too hot!", 500) // this calls os.Exit(1)
log.Printf(format, "baking cookies") // prints regardless of log level
// Use these in conjunction with `With(...)` to add more context
log.With("err", err).Errorf("unable to start %s", "oven")
Structured
All the functions above take a message and key-value pairs of anything. The message can also be of type any.
ingredients := []string{"flour", "butter", "sugar", "chocolate"}
log.Debug("Available ingredients", "ingredients", ingredients)
// DEBUG Available ingredients ingredients="[flour butter sugar chocolate]"
Options
You can customize the logger with options. Use log.NewWithOptions() and
log.Options{} to customize your new logger.
logger := log.NewWithOptions(os.Stderr, log.Options{
ReportCaller: true,
ReportTimestamp: true,
TimeFormat: time.Kitchen,
Prefix: "Baking 🍪 ",
})
logger.Info("Starting oven!", "degree", 375)
time.Sleep(10 * time.Minute)
logger.Info("Finished baking")
<picture>
<source media="(prefers-color-scheme: dark)" width="700" srcset="https://vhs.charm.sh/vhs-6oSCJcQ5EmFKKELcskJhLo.gif">
<source media="(prefers-color-scheme: light)" width="700" srcset="https://vhs.charm.sh/vhs-6oSCJcQ5EmFKKELcskJhLo.gif">
<!-- <source media="(prefers-color-scheme: light)" width="700" srcset="https://vhs.charm.sh/vhs-2X8Esd8ZsHo4DVPVgR36yx.gif"> -->
<img width="700" src="https://vhs.charm.sh/vhs-6oSCJcQ5EmFKKELcskJhLo.gif">
</picture>
You can also use logger setters to customize the logger.
logger := log.New(os.Stderr)
logger.SetReportTimestamp(false)
logger.SetReportCaller(false)
logger.SetLevel(log.DebugLevel)
Use log.SetFormatter() or log.Options{Formatter: } to change the output
format. Available options are:
log.TextFormatter(default)log.JSONFormatterlog.LogfmtFormatter
Note styling only affects the
TextFormatter. Styling is disabled if the output is not a TTY.
For a list of available options, refer to options.go.
Styles
You can customize the logger styles using [Lipgloss][lipgloss]. The styles are defined at a global level in styles.go.
// Override the default error level style.
styles := log.DefaultStyles()
styles.Levels[log.ErrorLevel] = lipgloss.NewStyle().
SetString("ERROR!!").
Padding(0, 1, 0, 1).
Background(lipgloss.Color("204")).
Foreground(lipgloss.Color("0"))
// Add a custom style for key `err`
styles.Keys["err"] = lipgloss.NewStyle().Foreground(lipgloss.Color("204"))
styles.Values["err"] = lipgloss.NewStyle().Bold(true)
logger := log.New(os.Stderr)
logger.SetStyles(styles)
logger.Error("Whoops!", "err", "kitchen on fire")
<picture>
<source media="(prefers-color-scheme: dark)" width="400" srcset="https://vhs.charm.sh/vhs-4LXsGvzyH4RdjJaTF4a9MG.gif">
<source media="(prefers-color-scheme: light)" width="400" srcset="https://vhs.charm.sh/vhs-4LXsGvzyH4RdjJaTF4a9MG.gif">
<!-- <source media="(prefers-color-scheme: light)" width="400" srcset="https://vhs.charm.sh/vhs-4f6qLnIfudMMLDD9sxXUrv.gif"> -->
<img width="400" src="https://vhs.charm.sh/vhs-4LXsGvzyH4RdjJaTF4a9MG.gif">
</picture>
Sub-logger
Create sub-loggers with their specific fields.
logger := log.NewWithOptions(os.Stderr, log.Options{
Prefix: "Baking 🍪 "
})
batch2 := logger.With("batch", 2, "chocolateChips", true)
batch2.Debug("Preparing batch 2...")
batch2.Debug("Adding chocolate chips")
<picture>
<source media="(prefers-color-scheme: dark)" width="700" srcset="https://vhs.charm.sh/vhs-1JgP5ZRL0oXVspeg50CczR.gif">
<source media="(prefers-color-scheme: light)" width="700" srcset="https://vhs.charm.sh/vhs-1JgP5ZRL0oXVspeg50CczR.gif">
<img width="700" src="https://vhs.charm.sh/vhs-1JgP5ZRL0oXVspeg50CczR.gif">
</picture>
Format Messages
You can use fmt.Sprintf() to format messages.
for item := 1; i <= 100; i++ {
log.Info(fmt.Sprintf("Baking %d/100...", item))
}
<picture>
<source media="(prefers-color-scheme: dark)" width="500" srcset="https://vhs.charm.sh/vhs-4nX5I7qHT09aJ2gU7OaGV5.gif">
<source media="(prefers-color-scheme: light)" width="500" srcset="https://vhs.charm.sh/vhs-4nX5I7qHT09aJ2gU7OaGV5.gif">
<!-- <source media="(prefers-color-scheme: light)" width="500" srcset="https://vhs.charm.sh/vhs-4RHXd4JSucomcPqJGZTpKh.gif"> -->
<img width="500" src="https://vhs.charm.sh/vhs-4nX5I7qHT09aJ2gU7OaGV5.gif">
</picture>
Or arguments:
for temp := 375; temp <= 400; temp++
Related Skills
node-connect
330.3kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
xurl
330.3kA CLI tool for making authenticated requests to the X (Twitter) API. Use this skill when you need to post tweets, reply, quote, search, read posts, manage followers, send DMs, upload media, or interact with any X API v2 endpoint.
frontend-design
81.3kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
330.3kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
