CodeBlanks Logo Icon CodeBlanks

Logging middleware

Learn to write a middleware that logs requests.

Logging middleware

The request method, path and duration are easy to log; but the status code requires wrapping the ResponseWriter, because the standard interface doesn't say which code the handler wrote:

type kayitci struct {
    http.ResponseWriter
    kod int
}

func (k *kayitci) WriteHeader(c int) {
    k.kod = c
    k.ResponseWriter.WriteHeader(c)
}

Structured logging with slog

With Go 1.21's log/slog package fields are logged separately, and log search tools can query them:

k := &kayitci{ResponseWriter: w, kod: 200}
bas := time.Now()
next.ServeHTTP(k, r)
slog.Info("istek", "yol", r.URL.Path, "kod", k.kod, "sure", time.Since(bas))

Practice Record the status code

Write the kayitci type (embedded http.ResponseWriter and kod int) and its WriteHeader method. The handler calls w.WriteHeader(404); run it with k := &kayitci{ResponseWriter: rec, kod: 200} and print k.kod.

Starter code

main.go
package main

import (
    "fmt"
    "net/http"
    "net/http/httptest"
)

func main() {
    // buraya yaz
}

Sample solution

main.go
package main

import (
    "fmt"
    "net/http"
    "net/http/httptest"
)

type kayitci struct {
    http.ResponseWriter
    kod int
}

func (k *kayitci) WriteHeader(c int) {
    k.kod = c
    k.ResponseWriter.WriteHeader(c)
}

func main() {
    rec := httptest.NewRecorder()
    k := &kayitci{ResponseWriter: rec, kod: 200}
    h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(404) })
    h.ServeHTTP(k, httptest.NewRequest("GET", "/yok", nil))
    fmt.Println(k.kod)
}

Expected output

404

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 If the handler never calls <code>WriteHeader</code>, what is the status code?

  • 200 Correct answer
  • 0
  • 404
  • 500

Explanation: The first Write implicitly writes 200; that's why the recorder starts its code field at 200.

2 Capture the code

Question
func (k *kayitci) ____(c int) {
    k.kod = c
    k.ResponseWriter.WriteHeader(c)
}
Answer
func (k *kayitci) WriteHeader(c int) {
    k.kod = c
    k.ResponseWriter.WriteHeader(c)
}

Explanation: Redefining WriteHeader captures the status code the handler writes.

3 Log fields

Term Meaning
r.Method GET, POST...
r.URL.Path Request path
k.kod Status code
time.Since Duration

All lessons in Advanced