Skip to content

alistairjevans/slog-betterstack

Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

49 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

slog: Betterstack handler

tag Go Version GoDoc Build Status Go report Coverage Contributors License

A Betterstack Handler for slog Go library.

See also:

HTTP middlewares:

Loggers:

Log sinks:

πŸš€ Install

go get github.com/samber/slog-betterstack

Compatibility: go >= 1.21

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

πŸ’‘ Usage

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

Handler options

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

  // token
  Token   string
  // optional: endpoint
  Endpoint string
  // default: 10s
  Timeout time.Duration

  // optional: minimum delay after the last record before a batch is sent (default: 1s)
  MinBatchWait time.Duration
  // optional: maximum time a record can be buffered before being sent (default: 3s)
  MaxBatchWait time.Duration
  // optional: maximum number of records in a batch (default: 1000)
  MaxBatchSize int
  // optional: maximum uncompressed size of a batch, in bytes (default: 5MB)
  MaxBatchByteSize int
  // optional: disable gzip compression of request bodies
  DisableCompression bool

  // optional: customize record builder
  Converter Converter
  // optional: custom marshaler, called once per batch with the full
  // []map[string]any payload; its output is sent as the request body
  Marshaler func(v any) ([]byte, error)
  // 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:

slogbetterstack.SourceKey = "runtime"
slogbetterstack.ContextKey = "context"
slogbetterstack.ErrorKeys = []string{"error", "err"}

Batching

Records are buffered and sent to Betterstack in gzip-compressed batches (unless DisableCompression is set), by a background goroutine. A batch is sent when:

  • it holds MaxBatchSize records ;
  • or it reaches MaxBatchByteSize bytes (uncompressed) ;
  • or no record has been logged for MinBatchWait ;
  • or the oldest buffered record has been waiting for MaxBatchWait.

The background goroutine is stopped automatically once the handler is garbage collected. Call Close() before exiting, to make sure the last buffered records are sent:

handler := slogbetterstack.Option{Token: "xxxxx"}.NewBetterstackHandler()
defer handler.(*slogbetterstack.BetterstackHandler).Close()

Example

import (
	"fmt"
	"net/http"
	"time"

	slogbetterstack "github.com/samber/slog-betterstack"

	"log/slog"
)

func main() {
	handler := slogbetterstack.Option{Level: slog.LevelDebug, Token: "xxxxx"}.NewBetterstackHandler()
	defer handler.(*slogbetterstack.BetterstackHandler).Close()

	logger := slog.New(handler)
	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", slog.Int("count", 1))
}

Tracing

Import the samber/slog-otel library.

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

	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.

Releases

Packages

Contributors

Languages