log

package module
v0.0.0-...-6610871 Latest Latest
Warning

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

Go to latest
Published: Apr 4, 2023 License: MIT Imports: 19 Imported by: 0

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.
  • 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.
log.ErrorLevelStyle = lipgloss.NewStyle().
    SetString("ERROR!!").
    Padding(0, 1, 0, 1).
    Background(lipgloss.AdaptiveColor{
        Light: "203",
        Dark:  "204",
    }).
    Foreground(lipgloss.Color("0"))
// Add a custom style for key `err`
log.KeyStyles["err"] = lipgloss.NewStyle().Foreground(lipgloss.Color("204"))
log.ValueStyles["err"] = lipgloss.NewStyle().Bold(true)
log.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().

function 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.

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

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 = "ts"
	// MessageKey is the key for the message.
	MessageKey = "msg"
	// LevelKey is the key for the level.
	LevelKey = "lvl"
	// CallerKey is the key for the caller.
	CallerKey = "caller"
	// PrefixKey is the key for the prefix.
	PrefixKey = "prefix"
)
View Source
var (
	// TimestampStyle is the style for timestamps.
	TimestampStyle = lipgloss.NewStyle()

	// CallerStyle is the style for caller.
	CallerStyle = lipgloss.NewStyle().Faint(true)

	// PrefixStyle is the style for prefix.
	PrefixStyle = lipgloss.NewStyle().Bold(true).Faint(true)

	// MessageStyle is the style for messages.
	MessageStyle = lipgloss.NewStyle()

	// KeyStyle is the style for keys.
	KeyStyle = lipgloss.NewStyle().Faint(true)

	// ValueStyle is the style for values.
	ValueStyle = lipgloss.NewStyle()

	// SeparatorStyle is the style for separators.
	SeparatorStyle = lipgloss.NewStyle().Faint(true)

	// DebugLevel is the style for debug level.
	DebugLevelStyle = lipgloss.NewStyle().
					SetString(strings.ToUpper(DebugLevel.String())).
					Bold(true).
					MaxWidth(4).
					Foreground(lipgloss.AdaptiveColor{
			Light: "63",
			Dark:  "63",
		})

	// InfoLevel is the style for info level.
	InfoLevelStyle = lipgloss.NewStyle().
					SetString(strings.ToUpper(InfoLevel.String())).
					Bold(true).
					MaxWidth(4).
					Foreground(lipgloss.AdaptiveColor{
			Light: "39",
			Dark:  "86",
		})

	// WarnLevel is the style for warn level.
	WarnLevelStyle = lipgloss.NewStyle().
					SetString(strings.ToUpper(WarnLevel.String())).
					Bold(true).
					MaxWidth(4).
					Foreground(lipgloss.AdaptiveColor{
			Light: "208",
			Dark:  "192",
		})

	// ErrorLevel is the style for error level.
	ErrorLevelStyle = lipgloss.NewStyle().
					SetString(strings.ToUpper(ErrorLevel.String())).
					Bold(true).
					MaxWidth(4).
					Foreground(lipgloss.AdaptiveColor{
			Light: "203",
			Dark:  "204",
		})

	// FatalLevel is the style for error level.
	FatalLevelStyle = lipgloss.NewStyle().
					SetString(strings.ToUpper(FatalLevel.String())).
					Bold(true).
					MaxWidth(4).
					Foreground(lipgloss.AdaptiveColor{
			Light: "133",
			Dark:  "134",
		})

	// KeyStyles overrides styles for specific keys.
	KeyStyles = map[string]lipgloss.Style{}

	// ValueStyles overrides value styles for specific keys.
	ValueStyles = map[string]lipgloss.Style{}
)
View Source
var (
	// ErrMissingValue is returned when a key is missing a value.
	ErrMissingValue = fmt.Errorf("missing value")
)

Functions

func Debug

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

Debug logs a debug message.

func Debugf

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

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

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

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

Infof logs an info message with formatting.

func LongCallerFormatter

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

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

func NowUTC

func NowUTC() 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

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

Printf logs a message with formatting and no level.

func SetCallerFormatter

func SetCallerFormatter(f CallerFormatter)

SetCallerFormatter sets the caller formatter for the default logger.

func SetDefault

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

func ShortCallerFormatter(file string, line int, funcName 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

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

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 = iota - 1
	// InfoLevel is the info level.
	InfoLevel
	// WarnLevel is the warn level.
	WarnLevel
	// ErrorLevel is the error level.
	ErrorLevel
	// FatalLevel is the fatal level.
	FatalLevel
)

func GetLevel

func GetLevel() Level

GetLevel returns the level for the default logger.

func ParseLevel

func ParseLevel(level string) Level

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

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

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

Debugf prints a debug message with formatting.

func (*Logger) Error

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

Error prints an error message.

func (*Logger) Errorf

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

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

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

Infof prints an info message with formatting.

func (*Logger) Print

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

Print prints a message with no level.

func (*Logger) Printf

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

Printf prints a message with no level and formatting.

func (*Logger) SetCallerFormatter

func (l *Logger) SetCallerFormatter(f CallerFormatter)

SetCallerFormatter sets the caller formatter.

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

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

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

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 CallerShort.
	CallerFormatter CallerFormatter
	// 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

type StandardLogOptions struct {
	ForceLevel Level
}

StandardLogOptions can be used to configure the standard log adapter.

type TimeFunction

type TimeFunction = func() 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