Categorygithub.com/DataWorkbench/glog
modulepackage
0.0.0-20220707065325-9c6ad406158f
Repository: https://github.com/dataworkbench/glog.git
Documentation: pkg.go.dev

# README

glog

A log designed for critical mission.

The glog package provides a fast and simple logger dedicated to TEXT/JSON output

Features

  • Sampling and fast
  • Low to zero allocation
  • Level logging
  • Additional fields
  • context.Context integration
  • JSON and TEXT encoding formats
  • User-define Encoder
  • User-define Exporter

Installation

go get -u github.com/DataWorkbench/glog

Used in go modules

go get -insecure github.com/DataWorkbench/glog

Quick Start

Simple Logging Example

package main

import (
	"github.com/DataWorkbench/glog"
)

func main() {
    // By default, the log message will output to os.Stdout
	l := glog.NewDefault()

	l.Debug().Msg("HelloWorld").String("s1", "v1").Int64("i1", 1).Fire()

	/* Output:
	2020-11-04T18:01:40.945196+08:00 [debug] HelloWorld s1=v1 i1=1
	*/
}

Add fixed fields into logger

package main

import (
	"github.com/DataWorkbench/glog"
)

func main() {
	l := glog.NewDefault()
	l.WithFields().AddString("requestid", "8da3aceea1ba")

	l.Debug().Msg("HelloWorld").String("s1", "v1").Int64("i1", 1).Fire()

	/* Output:
	2020-11-04T18:00:56.050655+08:00 [debug] HelloWorld s1=v1 i1=1 requestid=8da3aceea1ba
	*/
}

Set the logger level

package main

import (
	"github.com/DataWorkbench/glog"
)

func main() {
	l := glog.NewDefault()
	l.WithLevel(glog.InfoLevel)
	
	// The debug log will be ignored
	l.Debug().Msg("Hello Debug Message").Fire()
	l.Info().Msg("Hello Info Message").Fire()

	/* Output:
	2020-11-04T17:58:23.958602+08:00 [info] Hello Info Message
	*/
}

Set Time Format

package main

import (
	"time"

	"github.com/DataWorkbench/glog"
)

func main() {
	l := glog.NewDefault()
	l.WithTimeLayout(time.RFC822)

	l.Debug().Msg("HelloWorld").String("s1", "v1").Int64("i1", 1).Fire()

	/* Output:
	04 Nov 20 18:05 CST [debug] HelloWorld s1=v1 i1=1
	*/
}

Add caller info into log message

package main

import (
	"github.com/DataWorkbench/glog"
)

func main() {
	l := glog.NewDefault()
	l.WithCaller(true)

	l.Debug().Msg("HelloWorld").String("s1", "v1").Int64("i1", 1).Fire()

	/* Output:
	2020-11-04T18:06:13.151354+08:00 [debug] HelloWorld s1=v1 i1=1 (github.com/DataWorkbench/glog/examples/main.go:11)
	*/
}

Write log message into file

package main

import (
	"fmt"

	"github.com/DataWorkbench/glog"
)

func main() {
	logfile := "/tmp/testglog.log"
	exporter, err := glog.FileExporter(logfile, nil)
	if err != nil {
		fmt.Println("open file error:", err)
		return
	}
	defer exporter.Close()

	l := glog.NewDefault()
	l.WithExporter(exporter)

	l.Debug().Msg("Hello logfile").Fire()

	/* Output:
	$ cat /tmp/testglog.log
	2020-11-04T18:22:21.726335+08:00 [debug] Hello logfile
	*/
}

Use with context.Context

package main

import (
	"context"

	"github.com/DataWorkbench/glog"
)

func main() {
	// store logger into a context.Value
	ctx := glog.WithContext(context.Background(), glog.NewDefault())

	// get logger from context.Value
	l := glog.FromContext(ctx)

	l.Debug().Msg("Hello Context").Fire()

	/* Output:
	2020-11-04T21:15:21.002094+08:00 [debug] Hello Context
	*/
}

Use JSON Format

package main

import (
	"github.com/DataWorkbench/glog"
)

func main() {
	l := glog.NewDefault()
	l.WithEncoderFunc(glog.JSONEncoder)
	l.WithFields().AddString("requestid", "8da3aceea1ba")

	l.Debug().Msg("HelloWorld").String("s1", "v1").Int64("i1", 1).Fire()

	/* Output:
	{"time":"2020-11-04T18:27:41.080215+08:00","level":"debug","message":"HelloWorld","s1":"v1","i1":1"requestid":"8da3aceea1ba"}
	*/
}

Clone from a exits logger

package main

import (
	"github.com/DataWorkbench/glog"
)

func main() {
	l := glog.NewDefault()
	l.WithFields().AddString("requestid", "8da3aceea1ba")

	l.Debug().Msg("HelloWorld One").Fire()

	/* Output:
	2020-11-04T18:34:32.816702+08:00 [debug] HelloWorld One requestid=8da3aceea1ba
	*/

	// clone logger will
	lc := l.Clone()
	lc.WithFields().AddString("dup1", "dup-value")

	lc.Debug().Msg("Hello Clone Logger").Fire()

	/* Output:
	2020-11-04T18:34:32.816847+08:00 [debug] Hello Clone Logger requestid=8da3aceea1ba dup1=dup-value
	*/

	// any changed in close logger does not affects the sources
	lc.WithCaller(true)
	l.Debug().Msg("HelloWorld Two").Fire()

	/* Output:
	2020-11-04T18:34:32.816851+08:00 [debug] HelloWorld Two requestid=8da3aceea1ba
	*/
}

