| id | log |
|---|---|
| title | 📃 Log |
| description | Fiber's built-in log package |
| sidebar_position | 6 |
Logs help you observe program behavior, diagnose issues, and trigger alerts. Structured logs improve searchability and speed up troubleshooting.
Fiber logs to standard output by default and exposes global helpers such as log.Info, log.Errorf, and log.Warnw.
const (
LevelTrace Level = iota
LevelDebug
LevelInfo
LevelWarn
LevelError
LevelFatal
LevelPanic
)Fiber provides the generic AllLogger[T] interface for adapting various log libraries.
type CommonLogger interface {
Logger
FormatLogger
WithLogger
}
type ConfigurableLogger[T any] interface {
// SetLevel sets logging level.
SetLevel(level Level)
// SetOutput sets the logger output.
SetOutput(w io.Writer)
// Logger returns the logger instance.
Logger() T
}
type AllLogger[T any] interface {
CommonLogger
ConfigurableLogger[T]
WithLogger
}Note: The Fatal level method will terminate the program after printing the log message. Please use it with caution.
Call level-specific methods directly; entries use the messageKey (default msg).
log.Info("Hello, World!")
log.Debug("Are you OK?")
log.Info("42 is the answer to life, the universe, and everything")
log.Warn("We are under attack!")
log.Error("Houston, we have a problem.")
log.Fatal("So Long, and Thanks for All the Fish.")
log.Panic("The system is down.")Append f to format the message.
log.Debugf("Hello %s", "boy")
log.Infof("%d is the answer to life, the universe, and everything", 42)
log.Warnf("We are under attack, %s!", "boss")
log.Errorf("%s, we have a problem.", "John Smith")
log.Fatalf("So Long, and Thanks for All the %s.", "fish")Key-value helpers log structured fields; mismatched pairs emit KEYVALS UNPAIRED.
log.Debugw("", "greeting", "Hello", "target", "boy")
log.Infow("", "number", 42)
log.Warnw("", "job", "boss")
log.Errorw("", "name", "John Smith")
log.Fatalw("", "fruit", "fish")Fiber also exposes a global logger for quick messages.
import "github.com/gofiber/fiber/v3/log"
log.Info("info")
log.Warn("warn")The example uses log.DefaultLogger, which writes to stdout. The contrib repo offers adapters like fiberzap and fiberzerolog, or you can register your own with log.SetLogger.
Here's an example using a custom logger:
import (
"log"
fiberlog "github.com/gofiber/fiber/v3/log"
)
var _ fiberlog.AllLogger[*log.Logger] = (*customLogger)(nil)
type customLogger struct {
stdlog *log.Logger
}
// Implement required methods for the AllLogger interface...
// Inject your custom logger
fiberlog.SetLogger[*log.Logger](&customLogger{
stdlog: log.New(os.Stdout, "CUSTOM ", log.LstdFlags),
})
// Retrieve the underlying *log.Logger for direct use
std := fiberlog.DefaultLogger[*log.Logger]().Logger()
std.Println("custom logging")log.SetLevel sets the minimum level that will be output. The default is LevelTrace.
Note: This method is not concurrent safe.
import "github.com/gofiber/fiber/v3/log"
log.SetLevel(log.LevelInfo)Setting the log level allows you to control the verbosity of the logs, filtering out messages below the specified level.
log.SetOutput sets where logs are written. By default, they go to the console.
var logger fiberlog.AllLogger[*log.Logger] = &defaultLogger{
stdlog: log.New(os.Stderr, "", log.LstdFlags|log.Lshortfile|log.Lmicroseconds),
depth: 4,
}This lets you route logs to a file, service, or any destination.
To write to a file such as test.log:
// Output to ./test.log file
f, err := os.OpenFile("test.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
log.Fatal("Failed to open log file:", err)
}
log.SetOutput(f)Write to both test.log and stdout:
// Output to ./test.log file
file, err := os.OpenFile("test.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
log.Fatal("Failed to open log file:", err)
}
iw := io.MultiWriter(os.Stdout, file)
log.SetOutput(iw)Bind a logger to a context with log.WithContext, which returns a CommonLogger tied to that context.
commonLogger := log.WithContext(ctx)
commonLogger.Info("info")Context binding adds request-specific data for easier tracing. The method accepts fiber.Ctx, *fasthttp.RequestCtx, or context.Context. When using standard context.Context instances (such as c.Context()), enable PassLocalsToContext in the app config so that values stored in fiber.Ctx.Locals are propagated through the context chain.
Middleware that stores values in the request context can register extractors so that log.WithContext automatically includes those values in every log entry. The following middlewares register extractors when their New() constructor is called:
| Middleware | Log Field | Description |
|---|---|---|
requestid |
request-id |
Request identifier |
basicauth |
username |
Authenticated username |
keyauth |
api-key |
API key token (redacted) |
csrf |
csrf-token |
CSRF token (redacted) |
session |
session-id |
Session identifier (redacted) |
app.Use(requestid.New())
app.Get("/", func(c fiber.Ctx) error {
// Automatically includes request-id=<id> in the log output
log.WithContext(c).Info("processing request")
return c.SendString("OK")
})Use log.RegisterContextExtractor to register your own extractors. Each extractor receives the bound context and returns a field name, value, and success flag:
log.RegisterContextExtractor(func(ctx any) (string, any, bool) {
// Use fiber.ValueFromContext to extract from any supported context type
if traceID, ok := fiber.ValueFromContext[string](ctx, traceIDKey); ok && traceID != "" {
return "trace-id", traceID, true
}
return "", nil, false
}):::note
RegisterContextExtractor may be called at any time, including while your application is handling requests and emitting logs. Registrations are safe to perform concurrently with logging. In practice, register extractors during program initialization (e.g. in an init function or middleware constructor) so that they are in place before requests are processed.
:::
Use Logger to access the underlying logger and call its native methods:
logger := fiberlog.DefaultLogger[*log.Logger]() // Get the default logger instance
stdlogger := logger.Logger() // stdlogger is *log.Logger
stdlogger.SetFlags(0) // Hide timestamp by setting flags to 0