logger

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

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

Go to latest
Published: Feb 23, 2024 License: Apache-2.0 Imports: 6 Imported by: 0

README

Logger

Standardizing logging for GO applications

Uses slog from the standard library to have consistent structured logging across applications.

The logger should be configured and set up in the main function of the application and accessed through the slog package.

Configuration

The logger will take the following environment variables to configure the logger.

Environment Variable Description Default
LOG_LEVEL The log level to use. (DEBUG, INFO, WARN, ERROR) INFO
LOG_OUTPUT The output to write the logs to. (STDOUT, STDERR) stdout
HOSTNAME The hostname to set in the logs.
ENVIRONMENT The environment to set in the logs.

Usage

import (
    "errors"
    "log/slog"

    "github.com/jesse0michael/pkg/logger"
)

func main() {
    logger.SetLog()
    ctx := context.Background()

    // ...


    slog.With("key", "value").InfoContext(ctx, "writing logs")
    // {"time":"2023-08-21T09:15:18.111628-07:00","level":"INFO","msg":"writing logs","host":"local","environment":"test","key":"value"}

    slog.With("error", errors.New("test-error")).ErrorContext(ctx, "writing errors") 
    // {"time":"2023-08-21T09:15:18.111716-07:00","level":"ERROR","msg":"writing errors","host":"local","environment":"test","error":"test-error"}
}

Context Handler

The default logger is configured with a ContextHandler that allow you to set attributes in the GO context that will be logged with every log message.

import (
    "errors"
    "log/slog"

    "github.com/jesse0michael/pkg/logger"
)

func main() {
    _ = logger.NewLogger()
    ctx := context.Background()
    ctx = logger.AddAttrs(ctx, slog.String("accountID", "12345"))

    // ...

    slog.InfoContext(ctx, "writing logs")
    // {"time":"2023-08-21T09:15:18.111628-07:00","level":"INFO","msg":"writing logs","host":"local","environment":"test","accountID":"12345"}

    slog.With("error", errors.New("test-error")).ErrorContext(ctx, "writing errors") 
    // {"time":"2023-08-21T09:15:18.111628-07:00","level":"ERROR","msg":"writing errors","host":"local","environment":"test","error":"test-error","accountID":"12345"}
}

Error Warn Handler

The logger can be configured with an ErrorWarnHandler that will log errors as warnings if an error attribute matches a specified function.

import (
    "context"
    "errors"
    "log/slog"

    "github.com/jesse0michael/pkg/logger"
)

func main() {
    warnCheck := func(err error) bool { return err == context.Canceled }
    logger.NewLogger()
    logger.SetErrorWarnHandler(warnCheck)
    ctx := context.Background()

    // ...

    slog.With("error", context.Canceled).ErrorContext(ctx, "writing errors") 
    // {"time":"2023-08-21T09:15:18.111628-07:00","level":"WARN","msg":"writing errors","host":"local","environment":"test","error":"context canceled"}
}

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func AddAttrs

func AddAttrs(ctx context.Context, attrs ...slog.Attr) context.Context

AddAttrs adds attributes to the context.

func LogLevel

func LogLevel() slog.Leveler

LogLevel returns the slog level from the LOG_LEVEL environment variable.

func LogOutput

func LogOutput() io.Writer

LogOutput returns the slog output from the LOG_OUTPUT environment variable.

func NewContextHandler

func NewContextHandler(handler slog.Handler) slog.Handler

NewContextHandler returns a new ContextHandler.

func NewErrorWarnHandler

func NewErrorWarnHandler(handler slog.Handler, funcs ...ErrorCheckFunction) slog.Handler

NewErrorWarnHandler returns a new ErrorWarnHandler.

func NewLogger

func NewLogger() *slog.Logger

NewLogger sets and returns a new default logger.

Example
// Setup test
f, _ := os.CreateTemp("", "out")
os.Stderr = f
defer f.Close()

// Predefine environment
os.Setenv("ENVIRONMENT", "test")
os.Setenv("HOSTNAME", "local")
os.Setenv("LOG_OUTPUT", "stderr")
ctx := context.Background()

// Example
NewLogger()

slog.With("key", "value").InfoContext(ctx, "writing logs")
slog.With("error", errors.New("error")).ErrorContext(ctx, "writing errors")

// Post process output
ReplaceTimestamps(f, os.Stdout)
Output:

{"time":"TIMESTAMP","level":"INFO","msg":"writing logs","host":"local","environment":"test","key":"value"}
{"time":"TIMESTAMP","level":"ERROR","msg":"writing errors","host":"local","environment":"test","error":"error"}

func NewOtelHandler

func NewOtelHandler(handler slog.Handler) slog.Handler

NewOtelHandler returns a new OtelHandler.

func SetErrorWarnHandler

func SetErrorWarnHandler(funcs ...ErrorCheckFunction)

SetErrorWarnHandler will wrap the default slog.Logger's handler with an ErrorWarnHandler.

Types

type ContextHandler

