slogloki

package module
v0.0.0-...-177e68b Latest Latest
Warning

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

Go to latest
Published: Sep 9, 2024 License: MIT Imports: 10 Imported by: 0

README ΒΆ

Forked and fixed to work in 2024.

slog: Loki handler

tag Go Version GoDoc Build Status Go report Coverage Contributors License

A Loki Handler for slog Go library.

See also:

HTTP middlewares:

Loggers:

Log sinks:

πŸš€ Install

go get github.com/samber/slog-loki/v3

Compatibility: go >= 1.21

No breaking changes will be made to exported APIs before v4.0.0.

πŸ’‘ Usage

GoDoc: https://pkg.go.dev/github.com/samber/slog-loki/v3

Handler options
type Option struct {
	// log level (default: debug)
	Level slog.Leveler

	// loki
	Client *loki.Client

	// optional: customize webhook event builder
	Converter Converter
	// optional: fetch attributes from context
	AttrFromContext []func(ctx context.Context) []slog.Attr

	// optional: see slog.HandlerOptions
	AddSource   bool
	ReplaceAttr func(groups []string, a slog.Attr) slog.Attr
}

Attributes will be injected in log payload.

Other global parameters:

slogloki.SourceKey = "source"
slogloki.ErrorKeys = []string{"error", "err"}
slogloki.SubAttributeSeparator = "__"
slogloki.AttributeKeyInvalidCharReplacement = "_"
Example
import (
	"github.com/grafana/loki-client-go/loki"
	slogloki "github.com/samber/slog-loki/v3"
	"log/slog"
)

func main() {
	// setup loki client
	config, _ := loki.NewDefaultConfig("http://localhost:3100/loki/api/v1/push")
	config.TenantID = "xyz"
	client, _ := loki.New(config)

	logger := slog.New(slogloki.Option{Level: slog.LevelDebug, Client: client}.NewLokiHandler())
	logger = logger.
		With("environment", "dev").
		With("release", "v1.0.0")

	// log error
	logger.Error("caramba!")

	// log user signup
	logger.Info("user registration")

	// stop loki client and purge buffers
	client.Stop()
}
Tracing

Import the samber/slog-otel library.

import (
	slogloki "github.com/samber/slog-loki"
	slogotel "github.com/samber/slog-otel"
	"go.opentelemetry.io/otel/sdk/trace"
)

func main() {
	tp := trace.NewTracerProvider(
		trace.WithSampler(trace.AlwaysSample()),
	)
	tracer := tp.Tracer("hello/world")

	ctx, span := tracer.Start(context.Background(), "foo")
	defer span.End()

	span.AddEvent("bar")

	logger := slog.New(
		slogloki.Option{
			// ...
			AttrFromContext: []func(ctx context.Context) []slog.Attr{
				slogotel.ExtractOtelAttrFromContext([]string{"tracing"}, "trace_id", "span_id"),
			},
		}.NewLokiHandler(),
	)

	logger.ErrorContext(ctx, "a message")
}

🀝 Contributing

Don't hesitate ;)

# Install some dev dependencies
make tools

# Run tests
make test
# or
make watch-test

πŸ‘€ Contributors

Contributors

πŸ’« Show your support

Give a ⭐️ if this project helped you!

GitHub Sponsors

πŸ“ License

Copyright Β© 2023 Samuel Berthe.

This project is MIT licensed.

Documentation ΒΆ

Index ΒΆ

Constants ΒΆ

This section is empty.

Variables ΒΆ

View Source
var AttributeKeyInvalidCharReplacement = "_"
View Source
var ErrorKeys = []string{"error", "err"}
View Source
var SourceKey = "source"
View Source
var SubAttributeSeparator = "__"

See:

Functions ΒΆ

func DefaultConverter ΒΆ

func DefaultConverter(addSource bool, replaceAttr func(groups []string, a slog.Attr) slog.Attr, loggerAttr []slog.Attr, groups []string, record *slog.Record) model.LabelSet

Types ΒΆ

type Converter ΒΆ

type Converter func(addSource bool, replaceAttr func(groups []string, a slog.Attr) slog.Attr, loggerAttr []slog.Attr, groups []string, record *slog.Record) model.LabelSet

func NewDataConverter ΒΆ

func NewDataConverter(dataPrefix string, opts ...DataConverterOpt) Converter

type DataConverterOpt ΒΆ

type DataConverterOpt func(*DataConverterOpts)

func DataConverterDataKeyOpt ΒΆ

func DataConverterDataKeyOpt(key string) DataConverterOpt

func DataConverterErrorKeyOpt ΒΆ

func DataConverterErrorKeyOpt(keys ...string) DataConverterOpt

func DataConverterExemptDataPrefixOpt ΒΆ

func DataConverterExemptDataPrefixOpt(prefix string) DataConverterOpt

func DataConverterSourceKeyOpt ΒΆ

func DataConverterSourceKeyOpt(key string) DataConverterOpt

func DataConverterUseImpliedOpt ΒΆ

func DataConverterUseImpliedOpt() DataConverterOpt

func DataConveterSetExemptKeys ΒΆ

func DataConveterSetExemptKeys(keys ...string) DataConverterOpt

type DataConverterOpts ΒΆ

type DataConverterOpts struct {
	ErrorKeys        []string
	SourceKey        string
	DataKey          string
	ExemptDataPrefix string
	ExemptKeys       []string
	UseImplied       bool
}

func DefaultDataConverterOpts ΒΆ

func DefaultDataConverterOpts() *DataConverterOpts

type LokiHandler ΒΆ

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

func (*LokiHandler) Enabled ΒΆ

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

func (*LokiHandler) Handle ΒΆ

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

func (*LokiHandler) WithAttrs ΒΆ

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

func (*LokiHandler) WithGroup ΒΆ

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

type Option ΒΆ

type Option struct {
	// log level (default: debug)
	Level slog.Leveler

	// loki
	Client *loki.Client

	// optional: customize webhook event builder
	Converter Converter
	// optional: fetch attributes from context
	AttrFromContext []func(ctx context.Context) []slog.Attr

	// optional: see slog.HandlerOptions
	AddSource   bool
	ReplaceAttr func(groups []string, a slog.Attr) slog.Attr
}

func (Option) NewLokiHandler ΒΆ

func (o Option) NewLokiHandler() slog.Handler

Creating a Loki client at each `NewLokiHandler` call may lead to connection leak when chaining many operations: `logger.With(...).With(...).With(...).With(...)`

Directories ΒΆ

Path Synopsis

Jump to

Keyboard shortcuts

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