loglineparser

package module
v0.0.0-...-c33f924 Latest Latest
Warning

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

Go to latest
Published: Dec 20, 2022 License: Apache-2.0 Imports: 16 Imported by: 0

README

loglineparser

Travis CI Software License GoDoc Coverage Status goreport

log parser to parse log line to relative golang struct.

日志格式定义

2018/10/18 20:46:45 [notice] 19002#0: *53103423 [lua] gateway.lua:163: log_base(): [GatewayMonV2] [200], [200, 0.023999929428101, 1539866805.135, 108],  [true, -, -], [{}] request: "POST /dsvs/v1/pkcs1/verifyDigestSign HTTP/1.1", host: "192.168.108.11:8081"
  1. 在形如以上日志行的日志中,以[xx]包含起来的,是需要提取的部分(parts)。
    • 索引号从0开始。
    • 然后在xx中,可能有多个子字段(subs),比如[200, 0.023999929428101, 1539866805.135, 108],这个以逗号分隔的,是子字段(subs)。
  2. 或者使用正则表达式的捕获组提取字段值,见下面的示例

可以定义以下go语言的结构体,来映射这些提取部分(parts),或者提取子字段(subs):

package yourawesomepackage

import (
	"github.com/bingoohuang/loglineparser"
	"time"
)

type LogLine struct {
	LogLevel      string `llp:"0"` // 日志级别,提取第0+1个[]中整个部分
	GatewayStatus string `llp:"2"` // GatewayMonV2

	RespStatus            string    `llp:"4.0"`
	RespResponseTime      float32   `llp:"4.1"`
	RespInnerStartReqTime time.Time `llp:"4.2"`
	RespBodySize          int       `llp:"4.3"`

	AuthIsLocalIP         bool   `llp:"5.0"`
	AuthKeySecretCheckRst string `llp:"5.1"`

	ApiSessionVarMap map[string]string `llp:"6"`

	AppID      string `llp:"10.-3"` // 应用 ID,提取第10+1个[]中的倒数第3项
	CustomerID string `llp:"10.-2"` // 客户 ID,提取第10+1个[]中的倒数第2项
	DeviceID   string `llp:"10.-1"` // 设备 ID,提取第10+1个[]中的倒数第1项

	// 例如:捕获 request: "POST /dsvs/v1/pkcs1/verifyDigestSign HTTP/1.1" 中的 POST 部分
	Method string `llp:"reg" reg:"request: \"([A-Z]+)"` // 使用正则表达式捕获,默认捕获组 1
	// 例如:捕获 host: "192.168.108.11:8081" 中的 192.168.108.11:8081 部分
	Host string `llp:"reg" reg:"host: \"(.*?)\"" group:"1"` // 使用正则表达式捕获,捕获组序号 1
}

var logLineParser, _ = loglineparser.New(&LogLine{})

// ParseLogLine 解析一行日志
func ParseLogLine(line string) (*LogLine, error) {
	v, err := logLineParser.Parse(line)
	if err != nil {
		return nil, err
	}

	return v.(*LogLine), nil
}

其中,结构体LogLine各个字段tag中的llp(loglineparser的缩写)部分,使用以下表达方式:

  1. x 表示取第x个(从0开始)提取值,并且根据需要,进行合适的类型转换。
  2. x.y 表示取第x个(从0开始)提取值的第y个(从0开始)子值,进行合适的类型转换。

如果需要实现自定义解码,可以参考以下示例:

package yourawesomepackage

import (
	"encoding/json"
	"errors"
	"github.com/bingoohuang/loglineparser"
	"github.com/stretchr/testify/assert"
	"net"
	"testing"
	"time"
)

type MyIP net.IP

func (i *MyIP) Unmarshal(v string) error {
	ip := net.ParseIP(v)
	if ip == nil {
		return errors.New("bad format ip " + v)
	}
	*i = MyIP(ip)

	return nil
}

type LogLine struct {
	LogType      string     `llp:"2"`
	UserTime     time.Time  `llp:"3.0"`
	UserClientIP MyIP       `llp:"3.1"`
}


var logLineParser, _ = loglineparser.New(&LogLine{})

