zlog

package module
v0.4.5 Latest Latest
Warning

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

Go to latest
Published: Apr 5, 2024 License: MIT Imports: 20 Imported by: 0

README

zlog - JSON structured handler/logger for Golang slog

GoDoc Go Report Card Build Status Coverage License

Features

  • JSON Structured logging
  • Logger with format method(printf-style)
  • Development mode with human-friendly output
  • WithCallerSkip to skip caller
  • Context extractor for Record context
  • Custom time formatter for buildin attribute time value

Usage

More examples can be found in examples.

Because zlog implements the slog.Handler interface, you can create a zlog.JSONHander and use slog.Logger.

import (
    "context"
    "log/slog"

    "github.com/icefed/zlog"
)

func main() {
    h := zlog.NewJSONHandler(&zlog.Config{
		HandlerOptions: slog.HandlerOptions{
			Level: slog.LevelDebug,
		},
    })
    log := slog.New(h)

    log.Info("hello world")
    // ...
    log.With(slog.String("app", "test")).
        Error("db execution failed", "error", err)
    log.LogAttrs(context.Background(), slog.LevelInfo, "this is a info message", slog.String("app", "test"))
}

Or you can use zlog.Logger, which implements all slog.Logger methods and is compatible. Then you can use Infof and other methods that support format format.

import (
	"context"
	"log/slog"

	"github.com/icefed/zlog"
)

func main() {
	h := zlog.NewJSONHandler(&zlog.Config{
		HandlerOptions: slog.HandlerOptions{
			Level: slog.LevelDebug,
		},
	})
	log := zlog.New(h)
	log.Info("hello world")

	log.Log(context.Background(), slog.LevelInfo, "this is a info message")
	// ...
	log.Debugf("get value %s from map by key %s", v, k)
}
Development mode

Development mode, like zap development, outputs buildin attributes in Text format for better readability. If development mode is enabled and writer is a terminal, the level field will be printed in color.

package main

import (
	"log/slog"

	"github.com/icefed/zlog"
)

func main() {
	// start development mode with Config
	h := zlog.NewJSONHandler(&zlog.Config{
		HandlerOptions: slog.HandlerOptions{
			Level: slog.LevelDebug,
		},
		Development: true,
	})

	// turn on development mode with WithOptions
	h = h.WithOptions(zlog.WithDevelopment(true))
	log := zlog.New(h)

	log.Debug("Processing data file", "file", "data.json")
	log.Info("Application started successfully",
		slog.String("version", "1.0.0"),
		slog.String("environment", "dev"))
	log.Warn("Deprecated method 'foo()' is being used", slog.Int("warning_code", 123))
	log.Error("Failed to connect to the database", "error_code", 500, "component", "DatabaseConnection")
}

Outputs:

Enable stack trace

Set StacktraceEnabled to true to enable printing log stack trace, the default print slog.LevelError above the level,

h := zlog.NewJSONHandler(&zlog.Config{
    HandlerOptions: slog.HandlerOptions{
        Level: slog.LevelDebug,
    },
    StacktraceEnabled: true,
})

// set custom stacktrace key
h = h.WithOptions(zlog.WithStacktraceKey("stack"))
Custom time formatter

By default, when printing logs, the time field is formatted with RFC3339Milli(2006-01-02T15:04:05.999Z07:00). If you want to modify the format, you can configure TimeFormatter in Config.

h := zlog.NewJSONHandler(&zlog.Config{
    HandlerOptions: slog.HandlerOptions{
        Level: slog.LevelDebug,
    },
    TimeFormatter: func(buf []byte,t time.Time) []byte {
        return t.AppendFormat(buf, time.RFC3339Nano)
    },
})

log := zlog.New(h)
log.Info("this is a log message with RFC3339Nano format")

// use int timestamp format with microsecond precision
log = log.WithOptions(zlog.WithTimeFormatter(func(buf []byte, t time.Time) []byte {
    return strconv.AppendInt(buf, t.UnixMicro(), 10)
}))
log.Info("this is a log message in int timestamp format")

Outputs:

