How to Integrate Third-Party Logging Libraries (Zap, Zerolog) with Kratos

To integrate third-party logging libraries like Zap or Zerolog with Kratos, implement the log.Logger interface using the official adapter packages in contrib/log/ and inject the adapter via the Logger option when creating the application.

Kratos defines a generic logger interface in go-kratos/kratos that abstracts the underlying implementation, allowing you to replace the default StdLogger with high-performance structured loggers. The repository provides ready-to-use adapters that bridge popular third-party libraries to Kratos' logging contract without modifying your application code.

Understanding the Kratos Logger Interface

At the core of the framework is a minimal interface defined in log/log.go:

type Logger interface {
    Log(level Level, keyvals ...any) error
}

All built-in middleware—including the request logging middleware in middleware/logging/logging.go—accepts this log.Logger type. When you construct a Kratos application, you can replace the default logger by passing a concrete implementation via the Logger option defined in options.go:

func Logger(logger log.Logger) Option { … }

This design ensures your business logic remains decoupled from specific logging implementations while middleware automatically utilizes whatever logger you inject.

Official Adapter Packages

The Kratos project maintains dedicated adapter packages under contrib/log/ that wrap popular third-party loggers to satisfy the log.Logger contract.

Zap Adapter (contrib/log/zap/zap.go) The Zap adapter wraps a *zap.Logger and forwards Log calls by converting Kratos levels to Zap levels and building a slice of zap.Field from the key-value pairs.

Zerolog Adapter (contrib/log/zerolog/zerolog.go) The Zerolog adapter holds a *zerolog.Logger and creates a zerolog.Event matching the Kratos level, attaching the supplied fields to the event.

Logrus Adapter (contrib/log/logrus/logrus.go) The Logrus adapter translates Kratos levels to Logrus levels, builds a logrus.Fields map from the key-value pairs, and emits the structured log event.

Step-by-Step Integration Examples

Integrating Zap with Kratos

To use Uber's Zap logger, import the adapter from contrib/log/zap and wrap your configured *zap.Logger:

package main

import (
    "go.uber.org/zap"
    kratoszap "github.com/go-kratos/kratos/v2/contrib/log/zap"
    "github.com/go-kratos/kratos/v2"
)

func main() {
    // Build a Zap logger (you can configure any encoder/core you like)
    zapLogger, _ := zap.NewProduction()

    // Wrap it with the Kratos adapter
    zapAdapter := kratoszap.NewLogger(zapLogger)

    // Create the Kratos application, injecting the adapter
    app := kratos.New(
        kratos.Logger(zapAdapter),
        // … other options such as Server, Registrar, etc.
    )
    // Run the service
    if err := app.Run(); err != nil {
        panic(err)
    }
}

The kratoszap.NewLogger function handles the conversion between Kratos' Level type and Zap's logging levels, ensuring structured fields pass through correctly.

Integrating Zerolog with Kratos

For Zerolog integration, use the adapter from contrib/log/zerolog:

package main

import (
    "github.com/rs/zerolog"
    "os"
    kratoszero "github.com/go-kratos/kratos/v2/contrib/log/zerolog"
    "github.com/go-kratos/kratos/v2"
)

func main() {
    // Create a Zerolog logger (JSON output to stdout)
    zerologLogger := zerolog.New(os.Stdout).With().Timestamp().Logger()

    // Wrap it for Kratos
    zeroAdapter := kratoszero.NewLogger(&zerologLogger)

    // Build the Kratos app with the custom logger
    app := kratos.New(
        kratos.Logger(zeroAdapter),
        // … other options
    )
    if err := app.Run(); err != nil {
        panic(err)
    }
}

Integrating Logrus with Kratos

For Logrus users, the adapter in contrib/log/logrus provides similar functionality:

package main

import (
    logrus "github.com/sirupsen/logrus"
    kratoslogrus "github.com/go-kratos/kratos/v2/contrib/log/logrus"
    "github.com/go-kratos/kratos/v2"
)

func main() {
    // Initialise Logrus (JSON formatter, Info level)
    l := logrus.New()
    l.SetFormatter(&logrus.JSONFormatter{})
    l.SetLevel(logrus.InfoLevel)

    // Adapter
    logrusAdapter := kratoslogrus.NewLogger(l)

    // Kratos app
    app := kratos.New(
        kratos.Logger(logrusAdapter),
        // … other options
    )
    if err := app.Run(); err != nil {
        panic(err)
    }
}

How Middleware Uses Your Logger

Once injected via kratos.Logger(), your third-party logger automatically powers all observability features. The logging.Server and logging.Client middleware in middleware/logging/logging.go invoke the Log method to record request details, response latency, error traces, and structured context fields without requiring additional configuration.

Summary

  • Kratos exposes a minimal log.Logger interface in log/log.go with a single Log(level Level, keyvals ...any) error method.
  • Replace the default logger using the Logger option in options.go when calling kratos.New().
  • Official adapters in contrib/log/zap/, contrib/log/zerolog/, and contrib/log/logrus/ implement the interface for popular libraries.
  • Each adapter translates Kratos level types and key-value pairs into the native format of the underlying logger.
  • Middleware automatically uses the injected logger for request/response logging and error tracing.

Frequently Asked Questions

Can I use a custom logger that isn't Zap, Zerolog, or Logrus?

Yes. Any library that can implement the Log(level Level, keyvals ...any) error interface from log/log.go works with Kratos. Create a custom adapter type that satisfies this single method, then pass it to kratos.Logger() when building your application.

Does the logging middleware automatically use the injected logger?

Yes. The server and client logging middleware in middleware/logging/logging.go accepts the log.Logger interface. When you provide a custom logger via the Logger option, middleware automatically routes all request logs, latency metrics, and error traces through your third-party implementation.

How do I configure log levels when using these adapters?

Configure log levels on the underlying logger instance before wrapping it with the Kratos adapter. For example, set zap.NewProductionConfig().Level for Zap, or call zerolog.Logger.Level() for Zerolog. The adapter respects the underlying logger's level filtering and only forwards calls that pass those filters.

Where can I find the source code for these adapters?

The official adapters reside in the go-kratos/kratos repository under contrib/log/. Specific files include contrib/log/zap/zap.go for Zap, contrib/log/zerolog/zerolog.go for Zerolog, and contrib/log/logrus/logrus.go for Logrus. These files demonstrate how to map Kratos' generic interface to library-specific APIs.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →