Documentation Index Fetch the complete documentation index at: https://mintlify.com/go-kratos/kratos/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The logging middleware automatically logs incoming requests (server) and outgoing requests (client) with detailed information including operation name, status code, error reason, latency, and request arguments.
Installation
go get github.com/go-kratos/kratos/v2/middleware/logging
Server Middleware
The Server function creates a server-side logging middleware:
func Server ( logger log . Logger ) middleware . Middleware
Basic Usage
import (
" os "
" github.com/go-kratos/kratos/v2 "
" github.com/go-kratos/kratos/v2/log "
" github.com/go-kratos/kratos/v2/middleware/logging "
" github.com/go-kratos/kratos/v2/transport/http "
" github.com/go-kratos/kratos/v2/transport/grpc "
)
func main () {
// Create logger
logger := log . NewStdLogger ( os . Stdout )
// Create HTTP server with logging
httpSrv := http . NewServer (
http . Address ( ":8000" ),
http . Middleware (
logging . Server ( logger ),
),
)
// Create gRPC server with logging
grpcSrv := grpc . NewServer (
grpc . Address ( ":9000" ),
grpc . Middleware (
logging . Server ( logger ),
),
)
app := kratos . New (
kratos . Server ( httpSrv , grpcSrv ),
)
if err := app . Run (); err != nil {
log . Fatal ( err )
}
}
Client Middleware
The Client function creates a client-side logging middleware:
func Client ( logger log . Logger ) middleware . Middleware
Usage Example
import (
" github.com/go-kratos/kratos/v2/log "
" github.com/go-kratos/kratos/v2/middleware/logging "
" github.com/go-kratos/kratos/v2/transport/http "
)
// Create logger
logger := log . NewStdLogger ( os . Stdout )
// Create HTTP client with logging
conn , err := http . NewClient (
context . Background (),
http . WithEndpoint ( "127.0.0.1:8000" ),
http . WithMiddleware (
logging . Client ( logger ),
),
)
Log Fields
The logging middleware automatically includes the following fields:
Field Description Example kindAlways “server” or “client” "server", "client"componentTransport kind "http", "grpc"operationOperation name "/api.v1.Greeter/SayHello"argsRequest arguments "{\"name\":\"world\"}"codeResponse status code 200, 500reasonError reason (if error) "INTERNAL_ERROR", ""stackError stack trace (if error) Stack trace string latencyRequest latency in seconds 0.123
Structured Logging Example
import (
" os "
" github.com/go-kratos/kratos/v2/log "
" github.com/go-kratos/kratos/v2/middleware/logging "
" github.com/go-kratos/kratos/v2/middleware/tracing "
)
// Create structured logger with additional fields
logger := log . With (
log . NewStdLogger ( os . Stdout ),
"service.name" , "my-service" ,
"service.version" , "v1.0.0" ,
"trace.id" , tracing . TraceID (),
"span.id" , tracing . SpanID (),
)
// Use in middleware
httpSrv := http . NewServer (
http . Address ( ":8000" ),
http . Middleware (
tracing . Server (),
logging . Server ( logger ),
),
)
Log Output Examples
Successful Request
{
"level" : "INFO" ,
"kind" : "server" ,
"component" : "http" ,
"operation" : "/api.v1.Greeter/SayHello" ,
"args" : "{ \" name \" : \" world \" }" ,
"code" : 200 ,
"reason" : "" ,
"stack" : "" ,
"latency" : 0.123 ,
"service.name" : "my-service" ,
"trace.id" : "4bf92f3577b34da6a3ce929d0e0e4736"
}
Failed Request
{
"level" : "ERROR" ,
"kind" : "server" ,
"component" : "http" ,
"operation" : "/api.v1.Greeter/SayHello" ,
"args" : "{ \" name \" : \"\" }" ,
"code" : 400 ,
"reason" : "INVALID_ARGUMENT" ,
"stack" : "github.com/go-kratos/kratos/v2/errors.BadRequest... \n " ,
"latency" : 0.001 ,
"service.name" : "my-service" ,
"trace.id" : "5cf93f4688c45ea7b4df039e1f1f5847"
}
Sensitive Data Redaction
The logging middleware supports the Redacter interface for redacting sensitive data from logs:
type Redacter interface {
Redact () string
}
Usage Example
// Define a request type with sensitive data
type LoginRequest struct {
Username string
Password string
}
// Implement Redacter interface
func ( r * LoginRequest ) Redact () string {
return fmt . Sprintf ( "{username: %s , password: [REDACTED]}" , r . Username )
}
// Now the password will not appear in logs
Without implementing Redacter, the middleware will attempt to use fmt.Stringer interface, or fall back to fmt.Sprintf("%+v", req).
Redaction Priority
The middleware checks for log-friendly interfaces in this order:
Redacter interface - Custom redaction logic
fmt.Stringer interface - Custom string representation
Default formatting - Uses fmt.Sprintf("%+v", req)
// Custom string representation
func ( r * LoginRequest ) String () string {
return fmt . Sprintf ( "LoginRequest{Username: %s }" , r . Username )
}
Custom Logger Implementation
You can use any logger that implements the log.Logger interface:
type Logger interface {
Log ( level Level , keyvals ... interface {}) error
}
Zap Logger Example
import (
" github.com/go-kratos/kratos/v2/log "
" go.uber.org/zap "
)
// Create Zap logger
zapLogger , _ := zap . NewProduction ()
defer zapLogger . Sync ()
// Wrap with Kratos logger
logger := log . NewHelper ( log . With (
log . NewStdLogger ( zapLogger ),
"service" , "my-service" ,
))
// Use in middleware
logging . Server ( logger )
Logrus Logger Example
import (
" github.com/go-kratos/kratos/v2/log "
" github.com/sirupsen/logrus "
)
// Create Logrus logger
logrusLogger := logrus . New ()
logrusLogger . SetFormatter ( & logrus . JSONFormatter {})
// Wrap with Kratos logger
logger := log . NewHelper ( log . With (
log . NewStdLogger ( logrusLogger . Writer ()),
"service" , "my-service" ,
))
// Use in middleware
logging . Server ( logger )
Complete Example
package main
import (
" context "
" log "
" os "
" github.com/go-kratos/kratos/v2 "
kratoslog " github.com/go-kratos/kratos/v2/log "
" github.com/go-kratos/kratos/v2/middleware/logging "
" github.com/go-kratos/kratos/v2/middleware/recovery "
" github.com/go-kratos/kratos/v2/middleware/tracing "
" github.com/go-kratos/kratos/v2/transport/http "
" go.opentelemetry.io/otel "
" go.opentelemetry.io/otel/exporters/jaeger "
" go.opentelemetry.io/otel/sdk/resource "
tracesdk " go.opentelemetry.io/otel/sdk/trace "
semconv " go.opentelemetry.io/otel/semconv/v1.4.0 "
)
func initTracer ( serviceName string ) ( * tracesdk . TracerProvider , error ) {
exporter , err := jaeger . New ( jaeger . WithCollectorEndpoint (
jaeger . WithEndpoint ( "http://localhost:14268/api/traces" ),
))
if err != nil {
return nil , err
}
tp := tracesdk . NewTracerProvider (
tracesdk . WithBatcher ( exporter ),
tracesdk . WithResource ( resource . NewWithAttributes (
semconv . SchemaURL ,
semconv . ServiceNameKey . String ( serviceName ),
)),
)
otel . SetTracerProvider ( tp )
return tp , nil
}
func main () {
// Initialize tracer
tp , err := initTracer ( "logging-example" )
if err != nil {
log . Fatal ( err )
}
defer tp . Shutdown ( context . Background ())
// Create structured logger
logger := kratoslog . With (
kratoslog . NewStdLogger ( os . Stdout ),
"service.name" , "logging-example" ,
"service.version" , "v1.0.0" ,
"service.id" , "12345" ,
"trace.id" , tracing . TraceID (),
"span.id" , tracing . SpanID (),
)
// Create HTTP server with logging
httpSrv := http . NewServer (
http . Address ( ":8000" ),
http . Middleware (
recovery . Recovery (),
tracing . Server (),
logging . Server ( logger ),
),
)
app := kratos . New (
kratos . Name ( "logging-example" ),
kratos . Logger ( logger ),
kratos . Server ( httpSrv ),
)
if err := app . Run (); err != nil {
log . Fatal ( err )
}
}
Log Levels
The logging middleware uses different log levels based on the result:
INFO - Successful requests (no error)
ERROR - Failed requests (with error)
if err != nil {
return log . LevelError , fmt . Sprintf ( " %+v " , err )
}
return log . LevelInfo , ""
Best Practices
Always Redact Sensitive Data
Implement the Redacter interface for any request types containing passwords, tokens, or PII. func ( r * SecureRequest ) Redact () string {
return fmt . Sprintf ( "{id: %s , token: [REDACTED]}" , r . ID )
}
Always include trace IDs in logs for correlation with distributed traces. logger := log . With (
logger ,
"trace.id" , tracing . TraceID (),
"span.id" , tracing . SpanID (),
)
Use structured (JSON) logging in production for easier parsing and analysis.
High-traffic services can generate large log volumes. Consider sampling or filtering in production.
Send logs to a centralized logging system (ELK, Loki, CloudWatch) for aggregation and analysis.
Filtering Requests
Use the selector middleware to log only specific operations:
import (
" github.com/go-kratos/kratos/v2/middleware/logging "
" github.com/go-kratos/kratos/v2/middleware/selector "
)
// Log only API requests, skip health checks
http . Middleware (
selector . Server (
logging . Server ( logger ),
). Match ( func ( ctx context . Context , operation string ) bool {
// Don't log health check requests
return operation != "/healthz"
}). Build (),
)
Source Reference
The logging middleware implementation can be found in:
middleware/logging/logging.go:22 - Server middleware
middleware/logging/logging.go:63 - Client middleware
middleware/logging/logging.go:17 - Redacter interface
middleware/logging/logging.go:102 - extractArgs function
Next Steps
Tracing Add distributed tracing for request correlation
Metrics Collect performance metrics