func TestCustomDecode(t *testing.T) {
	line := `2018/10/18 20:46:45 [notice] 19002#0: *53103423 [lua] gateway.lua:163: log_base(): [GatewayMonV2], [1539866805.135, 192.168.106.8, -, 208] [x,y] xxxxx`

	v, err := logLineParser.Parse(line)

	assert.Nil(t, err)
	assert.Equal(t, LogLine{
		LogType:      "GatewayMonV2",
		UserTime:     loglineparser.ParseTime("1539866805.135"),
		UserClientIP: MyIP(net.ParseIP("192.168.106.8")),
	}, *v)
}

运行测试

  1. 运行测试用例 go fmt ./...; go test ./... -v -count=1
  2. 运行基准用例 go test -bench=.
$ go test ./...
ok  	github.com/bingoohuang/loglineparser	0.013s

$ go test -bench=.
*loglineparser_test.Papa
goos: darwin
goarch: amd64
pkg: github.com/bingoohuang/loglineparser
BenchmarkParseGatewayMonV2-12          	   20000	     97816 ns/op
BenchmarkFastParseGatewayMonV2-12      	   20000	     81113 ns/op
BenchmarkMakeBracketPartSplitter-12    	   30000	     52485 ns/op
PASS
ok  	github.com/bingoohuang/loglineparser	4.730s

97816 Nanoseconds = 0.097816 Milliseconds

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AssignBasicValue

func AssignBasicValue(f reflect.Value, v interface{}) bool

AssignBasicValue assigns v as basic types lie string/(u)int(8/16/32/64) or its type self.

func IsAlphanumeric

func IsAlphanumeric(s string) bool

IsAlphanumeric tells if the string contains only alphanumeric characters(a-zA-Z0-9).

func IsBlank

func IsBlank(str string) bool

IsBlank checks if a string is whitespace or empty (""). Observe the following behavior:

IsBlank("")        = true
IsBlank(" ")       = true
IsBlank("bob")     = false
IsBlank("  bob  ") = false

Parameter:

str - the string to check

Returns:

true - if the string is whitespace or empty ("")

func ParseBool

func ParseBool(s string, defaultValue bool) bool

ParseBool parse s as bool or return defaultValue.

func ParseFloat32

func ParseFloat32(s string, defaultValue float32) float32

ParseFloat32 parse s as float or return defaultValue.

func ParseInt

func ParseInt(s string) *int

ParseInt parse s as int.

func ParseTime

func ParseTime(s interface{}) time.Time

ParseTime parses s as a time.Time.

func Split2

func Split2(s, sep string) (s0, s1 string)

Split2 将s按分隔符sep分成x份,取第x份,取第1、2、...份

func SplitN

func SplitN(s, sep string, trimSpace, ignoreEmpty bool) []string

SplitN splits a string

func UnmarshalMap

func UnmarshalMap(s string) map[string]string

UnmarshalMap unmarshals s to a map[string]string

Types

type GatewayMonV2

