Zap

Zap is a blazing-fast, structured logging library for Go. This guide demonstrates how to integrate zap with Sentry to capture and send logs to Sentry.

For a quick reference, there is a complete example at the Go SDK source code repository.

Go API documentation for the sentryzap package is also available.

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

Copied
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)

sentryzap provides a Core implementation that integrates with zap's logging pipeline. It accepts a struct of sentryzap.Option that allows you to configure how logs are captured and sent to Sentry. The options are:

FieldTypeDescriptionDefault
Level[]zapcore.LevelZap levels to capture and send to Sentry as log entriesAll levels (Debug through Fatal)
AddCallerboolInclude caller info (file, line, function) in logsfalse
FlushTimeouttime.DurationHow long to wait when syncing/flushing logs5 seconds

This example shows how to create a zap logger that sends logs to Sentry.

Copied
package main

import (
    "context"
    "errors"
    "time"

    "github.com/getsentry/sentry-go"
    sentryzap "github.com/getsentry/sentry-go/zap"
    "go.uber.org/zap"
    "go.uber.org/zap/zapcore"
)

func main() {
    // Initialize Sentry with logs enabled
    err := sentry.Init(sentry.ClientOptions{
        Dsn:        "___PUBLIC_DSN___",
        EnableLogs: true,
    })
    if err != nil {
        panic(err)
    }
    defer sentry.Flush(2 * time.Second)

    // Create the Sentry core
    ctx := context.Background()
    sentryCore := sentryzap.NewSentryCore(ctx, sentryzap.Option{
        Level: []zapcore.Level{
            zapcore.InfoLevel,
            zapcore.WarnLevel,
            zapcore.ErrorLevel,
        },
        AddCaller: true,
    })

    // Create a zap logger with the Sentry core
    logger := zap.New(sentryCore)

    // Log messages will be sent to Sentry
    logger.Info("Application started",
        zap.String("version", "1.0.0"),
        zap.String("environment", "production"),
    )

    logger.Warn("High memory usage",
        zap.Float64("usage_percent", 85.5),
    )

    logger.Error("Database connection failed",
        zap.Error(errors.New("connection timeout")),
        zap.String("host", "db.example.com"),
    )
}

The Sentry core respects the context passed during initialization. If you have Sentry tracing enabled, logs will be associated with the current span.

This example shows how to pass a context with an active span when creating the core.

Copied
ctx := context.Background()

// Start a transaction
span := sentry.StartSpan(ctx, "operation.name")
defer span.Finish()

// Create logger with the span's context
ctx = span.Context()
sentryCore := sentryzap.NewSentryCore(ctx, sentryzap.Option{})
logger := zap.New(sentryCore)

// This log will be associated with the transaction
logger.Info("Processing started")

This example shows how to use the Context() helper to propagate different contexts for different log calls.

Copied
// Create logger with base context
sentryCore := sentryzap.NewSentryCore(context.Background(), sentryzap.Option{})
logger := zap.New(sentryCore)

// Start a transaction
span := sentry.StartTransaction(ctx, "operation.name")
defer span.Finish()

// Create a logger scoped to this transaction
scopedLogger := logger.With(sentryzap.Context(span.Context()))

// These logs will be associated with the transaction
scopedLogger.Info("Processing started")
scopedLogger.Info("Processing completed")

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 zap, including advanced configuration options and best practices, see the Go Logs documentation. The zap 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").