Bu örnek, yanıt durum kodunu ve vücut boyutunu yakalamanıza, ardından da günlüğe kaydetmenize yardımcı olacaktır. İsterseniz istek ile ilgili verileri de kaydedebilirsiniz, ancak bu yazının kapsamı dışındadır.


ResponseWriter


package response

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

// Acts as an adapter for `http.ResponseWriter` type to store response status
// code and size.
type ResponseWriter struct {
http.ResponseWriter

code int
size int
}

// Returns a new `ResponseWriter` type by decorating `http.ResponseWriter` type.
func NewResponseWriter(w http.ResponseWriter) *ResponseWriter {
return &ResponseWriter{
ResponseWriter: w,
}
}

// Overrides `http.ResponseWriter` type.
func (r *ResponseWriter) WriteHeader(code int) {
if r.Code() == 0 {
r.code = code
r.ResponseWriter.WriteHeader(code)
}
}

// Overrides `http.ResponseWriter` type.
func (r *ResponseWriter) Write(body []byte) (int, error) {
if r.Code() == 0 {
r.WriteHeader(http.StatusOK)
}

var err error
r.size, err = r.ResponseWriter.Write(body)

return r.size, err
}

// Overrides `http.Flusher` type.
func (r *ResponseWriter) Flush() {
if fl, ok := r.ResponseWriter.(http.Flusher); ok {
if r.Code() == 0 {
r.WriteHeader(http.StatusOK)
}

fl.Flush()
}
}

// Overrides `http.Hijacker` type.
func (r *ResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
hj, ok := r.ResponseWriter.(http.Hijacker)
if !ok {
return nil, nil, fmt.Errorf("the hijacker interface is not supported")
}

return hj.Hijack()
}

// Returns response status code.
func (r *ResponseWriter) Code() int {
return r.code
}

// Returns response size.
func (r *ResponseWriter) Size() int {
return r.size
}

AccessLoger


package middleware

import (
"log"
"net/http"

"response"
)

// AccessLoger helps logging request and response related data.
func AccessLoger(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
rw := response.NewResponseWriter(w)

h.ServeHTTP(rw, r)

log.Println("status:", rw.Code(), "size:", rw.Size(), "bytes")
})
}

Server


package http

import (
"net/http"
)

// NewServer returns `http.Server` pointer type.
func NewServer(address string, handler http.Handler) *http.Server {
return &http.Server{
Addr: address,
Handler: AccessLoger(handler),
}
}

Test


Uç noktalarınızdan birine örnek bir istek gönderirseniz, günlük aşağıdaki gibi görünecektir.


2021/01/27 17:19:39 status: 200 size: 63 bytes