{"time":"2023-09-09T19:02:28.704746+08:00","level":"INFO","msg":"this is a log message with RFC3339Nano format"}
{"time":"1694257348705059","level":"INFO","msg":"this is a log message with int timestamp format"}
Context extractor

We often need to extract the value from the context and print it to the log, for example, an apiserver receives a user request and prints trace and user information to the log.

This example shows how to use the context, and print OpenTelemetry trace in log. If you have an api server that supports OpenTelemetry, you can use this example in your handler middleware and print trace in each log.

package main

import (
	"context"
	"log/slog"

	"go.opentelemetry.io/otel"
	sdktrace "go.opentelemetry.io/otel/sdk/trace"
	"go.opentelemetry.io/otel/sdk/trace/tracetest"
	"go.opentelemetry.io/otel/trace"

	"github.com/icefed/zlog"
)

// traceContextExtractor implement the ContextExtractor, extracts trace context from context
func traceContextExtractor(ctx context.Context) []slog.Attr {
	spanContext := trace.SpanContextFromContext(ctx)
	if spanContext.IsValid() {
		return []slog.Attr{
			slog.Group("trace",
				slog.String("traceID", spanContext.TraceID().String()),
				slog.String("spanID", spanContext.SpanID().String()),
			),
		}
	}
	return nil
}

func parentFun(ctx context.Context, tracer trace.Tracer) {
	ctx, parentSpan := tracer.Start(ctx, "caller1")
	defer parentSpan.End()

	// print log
	slog.InfoContext(ctx, "call parentFun")

	childFun(ctx, tracer)
}

func childFun(ctx context.Context, tracer trace.Tracer) {
	ctx, childSpan := tracer.Start(ctx, "caller2")
	defer childSpan.End()

	// print log
	slog.InfoContext(ctx, "call childFun")
}

func main() {
	// create a logger with traceContextExtractor
	h := zlog.NewJSONHandler(nil)
	h = h.WithOptions(zlog.WithContextExtractor(traceContextExtractor))
	log := slog.New(h)
	slog.SetDefault(log)

	// prepare a call with trace context
	exporter := tracetest.NewInMemoryExporter()
	tracerProvider := sdktrace.NewTracerProvider(
		sdktrace.WithBatcher(exporter),
	)
	otel.SetTracerProvider(tracerProvider)
	tracer := otel.Tracer("api")
	ctx := context.Background()
	parentFun(ctx, tracer)
}

Outputs:

{"time":"2023-09-08T20:12:14.733","level":"INFO","msg":"call parentFun","trace":{"traceID":"95f0717d9da16177176efdbc7c06bfbd","spanID":"7718edf7b2a8388d"}}
{"time":"2023-09-08T20:12:14.733","level":"INFO","msg":"call childFun","trace":{"traceID":"95f0717d9da16177176efdbc7c06bfbd","spanID":"ef83f673951742b0"}}

Benchmarks

Test modified from zap benchmarking suite.

