httplogger

package module
v1.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 31, 2023 License: MIT Imports: 10 Imported by: 3

README

test Go Reference

go-http-logger

go-http-logger package is a logger for HTTP requests. It is similar to "github.com/gorilla/handlers".LoggingHandler, but more flexible.

SYNOPSIS

If you want to write a custom logger:

package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/shogo82148/go-http-logger"
)

func Handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "Hello World")
}

func Logger(l httplogger.Attrs, r *http.Request) {
	log.Println("size:", l.RequestSize())
	log.Println("status:", l.Status())
	log.Println("method:", r.Method)
	log.Println("request uri:", r.RequestURI)
}

func main() {
	h := httplogger.LoggingHandler(httplogger.LoggerFunc(Logger), http.HandlerFunc(Handler))
	http.Handle("/", h)
	http.ListenAndServe(":8000", nil)
}

Here is a ready-made logger for log/slog:

package main

import (
	"fmt"
	"log/slog"
	"net/http"

	"github.com/shogo82148/go-http-logger"
)

func Handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "Hello World")
}

func main() {
	logger := NewSlogLogger(slog.LevelInfo, "message for http access", slog.Default())
	h := httplogger.LoggingHandler(logger, http.HandlerFunc(Handler))
	http.Handle("/", h)
	http.ListenAndServe(":8000", nil)
}

LICENSE

This software is released under the MIT License, see LICENSE.md.

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func LoggingHandler

func LoggingHandler(logger Logger, handler http.Handler) http.Handler

LoggingHandler wraps the HTTP handler with the logger.

Example
package main

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

	httplogger "github.com/shogo82148/go-http-logger"
)

func main() {
	originalHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "text/plain")
		fmt.Fprint(w, "Hello World")
	})

	loggingHandler := httplogger.LoggingHandler(httplogger.LoggerFunc(func(l httplogger.Attrs, r *http.Request) {
		fmt.Println("size:", l.ResponseSize())
		fmt.Println("status:", l.Status())
		fmt.Println("method:", r.Method)
		fmt.Println("request uri:", r.RequestURI)
		fmt.Println("content type:", l.Header().Get("Content-Type"))
	}), originalHandler)

	ts := httptest.NewServer(loggingHandler)
	defer ts.Close()

	resp, err := http.Get(ts.URL)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()

}
Output:

size: 11
status: 200
method: GET
request uri: /
content type: text/plain
Example (Slog)
package main

import (
	"fmt"
	"log"
	"log/slog"
	"net/http"
	"net/http/httptest"
	"os"

	httplogger "github.com/shogo82148/go-http-logger"
)

func main() {
	originalHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "text/plain")
		fmt.Fprint(w, "Hello World")
	})

	replace := func(groups []string, a slog.Attr) slog.Attr {
		// Remove time.
		if a.Key == slog.TimeKey && len(groups) == 0 {
			return slog.Attr{}
		}
		// Remove unstable attributes for testing.
		if a.Key == "received_time" || a.Key == "request_time" || a.Key == "vhost" || a.Key == "host" {
			return slog.Attr{}
		}
		return a
	}

	slogger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{ReplaceAttr: replace}))
	logger := httplogger.NewSlogLogger(slog.LevelInfo, "test", slogger)
	loggingHandler := httplogger.LoggingHandler(logger, originalHandler)

	ts := httptest.NewServer(loggingHandler)
	defer ts.Close()

	resp, err := http.Get(ts.URL)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()

}
Output:

level=INFO msg=test forwardedfor="" user="" req="GET / HTTP/1.1" method=GET uri=/ protocol=HTTP/1.1 status=200 sent_bytes=11 received_bytes=0 referer="" ua=Go-http-client/1.1

Types

type Attrs added in v1.3.0

type Attrs interface {
	// Header returns HTTP Header of the response.
	Header() http.Header

	// Status returns HTTP Status code.
	Status() int

	// The size of response body.
	//
	// Deprecated: Use ResponseSize instead.
	Size() int

	// Time returns the time when the request was received.
	//
	// Deprecated: Use RequestTime instead.
	Time() time.Time

	// RequestSize returns the size of request body.
	RequestSize() int64

	// ResponseSize returns the size of response body.
	ResponseSize() int64

	// RequestTime returns the time when the request was received.
	RequestTime() time.Time

	// WriteHeaderTime returns the time when the response header was written.
	WriteHeaderTime() time.Time
	// contains filtered or unexported methods
}

Attrs is the information of the response.

type Logger

type Logger interface {
	WriteHTTPLog(l Attrs, r *http.Request)
}

Logger is the interface for your custom logger.

func NewSlogLogger added in v1.3.0

func NewSlogLogger(level slog.Level, msg string, logger *slog.Logger) Logger

NewSlogLogger returns a Logger that logs to the given slog.Logger. Logged attributes are:

  • received_time: Time the request was received.
  • host: Remote host.
  • forwardedfor: X-Forwarded-For header.
  • user: Remote user.
  • req: First line of request.
  • method: Request method.
  • uri: Request URI.
  • protocol: Requested Protocol (usually "HTTP/1.0" or "HTTP/1.1").
  • status: HTTP status code of the response.
  • sent_bytes: Size of response body in bytes, excluding HTTP headers.
  • received_bytes: Size of request body in bytes, excluding HTTP headers.
  • referer: Referer header.
  • ua: User agent header.
  • request_time: Time taken to serve the request, in seconds.

type LoggerFunc

type LoggerFunc func(l Attrs, r *http.Request)

The LoggerFunc type is an adapter to allow the use of ordinary functions as Logger.

func (LoggerFunc) WriteHTTPLog

func (f LoggerFunc) WriteHTTPLog(l Attrs, r *http.Request)

WriteHTTPLog implements the Logger interface.

type ResponseLog deprecated

type ResponseLog = Attrs

ResponseLog is the interface for the response information.

Deprecated: Use Attrs instead.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL