Giter VIP home page Giter VIP logo

slog-sentry's Introduction

slog: Sentry handler

tag Go Version GoDoc Build Status Go report Coverage Contributors License

A Sentry Handler for slog Go library.

See also:

HTTP middlewares:

Loggers:

Log sinks:

๐Ÿš€ Install

go get github.com/samber/slog-sentry/v2

Compatibility: go >= 1.21

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

๐Ÿ’ก Usage

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

Handler options

type Option struct {
    // Level sets the minimum log level to capture and send to Sentry.
    // Logs at this level and above will be processed. The default level is debug.
    Level slog.Leveler
    // Hub specifies the Sentry Hub to use for capturing events.
    // If not provided, the current Hub is used by default.
    Hub *sentry.Hub

    // Converter is an optional function that customizes how log records
    // are converted into Sentry events. By default, the DefaultConverter is used.
    Converter Converter
    // AttrFromContext is an optional slice of functions that extract attributes
    // from the context. These functions can add additional metadata to the log entry.
    AttrFromContext []func(ctx context.Context) []slog.Attr

    // AddSource is an optional flag that, when set to true, includes the source
    // information (such as file and line number) in the Sentry event.
    // This can be useful for debugging purposes.
    AddSource bool
    // ReplaceAttr is an optional function that allows for the modification or
    // replacement of attributes in the log record. This can be used to filter
    // or transform attributes before they are sent to Sentry.
ReplaceAttr func(groups []string, a slog.Attr) slog.Attr
}

Other global parameters:

slogsentry.SourceKey = "source"
slogsentry.ContextKey = "extra"
slogsentry.ErrorKeys = []string{"error", "err"}
slogsentry.LogLevels = map[slog.Level]sentry.Level{...}

Supported attributes

The following attributes are interpreted by slogsentry.DefaultConverter:

Atribute name slog.Kind Underlying type
"dist" string
"environment" string
"event_id" string
"platform" string
"release" string
"server_name" string
"tags" group (see below)
"transaction" string
"user" group (see below)
"error" any error
"request" any *http.Request
other attributes *

Other attributes will be injected in context Sentry field.

Users and tags 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()),
)

The Sentry agent is responsible for collecting modules.

Example

import (
    "github.com/getsentry/sentry-go"
    slogsentry "github.com/samber/slog-sentry/v2"
    "log/slog"
)

func main() {
    err := sentry.Init(sentry.ClientOptions{
        Dsn:           myDSN,
        EnableTracing: false,
    })
    if err != nil {
        log.Fatal(err)
    }

    defer sentry.Flush(2 * time.Second)

    logger := slog.New(slogsentry.Option{Level: slog.LevelDebug}.NewSentryHandler())
    logger = logger.
        With("environment", "dev").
        With("release", "v1.0.0")

    // log error
    logger.
        With("category", "sql").
        With("query.statement", "SELECT COUNT(*) FROM users;").
        With("query.duration", 1*time.Second).
        With("error", fmt.Errorf("could not count users")).
        Error("caramba!")

    // log user request
    logger.
        With(
            slog.Group("user",
                slog.String("id", "user-123"),
                slog.Time("created_at", time.Now()),
            ),
        ).
        With("request", httpRequest)
        With("status", 200).
        Info("received http request")
}

Tracing

Import the samber/slog-otel library.

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

	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.

slog-sentry's People

Contributors

ferhatelmas avatar samber avatar topi314 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

slog-sentry's Issues

Bug: "error" attribute always converts to map

Hello Mr. Samber. Thank you for your work, very appreciate you for this package

In current implementation I can't achieve stack trace in my sentry panel
And its seems what in default converter any errors converts to map, so stack is gone

At my screenshot, at 3rd step, "ok" is always false, because previously all error was converted to map

image

Adding slog Handler in Sentry

Hi,

I'm a contributor at Go SDK for sentry.

Instead of me implementing this in the Sentry repository, would you mind creating a Pull Request in Sentry-Go to add this support?

Thanks!

bug: func(slog.Attr) bool value in argument to record.Attrs

Hello Samber!

Thank you for your package, great docs!

I was wondering whether there is a bug in the converter.go as per:
/go/pkg/mod/github.com/samber/[email protected]/converter.go:28:15: cannot use func(attr slog.Attr) {โ€ฆ} (value of type func(attr slog.Attr)) as func(slog.Attr) bool value in argument to record.Attrs

To reproduce

func main() {
	err := sentry.Init(sentry.ClientOptions{
		Dsn: "my dsn",
		// Debug: true,
		// Set TracesSampleRate to 1.0 to capture 100%
		// of transactions for performance monitoring.
		// We recommend adjusting this value in production,
		TracesSampleRate: 1.0,
	})
	if err != nil {
		log.Fatal(fmt.Sprintf("cannot initialise sentry %s", err))
	}

	handler := slogsentry.Option(slogsentry.Option{Level: slog.LevelInfo}).NewSentryHandler()

	logger := slog.New(handler)
	logger = logger.
		With("environment", "dev").
		With("release", "v1.0.0")

	slog.SetDefault(logger)

	slog.Error("slog error", "key", "value")
}

OS: MacOs 11.7.3
GO version: go version go1.20.3 darwin/amd64

Any thoughts?
Thank you!

Put extra attributes in Sentry context instead of extra

First of all thanks for your slog plugins! I have a question about the Sentry plugin: You are currently putting all non-recognized log attributes into the Extra field of the Sentry Event struct in the DefaultConverter. However, looking at the Sentry documentation, it seems like they should go into Contexts instead, as Extra has been deprecated.

To quote:

Additional Data is deprecated in favor of structured contexts.

Sentry used to support adding unstructured "Additional Data" via setExtra.

Was it a conscious choice to put it in Extra? (Groupings are also supported in Context where in Extra they are not)

Feature Request: Breadcrumbs

Hi, I'd like to have the ability for this package to also send Sentry breadcrumbs when the user logs at a certain level, for example logger.Info

Invalid ErrorKey default value

This looks very wrong:

converter.go:15

var ContextKey = "extra"
var ErrorKey = "extra"

Please default ErrorKey to "error" again

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.