goos: darwin
goarch: arm64
pkg: github.com/icefed/zlog/benchmarks
BenchmarkDisabledWithoutFields/slog-10          1000000000               0.6019 ns/op          0 B/op          0 allocs/op
BenchmarkDisabledWithoutFields/slog_with_zlog-10                1000000000               0.5913 ns/op          0 B/op          0 allocs/op
BenchmarkDisabledWithoutFields/zlog-10                          1000000000               0.5496 ns/op          0 B/op          0 allocs/op
BenchmarkDisabledWithoutFields/slog_with_zap-10                 1000000000               0.8184 ns/op          0 B/op          0 allocs/op
BenchmarkDisabledWithoutFields/zap-10                           1000000000               0.6048 ns/op          0 B/op          0 allocs/op
BenchmarkDisabledWithoutFields/zerolog-10                       1000000000               0.3016 ns/op          0 B/op          0 allocs/op
BenchmarkDisabledAddingFields/slog-10                           57371786               208.7 ns/op           576 B/op          6 allocs/op
BenchmarkDisabledAddingFields/slog_with_zlog-10                 56256844               208.3 ns/op           576 B/op          6 allocs/op
BenchmarkDisabledAddingFields/zlog-10                           58574133               205.8 ns/op           576 B/op          6 allocs/op
BenchmarkDisabledAddingFields/slog_with_zap-10                  58468917               206.9 ns/op           576 B/op          6 allocs/op
BenchmarkDisabledAddingFields/zap-10                            41587197               295.7 ns/op           864 B/op          6 allocs/op
BenchmarkDisabledAddingFields/zerolog-10                        303398799               39.08 ns/op           88 B/op          2 allocs/op
BenchmarkWithoutFields/slog-10                                  47158194               231.9 ns/op             0 B/op          0 allocs/op
BenchmarkWithoutFields/slog_with_zlog-10                        143867673               81.77 ns/op            0 B/op          0 allocs/op
BenchmarkWithoutFields/zlog-10                                  182174908               64.98 ns/op            0 B/op          0 allocs/op
BenchmarkWithoutFields/slog_with_zap-10                         125818678               95.04 ns/op            0 B/op          0 allocs/op
BenchmarkWithoutFields/zap-10                                   169056685               72.34 ns/op            0 B/op          0 allocs/op
BenchmarkWithoutFields/zerolog-10                               348895234               35.03 ns/op            0 B/op          0 allocs/op
BenchmarkAccumulatedContext/slog-10                             51551946               241.8 ns/op             0 B/op          0 allocs/op
BenchmarkAccumulatedContext/slog_with_zlog-10                   138282912               90.81 ns/op            0 B/op          0 allocs/op
BenchmarkAccumulatedContext/zlog-10                             184607311               66.28 ns/op            0 B/op          0 allocs/op
BenchmarkAccumulatedContext/slog_with_zap-10                    132471319               89.32 ns/op            0 B/op          0 allocs/op
BenchmarkAccumulatedContext/zap-10                              167639162               76.73 ns/op            0 B/op          0 allocs/op
BenchmarkAccumulatedContext/zerolog-10                          314418170               36.53 ns/op            0 B/op          0 allocs/op
BenchmarkAddingFields/slog-10                                    4498432              2639 ns/op            3951 B/op         38 allocs/op
BenchmarkAddingFields/slog_with_zlog-10                          9287110              1300 ns/op            1344 B/op         20 allocs/op
BenchmarkAddingFields/zlog-10                                    9383146              1290 ns/op            1344 B/op         20 allocs/op
BenchmarkAddingFields/slog_with_zap-10                           6758552              1776 ns/op            2218 B/op         23 allocs/op
BenchmarkAddingFields/zap-10                                     8615821              1389 ns/op            1508 B/op         18 allocs/op
BenchmarkAddingFields/zerolog-10                                 9067814              1309 ns/op            2031 B/op         15 allocs/op
BenchmarkKVArgs/slog-10                                          4663335              2562 ns/op            3586 B/op         40 allocs/op
BenchmarkKVArgs/slog_with_zlog-10                                9989289              1186 ns/op             978 B/op         22 allocs/op
BenchmarkKVArgs/zlog-10                                         10343742              1171 ns/op             978 B/op         22 allocs/op
BenchmarkKVArgs/slog_with_zap-10                                 7146567              1661 ns/op            1851 B/op         25 allocs/op
BenchmarkKVArgs/zap-10                                           6913246              1730 ns/op            2352 B/op         24 allocs/op
BenchmarkKVArgs/zerolog-10                                       4937739              2431 ns/op            3355 B/op         40 allocs/op
PASS
ok      github.com/icefed/zlog/benchmarks       471.856s

Documentation

Overview

Package zlog implements JSON-structured logging for slog.Handler interface. It provides the ability to print stacktrace, a development mode that renders logs in a user-friendly output like a zap library, flexible custom time formatters and other features, and almost fully compatible with slog.Handler rules, while maintaining high performance.

zlog also provides a Logger for better use the formatted logging methods (printf-style).

Getting Started

Create a JSONHandler with default Config.

handler := zlog.NewJSONHandler(nil)

Use slog.Logger with zlog.JSONHandler.

log := slog.New(handler)
log.Info("hello world", slog.String("foo", "bar"))
log.WithGroup("request").
	With(slog.String("method", "GET")).
	Info("received request", "params", params)

Use zlog.Logger with zlog.JSONHandler.

