Skip to content

samber/slog-nats

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

37 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

slog: NATS handler

tag Go Version GoDoc Build Status Go report Coverage Contributors License

A NATS Handler for slog Go library.

See also:

HTTP middlewares:

Loggers:

Log sinks:

πŸš€ Install

go get github.com/samber/slog-nats

Compatibility: go >= 1.21

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

πŸ’‘ Usage

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

Handler options

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

	// NATS client
	EncodedConnection *nats.EncodedConn
	Subject           string

	// optional: customize NATS 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
}

Other global parameters:

slognats.SourceKey = "source"
slognats.ContextKey = "extra"
slognats.RequestKey = "request"
slognats.ErrorKeys = []string{"error", "err"}
slognats.RequestIgnoreHeaders = false

Supported attributes

The following attributes are interpreted by slognats.DefaultConverter:

Atribute name slog.Kind Underlying type
"user" group (see below)
"error" any error
"request" any *http.Request
other attributes *

Other attributes will be injected in extra field.

Users must be of type slog.Group. Eg:

slog.Group("user",
    slog.String("id", "user-123"),
    slog.String("username", "samber"),
    slog.Time("created_at", time.Now()),
)

Example

import (
	"context"
	"fmt"
	"time"

	slognats "github.com/samber/slog-nats"
	"github.com/nats-io/nats.go"

	"log/slog"
)

func main() {
	// docker-compose up -d
	// brew tap nats-io/nats-tools
	// brew install nats-io/nats-tools/nats
	// nats subscribe test

	uri := "nats://127.0.0.1:4222"

	nc, err := nats.Connect(uri)
	if err != nil {
		panic(err)
	}

	ec, err := nats.NewEncodedConn(nc, nats.JSON_ENCODER)
	if err != nil {
		panic(err)
	}

	defer nc.Flush()
	defer nc.Close()

	logger := slog.New(slognats.Option{Level: slog.LevelDebug, EncodedConnection: ec, Subject: "test"}.NewNATSHandler())
	logger = logger.With("release", "v1.0.0")

	logger.
		With(
			slog.Group("user",
				slog.String("id", "user-123"),
				slog.Time("created_at", time.Now()),
			),
		).
		With("error", fmt.Errorf("an error")).
		Error("a message")
}

NATS message:

{
  	"level": "ERROR",
	"logger.name": "samber/slog-nats",
	"logger.version": "1.0.0",
	"message": "a message",
	"timestamp": "2023-04-30T01:33:21.676768Z",
	"error": {
		"error": "an error",
		"kind": "*errors.errorString",
		"stack": null
	},
	"extra": {
		"release": "v1.0.0"
	},
	"user": {
		"created_at": "2023-04-30T01:33:21.676704Z",
		"id": "user-123"
	}
}

Tracing

Import the samber/slog-otel library.

import (
	slognats "github.com/samber/slog-nats"
	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(
		slognats.Option{
			// ...
			AttrFromContext: []func(ctx context.Context) []slog.Attr{
				slogotel.ExtractOtelAttrFromContext([]string{"tracing"}, "trace_id", "span_id"),
			},
		}.NewNATSHandler(),
	)

	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.

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy