log

package module
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 20, 2024 License: MIT Imports: 20 Imported by: 905

README

Log


Latest Release Go Docs Build Status Codecov branch Go Report Card

A minimal and colorful Go logging library. 🪵

Made with VHS

It provides a leveled structured human readable logger with a small API. Unlike standard log, the Charm logger provides customizable colorful human readable logging with batteries included.

  • Uses Lip Gloss 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!")
Made with VHS

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)
Made with VHS

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

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.JSONFormatter
  • log.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. 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")
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")
Format Messages

You can use fmt.Sprintf() to format messages.

for item := 1; i <= 100; i++ {
    log.Info(fmt.Sprintf("Baking %d/100...", item))
}

Or arguments:

for temp := 375; temp <= 400; temp++ {
    log.Info("Increasing temperature", "degree", fmt.Sprintf("%d°F", temp))
}
Helper Functions

Skip caller frames in helper functions. Similar to what you can do with testing.TB().Helper().

func startOven(degree int) {
    log.Helper()
    log.Info("Starting oven", "degree", degree)
}

log.SetReportCaller(true)
startOven(400) // INFO <cookies/oven.go:123> Starting oven degree=400

This will use the caller function (startOven) line number instead of the logging function (log.Info) to report the source location.

Slog Handler

You can use Log as an log/slog handler. Just pass a logger instance to Slog and you're good to go.

handler := log.New(os.Stderr)
logger := slog.New(handler)
logger.Error("meow?")
Standard Log Adapter

Some Go libraries, especially the ones in the standard library, will only accept the standard logger interface. For instance, the HTTP Server from net/http will only take a *log.Logger for its ErrorLog field.

For this, you can use the standard log adapter, which simply wraps the logger in a *log.Logger interface.

logger := log.NewWithOptions(os.Stderr, log.Options{Prefix: "http"})
stdlog := logger.StandardLog(log.StandardLogOptions{
    ForceLevel: log.ErrorLevel,
})
s := &http.Server{
    Addr:     ":8080",
    Handler:  handler,
    ErrorLog: stdlog,
}
stdlog.Printf("Failed to make bake request, %s", fmt.Errorf("temperature is too low"))
// ERROR http: Failed to make bake request, temperature is too low

Gum

Running gum log with debug and error levels

Log integrates with Gum to log messages to output. Use gum log [flags] [message] to handle logging in your shell scripts. See charmbracelet/gum for more information.

License

MIT


Part of Charm.

the Charm logo

Charm热爱开源 • Charm loves open source • نحنُ نحب المصادر المفتوحة

Documentation

Index

Constants

View Source
const DefaultTimeFormat = "2006/01/02 15:04:05"

DefaultTimeFormat is the default time format.

Variables

View Source
var (
	// TimestampKey is the key for the timestamp.
	TimestampKey = "time"
	// MessageKey is the key for the message.
	MessageKey = "msg"
	// LevelKey is the key for the level.
	LevelKey = "level"
	// CallerKey is the key for the caller.
	CallerKey = "caller"
	// PrefixKey is the key for the prefix.
	PrefixKey = "prefix"
)
View Source
var ContextKey = contextKey{"log"}

ContextKey is the key used to store the logger in context.

View Source
var ErrInvalidLevel = errors.New("invalid level")

ErrInvalidLevel is an error returned when parsing an invalid level string.

View Source
var ErrMissingValue = fmt.Errorf("missing value")

ErrMissingValue is returned when a key is missing a value.

Functions

func Debug

func Debug(msg interface{}, keyvals ...interface{})

Debug logs a debug message.

func Debugf added in v0.2.0

func Debugf(format string, args ...interface{})

Debugf logs a debug message with formatting.

func Error

func Error(msg interface{}, keyvals ...interface{})

Error logs an error message.

func Errorf added in v0.2.0

func Errorf(format string, args ...interface{})

Errorf logs an error message with formatting.

func Fatal

func Fatal(msg interface{}, keyvals ...interface{})

Fatal logs a fatal message and exit.

func Fatalf added in v0.2.0

func Fatalf(format string, args ...interface{})

Fatalf logs a fatal message with formatting and exit.

func GetPrefix

func GetPrefix() string

GetPrefix returns the prefix for the default logger.

func Helper

func Helper()

Helper marks the calling function as a helper and skips it for source location information. It's the equivalent of testing.TB.Helper().

func Info

func Info(msg interface{}, keyvals ...interface{})