log := zlog.New(handler)
log.Info("hello world", slog.String("foo", "bar"))
// ...
log.Errorf("Read file %s failed: %s", filePath, err)

Use default zlog.Logger

zlog.Warn("hello world", slog.String("foo", "bar"))

// set the logger you created as the default.
log := zlog.New(handler)
zlog.SetDefault(log)
zlog.Warn("hello world", slog.String("foo", "bar"))

Custom Configuration

Create a JSONHandler with custom Config.

h := zlog.NewJSONHandler(&zlog.Config{
	HandlerOptions: slog.HandlerOptions{
		// enable AddSource
		AddSource: true,
		// set the level
		Level: slog.LevelDebug,
	}
	// enable development mode
	Development: true,
})

// use WithOptions to override the handler Config.
h = h.WithOptions(zlog.WithStacktraceEnabled(true))
log:= slog.New(h)

TraceContext

The Context may contain some values that you want to print in each log. You need to implement the ContextExtractor function, which extracts the value you want and returns []slog.Attr.

The TraceContextExtractor function extracts trace span information from the Context.

func TraceContextExtractor(ctx context.Context) []slog.Attr {
	spanContext := trace.SpanContextFromContext(ctx)
	if spanContext.IsValid() {
		return []slog.Attr{
			slog.Group("trace",
				slog.String("traceID", spanContext.TraceID().String()),
				slog.String("spanID", spanContext.SpanID().String()),
			),
		}
	}
	return nil
}

Index

Examples

Constants

View Source
const RFC3339Milli = "2006-01-02T15:04:05.999Z07:00"

RFC3339Milli define the time format as RFC3339 with millisecond precision.

Variables

This section is empty.

Functions

func Debug

func Debug(msg string, args ...any)

Debug calls Logger.Debug on the default logger.

func DebugContext

func DebugContext(ctx context.Context, msg string, args ...any)

DebugContext calls Logger.DebugContext on the default logger.

func DebugContextf

func DebugContextf(ctx context.Context, format string, args ...any)

DebugContextf calls Logger.DebugContextf on the default logger.

func Debugf

func Debugf(format string, args ...any)

Debugf calls Logger.Debugf on the default logger.

func Error

func Error(msg string, args ...any)

Error calls Logger.Error on the default logger.

func ErrorContext

func ErrorContext(ctx context.Context, msg string, args ...any)

ErrorContext calls Logger.ErrorContext on the default logger.

func ErrorContextf

func ErrorContextf(ctx context.Context, format string, args ...any)

ErrorContextf calls Logger.ErrorContextf on the default logger.

func Errorf

func Errorf(format string, args ...any)

Errorf calls Logger.Errorf on the default logger.

func Info

func Info(msg string, args ...any)

Info calls Logger.Info on the default logger.

func InfoContext

func InfoContext(ctx context.Context, msg string, args ...any)

InfoContext calls Logger.InfoContext on the default logger.

func InfoContextf

func InfoContextf(ctx context.Context, format string, args ...any)

InfoContextf calls Logger.InfoContextf on the default logger.

func Infof

func Infof(format string, args ...any)

Infof calls Logger.Infof on the default logger.

func Log

func Log(ctx context.Context, level slog.Level, msg string, args ...any)

Log calls Logger.Log on the default logger.

func LogAttrs

func LogAttrs(ctx context.Context, level slog.Level, msg string, attrs ...slog.Attr)

LogAttrs calls Logger.LogAttrs on the default logger.

func NewNopHandler

func NewNopHandler() slog.Handler

NewNopHandler creates a slog handler that discards all log messages.

func NewNopSlogger

func NewNopSlogger() *slog.Logger

NewNopSlogger creates a slog logger that discards all log messages.

func SetDefault

func SetDefault(l *Logger)

SetDefault sets the default logger.

func Warn

func Warn(msg string, args ...any)

Warn calls Logger.Warn on the default logger.

func WarnContext

func WarnContext(ctx context.Context, msg string, args ...any)

WarnContext calls Logger.WarnContext on the default logger.

func WarnContextf

func WarnContextf(ctx context.Context, format string, args ...any)

WarnContextf calls Logger.WarnContextf on the default logger.

