Logging
Configure router request logging for local development and production using Go slog and the NLG Logger package.
The router package uses Go’s standard log/slog ecosystem for logging.
It does not configure a global logger automatically. This is intentional: applications should decide how logs are formatted, where they are written, and which log levels are enabled.
For local development, you can use the github.com/netlifeguru/logger package to enable colorized terminal output together with structured file logging.
package main
import (
"io"
"log/slog"
"net/http"
"os"
"github.com/netlifeguru/logger"
"github.com/netlifeguru/router"
)
func main() {
r := router.New()
closer, err := logger.Init(logger.Config{
Dir: "./logs",
TerminalOutput: true,
DisableColors: false,
MinLevel: slog.LevelInfo,
ConsoleMinLevel: slog.LevelDebug,
MaxFileSize: 100 * 1024 * 1024,
MaxLogFiles: 10,
})
if err != nil {
slog.Error("failed to initialize logger", "error", err)
os.Exit(1)
}
defer func() {
if err := closer.Close(); err != nil {
slog.Error("failed to close logger", "error", err)
}
}()
r.Use(router.Logger())
r.GET("/", func(w http.ResponseWriter, req *http.Request, ctx *router.Context) {
w.Header().Set("Content-Type", "text/html")
w.WriteHeader(http.StatusCreated)
w.Write([]byte(`Hello World`))
})
if err := r.ListenAndServe(":8080"); err != nil {
slog.Error("failed to start server", "error", err)
os.Exit(1)
}
}Run the application:
go run .With terminal output enabled, logs are written to the console in a human-readable format and structured log files are written to the configured log directory.
Example terminal output:
2026-05-12 17:32:47 [INFO] Starting server
2026-05-12 17:32:47 [INFO] System resources cpu_cores=12
2026-05-12 17:32:47 [INFO] web server started server=NetLifeGuru version=v0.0.1 listen_addr=:8080
2026-05-12 17:32:51 [INFO] request processed request_id= method=GET host=localhost:8080 path=/ query= duration=6.917µsLogger Initialization
The logger configuration initializes the global log/slog handler used by the application and router middleware.
closer, err := logger.Init(logger.Config{
Dir: "./logs",
TerminalOutput: true,
DisableColors: false,
MinLevel: slog.LevelInfo,
ConsoleMinLevel: slog.LevelDebug,
MaxFileSize: 100 * 1024 * 1024,
MaxLogFiles: 10,
})
if err != nil {
slog.Error("failed to initialize logger", "error", err)
os.Exit(1)
}
defer closer.Close()This configuration enables:
- colorized terminal output for local development
- structured JSON log files
- automatic log rotation
- configurable log levels for terminal and file output
- graceful shutdown of the logging subsystem
The returned closer should be closed before application shutdown to ensure the logger releases its resources correctly.
If no custom logger is configured, the application falls back to Go’s default log/slog behavior.
In that case:
- terminal output is not colorized
- log rotation is not available
- structured file logging is not configured automatically
Request Logging Middleware
HTTP request logging is enabled through middleware registration.
r.Use(router.Logger())The middleware records request-specific information through slog, including:
- HTTP method
- request path
- query string
- host
- request duration
- request identifier
Request logging is optional and disabled by default.
This keeps the router lightweight while allowing applications to enable request logging only when needed.
Logging Philosophy
The router package intentionally does not configure logging automatically.
Instead of embedding a custom logging system directly into the router, logging is handled through Go’s standard log/slog ecosystem and optional middleware registration.
This approach keeps the router lightweight, predictable, and fully compatible with existing logging infrastructure.
Applications remain free to:
- use any
slog.Handler - configure custom log formatting
- write logs to files, terminals, or external systems
- control log levels independently
- enable or disable request logging explicitly
For development environments, the github.com/netlifeguru/logger package can be used to provide colorized terminal output, structured JSON logging, file rotation, and production-ready log management on top of the standard slog API.
Production Logging
For production environments, terminal output is often disabled.
closer, err := logger.Init(logger.Config{
Dir: "./logs",
TerminalOutput: false,
MinLevel: slog.LevelInfo,
MaxFileSize: 100 * 1024 * 1024,
MaxLogFiles: 10,
})When TerminalOutput is disabled, logs are written only to structured log files.
This is useful when:
- running inside containers
- forwarding logs through a collector
- avoiding ANSI color codes in production output
- reducing unnecessary terminal I/O
The router middleware remains the same:
r.Use(router.Logger())The middleware records request information through slog, while the active logger configuration decides where those log entries are written.
Notes
The router does not require the NLG Logger package to run.
You can use any slog.Handler, including the standard library JSON or text handlers.
The NLG Logger package is recommended when you want colorized development output, file rotation, daily log files, and structured production logs with minimal setup.