Logrus

Logrus is a structured logger for Go, used to log messages in different formats and levels. This guide demonstrates how to integrate Logrus with Sentry to capture and send both logs and events to Sentry.

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.

Copied
go get github.com/getsentry/sentry-go
go get github.com/getsentry/sentry-go/logrus

Copied
err := sentry.Init(sentry.ClientOptions{
    Dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
    // 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,
    //  performance
    EnableTracing: true,
    // Set TracesSampleRate to 1.0 to capture 100%
    // of transactions for tracing.
    TracesSampleRate: 1.0,
    //  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.Level specifying which log levels to capture
  • ClientOptions: Standard sentry.ClientOptions for configuration

To integrate Sentry with Logrus, you can set up both log hooks and event hooks to capture different types of data at various log levels.

Copied
// Initialize Sentry SDK
if err := sentry.Init(sentry.ClientOptions{
    Dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
    EnableLogs:       true,
}); 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")
}

// Create log hook to send logs on Info level
logHook := sentrylogrus.NewLogHookFromClient(
    []logrus.Level{logrus.InfoLevel},
    client,
)

// Create event hook to send events on Error, Fatal, Panic levels
eventHook := sentrylogrus.NewEventHookFromClient(
    []logrus.Level{
        logrus.ErrorLevel,
        logrus.FatalLevel,
        logrus.PanicLevel,
    },
    client,
)

defer eventHook.Flush(5 * time.Second)
defer logHook.Flush(5 * time.Second)
logger.AddHook(eventHook)
logger.AddHook(logHook)

// Flushes before calling os.Exit(1) when using logger.Fatal
// (else all defers are not called, and Sentry does not have time to send the event)
logrus.RegisterExitHandler(func() {
    eventHook.Flush(5 * time.Second)
    logHook.Flush(5 * time.Second)
})

// Info level is sent as a log to Sentry
logger.Infof("Application has started")

// Example of logging with attributes
logger.WithField("user", "test-user").Error("An error occurred")

// Error level is sent as an error event to Sentry
logger.Errorf("oh no!")

// Fatal level is sent as an error event to Sentry and terminates the application
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.

Copied
logHook, err := sentrylogrus.NewLogHook(
    []logrus.Level{logrus.InfoLevel, logrus.WarnLevel},
    sentry.ClientOptions{
        Dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
        EnableLogs: true, // Required for log entries
    },
)

Use NewLogHookFromClient if you've already initialized the Sentry SDK.

Copied
if err := sentry.Init(sentry.ClientOptions{
    Dsn:        "https://examplePublicKey@o0.ingest.sentry.io/0",
    EnableLogs: true,
}); 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")
}

You also have two ways to create a new EventHook. Either by using sentrylogrus.NewEventHook() and passing the sentry.ClientOptions, or by using sentrylogrus.NewEventFromClient() and passing an already created sentry.Client. These hook captures log entries and send them as events. This is helpful for error tracking and alerting.

Copied
eventHook, err := sentrylogrus.NewEventHook(
    []logrus.Level{logrus.ErrorLevel, logrus.FatalLevel, logrus.PanicLevel},
    sentry.ClientOptions{
        Dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
        Debug: true,
        AttachStacktrace: true,
    },
)

Use NewEventHookFromClient if you've already initialized the Sentry SDK.

Copied
if err := sentry.Init(sentry.ClientOptions{
    Dsn:        "https://examplePublicKey@o0.ingest.sentry.io/0",
    EnableLogs: true,
}); err != nil {
    log.Fatalf("Sentry initialization failed: %v", err)
}
hub := sentry.CurrentHub()
client := hub.Client()
if client != nil {
    eventHook := sentrylogrus.NewEventHookFromClient(
        []logrus.Level{logrus.InfoLevel, logrus.WarnLevel},
        client,
    )
} else {
    log.Fatalf("Sentrylogrus initialization failed: nil client")
}

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.

For comprehensive logging setup with Logrus, including advanced configuration options and best practices, see the Go Logs documentation. The Logrus integration shown above provides seamless integration with Sentry's structured logging features.

Was this helpful?
Help improve this content
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").