clog

package module
v0.0.0-...-871c1e5 Latest Latest
Warning

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

Go to latest
Published: Jan 14, 2026 License: Apache-2.0 Imports: 7 Imported by: 73

README

clog, fmt.Format semantics and slog access via context

The log/slog package is very well-designed and extendable, but it's not fully context-oriented. You'll need to either pass the logger around everywhere or use a global logger even if the code where you use it is fully context-oriented. Furthermore, it doesn't provide the very convenient fmt.Sprintf semantics for logging.

clog

The clog package provides the following functionality:

  • A WithLogger function that returns a context with the logger attached.
  • Global functions needed to use the logger, such as Info(context.Context, string, ...any) and With(context.Context, ...any) context.Context
  • Functions like Errorf, Warningf, Infof, Debugf and Tracef that understans standard fmt.Format semantics.
  • A CondensedHandler that outputs a condensed version of the log message, using key=value pairs only for extra slog.Attr values. This handler also defers the creation of the log message when the message stems from a function that uses fmt.Format semantics so that it is produced with fmt.Fprintf on an internal buffer.

The clog package has no external dependencies.

Usage

package main
import (
	"context"
	"log/slog"
	"os"

	"github.com/telepresenceio/clog"
	"github.com/telepresenceio/clog/handler"
)

func main() {
	h := handler.NewText(
		handler.Output(os.Stdout), handler.TimeFormat("15:04:05.0000"), handler.EnabledLevel(clog.LevelDebug))
	ctx := clog.WithLogger(context.Background(), slog.New(h))
	clog.Infof(ctx, "Hello, %s!", "world")
}

Documentation

Index

Examples

Constants

View Source
const LevelTrace = slog.LevelDebug - 4

LevelTrace is the most verbose log level. When used, the output will also contain file:line information.

Variables

View Source
var LevelStrings = []string{
	"ERROR", "WARN", "INFO", "DEBUG", "TRACE",
}

LevelStrings is the list of log level strings in order of increasing verbosity.

Functions

func Debug

func Debug(ctx context.Context, args ...any)

Debug is similar to slog.Logger.DebugContext on the context logger. The first argument is converted using fmt.Sprint and used as the log message. Remaining args are handled according to slog.Logger.Log.

func DebugAttrs

func DebugAttrs(ctx context.Context, message string, attrs ...slog.Attr)

DebugAttrs is similar to slog.Logger.LogAttrs on the context logger, called with slog.LevelDebug.

func Debugf

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

Debugf is similar to slog.Logger.DebugContext on the context logger, called with a message formatted with fmt.Sprintf.

func Enabled

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

func Error

func Error(ctx context.Context, args ...any)

Error is similar to slog.Logger.ErrorContext on the context logger. The first argument is converted using fmt.Sprint and used as the log message. Remaining args are handled according to slog.Logger.Log.

func ErrorAttrs

func ErrorAttrs(ctx context.Context, message string, attrs ...slog.Attr)

ErrorAttrs is similar to slog.Logger.LogAttrs on the context logger, called with slog.LevelError.

func Errorf

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

Errorf is similar to slog.Logger.ErrorContext on the context logger, called with a message formatted with fmt.Sprintf.

func Info

func Info(ctx context.Context, args ...any)

Info is similar to slog.Logger.InfoContext on the context logger. The first argument is converted using fmt.Sprint and used as the log message. Remaining args are handled according to slog.Logger.Log.

func InfoAttrs

func InfoAttrs(ctx context.Context, message string, attrs ...slog.Attr)

InfoAttrs is similar to slog.Logger.LogAttrs on the context logger, called with slog.LevelInfo.

func Infof

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

Infof is similar to slog.Logger.InfoContext on the context logger, called with a message formatted with fmt.Sprintf.

Example
package main

import (
	"context"
	"log/slog"
	"os"
	"time"

	"github.com/telepresenceio/clog"
	"github.com/telepresenceio/clog/internal"
)

func fakeTime() {
	internal.TimeNow = func() time.Time { return time.Date(2026, 1, 2, 3, 4, 5, 678900000, time.UTC) }
}

func main() {
	fakeTime()
	lg := slog.New(slog.NewTextHandler(os.Stdout, nil))
	ctx := clog.WithLogger(context.Background(), lg)
	clog.Infof(ctx, "Hello, %s!", "world")
}
Output:
time=2026-01-02T03:04:05.678Z level=INFO msg="Hello, world!"
Example (WithAttrsAndGroups)
package main

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

	"github.com/telepresenceio/clog"
	"github.com/telepresenceio/clog/handler"
	"github.com/telepresenceio/clog/internal"
)

func fakeTime() {
	internal.TimeNow = func() time.Time { return time.Date(2026, 1, 2, 3, 4, 5, 678900000, time.UTC) }
}