Info logs an info message.

func Infof added in v0.2.0

func Infof(format string, args ...interface{})

Infof logs an info message with formatting.

func Log added in v0.4.0

func Log(level Level, msg interface{}, keyvals ...interface{})

Log logs a message with the given level.

func Logf added in v0.4.0

func Logf(level Level, format string, args ...interface{})

Logf logs a message with formatting and level.

func LongCallerFormatter added in v0.2.0

func LongCallerFormatter(file string, line int, _ string) string

LongCallerFormatter is a caller formatter that returns the full path and line number.

func NowUTC

func NowUTC(t time.Time) time.Time

NowUTC is a convenient function that returns the current time in UTC timezone.

This is to be used as a time function. For example:

log.SetTimeFunction(log.NowUTC)

func Print

func Print(msg interface{}, keyvals ...interface{})

Print logs a message with no level.

func Printf added in v0.2.0

func Printf(format string, args ...interface{})

Printf logs a message with formatting and no level.

func SetCallerFormatter added in v0.2.0

func SetCallerFormatter(f CallerFormatter)

SetCallerFormatter sets the caller formatter for the default logger.

func SetCallerOffset added in v0.2.2

func SetCallerOffset(offset int)

SetCallerOffset sets the caller offset for the default logger.

func SetColorProfile added in v0.2.5

func SetColorProfile(profile termenv.Profile)

SetColorProfile force sets the underlying Lip Gloss renderer color profile for the TextFormatter.

func SetDefault added in v0.2.0

func SetDefault(logger *Logger)

SetDefault sets the default global logger.

func SetFormatter

func SetFormatter(f Formatter)

SetFormatter sets the formatter for the default logger.

func SetLevel

func SetLevel(level Level)

SetLevel sets the level for the default logger.

func SetOutput

func SetOutput(w io.Writer)

SetOutput sets the output for the default logger.

func SetPrefix

func SetPrefix(prefix string)

SetPrefix sets the prefix for the default logger.

func SetReportCaller

func SetReportCaller(report bool)

SetReportCaller sets whether to report caller location for the default logger.

func SetReportTimestamp

func SetReportTimestamp(report bool)

SetReportTimestamp sets whether to report timestamp for the default logger.

func SetStyles added in v0.3.0

func SetStyles(s *Styles)

SetStyles sets the logger styles for the TextFormatter.

func SetTimeFormat

func SetTimeFormat(format string)

SetTimeFormat sets the time format for the default logger.

func SetTimeFunction

func SetTimeFunction(f TimeFunction)

SetTimeFunction sets the time function for the default logger.

func ShortCallerFormatter added in v0.2.0

func ShortCallerFormatter(file string, line int, _ string) string

ShortCallerFormatter is a caller formatter that returns the last 2 levels of the path and line number.

func StandardLog

func StandardLog(opts ...StandardLogOptions) *log.Logger

StandardLog returns a standard logger from the default logger.

func Warn

func Warn(msg interface{}, keyvals ...interface{})

Warn logs a warning message.

func Warnf added in v0.2.0

func Warnf(format string, args ...interface{})

Warnf logs a warning message with formatting.

func WithContext

func WithContext(ctx context.Context, logger *Logger) context.Context

WithContext wraps the given logger in context.

Types

type CallerFormatter added in v0.2.0

type CallerFormatter func(string, int, string) string

CallerFormatter is the caller formatter.

type Formatter

type Formatter uint8

Formatter is a formatter for log messages.

const (
	// TextFormatter is a formatter that formats log messages as text. Suitable for
	// console output and log files.
	TextFormatter Formatter = iota
	// JSONFormatter is a formatter that formats log messages as JSON.
	JSONFormatter
	// LogfmtFormatter is a formatter that formats log messages as logfmt.
	LogfmtFormatter
)

type Level

type Level int32

Level is a logging level.

const (
	// DebugLevel is the debug level.
	DebugLevel Level = -4
	// InfoLevel is the info level.
	InfoLevel Level = 0
	// WarnLevel is the warn level.
	WarnLevel Level = 4
	// ErrorLevel is the error level.
	ErrorLevel Level = 8
	// FatalLevel is the fatal level.
	FatalLevel Level = 12
)

func GetLevel

func GetLevel() Level

GetLevel returns the level for the default logger.

func ParseLevel added in v0.1.2

func ParseLevel(level string) (Level, error)

ParseLevel converts level in string to Level type. Default level is InfoLevel.