Write log message into multiple file

package main

import (
	"fmt"

	"github.com/DataWorkbench/glog"
)

func main() {
	logFile := "/tmp/testglog.log"
	errLogFile := "/tmp/testglog.log.wf"

	e1, err := glog.FileExporter(logFile, glog.MatchGELevel(glog.DebugLevel))
	if err != nil {
		fmt.Println("open log file fail:", err)
		return
	}

	e2, err := glog.FileExporter(errLogFile, glog.MatchGELevel(glog.ErrorLevel))
	if err != nil {
		fmt.Println("open error log file fail:", err)
		return
	}

	l := glog.NewDefault()
	l.WithExporter(glog.MultipleExporter(e1, e2))

	l.Debug().Msg("DebugMessage").Fire()
	l.Info().Msg("InfoMessage").Fire()
	l.Error().Msg("ErrorMessage").Fire()
	l.Fatal().Msg("FatalMessage").Fire()

	/* Output:
	$cat /tmp/testglog.log
	2020-11-04T21:09:50.828122+08:00 [debug] DebugMessage
	2020-11-04T21:09:50.828354+08:00 [info] InfoMessage
	2020-11-04T21:09:50.828365+08:00 [error] ErrorMessage
	2020-11-04T21:09:50.828394+08:00 [fatal] FatalMessage

	$cat /tmp/testglog.log.wf
	2020-11-04T21:09:50.828365+08:00 [error] ErrorMessage
	2020-11-04T21:09:50.828394+08:00 [fatal] FatalMessage
	*/
}

Benchmarks

BenchmarkNewDefault-48     	 3656020	       332 ns/op	     392 B/op	       4 allocs/op
BenchmarkLogEmpty-48       	19264894	        60.5 ns/op	      40 B/op	       2 allocs/op
BenchmarkDisabled-48       	1000000000	         0.164 ns/op	       0 B/op	       0 allocs/op
BenchmarkInfo-48           	17027442	        64.3 ns/op	      40 B/op	       2 allocs/op
BenchmarkWithFields-48     	18255840	        65.5 ns/op	      40 B/op	       2 allocs/op
BenchmarkLogFields-48      	12839894	        88.3 ns/op	      40 B/op	       2 allocs/op
BenchmarkLog10Fields-48    	 8441210	       128 ns/op	      75 B/op	       4 allocs/op
BenchmarkLog10String-48    	14184310	        90.9 ns/op	      40 B/op	       2 allocs/op
BenchmarkLog10Int64-48     	10568299	        99.8 ns/op	      40 B/op	       2 allocs/op

References

Inspired by following projects:

# Packages

No description provided by the author

# Functions

AppendDuration encode the time.Duration to a strings by specified layout.
AppendStringEscape encodes the input string to buffer.Buffer The operation loops though each byte in the string looking for characters that need json or utf8 encoding.
FilterExporter return a Exporter implements by matcherExporter; This used to write only the specified level of Entry.
FromContext get *Logger from context.
FromContextDefault get *Logger from context.
JSONEncoder return a new encoder implements by jsonEncoder.
MatchEQLevel used to match an level is equal the level(`lvl`).
MatchGTELevel used to match an level is granter than or equal the specified level(`lvl`).
MatchGTLevel used to match an level is granter than the level(`lvl`).
MatchLTELevel used to match an level is less than or equal the level(`lvl`).
MatchLTLevel used to match an level is less than the level(`lvl`).
MatchNELevel used to match an level is not equal the level(`lvl`).
MultipleExporter used for apply multiple Exporter to a Entry.
No description provided by the author
NopWriterCloser returns a ReadCloser with a no-op Close method wrapping the provided Reader r.
StandardExporter return a Exporter implements by standardExporter.
TextEncoder return a new encoder implements by textEncoder.
WithContext set *Logger into context and returned with given ctx.

# Constants

DebugLevel defines debug log level.
Defines the format type for time.Duration.
Defines the format type for time.Duration.
Defines the format type for time.Duration.
Defines the format type for time.Duration.
Defines the format type for time.Duration.
Defines the format type for time.Duration.
ErrorLevel defines error log level.
FatalLevel defines fatal log level.
InfoLevel defines info log level.
NoLevel is the lowest level.
TimeFormatUnixMicro defines a time format that makes time fields to be serialized as Unix timestamp integers in microseconds.
TimeFormatUnixMilli defines a time format that makes time fields to be serialized as Unix timestamp integers in milliseconds.
TimeFormatUnixNano defines a time format that makes time fields to be serialized as Unix timestamp integers in nanoseconds.
TimeFormatUnixSecond defines a time format that makes time fields to be serialized as Unix timestamp integers in seconds.
WarnLevel defines warn log level.

# Variables

No description provided by the author

# Structs

Entry
Entry used to build a log record.
Logger declares the logger.
Record represents the Entry's content.

# Interfaces

ArrayEncoder used to add array-type field.
ArrayMarshaler allows user-defined data types to efficiently add an array into to the log entry.
BuildEncoder used to add some specific fields.
No description provided by the author
Exporter used to handle the Entry.
FieldEncoder used to add single elements.
Filter used to control the export behavior in Exporter.
ObjectEncoder used to add an k/v field.
ObjectMarshaler allows user-defined data types to efficiently add an object into to the log entry.

# Type aliases

ArrayMarshalerFunc is a type adapter that turns a function into an ArrayMarshaler.
EncoderFunc used to return a new Encoder instances.
Level declares log level.
MatchFunc is wrappers for match the specified level.
ObjectMarshalerFunc is a type adapter that turns a function into an ObjectMarshaler.