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.
go get github.com/getsentry/sentry-go
go get github.com/getsentry/sentry-go/zap
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:
| Field | Type | Description | Default |
|---|---|---|---|
Level | []zapcore.Level | Zap levels to capture and send to Sentry as log entries | All levels (Debug through Fatal) |
AddCaller | bool | Include caller info (file, line, function) in logs | false |
FlushTimeout | time.Duration | How long to wait when syncing/flushing logs | 5 seconds |
This example shows how to create a zap logger that sends logs to Sentry.
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.
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.
// 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.
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").