func (Level) String

func (l Level) String() string

String returns the string representation of the level.

type Logger

type Logger struct {
	// contains filtered or unexported fields
}

Logger is a Logger that implements Logger.

func Default

func Default() *Logger

Default returns the default logger. The default logger comes with timestamp enabled.

func FromContext

func FromContext(ctx context.Context) *Logger

FromContext returns the logger from the given context. This will return the default package logger if no logger found in context.

func New

func New(w io.Writer) *Logger

New returns a new logger with the default options.

func NewWithOptions added in v0.2.0

func NewWithOptions(w io.Writer, o Options) *Logger

NewWithOptions returns a new logger using the provided options.

func With

func With(keyvals ...interface{}) *Logger

With returns a new logger with the given keyvals.

func WithPrefix

func WithPrefix(prefix string) *Logger

WithPrefix returns a new logger with the given prefix.

func (*Logger) Debug

func (l *Logger) Debug(msg interface{}, keyvals ...interface{})

Debug prints a debug message.

func (*Logger) Debugf added in v0.2.0

func (l *Logger) Debugf(format string, args ...interface{})

Debugf prints a debug message with formatting.

func (*Logger) Enabled added in v0.3.0

func (l *Logger) Enabled(_ context.Context, level slog.Level) bool

Enabled reports whether the logger is enabled for the given level.

Implements slog.Handler.

func (*Logger) Error

func (l *Logger) Error(msg interface{}, keyvals ...interface{})

Error prints an error message.

func (*Logger) Errorf added in v0.2.0

func (l *Logger) Errorf(format string, args ...interface{})

Errorf prints an error message with formatting.

func (*Logger) Fatal

func (l *Logger) Fatal(msg interface{}, keyvals ...interface{})

Fatal prints a fatal message and exits.

func (*Logger) Fatalf added in v0.2.0

func (l *Logger) Fatalf(format string, args ...interface{})

Fatalf prints a fatal message with formatting and exits.

func (*Logger) GetLevel

func (l *Logger) GetLevel() Level

GetLevel returns the current level.

func (*Logger) GetPrefix

func (l *Logger) GetPrefix() string

GetPrefix returns the current prefix.

func (*Logger) Handle added in v0.3.0

func (l *Logger) Handle(ctx context.Context, record slog.Record) error

Handle handles the Record. It will only be called if Enabled returns true.

Implements slog.Handler.

func (*Logger) Helper

func (l *Logger) Helper()

Helper marks the calling function as a helper and skips it for source location information. It's the equivalent of testing.TB.Helper().

func (*Logger) Info

func (l *Logger) Info(msg interface{}, keyvals ...interface{})

Info prints an info message.

func (*Logger) Infof added in v0.2.0

func (l *Logger) Infof(format string, args ...interface{})

Infof prints an info message with formatting.

func (*Logger) Log added in v0.4.0

func (l *Logger) Log(level Level, msg interface{}, keyvals ...interface{})

Log logs the given message with the given keyvals for the given level.

func (*Logger) Logf added in v0.4.0

func (l *Logger) Logf(level Level, format string, args ...interface{})

Logf logs a message with formatting.

func (*Logger) Print

func (l *Logger) Print(msg interface{}, keyvals ...interface{})

Print prints a message with no level.

func (*Logger) Printf added in v0.2.0

func (l *Logger) Printf(format string, args ...interface{})

Printf prints a message with no level and formatting.

func (*Logger) SetCallerFormatter added in v0.2.0

func (l *Logger) SetCallerFormatter(f CallerFormatter)

SetCallerFormatter sets the caller formatter.

func (*Logger) SetCallerOffset added in v0.2.2

func (l *Logger) SetCallerOffset(offset int)

SetCallerOffset sets the caller offset.

func (*Logger) SetColorProfile added in v0.2.5

func (l *Logger) SetColorProfile(profile termenv.Profile)

SetColorProfile force sets the underlying Lip Gloss renderer color profile for the TextFormatter.

func (*Logger) SetFormatter

func (l *Logger) SetFormatter(f Formatter)

SetFormatter sets the formatter.

func (*Logger) SetLevel

func (l *Logger) SetLevel(level Level)

SetLevel sets the current level.

func (*Logger) SetOutput

func (l *Logger) SetOutput(w io.Writer)

SetOutput sets the output destination.

func (*Logger) SetPrefix

func (l *Logger) SetPrefix(prefix string)

