access log

This middleware is used to hertz that logs HTTP request/response details.

This middleware is used to hertz that logs HTTP request/response details and inspired by logger.

Install

go get github.com/hertz-contrib/logger/accesslog

Example

package main

import (
	"context"

	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/app/server"
	"github.com/cloudwego/hertz/pkg/common/utils"
	"github.com/hertz-contrib/logger/accesslog"
)

func main() {
	h := server.Default(
		server.WithHostPorts(":8080"),
	)
	h.Use(accesslog.New())
	h.GET("/ping", func(ctx context.Context, c *app.RequestContext) {
		c.JSON(200, utils.H{"msg": "pong"})
	})
	h.Spin()
}

Config

Hertz provides the accesslog.Option function to custom the log format and content.

WithFormat

The accesslog provides WithFormat to help users set the format of the log, default is [${time}] ${status} - ${latency} ${method} ${path}. The format parameter consists of ${tag}, The tag details are as follows Supported tags.

Function signatures:

func WithFormat(s string) Option

Sample Code:

package main

import (
	"context"

	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/app/server"
	"github.com/cloudwego/hertz/pkg/common/utils"
	"github.com/hertz-contrib/logger/accesslog"
)

func main() {
	h := server.Default(
		server.WithHostPorts(":8080"),
	)
	h.Use(accesslog.New(accesslog.WithFormat("[${time}] ${status} - ${latency} ${method} ${path} ${queryParams}")))
	h.GET("/ping", func(ctx context.Context, c *app.RequestContext) {
		c.JSON(200, utils.H{"msg": "pong"})
	})
	h.Spin()
}

WithTimeFormat

The accesslog provides WithTimeFormat to help users set the format of the time, default is 15:04:05. For specific information, please refer to the time package of go.

Function signatures:

func WithTimeFormat(s string) Option

Sample Code:

package main

import (
	"context"
	"time"

	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/app/server"
	"github.com/cloudwego/hertz/pkg/common/utils"
	"github.com/hertz-contrib/logger/accesslog"
)

func main() {
	h := server.Default(
		server.WithHostPorts(":8080"),
	)
	h.Use(accesslog.New(
		accesslog.WithTimeFormat(time.RFC822),
	))
	h.GET("/ping", func(ctx context.Context, c *app.RequestContext) {
		c.JSON(200, utils.H{"msg": "pong"})
	})
	h.Spin()
}

WithTimeInterval

The accesslog provides WithTimeInterval to help the user set the update interval of the timestamp, default is 500ms.

Function signatures:

func WithTimeInterval(t time.Duration) Option

Sample Code:

package main

import (
	"context"
	"time"

	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/app/server"
	"github.com/cloudwego/hertz/pkg/common/utils"
	"github.com/hertz-contrib/logger/accesslog"
)

func main() {
	h := server.Default(
		server.WithHostPorts(":8080"),
	)
	h.Use(accesslog.New(
		accesslog.WithTimeInterval(time.Second),
	))
	h.GET("/ping", func(ctx context.Context, c *app.RequestContext) {
		c.JSON(200, utils.H{"msg": "pong"})
	})
	h.Spin()
}

WithAccessLogFunc

The accesslog provides WithAccessLogFunc to help users set the log printing functions.

Function signatures:

func WithAccessLogFunc(f func(ctx context.Context, format string, v ...interface{})) Option

Sample Code:

package main

import (
	"context"

	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/app/server"
	"github.com/cloudwego/hertz/pkg/common/hlog"
	"github.com/cloudwego/hertz/pkg/common/utils"
	"github.com/hertz-contrib/logger/accesslog"
)

func main() {
	h := server.Default(
		server.WithHostPorts(":8080"),
	)
	h.Use(accesslog.New(
		accesslog.WithAccessLogFunc(hlog.CtxInfof),
	))
	h.GET("/ping", func(ctx context.Context, c *app.RequestContext) {
		c.JSON(200, utils.H{"msg": "pong"})
	})
	h.Spin()
}

WithTimeZoneLocation

The accesslog provides WithTimeZoneLocation to help users set the log printing location.

Function signatures:

func WithTimeZoneLocation(loc *time.Location) Option

Sample Code:

package main

import (
	"context"

	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/app/server"
	"github.com/cloudwego/hertz/pkg/common/hlog"
	"github.com/cloudwego/hertz/pkg/common/utils"
	"github.com/hertz-contrib/logger/accesslog"
)

func main() {
	h := server.Default(
		server.WithHostPorts(":8080"),
	)

	location, err := time.LoadLocation("Asia/Shanghai")
	if err != nil {
		return
	}
	h.Use(accesslog.New(
		accesslog.WithTimeZoneLocation(location),
	))
	h.GET("/ping", func(ctx context.Context, c *app.RequestContext) {
		c.JSON(200, utils.H{"msg": "pong"})
	})
	h.Spin()
}

WithLogConditionFunc

The accesslog provides WithLogConditionFunc to allow user decide whether to print logs based on conditions.

Function signatures:

func WithLogConditionFunc(f logConditionFunc) Option

Sample Code:

package main

import (
	"context"
	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/app/server"
	"github.com/cloudwego/hertz/pkg/common/utils"
	"github.com/hertz-contrib/logger/accesslog"
)

func main() {
	h := server.Default(
		server.WithHostPorts(":8080"),
	)

	h.Use(accesslog.New(
		accesslog.WithLogConditionFunc(func(ctx context.Context, c *app.RequestContext) bool {
			if c.FullPath() == "/ping" {
				return false
			}
			return true
		}),
	))
	h.GET("/ping", func(ctx context.Context, c *app.RequestContext) {
		c.JSON(200, utils.H{"msg": "pong"})
	})
	h.Spin()
}

Log Format

Default Log Format

[${time}] ${status} - ${latency} ${method} ${path}

example:

[21:54:36] 200 - 2.906859ms GET /ping

Supported tags

tagIntroduction
pidpid
timetime
refererthe referer HTTP request header contains the absolute or partial address from which a resource has been requested
protocolprotocol
portport
ipthe ip info in Host
ipsX-Forwarded-For
hosthost
methodmethod
pathpath
urlurl
uaUser-Agent
latencylatency
statusthe status code of response
resBodyresponse body
reqHeadersrequest headers
resHeadersresponse headers
queryParamsrequest parameters
bodyrequest body
bytesSentthe length of response body
bytesReceivedthe length of request body
routethe path of route

Custom Tag

We can add custom tags to the accesslog.Tags, but please note that it is not thread-safe.

Sample Code:

package main

import (
	"context"

	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/app/server"
	"github.com/cloudwego/hertz/pkg/common/bytebufferpool"
	"github.com/cloudwego/hertz/pkg/common/utils"
	"github.com/hertz-contrib/logger/accesslog"
)

func main() {
	accesslog.Tags["test_tag"] = func(ctx context.Context, c *app.RequestContext, buf *bytebufferpool.ByteBuffer) (int, error) {
		return buf.WriteString("test")
	}
	h := server.Default(
		server.WithHostPorts(":8080"),
	)
	h.Use(accesslog.New(accesslog.WithFormat("${test_tag}")))
	h.GET("/ping", func(ctx context.Context, c *app.RequestContext) {
		c.JSON(200, utils.H{"msg": "pong"})
	})
	h.Spin()
}