accesslog

package module
v0.0.0-...-6b18af4 Latest Latest
Warning

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

Go to latest
Published: Jan 28, 2024 License: Apache-2.0 Imports: 16 Imported by: 14

README

accesslog (This is a community driven project)

Introduction

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

Usage

Download and install it:

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

Import it in your code:

import github.com/hertz-contrib/logger/accesslog

Simple 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

WithFormat

The accesslog provides WithFormat to help users set the format of the log.

Simple 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.

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.

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.

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()
}

Log Format

Default Log Format
[${time}] ${status} - ${latency} ${method} ${path}

example

[21:54:36] 200 - 2.906859ms GET /ping
Supported tags
const (
	TagPid               = "pid"
	TagTime              = "time"
	TagReferer           = "referer"
	TagProtocol          = "protocol"
	TagPort              = "port"
	TagIP                = "ip"
	TagIPs               = "ips"
	TagClientIP          = "clientIP"
	TagHost              = "host"
	TagMethod            = "method"
	TagPath              = "path"
	TagURL               = "url"
	TagUA                = "ua"
	TagLatency           = "latency"
	TagStatus            = "status"       // response status
	TagResBody           = "resBody"      // response body
	TagReqHeaders        = "reqHeaders"
	TagResHeaders        = "resHeaders"
	TagQueryStringParams = "queryParams"  // request query parameters
	TagBody              = "body"         // request body
	TagBytesSent         = "bytesSent"
	TagBytesReceived     = "bytesReceived"
	TagRoute             = "route"        // request path
)
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()
}

Log By Condition

We can add a method logConditionFunc to determine whether to log based on the conditions.

Sample Code:

package main