func Warnf

func Warnf(format string, args ...any)

Warnf calls Logger.Warnf on the default logger.

Types

type AppendTimeFunc added in v0.3.0

type AppendTimeFunc func(buf []byte, t time.Time) []byte

AppendTimeFunc append the formatted value to buf and returns the extended buffer.

type Config

type Config struct {
	// If nil, a default handler is used.
	slog.HandlerOptions

	// Development enables development mode like zap development Logger,
	// that will write logs in human-friendly format,
	// also level will be colored if output is a terminal.
	Development bool

	// Writer is the writer to use. If nil, os.Stderr is used.
	Writer io.Writer

	// TimeFormatter is the time formatter to use for buildin attribute time value. If nil, use format RFC3339Milli as default.
	TimeFormatter AppendTimeFunc

	// built-in attribute keys, use slog's default if not set.
	// https://pkg.go.dev/log/slog#pkg-constants
	TimeKey    string
	LevelKey   string
	MessageKey string
	SourceKey  string

	// StacktraceEnabled enables stack trace for slog.Record.
	StacktraceEnabled bool
	// StacktraceLevel means which slog.Level from we should enable stack trace.
	// Default is slog.LevelError.
	StacktraceLevel slog.Leveler
	// StacktraceKey is the key for stacktrace field, default is "stacktrace".
	StacktraceKey string

	// ContextExtractors will be used in Handler.Handle
	ContextExtractors []ContextExtractor

	// If a group has no Attrs (even if it has a non-empty key), ignore it.
	IgnoreEmptyGroup bool
}

Config the configuration for the JSONHandler.

type ContextExtractor

type ContextExtractor func(context.Context) []slog.Attr

ContextExtractor get attributes from context, that can be used in slog.Handler.

Example (UserContext)
package main

import (
	"context"
	"log/slog"
	"net/http"
	"time"

	"github.com/icefed/zlog"
)

func AuthMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// ...
		// Pretend that we read and parsed the token, and the user authentication succeeded
		ctx := context.WithValue(context.Background(), userKey{}, user{
			Name: "test@test.com",
			Id:   "a2067a0a-6b0b-4ee5-a049-16bdb8ed6ff5",
		})
		next.ServeHTTP(w, r.WithContext(ctx))
	})
}

func LogMiddleware(log *zlog.Logger, next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()

		next.ServeHTTP(w, r)

		duration := time.Since(start)
		log.InfoContext(r.Context(), "Received request",
			slog.String("method", r.Method),
			slog.String("path", r.URL.Path),
			slog.String("duration", duration.String()),
		)
	})
}

func hello(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusOK)
	w.Write([]byte("Hello, World!"))
}

func userContextExtractor(ctx context.Context) []slog.Attr {
	user, ok := ctx.Value(userKey{}).(user)
	if ok {
		return []slog.Attr{
			slog.Group("user", slog.String("name", user.Name), slog.String("id", user.Id)),
		}
	}
	return nil
}

type userKey struct{}
type user struct {
	Name string
	Id   string
}

// The following is an example of printing a user request in http server. The log
// contains user information and can be used as an audit log.

func main() {
	h := zlog.NewJSONHandler(&zlog.Config{
		HandlerOptions: slog.HandlerOptions{
			Level: slog.LevelDebug,
		},
	})
	h = h.WithOptions(zlog.WithContextExtractor(userContextExtractor))
	log := zlog.New(h)

	httpHandler := http.HandlerFunc(hello)
	// set auth middleware
	handler := AuthMiddleware(httpHandler)
	// set log middleware
	handler = LogMiddleware(log, handler)

	log.Info("starting server, listening on port 8080")
	http.ListenAndServe(":8080", handler)

	// Send a request using curl.
	// $ curl http://localhost:8080/api/v1/products
	// Hello, World!

	// Output like:
	// {"time":"2023-09-09T19:51:55.683+08:00","level":"INFO","msg":"starting server, listening on port 8080"}
	// {"time":"2023-09-09T19:52:04.228+08:00","level":"INFO","msg":"Received request","user":{"name":"test@test.com","id":"a2067a0a-6b0b-4ee5-a049-16bdb8ed6ff5"},"method":"GET","path":"/api/v1/products","duration":"6.221µs"}
}
Output:

