httplog

package module
v0.2.4 Latest Latest
Warning

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

Go to latest
Published: Aug 30, 2021 License: MIT Imports: 14 Imported by: 0

README

httplog

This is a simple forked of go-chi/httplog middleware, with additional support of dumping request and response body. This is mostly useful for auditing purpose.

Differences

Changes made in this repo only takes effect in non-concise mode. Otherwise, the behavior would remain the same.

  • response body limit is now configurable with default changed from 512 to 128000 bytes
  • In non-concise mode
    • instead of duplicating httpRequest log between the context and message, header and body is logged under httpRequestExtra
    • response body is always included in the log message (go-chi/httplog include response only when http code is 4xx)

Log Example

Making POST request.

curl --request POST \
  --url http://localhost:5555/reflect \
  --header 'content-type: application/json' \
  --data '{"title": "example"}'

Log output.

{
    "level": "info",
    "service": "httplog-example",
    "httpRequest": {
        "proto": "HTTP/1.1",
        "remoteIP": "[::1]:50389",
        "requestID": "machine.local/8Ecrdfj1sf-000007",
        "requestMethod": "POST",
        "requestPath": "/reflect",
        "requestURL": "http://localhost:5555/reflect"
    },
    "httpRequestExtra": {
        "body": "{\"title\": \"example\"}",
        "header": {
            "accept": "*/*",
            "content-length": "20",
            "content-type": "application/json",
            "user-agent": "insomnia/2020.4.1"
        }
    },
    "timestamp": "2021-02-19T23:38:24.840108+07:00",
    "message": "Request: POST /reflect"
}
{
    "level": "info",
    "service": "httplog-example",
    "httpRequest": {
        "proto": "HTTP/1.1",
        "remoteIP": "[::1]:50389",
        "requestID": "machine.local/8Ecrdfj1sf-000007",
        "requestMethod": "POST",
        "requestPath": "/reflect",
        "requestURL": "http://localhost:5555/reflect"
    },
    "httpResponse": {
        "body": "POST /reflect HTTP/1.1\r\nHost: localhost:5555\r\nAccept: */*\r\nContent-Length: 20\r\nContent-Type: application/json\r\nUser-Agent: insomnia/2020.4.1\r\n\r\n{\"title\": \"example\"}",
        "bytes": 164,
        "elapsed": 0.026024,
        "status": 200
    },
    "timestamp": "2021-02-19T23:38:24.840224+07:00",
    "message": "Response: 200 OK"
}

Server Example

Also available in _example/

package main

import (
  "net/http"
  "net/http/httputil"

  "github.com/go-chi/chi/v5"
  "github.com/go-chi/chi/v5/middleware"

  "github.com/manat/httplog"
)

func main() {
	logger := httplog.NewLogger("httplog-example", httplog.Options{
		JSON: true,
	})

	// Service
	r := chi.NewRouter()
	r.Use(httplog.RequestLogger(logger))

	r.Get("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("hello world"))
	})

	r.Post("/reflect", func(w http.ResponseWriter, r *http.Request) {
		dump, _ := httputil.DumpRequest(r, true)
		w.Write(dump)
	})

	http.ListenAndServe(":5555", r)
}

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

View Source
var DefaultOptions = Options{
	LogLevel:      "info",
	JSON:          false,
	Concise:       false,
	Tags:          nil,
	SkipHeaders:   nil,
	LimitBodySize: 128000,
}

Functions

func Configure

func Configure(opts Options)

Configure will set new global/default options for the httplog and behaviour of underlying zerolog pkg and its global logger.

func Handler

func Handler(logger zerolog.Logger) func(next http.Handler) http.Handler

func LogEntry

func LogEntry(ctx context.Context) zerolog.Logger

func LogEntrySetField

func LogEntrySetField(ctx context.Context, key, value string)

func LogEntrySetFields

func LogEntrySetFields(ctx context.Context, fields map[string]interface{})

func NewLogger

func NewLogger(serviceName string, opts ...Options) zerolog.Logger

func RequestLogger

func RequestLogger(logger zerolog.Logger) func(next http.Handler) http.Handler

RequestLogger is an http middleware to log http requests and responses.

NOTE: for simplicty, RequestLogger automatically makes use of the chi RequestID and Recoverer middleware.

Types

type Options

type Options struct {
	// LogLevel defines the minimum level of severity that app should log.
	//
	// Must be one of: ["trace", "debug", "info", "warn", "error", "critical"]
	LogLevel string

	// JSON enables structured logging output in json. Make sure to enable this
	// in production mode so log aggregators can receive data in parsable format.
	//
	// In local development mode, its appropriate to set this value to false to
	// receive pretty output and stacktraces to stdout.
	JSON bool

	// Concise mode includes fewer log details during the request flow. For example
	// exluding details like request content length, user-agent and other details.
	// This is useful if during development your console is too noisy.
	Concise bool

	// Tags are additional fields included at the root level of all logs.
	// These can be useful for example the commit hash of a build, or an environment
	// name like prod/stg/dev
	Tags map[string]string

	// SkipHeaders are additional headers which are redacted from the logs.
	SkipHeaders []string

	// LimitBodySize indicates how large the response body will be logged.
	LimitBodySize int
}

type RequestLoggerEntry

type RequestLoggerEntry struct {
	Logger zerolog.Logger
	// contains filtered or unexported fields
}

func (*RequestLoggerEntry) Panic

func (l *RequestLoggerEntry) Panic(v interface{}, stack []byte)

func (*RequestLoggerEntry) Write

func (l *RequestLoggerEntry) Write(status, bytes int, header http.Header, elapsed time.Duration, extra interface{})

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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