type ContextHandler struct {
	slog.Handler
}

ContextHandler is a slog.Handler that adds attributes to the log record from the context.

Example
// Setup test
f, _ := os.CreateTemp("", "out")
os.Stderr = f
defer f.Close()

// Predefine environment
os.Setenv("ENVIRONMENT", "test")
os.Setenv("HOSTNAME", "local")
os.Setenv("LOG_OUTPUT", "stderr")
ctx := context.Background()

// Example
NewLogger()

ctx = AddAttrs(ctx, slog.String("accountID", "12345"))

slog.InfoContext(ctx, "writing logs")
slog.With("key", "value").InfoContext(ctx, "writing logs with attributes")
slog.Default().WithGroup("request").With("path", "/", "verb", "GET").InfoContext(ctx, "writing logs with group")

// Post process output
ReplaceTimestamps(f, os.Stdout)
Output:

{"time":"TIMESTAMP","level":"INFO","msg":"writing logs","host":"local","environment":"test","accountID":"12345"}
{"time":"TIMESTAMP","level":"INFO","msg":"writing logs with attributes","host":"local","environment":"test","key":"value","accountID":"12345"}
{"time":"TIMESTAMP","level":"INFO","msg":"writing logs with group","host":"local","environment":"test","request":{"path":"/","verb":"GET","accountID":"12345"}}

func (ContextHandler) Handle

func (h ContextHandler) Handle(ctx context.Context, record slog.Record) error

Handle adds attributes from the context to the log record.

func (ContextHandler) WithAttrs

func (h ContextHandler) WithAttrs(attrs []slog.Attr) slog.Handler

WithAttrs returns a new ContextHandler with the given attributes.

func (ContextHandler) WithGroup

func (h ContextHandler) WithGroup(name string) slog.Handler

WithGroup returns a new ContextHandler with the given group name.

type ErrorCheckFunction

type ErrorCheckFunction func(error) bool

ErrorCheckFunction is a function that checks if an error matches a condition.

type ErrorWarnHandler

type ErrorWarnHandler struct {
	slog.Handler
	// contains filtered or unexported fields
}

ErrorWarnHandler is a slog.Handler that will downgrade the log level of a record to WARN if there is an "error" attr that match one of the error check functions.

Example
// Setup test
f, _ := os.CreateTemp("", "out")
os.Stderr = f
defer f.Close()

// Predefine environment
os.Setenv("ENVIRONMENT", "test")
os.Setenv("HOSTNAME", "local")
os.Setenv("LOG_OUTPUT", "stderr")
ctx := context.Background()
warnCheck := func(err error) bool { return err != nil && err.Error() == "warn" }

// Example
NewLogger()
SetErrorWarnHandler(warnCheck)

slog.With("error", errors.New("error")).ErrorContext(ctx, "writing errors")
slog.With("error", errors.New("warn")).ErrorContext(ctx, "writing errors that should be warnings")
slog.Default().WithGroup("request").With("path", "/", "verb", "GET").With("error", errors.New("warn")).ErrorContext(ctx, "writing errors that should be warnings with group")

// Post process output
ReplaceTimestamps(f, os.Stdout)
Output:

{"time":"TIMESTAMP","level":"ERROR","msg":"writing errors","host":"local","environment":"test","error":"error"}
{"time":"TIMESTAMP","level":"WARN","msg":"writing errors that should be warnings","host":"local","environment":"test","error":"warn"}
{"time":"TIMESTAMP","level":"WARN","msg":"writing errors that should be warnings with group","host":"local","environment":"test","request":{"path":"/","verb":"GET","error":"warn"}}

func (ErrorWarnHandler) Handle

func (h ErrorWarnHandler) Handle(ctx context.Context, record slog.Record) error

Handle checks the log record for an error attr and compares it against the ErrorCheckFunctions. If any of the ErrorCheckFunctions return true, the log level will be overridden to WARN.

func (ErrorWarnHandler) WithAttrs

func (h ErrorWarnHandler) WithAttrs(attrs []slog.Attr) slog.Handler

WithAttrs returns a new ContextHandler with the given attributes.

func (ErrorWarnHandler) WithGroup

func (h ErrorWarnHandler) WithGroup(name string) slog.Handler

WithGroup returns a new ContextHandler with the given group name.

type OtelHandler

type OtelHandler struct {
	slog.Handler
}

OtelHandler is a slog.Handler that adds attributes to the log record from the context.

func (OtelHandler) Handle

func (h OtelHandler) Handle(ctx context.Context, record slog.Record) error

Handle adds attributes from the context to the log record.

func (OtelHandler) WithAttrs

func (h OtelHandler) WithAttrs(attrs []slog.Attr) slog.Handler

WithAttrs returns a new OtelHandler with the given attributes.

func (OtelHandler) WithGroup

func (h OtelHandler) WithGroup(name string) slog.Handler

WithGroup returns a new OtelHandler with the given group name.

Jump to

Keyboard shortcuts

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