import (
	"context"

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

func main() {
	h := server.Default(server.WithHostPorts(":8081"))
	h.GET("/ping", func(c context.Context, ctx *app.RequestContext) {
		ctx.JSON(200, map[string]string{"ping": "pong"})
	})
	h.Use(accesslog.New(accesslog.WithLogConditionFunc(func(ctx context.Context, c *app.RequestContext) bool {
		if c.FullPath() == "/ping" {
			return false
		} else {
			return true
		}
	})))
	h.Spin()
}

Documentation

Index

Constants

View Source
const (
	TagPid               = "pid"
	TagTime              = "time"
	TagReferer           = "referer"
	TagProtocol          = "protocol"
	TagPort              = "port"
	TagIP                = "ip"
	TagIPs               = "ips"
	TagHost              = "host"
	TagClientIP          = "clientIP"
	TagMethod            = "method"
	TagPath              = "path"
	TagURL               = "url"
	TagUA                = "ua"
	TagLatency           = "latency"
	TagStatus            = "status"
	TagResBody           = "resBody"
	TagReqHeaders        = "reqHeaders"
	TagResHeaders        = "resHeaders"
	TagQueryStringParams = "queryParams"
	TagBody              = "body"
	TagBytesSent         = "bytesSent"
	TagBytesReceived     = "bytesReceived"
	TagRoute             = "route"
)
View Source
const MaxStringLen = 0x7fff0000 // Maximum string length for UnsafeBytes. (decimal: 2147418112)

Variables

View Source
var Tags = map[string]LogFunc{
	TagReferer: func(output Buffer, c *app.RequestContext, data *Data, extraParam string) (int, error) {
		return output.WriteString(c.Request.Header.Get("Referer"))
	},
	TagProtocol: func(output Buffer, c *app.RequestContext, data *Data, extraParam string) (int, error) {
		return output.WriteString(string(c.Request.URI().Scheme()))
	},
	TagPort: func(output Buffer, c *app.RequestContext, data *Data, extraParam string) (int, error) {
		host := string(c.Request.URI().Host())
		split := strings.Split(host, ":")
		return output.WriteString(split[1])
	},
	TagIP: func(output Buffer, c *app.RequestContext, data *Data, extraParam string) (int, error) {
		host := string(c.Request.URI().Host())
		split := strings.Split(host, ":")
		return output.WriteString(split[0])
	},
	TagIPs: func(output Buffer, c *app.RequestContext, data *Data, extraParam string) (int, error) {
		return output.WriteString(c.Request.Header.Get("X-Forwarded-For"))
	},
	TagResBody: func(output Buffer, c *app.RequestContext, data *Data, extraParam string) (int, error) {
		return output.WriteString(string(c.Response.Body()))
	},
	TagHost: func(output Buffer, c *app.RequestContext, data *Data, extraParam string) (int, error) {
		return output.WriteString(string(c.Request.URI().Host()))
	},
	TagClientIP: func(output Buffer, c *app.RequestContext, data *Data, extraParam string) (int, error) {
		return output.WriteString(c.ClientIP())
	},
	TagPath: func(output Buffer, c *app.RequestContext, data *Data, extraParam string) (int, error) {
		return output.WriteString(string(c.Request.Path()))
	},
	TagURL: func(output Buffer, c *app.RequestContext, data *Data, extraParam string) (int, error) {
		return output.WriteString(string(c.Request.Header.RequestURI()))
	},
	TagUA: func(output Buffer, c *app.RequestContext, data *Data, extraParam string) (int, error) {
		return output.WriteString(c.Request.Header.Get("User-Agent"))
	},
	TagBody: func(output Buffer, c *app.RequestContext, data *Data, extraParam string) (int, error) {
		return output.Write(c.Request.Body())
	},
	TagBytesSent: func(output Buffer, c *app.RequestContext, data *Data, extraParam string) (int, error) {
		if c.Response.Header.ContentLength() < 0 {
			return appendInt(output, 0)
		}
		return appendInt(output, len(c.Response.Body()))
	},
	TagBytesReceived: func(output Buffer, c *app.RequestContext, data *Data, extraParam string) (int, error) {
		return appendInt(output, len(c.Request.Body()))
	},
	TagRoute: func(output Buffer, c *app.RequestContext, data *Data, extraParam string) (int, error) {
		return output.WriteString(string(c.Path()))
	},
	TagStatus: func(output Buffer, c *app.RequestContext, data *Data, extraParam string) (int, error) {
		return appendInt(output, c.Response.StatusCode())
	},
	TagReqHeaders: func(output Buffer, c *app.RequestContext, data *Data, extraParam string) (int, error) {
		reqHeaders := make([]string, 0)
		c.Request.Header.VisitAll(func(k, v []byte) {
			reqHeaders = append(reqHeaders, string(k)+"="+string(v))
		})
		return output.Write([]byte(strings.Join(reqHeaders, "&")))
	},
	TagResHeaders: func(output Buffer, c *app.RequestContext, data *Data, extraParam string) (int, error) {
		resHeaders := make([]string, 0)
		c.Response.Header.VisitAll(func(k, v []byte) {
			resHeaders = append(resHeaders, string(k)+"="+string(v))
		})
		return output.Write([]byte(strings.Join(resHeaders, "&")))
	},
	TagQueryStringParams: func(output Buffer, c *app.RequestContext, data *Data, extraParam string) (int, error) {
		return output.WriteString(c.Request.URI().QueryArgs().String())
	},
	TagMethod: func(output Buffer, c *app.RequestContext, data *Data, extraParam string) (int, error) {
		return output.WriteString(string(c.Method()))
	},
	TagLatency: func(output Buffer, c *app.RequestContext, data *Data, extraParam string) (int, error) {
		latency := data.Stop.Sub(data.Start)
		return output.WriteString(fmt.Sprintf("%13v", latency))
	},
	TagPid: func(output Buffer, c *app.RequestContext, data *Data, extraParam string) (int, error) {
		return output.WriteString(data.Pid)
	},
	TagTime: func(output Buffer, c *app.RequestContext, data *Data, extraParam string) (int, error) {
		return output.WriteString(data.Timestamp.Load().(string))
	},
}

Functions

func New

func New(opts ...Option) app.HandlerFunc

func NewWithContext

func NewWithContext(ctx context.Context, opts ...Option) app.HandlerFunc

Types

type Buffer

type Buffer interface {
	Len() int
	ReadFrom(r io.Reader) (int64, error)
	WriteTo(w io.Writer) (int64, error)
	Bytes() []byte
	Write(p []byte) (int, error)
	WriteByte(c byte) error
	WriteString(s string) (int, error)
	Set(p []byte)
	SetString(s string)
	String() string
}

type Data

type Data struct {
	Pid       string
	Start     time.Time
	Stop      time.Time
	Timestamp atomic.Value
}

Data is a struct to define some variables to use in custom logger function.

type LogFunc

type LogFunc func(output Buffer, c *app.RequestContext, data *Data, extraParam string) (int, error)

type Option

type Option func(o *options)

func WithAccessLogFunc

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

WithAccessLogFunc set print log function

func WithFormat

func WithFormat(s string) Option

WithFormat set log format

func WithLogConditionFunc

func WithLogConditionFunc(f logConditionFunc) Option

WithLogConditionFunc set logConditionFunc

func WithTimeFormat

func WithTimeFormat(s string) Option

WithTimeFormat set log time format

func WithTimeInterval

func WithTimeInterval(t time.Duration) Option

WithTimeInterval set timestamp refresh interval

func WithTimeZoneLocation

func WithTimeZoneLocation(loc *time.Location) Option

WithTimeZoneLocation set timestamp zone

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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