type JSONHandler

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

JSONHandler implements the slog.Handler interface, transforming r.Record into the JSON format, and follows therules set by slog.Handler.

Additionally, it provides support for the development mode, akin to zap, which allows built-in attributes to be output in a human-friendly format.

func NewJSONHandler

func NewJSONHandler(config *Config) *JSONHandler

NewJSONHandler creates a slog handler that writes log messages as JSON. If config is nil, a default configuration is used.

func (*JSONHandler) CapturePC added in v0.4.3

func (h *JSONHandler) CapturePC(level slog.Level) bool

CapturePC returns true if the handler has AddSource option enabled or the stacktrace is enabled at the given level. Logger should set PC in the slog.Record if this function returns true.

func (*JSONHandler) Enabled

func (h *JSONHandler) Enabled(_ context.Context, level slog.Level) bool

Enabled reports whether the handler handles records at the given level. The handler ignores records whose level is lower. https://pkg.go.dev/log/slog#Handler

func (*JSONHandler) Handle

func (h *JSONHandler) Handle(ctx context.Context, r slog.Record) error

Handle formats its argument Record as a JSON object on a single line. https://pkg.go.dev/log/slog#Handler

func (*JSONHandler) WithAttrs

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

WithAttrs implements the slog.Handler WithAttrs method. https://pkg.go.dev/log/slog#Handler

func (*JSONHandler) WithGroup

func (h *JSONHandler) WithGroup(name string) slog.Handler

WithGroup implements the slog.Handler WithGroup method. https://pkg.go.dev/log/slog#Handler

func (*JSONHandler) WithOptions

func (h *JSONHandler) WithOptions(opts ...Option) *JSONHandler

WithOptions return a new handler with the given options. Options will override the hander's config.

type Logger

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

func New

func New(h *JSONHandler) *Logger

New creates a new Logger. NewJSONHandler(nil) will be used if h is nil.

func NewNopLogger

func NewNopLogger() *Logger

NewNopLogger creates a nop logger that discards all log messages.

func With

func With(args ...any) *Logger

With calls Logger.With on the default logger.

func WithGroup

func WithGroup(name string) *Logger

WithGroup calls Logger.WithGroup on the default logger.

func (*Logger) Debug

func (l *Logger) Debug(msg string, args ...any)

Debug prints log message at the debug level.

func (*Logger) DebugContext

func (l *Logger) DebugContext(ctx context.Context, msg string, args ...any)

DebugContext prints log message at the debug level with context.

func (*Logger) DebugContextf

func (l *Logger) DebugContextf(ctx context.Context, format string, args ...any)

DebugContextf prints log message at the debug level with context, fmt.Sprintf is used to format.

func (*Logger) Debugf

func (l *Logger) Debugf(format string, args ...any)

Debugf prints log message at the debug level, fmt.Sprintf is used to format.

func (*Logger) Enabled

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

Enabled reports whether the handler handles records at the given level.

func (*Logger) Error

func (l *Logger) Error(msg string, args ...any)

Error prints log message at the error level.

func (*Logger) ErrorContext

func (l *Logger) ErrorContext(ctx context.Context, msg string, args ...any)

ErrorContext prints log message at the error level with context.

func (*Logger) ErrorContextf

func (l *Logger) ErrorContextf(ctx context.Context, format string, args ...any)

ErrorContextf prints log message at the error level with context, fmt.Sprintf is used to format.

func (*Logger) Errorf

func (l *Logger) Errorf(format string, args ...any)

Errorf prints log message at the error level, fmt.Sprintf is used to format.

func (*Logger) Handler

func (l *Logger) Handler() *JSONHandler

Handler returns the handler.

func (*Logger) Info

func (l *Logger) Info(msg string, args ...any)

Info prints log message at the info level.

func (*Logger) InfoContext

func (l *Logger) InfoContext(ctx context.Context, msg string, args ...any)

InfoContext prints log message at the info level with context.

func (*Logger) InfoContextf

func (l *Logger) InfoContextf(ctx context.Context, format string, args ...any)