type GatewayMonV2 struct {
	LogType       string `llp:"2" json:"logType"` // GatewayMonV2
	GatewayStatus string `llp:"3" json:"gatewayFlag"`
	APIVersionID  string `llp:"4" json:"apiVersionId"`

	RespStatus            string    `llp:"5.0" json:"respStatus"`
	RespResponseTime      float32   `llp:"5.1" json:"respResponseTime"`
	RespInnerResponseTime float32   `llp:"5.2" json:"respInnerResponseTime"`
	RespInnerStartReqTime time.Time `llp:"5.3" json:"respInnerStartReqTime"`
	RespBodySize          int       `llp:"5.4" json:"respBodySize"`

	UserTime     time.Time `llp:"6.0" json:"reqTime"`
	UserClientIP string    `llp:"6.1" json:"userClientIP"`
	UserUID      string    `llp:"6.2" json:"userUid"`
	RequestSize  int       `llp:"6.3" json:"requestSize"`

	RequestID string `llp:"7.0" json:"requestId"`
	TraceID   string `llp:"7.1" json:"TraceId"`
	ServiceID string `llp:"7.2" json:"serviceId"`

	AuthIsLocalIP          bool   `llp:"8.0" json:"authIsLocalIP"`
	AuthKeySecretCheckRst  string `llp:"8.1" json:"authKeySecretCheckRst"`
	AuthSessionCheckRst    string `llp:"8.2" json:"authSessionCheckRst"`
	AuthSid                string `llp:"8.3" json:"authSid"`
	AuthUcenterPlatform    string `llp:"8.4" json:"authUcenterPlatform"`
	AuthCheckLoginTokenRst string `llp:"8.5" json:"authCheckLoginTokenRst"`
	AuthCookie             string `llp:"8.6" json:"authCookie"`
	AuthInvalidMsg         string `llp:"8.7" json:"authInvalidMsg"`

	APISessionVarMap map[string]string `llp:"9" json:"apiSessionVarMap"`

	UserRealIP        string `llp:"10.0" json:"userRealIP"`
	UserUa            string `llp:"10.1" json:"userUa"`
	LastHop           string `llp:"10.2" json:"lastHop"`
	UserXForwardedFor string `llp:"10.3" json:"userXForwardedFor"`

	RequestBody string `llp:"11" json:"requestBody"`
	RespBody    string `llp:"12" json:"respBody"`

	AnchorInitVar         string `llp:"13.0" json:"anchorInitVar"`
	AnchorSearchAPI       string `llp:"13.1" json:"anchorSearchApi"`
	AnchorCheckDevelop    string `llp:"13.2" json:"anchorCheckDevelop"`
	AnchorCheckApp        string `llp:"13.3" json:"anchorCheckApp"`
	AnchorCheckSession    string `llp:"13.4" json:"anchorCheckSession"`
	AnchorCheckSafe       string `llp:"13.5" json:"anchorCheckSafe"`
	AnchorStartRequest    string `llp:"13.6" json:"anchorStartRequest"`
	AnchorProduceCookie   string `llp:"13.7" json:"anchorProduceCookie"`
	AnchorEncryptCookie   string `llp:"13.8" json:"anchorEncryptCookie"`
	AnchorProduceResponse string `llp:"13.9" json:"anchorProduceResponse"`
	AnchorOutputLog       string `llp:"13.10" json:"anchorOutputLog"`

	Method string `llp:"reg" reg:"request: \"([A-Z]+)"` // 使用正则表达式捕获,默认捕获组
	//  host: "192.168.108.11:8081"
	Host string `llp:"reg" reg:"host: \"(.*?)\"" group:"1"` // 使用正则表达式捕获,默认捕获组
}

GatewayMonV2 is a special log line format for ngx gateway.

func FastCreateGatewayMonV2

func FastCreateGatewayMonV2(line string) GatewayMonV2

FastCreateGatewayMonV2 ... nolint funlen

type LogLineParser

type LogLineParser struct {
	FieldsCache  StructFieldsCache
	StructType   reflect2.Type
	Ptr          bool
	PartSplitter PartSplitter
	SubSplitter  PartSplitter
}

LogLineParser defines the struct representing parser for log line.

func New

func New(structPointerOrName interface{}) (*LogLineParser, error)

New creates a new LogLineParser.

func (*LogLineParser) Parse

func (l *LogLineParser) Parse(line string) (interface{}, error)

Parse parses a line string.

type PartSplitter

type PartSplitter interface {
	// Parse 解析成各个部分
	Parse(s string) []string
}

PartSplitter 表示日志行分割器

func NewBracketPartSplitter

func NewBracketPartSplitter(emptyPlaceholder string) PartSplitter

NewBracketPartSplitter creates a new instance of PartSplitter.

func NewSubSplitter

func NewSubSplitter(sep, emptyPlaceholder string) PartSplitter

NewSubSplitter creates a new PartSplitter.

type StructFieldsCache

type StructFieldsCache struct {
	// contains filtered or unexported fields
}

StructFieldsCache defines the cache of struct fields.

func (*StructFieldsCache) CachedStructFields

func (s *StructFieldsCache) CachedStructFields(t reflect.Type,
	fn func(fieldIndex int, f reflect.StructField) interface{},
) interface{}

CachedStructFields caches fields of struct type

type Unmarshaler

type Unmarshaler interface {
	Unmarshal(string) error
}

Unmarshaler defines the interface for unmarshaling from a string.

Jump to

Keyboard shortcuts

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