Documentation Index
Fetch the complete documentation index at: https://docs.go-mizu.dev/llms.txt
Use this file to discover all available pages before exploring further.
Logging with slog
In this lesson, you will learn how to add structured logging to your Mizu applications using Goβs built-in log/slog package. Logs help you see what your app is doing, measure how long things take, and understand when something goes wrong. Mizu already includes a built-in request logger, so every request is automatically logged in a human-readable format by default. You can customize the log output, format, and level using your own slog setup.
Create a file named main.go and add this code:
package main
import (
"fmt"
"log/slog"
"os"
"time"
"github.com/go-mizu/mizu"
)
// Example route that adds custom log entries
func home(c *mizu.Ctx) error {
c.Logger().Info("user visited home",
"method", c.Request().Method,
"path", c.Request().URL.Path,
"client_ip", c.ClientIP(),
)
return c.Text(200, "Home page")
}
// Simulate a slow route
func slow(c *mizu.Ctx) error {
start := time.Now()
time.Sleep(2 * time.Second)
elapsed := time.Since(start)
c.Logger().Info("slow request finished",
"path", c.Request().URL.Path,
"duration", elapsed.String(),
)
return c.Text(200, "Finished slow operation")
}
// Simulate an error and log the details
func fail(c *mizu.Ctx) error {
err := doSomething()
if err != nil {
c.Logger().Error("operation failed",
"error", err,
"user_agent", c.Request().UserAgent(),
"client_ip", c.ClientIP(),
)
return c.Text(500, "Something went wrong")
}
return c.Text(200, "Success")
}
func doSomething() error {
return fmt.Errorf("database connection lost")
}
func main() {
app := mizu.New()
// Mizu logs in plain text by default.
// You can attach your own structured logger if you want.
handler := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo})
logger := slog.New(handler)
app.SetLogger(logger)
// Mizu automatically logs every request,
// so you do not need to add another logging middleware.
app.Get("/", home)
app.Get("/slow", slow)
app.Get("/fail", fail)
if err := app.Listen(":8080"); err != nil {
logger.Error("server failed", "error", err)
}
}
Start the server:
Then open these routes in your browser:
INFO request completed method=GET path=/ status=200 duration=1.3ms
INFO user visited home method=GET path=/ client_ip=127.0.0.1
INFO request completed method=GET path=/slow status=200 duration=2.001s
INFO slow request finished path=/slow duration=2.001s
ERROR operation failed error=database connection lost user_agent=curl/8.1.0 client_ip=127.0.0.1
By default, Mizu logs all requests using a readable text format. If you run your app in a terminal, it will even use color output if your environment supports it.
How it works
Mizu automatically adds a request logger middleware when your app starts. It logs details such as:
- HTTP method
- Path
- Status code
- Duration
- Any errors returned by handlers
When you set a custom slog.Logger using app.SetLogger(), all logs from Mizu and your handlers use that logger instance.
| Feature | What it does | Example |
|---|
| Built-in logs | Logs every request automatically | INFO request completed method=GET path=/ |
app.SetLogger() | Use your own slog configuration | app.SetLogger(logger) |
c.Logger() | Log custom messages inside a handler | c.Logger().Info("event", "path", c.Request().URL.Path) |
c.ClientIP() | Get the visitorβs IP for logs | Useful for tracking and debugging |
Try something new
You can switch to JSON output for production environments:
handler := slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo})
logger := slog.New(handler)
That will print structured logs like this:
{
"time": "2025-11-04T10:30:00Z",
"level": "INFO",
"msg": "request completed",
"method": "GET",
"path": "/slow",
"status": 200,
"duration": "2.001s"
}
You can also set LevelDebug to get more detailed logs during development.
Logging gives you a clear picture of what your app is doing, helps you understand user behavior, and makes it easy to spot and fix problems.
Continue to the next lesson: Request IDs and Correlation to learn how to attach unique IDs to each request for tracing across logs and services.