SetPrefix sets the current prefix.

func (*Logger) SetReportCaller

func (l *Logger) SetReportCaller(report bool)

SetReportCaller sets whether the caller location should be reported.

func (*Logger) SetReportTimestamp

func (l *Logger) SetReportTimestamp(report bool)

SetReportTimestamp sets whether the timestamp should be reported.

func (*Logger) SetStyles added in v0.3.0

func (l *Logger) SetStyles(s *Styles)

SetStyles sets the logger styles for the TextFormatter.

func (*Logger) SetTimeFormat

func (l *Logger) SetTimeFormat(format string)

SetTimeFormat sets the time format.

func (*Logger) SetTimeFunction

func (l *Logger) SetTimeFunction(f TimeFunction)

SetTimeFunction sets the time function.

func (*Logger) StandardLog

func (l *Logger) StandardLog(opts ...StandardLogOptions) *log.Logger

StandardLog returns a standard logger from Logger. The returned logger can infer log levels from message prefix. Expected prefixes are DEBUG, INFO, WARN, ERROR, and ERR.

func (*Logger) Warn

func (l *Logger) Warn(msg interface{}, keyvals ...interface{})

Warn prints a warning message.

func (*Logger) Warnf added in v0.2.0

func (l *Logger) Warnf(format string, args ...interface{})

Warnf prints a warning message with formatting.

func (*Logger) With

func (l *Logger) With(keyvals ...interface{}) *Logger

With returns a new logger with the given keyvals added.

func (*Logger) WithAttrs added in v0.3.0

func (l *Logger) WithAttrs(attrs []slog.Attr) slog.Handler

WithAttrs returns a new Handler with the given attributes added.

Implements slog.Handler.

func (*Logger) WithGroup added in v0.3.0

func (l *Logger) WithGroup(name string) slog.Handler

WithGroup returns a new Handler with the given group name prepended to the current group name or prefix.

Implements slog.Handler.

func (*Logger) WithPrefix added in v0.2.0

func (l *Logger) WithPrefix(prefix string) *Logger

WithPrefix returns a new logger with the given prefix.

type LoggerOption

type LoggerOption = func(*Logger)

LoggerOption is an option for a logger.

type Options added in v0.2.0

type Options struct {
	// TimeFunction is the time function for the logger. The default is time.Now.
	TimeFunction TimeFunction
	// TimeFormat is the time format for the logger. The default is "2006/01/02 15:04:05".
	TimeFormat string
	// Level is the level for the logger. The default is InfoLevel.
	Level Level
	// Prefix is the prefix for the logger. The default is no prefix.
	Prefix string
	// ReportTimestamp is whether the logger should report the timestamp. The default is false.
	ReportTimestamp bool
	// ReportCaller is whether the logger should report the caller location. The default is false.
	ReportCaller bool
	// CallerFormatter is the caller format for the logger. The default is ShortCallerFormatter.
	CallerFormatter CallerFormatter
	// CallerOffset is the caller format for the logger. The default is 0.
	CallerOffset int
	// Fields is the fields for the logger. The default is no fields.
	Fields []interface{}
	// Formatter is the formatter for the logger. The default is TextFormatter.
	Formatter Formatter
}

Options is the options for the logger.

type StandardLogOptions added in v0.2.0

type StandardLogOptions struct {
	ForceLevel Level
}

StandardLogOptions can be used to configure the standard log adapter.

type Styles added in v0.3.0

type Styles struct {
	// Timestamp is the style for timestamps.
	Timestamp lipgloss.Style

	// Caller is the style for source caller.
	Caller lipgloss.Style

	// Prefix is the style for prefix.
	Prefix lipgloss.Style

	// Message is the style for messages.
	Message lipgloss.Style

	// Key is the style for keys.
	Key lipgloss.Style

	// Value is the style for values.
	Value lipgloss.Style

	// Separator is the style for separators.
	Separator lipgloss.Style

	// Levels are the styles for each level.
	Levels map[Level]lipgloss.Style

	// Keys overrides styles for specific keys.
	Keys map[string]lipgloss.Style

	// Values overrides value styles for specific keys.
	Values map[string]lipgloss.Style
}

Styles defines the styles for the text logger.

func DefaultStyles added in v0.3.0

func DefaultStyles() *Styles

DefaultStyles returns the default styles.

type TimeFunction

type TimeFunction = func(time.Time) time.Time

TimeFunction is a function that returns a time.Time.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL