Zerolog
Capture error events from Zerolog and send them to Sentry. Note: Zerolog does not support Structured Logs.
The zerolog integration sends error events to Sentry but does not support Structured Logs due to architectural limitations:
- The
io.Writerinterface lacks access tocontext.Context, preventing proper per-request hub isolation - In concurrent applications, breadcrumbs from different requests may leak into each other's events
- Related issues: #1178, #1029
For Structured Logs, use our Sentry.Logger or any of the supported integrations instead.
For a complete example, visit the Go SDK source code repository.
Go Dev-style API documentation is also available.
go get github.com/getsentry/sentry-go
go get github.com/getsentry/sentry-go/zerolog
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,
// ___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
// ___PRODUCT_OPTION_START___ logs
EnableLogs: true,
// ___PRODUCT_OPTION_END___ logs
})
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)
sentryzerolog provides options to configure the integration with Sentry. It expects a sentryzerolog.Config that has sentry.ClientOptions and sentryzerolog.Options. The sentryzerolog.Options struct has the following fields:
// Levels specifies the log levels that will trigger event sending to Sentry.
// Only log messages at these levels will be sent as error events. By default,
// the levels are Error, Fatal, and Panic.
Levels []zerolog.Level
// WithBreadcrumbs, when enabled, adds log entries as breadcrumbs in Sentry.
// Breadcrumbs provide a trail of events leading up to an error, which can
// be invaluable for understanding the context of issues.
WithBreadcrumbs bool
// FlushTimeout sets the maximum duration allowed for flushing events to Sentry.
// This is the time limit within which all pending events must be sent to Sentry
// before the application exits. The default timeout is usually 3 seconds.
FlushTimeout time.Duration
The zerolog integration does support sending error events to Sentry:
import (
"errors"
"time"
"os"
"github.com/getsentry/sentry-go"
sentryzerolog "github.com/getsentry/sentry-go/zerolog"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
func main() {
// Initialize Sentry
err := sentry.Init(sentry.ClientOptions{
Dsn: "___PUBLIC_DSN___",
// Note: EnableLogs is for Structured Logs, not zerolog error events
})
if err != nil {
log.Fatal().Err(err).Msg("sentry initialization failed")
}
defer sentry.Flush(2 * time.Second)
// Configure Zerolog to send error events to Sentry
sentryWriter, err := sentryzerolog.New(sentryzerolog.Config{
Options: sentryzerolog.Options{
// These levels will be sent as error events
Levels: []zerolog.Level{zerolog.ErrorLevel, zerolog.FatalLevel, zerolog.PanicLevel},
// Disable breadcrumbs in concurrent applications to prevent leakage
WithBreadcrumbs: false,
FlushTimeout: 3 * time.Second,
},
})
if err != nil {
log.Fatal().Err(err).Msg("failed to create sentry writer")
}
defer sentryWriter.Close()
// Use Sentry writer in Zerolog
log.Logger = log.Output(zerolog.MultiLevelWriter(zerolog.ConsoleWriter{Out: os.Stderr}, sentryWriter))
// This will be sent as an error event to Sentry
log.Error().Msg("This is an error event, not a structured log")
}
To integrate Sentry with Zerolog, you need to set up a custom writer that sends error events to Sentry based on the configured levels.
import (
"errors"
"time"
"os"
"github.com/getsentry/sentry-go"
sentryzerolog "github.com/getsentry/sentry-go/zerolog"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
func main() {
// Initialize Sentry
err := sentry.Init(sentry.ClientOptions{
Dsn: "___PUBLIC_DSN___",
// Adds request headers and IP for users,
// visit: https://docs.sentry.io/platforms/go/data-management/data-collected/ for more info
SendDefaultPII: true,
BeforeSend: func(event *sentry.Event, hint *sentry.EventHint) *sentry.Event {
// Modify or filter events before sending them to Sentry
return event
},
Debug: true,
AttachStacktrace: true,
})
if err != nil {
log.Fatal().Err(err).Msg("sentry initialization failed")
}
defer sentry.Flush(2 * time.Second)
// Configure Zerolog to use Sentry as a writer,
// reusing the already existing client.
sentryWriter, err := sentryzerolog.NewWithHub(sentry.CurrentHub(), sentryzerolog.Options{
Levels: []zerolog.Level{zerolog.ErrorLevel, zerolog.FatalLevel, zerolog.PanicLevel},
WithBreadcrumbs: true,
FlushTimeout: 3 * time.Second,
})
if err != nil {
log.Fatal().Err(err).Msg("failed to create sentry writer")
}
defer sentryWriter.Close()
// Use Sentry writer in Zerolog
log.Logger = log.Output(zerolog.MultiLevelWriter(zerolog.ConsoleWriter{Out: os.Stderr}, sentryWriter))
// Log an InfoLevel entry to STDERR (not sent to Sentry)
log.Info().Msg("Application has started")
// Log an ErrorLevel entry to STDERR and send as error event to Sentry
log.Error().Msg("oh no!")
// Log a FatalLevel entry to STDERR, send as error event to Sentry, and terminate the application
log.Fatal().Err(errors.New("can't continue")).Msg("fatal error occurred")
}
The hubProvider allows you to configure the Sentry hook to use a custom Sentry hub. This can be particularly useful when you want to scope error events to specific goroutines or operations, enabling more precise grouping and context in Sentry.
You can set a custom hubProvider function using the SetHubProvider method:
sentryHook.SetHubProvider(func() *sentry.Hub {
// Create or return a specific Sentry hub
return sentry.NewHub(sentry.CurrentHub().Client(), sentry.NewScope())
})
This ensures that error events from specific contexts or threads use the appropriate Sentry hub and scope.
Use Zerolog as you normally would, and it will automatically send error events at or above the specified levels to Sentry.
Note: Ensure Sentry is flushed before the application exits to avoid losing any pending events.
For concurrent applications (HTTP/gRPC servers), use scoped hubs to link error events to traces. See the hubProvider section above and the Custom Instrumentation documentation for best practices on proper hub management.
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").