func main() {
	fakeTime()
	lg := slog.New(handler.NewText(handler.TimeFormat("15:04:05.0000"), handler.EnabledLevel(slog.LevelInfo)))
	topCtx := clog.WithLogger(context.Background(), lg)

	clog.Debug(topCtx, "Hello, world!")

	clog.Infof(topCtx, "Hello, %s!", "world")

	ctx := clog.WithGroup(topCtx, "group")
	clog.Infof(ctx, "Hello, %s!", "world")

	clog.Info(topCtx, "Hello, world!", slog.Group("group", slog.Group("hello", "this", "value")))

	clog.Info(topCtx, "Hello, world!", slog.GroupAttrs("group", slog.String("this", "value"), slog.Group("hello", "that", "thing", "is", `so "cool"`)))

	clog.Info(topCtx, "Hello, world!", slog.GroupAttrs("group", slog.String("this", "value"), slog.Group("hello", slog.Group("that", "thing", "is cool"))))

	clog.Info(clog.With(topCtx, "what", "world"), "Hello!")

	clog.Info(topCtx, "Hello, world!", slog.String("this", "value"), slog.Group("hello", slog.Group("that", "thing", "is cool")))

	clog.Infof(ctx, "Hello, world! %s", slog.GroupAttrs("group", slog.String("this", "value"), slog.Group("hello", slog.Group("that", "thing", `is "cool"`))))

	clog.Infof(ctx, "Hello, world! %s", slog.Float64("value", 2.24))

	clog.Infof(ctx, "Hello, world! value: %.3f", 2.24)

}
Output:
03:04:05.6789 INFO  Hello, world!
03:04:05.6789 INFO  group: Hello, world!
03:04:05.6789 INFO  group/hello: Hello, world! : this=value
03:04:05.6789 INFO  group: Hello, world! : this=value hello={that=thing is="so \"cool\""}
03:04:05.6789 INFO  group: Hello, world! : this=value hello/that={thing="is cool"}
03:04:05.6789 INFO  Hello! : what=world
03:04:05.6789 INFO  Hello, world! : this=value hello/that={thing="is cool"}
03:04:05.6789 INFO  group: Hello, world! group=[this=value hello=[that=[thing=is "cool"]]]
03:04:05.6789 INFO  group: Hello, world! value=2.24
03:04:05.6789 INFO  group: Hello, world! value: 2.240

func Log

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

Log is similar to calling slog.Logger.Log on the context logger. The first argument is converted using fmt.Sprint and used as the log message. Remaining args are handled according to slog.Logger.Log.

func LogAttrs

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

LogAttrs is similar to slog.Logger.LogAttrs on the context logger.

func Logf

func Logf(ctx context.Context, level slog.Level, format string, args ...any)

Logf is similar to slog.Logger.Log on the context logger, called with a message formatted with fmt.Sprintf.

func Logger

func Logger(ctx context.Context) *slog.Logger

Logger returns the logger from the context, or the default logger if none is set.

func MustParseLevel

func MustParseLevel(s string) slog.Level

MustParseLevel is like ParseLevel, but panics if the string is invalid.

func ParseLevel

func ParseLevel(s string) (slog.Level, error)

ParseLevel parses a log level string into a Level. It panics if the lowercased version of the string is not one of "trace", "debug", "info", "warn", "warning", or "error".

func SetTreeLevel

func SetTreeLevel(ctx context.Context, level slog.Level) bool

SetTreeLevel sets the root slog.Level for the context where the WithTreeLevel was set, which might be the provided context itself or any parent of that context. Any children of context holding the root level is affected by this change.

func StdLogger

func StdLogger(ctx context.Context, level slog.Level) *stdLog.Logger

func Trace

func Trace(ctx context.Context, args ...any)

Trace is similar to slog.Logger.Log on the context logger, called with slog.LevelTrace. The first argument is converted using fmt.Sprint and used as the log message. Remaining args are handled according to slog.Logger.Log.

func TraceAttrs

func TraceAttrs(ctx context.Context, message string, attrs ...slog.Attr)

TraceAttrs is similar to slog.Logger.LogAttrs on the context logger, called with slog.LevelTrace.

func Tracef

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

Tracef is similar to slog.Logger.Log on the context logger, called with slog.LevelTrace and a message formatted with fmt.Sprintf.

func TreeEnabled

func TreeEnabled(ctx context.Context, level slog.Level) bool

TreeEnabled returns true if the root slog.Level is enabled for the given context. This function is suitable as an argument to a [handler.LevelEnabler] option.

func Warn

func Warn(ctx context.Context, args ...any)

Warn is similar to slog.Logger.WarnContext on the context logger. The first argument is converted using fmt.Sprint and used as the log message. Remaining args are handled according to slog.Logger.Log.

func WarnAttrs

func WarnAttrs(ctx context.Context, message string, attrs ...slog.Attr)

WarnAttrs is similar to slog.Logger.LogAttrs on the context logger, called with slog.LevelWarn.

func Warnf

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

Warnf is similar to slog.Logger.WarnContext on the context logger, called with a message formatted with fmt.Sprintf.

func With

func With(ctx context.Context, args ...any) context.Context

With creates a clone of the context logger, adds the attributes, and assigns the clone to a child context which is returned.

func WithGroup

func WithGroup(ctx context.Context, group string) context.Context

WithGroup creates a clone of the context logger, adds the group, and assigns the clone to a child context which is returned.

func WithLogger

func WithLogger(ctx context.Context, logger *slog.Logger) context.Context

WithLogger assigns the logger to a child context which is returned.

func WithTreeLevel

func WithTreeLevel(ctx context.Context, level slog.Level) context.Context

WithTreeLevel assigns the log level root to a child context which is returned. Children of this context will inherit the level.

Types

type FormatHandler

type FormatHandler = internal.FormatHandler

type LevelWithTrace

type LevelWithTrace slog.Level

LevelWithTrace redefines slog.Level with an UnmarshalText to support the "trace" log level. It's suitable when used as a field that well be subjected to automatic parsing but shouldn't otherwise be used. Use `slog.Level` whenever possible.

func (LevelWithTrace) MarshalText

func (l LevelWithTrace) MarshalText() ([]byte, error)

MarshalText implements encoding.TextMarshaler.

func (LevelWithTrace) String

func (l LevelWithTrace) String() (s string)

func (*LevelWithTrace) UnmarshalText

func (l *LevelWithTrace) UnmarshalText(value []byte) error

UnmarshalText will unmarshal a log level string into a Level. An error is returned if the string is not one of "TRACE", "DEBUG", "INFO", "WARN", or "ERROR" using case-insensitive comparison.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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