Skip to main content

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.

Code

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)
	}
}

Run

Start the server:
go run .
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.
FeatureWhat it doesExample
Built-in logsLogs every request automaticallyINFO request completed method=GET path=/
app.SetLogger()Use your own slog configurationapp.SetLogger(logger)
c.Logger()Log custom messages inside a handlerc.Logger().Info("event", "path", c.Request().URL.Path)
c.ClientIP()Get the visitor’s IP for logsUseful 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.