InfoContextf prints log message at the info level with context, fmt.Sprintf is used to format.

func (*Logger) Infof

func (l *Logger) Infof(format string, args ...any)

Infof prints log message at the info level, fmt.Sprintf is used to format.

func (*Logger) Log

func (l *Logger) Log(ctx context.Context, level slog.Level, msg string, args ...any)

Log prints log as a JSON object on a single line with the given level and message. Log follows the rules of slog.Logger.Log, args can be slog.Attr or will be converted to slog.Attr in pairs.

func (*Logger) LogAttrs

func (l *Logger) LogAttrs(ctx context.Context, level slog.Level, msg string, attrs ...slog.Attr)

Logf prints log as a JSON object on a single line with the given level, message and attrs.

func (*Logger) Warn

func (l *Logger) Warn(msg string, args ...any)

Warn prints log message at the warn level.

func (*Logger) WarnContext

func (l *Logger) WarnContext(ctx context.Context, msg string, args ...any)

WarnContext prints log message at the warn level with context.

func (*Logger) WarnContextf

func (l *Logger) WarnContextf(ctx context.Context, format string, args ...any)

WarnContextf prints log message at the warn level with context, fmt.Sprintf is used to format.

func (*Logger) Warnf

func (l *Logger) Warnf(format string, args ...any)

Warnf prints log message at the warn level, fmt.Sprintf is used to format.

func (*Logger) With

func (l *Logger) With(args ...any) *Logger

With returns a new logger with the given arguments.

func (*Logger) WithCallerSkip

func (l *Logger) WithCallerSkip(skip int) *Logger

WithCallerSkip returns a new logger with the given caller skip. argument 'skip' will be added to the caller skip in the logger, which is passed as the first parameter 'skip' when calling runtime.Callers to get the source's pc. If 'skip' is 1, then skip a caller frame, if you have set callerskip, 'skip' can also be negative to subtract callerskip.

func (*Logger) WithGroup

func (l *Logger) WithGroup(name string) *Logger

WithGroup returns a new logger with the given group name.

func (*Logger) WithOptions

func (l *Logger) WithOptions(opts ...Option) *Logger

WithContext returns a new logger with the given handler options.

type Option

type Option interface {
	// contains filtered or unexported methods
}

Option is the option for JSONHandler.

Example (WithOptions)

WithOptions can be used in handler and logger.

package main

import (
	"github.com/icefed/zlog"
)

func main() {
	// use WithOptions in handler
	// first, create a default handler
	h := zlog.NewJSONHandler(nil)

	// set options for handler
	h = h.WithOptions(
		zlog.WithAddSource(true),
		zlog.WithStacktraceEnabled(true),
		zlog.WithDevelopment(true),
	)

	// use WithOptions in logger
	log := zlog.New(h)

	// set options for logger
	log = log.WithOptions(
		zlog.WithAddSource(false),
	)

	// ...
}
Output:

func WithAddSource

func WithAddSource(addSource bool) Option

WithAddSource enables add source field.

func WithContextExtractor

func WithContextExtractor(extractors ...ContextExtractor) Option

WithContextExtractor adds context extractors.

func WithDevelopment

func WithDevelopment(development bool) Option

WithDevelopment enables development mode like zap development Logger.

func WithLevel

func WithLevel(level slog.Leveler) Option

WithLevel sets the level.

func WithReplaceAttr

func WithReplaceAttr(replaceAttr func(groups []string, a slog.Attr) slog.Attr) Option

WithReplaceAttr sets the replaceAttr.

func WithStacktraceEnabled

func WithStacktraceEnabled(enabled bool) Option

WithStacktraceEnabled enables stacktrace for slog.Record.

func WithStacktraceKey

func WithStacktraceKey(key string) Option

WithStacktraceKey sets the key for stacktrace field.

func WithStacktraceLevel

func WithStacktraceLevel(level slog.Leveler) Option

WithStacktraceLevel sets the level for stacktrace.

func WithTimeFormatter

func WithTimeFormatter(formatter func([]byte, time.Time) []byte) Option

WithTimeFormatter sets the time formatter.

func WithWriter

func WithWriter(w io.Writer) Option

WithWriter sets the writer.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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