Slog
Integrate slog with Sentry to capture and send structured logs.
For a quick reference, there is a complete example at the Go SDK source code repository.
Go API documentation for the sentryslog package is also available.
Slog structured logging is supported in Sentry Go SDK version 0.34.0 and above.
go get github.com/getsentry/sentry-go
go get github.com/getsentry/sentry-go/slog
err := sentry.Init(sentry.ClientOptions{
Dsn: "___PUBLIC_DSN___",
// Enable printing of SDK debug messages.
// Useful when getting started or trying to figure something out.
Debug: true,
// Adds request headers and IP for users,
// visit: https://docs.sentry.io/platforms/go/data-management/data-collected/ for more info
SendDefaultPII: true,
EnableLogs: true,
// ___PRODUCT_OPTION_START___ performance
EnableTracing: true,
// Set TracesSampleRate to 1.0 to capture 100%
// of transactions for tracing.
TracesSampleRate: 1.0,
// ___PRODUCT_OPTION_END___ performance
})
if err != nil {
log.Fatalf("sentry.Init: %s", err)
}
// Flush buffered events before the program terminates.
// Set the timeout to the maximum duration the program can afford to wait.
defer sentry.Flush(2 * time.Second)
sentryslog accepts a sentryslog.Option struct to control which records are sent to Sentry and how they're enriched before sending.
| Field | Type | Description | Default |
|---|---|---|---|
EventLevel | []slog.Level | Log levels to capture as Sentry events | []slog.Level{slog.LevelError, sentryslog.LevelFatal} |
LogLevel | []slog.Level | Log levels to capture as Sentry log entries | []slog.Level{slog.LevelDebug, slog.LevelInfo, slog.LevelWarn, slog.LevelError, sentryslog.LevelFatal} |
Hub | *sentry.Hub | Hub to use when capturing events | Current hub |
Converter | Converter | Custom converter for turning log records into Sentry events | sentryslog.DefaultConverter |
AttrFromContext | []func(context.Context) []slog.Attr | Functions that add attributes from the current context | None |
AddSource | bool | Include file and line information in Sentry output | false |
ReplaceAttr | func([]string, slog.Attr) slog.Attr | Rewrite or filter attributes before sending | None |
This example sends ERROR records as events and INFO/WARN records as structured logs.
package main
import (
"context"
"log/slog"
sentryslog "github.com/getsentry/sentry-go/slog"
)
func main() {
ctx := context.Background()
handler := sentryslog.Option{
EventLevel: []slog.Level{slog.LevelError, sentryslog.LevelFatal},
LogLevel: []slog.Level{slog.LevelInfo, slog.LevelWarn},
AddSource: true,
}.NewSentryHandler(ctx)
logger := slog.New(handler)
logger.Info("Application started", "service", "image-processor")
logger.Warn("Cache miss", "key", "thumbnail:123")
logger.Error("Image processing failed", "image_id", "img_123")
}
If you also want to keep writing logs somewhere else, Go 1.26+ includes slog.NewMultiHandler.
package main
import (
"context"
"log/slog"
"os"
sentryslog "github.com/getsentry/sentry-go/slog"
)
func main() {
ctx := context.Background()
sentryHandler := sentryslog.Option{
LogLevel: []slog.Level{slog.LevelInfo, slog.LevelWarn, slog.LevelError},
}.NewSentryHandler(ctx)
textHandler := slog.NewTextHandler(os.Stdout, nil)
logger := slog.New(slog.NewMultiHandler(sentryHandler, textHandler))
logger.Info("Application started", "service", "image-processor")
}
In order to properly attach the correct trace with each log entry, a context.Context is required. If you're using logs combined with tracing, you should pass the correct context to properly attach each trace with the appropriate logs.
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").