Logrus
Integrate Logrus with Sentry to capture structured logs.
For a quick reference, there is a complete example at the Go SDK source code repository.
Go API documentation for the sentrylogrus package is also available.
Logrus 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/logrus
go get github.com/getsentry/sentry-go
go get github.com/getsentry/sentry-go/logrus
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
})
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)
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
})
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)
sentrylogrus provides two types of hooks to configure the integration with Sentry. Both hooks accept these options:
- Levels: A slice of
logrus.Levelspecifying which log levels to capture - ClientOptions: Standard
sentry.ClientOptionsfor configuration
To integrate Sentry with Logrus, configure the log hook with the levels you want to send as structured logs.
// Initialize Sentry SDK
if err := sentry.Init(sentry.ClientOptions{
Dsn: "___PUBLIC_DSN___",
}); err != nil {
log.Fatalf("Sentry initialization failed: %v", err)
}
logger := logrus.New()
logger.Level = logrus.DebugLevel
logger.Out = os.Stderr
// Get the Sentry client from the current hub
hub := sentry.CurrentHub()
client := hub.Client()
if client == nil {
log.Fatalf("Sentry client is nil")
}
// Send selected log levels as structured logs.
logHook := sentrylogrus.NewLogHookFromClient(
[]logrus.Level{logrus.InfoLevel, logrus.WarnLevel, logrus.ErrorLevel},
client,
)
defer logHook.Flush(5 * time.Second)
logger.AddHook(logHook)
// Flush before calling os.Exit(1) when using logger.Fatal.
logrus.RegisterExitHandler(func() {
logHook.Flush(5 * time.Second)
})
// Sending an info-level log to Sentry.
logger.Infof("Application has started")
// Example of logging with attributes
logger.WithField("user", "test-user").Error("An error occurred")
// Sending an error-level log to Sentry.
logger.Errorf("oh no!")
// Fatal also sends an error level log to Sentry, while also terminating the current process.
logger.Fatalf("can't continue...")
// Initialize Sentry SDK
if err := sentry.Init(sentry.ClientOptions{
Dsn: "___PUBLIC_DSN___",
}); err != nil {
log.Fatalf("Sentry initialization failed: %v", err)
}
logger := logrus.New()
logger.Level = logrus.DebugLevel
logger.Out = os.Stderr
// Get the Sentry client from the current hub
hub := sentry.CurrentHub()
client := hub.Client()
if client == nil {
log.Fatalf("Sentry client is nil")
}
// Send selected log levels as structured logs.
logHook := sentrylogrus.NewLogHookFromClient(
[]logrus.Level{logrus.InfoLevel, logrus.WarnLevel, logrus.ErrorLevel},
client,
)
defer logHook.Flush(5 * time.Second)
logger.AddHook(logHook)
// Flush before calling os.Exit(1) when using logger.Fatal.
logrus.RegisterExitHandler(func() {
logHook.Flush(5 * time.Second)
})
// Sending an info-level log to Sentry.
logger.Infof("Application has started")
// Example of logging with attributes
logger.WithField("user", "test-user").Error("An error occurred")
// Sending an error-level log to Sentry.
logger.Errorf("oh no!")
// Fatal also sends an error level log to Sentry, while also terminating the current process.
logger.Fatalf("can't continue...")
You have two ways to create a new LogHook. Either by using sentrylogrus.NewLogHook() and passing the sentry.ClientOptions, or by using sentrylogrus.NewLogHookFromClient() and passing an already created sentry.Client. These hook captures log entries and send them to Sentry's structured logging system.
logHook, err := sentrylogrus.NewLogHook(
[]logrus.Level{logrus.InfoLevel, logrus.WarnLevel},
sentry.ClientOptions{
Dsn: "___PUBLIC_DSN___",
},
)
logHook, err := sentrylogrus.NewLogHook(
[]logrus.Level{logrus.InfoLevel, logrus.WarnLevel},
sentry.ClientOptions{
Dsn: "___PUBLIC_DSN___",
},
)
Use NewLogHookFromClient if you've already initialized the Sentry SDK.
if err := sentry.Init(sentry.ClientOptions{
Dsn: "___PUBLIC_DSN___",
}); err != nil {
log.Fatalf("Sentry initialization failed: %v", err)
}
hub := sentry.CurrentHub()
client := hub.Client()
if client != nil {
logHook := sentrylogrus.NewLogHookFromClient(
[]logrus.Level{logrus.InfoLevel, logrus.WarnLevel},
client,
)
} else {
log.Fatalf("Sentrylogrus initialization failed: nil client")
}
if err := sentry.Init(sentry.ClientOptions{
Dsn: "___PUBLIC_DSN___",
}); err != nil {
log.Fatalf("Sentry initialization failed: %v", err)
}
hub := sentry.CurrentHub()
client := hub.Client()
if client != nil {
logHook := sentrylogrus.NewLogHookFromClient(
[]logrus.Level{logrus.InfoLevel, logrus.WarnLevel},
client,
)
} else {
log.Fatalf("Sentrylogrus initialization failed: nil client")
}
Logrus sends records as structured logs. To capture an error as an issue, call sentry.CaptureException or sentry.CaptureMessage explicitly.
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").