ltsvlog

package module
v2.0.4+incompatible Latest Latest
Warning

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

Go to latest
Published: Jul 3, 2017 License: MIT Imports: 9 Imported by: 9

README

ltsvlog Build Status Go Report Card GoDoc MIT licensed

ltsvlog is a minimalist LTSV; Labeled Tab-separated Values logging library in Go. See https://godoc.org/github.com/hnakamur/ltsvlog for the API document.

I wrote a blog article about this library in Japanese: GoでLTSV形式でログ出力するライブラリを書いた · hnakamur's blog at github.

An example code and output

An example code:

package main

import (
	"errors"
	"fmt"

	"github.com/hnakamur/ltsvlog"
)

func main() {
	if ltsvlog.Logger.DebugEnabled() {
		ltsvlog.Logger.Debug().String("msg", "This is a debug message").
			String("str", "foo").Int("int", 234).Log()
	}

	ltsvlog.Logger.Info().Sprintf("float1", "%3.2f", 3.14).Log()

	err := a()
	if err != nil {
		ltsvlog.Logger.Err(err)
	}
}

func a() error {
	err := b()
	if err != nil {
		return ltsvlog.WrapErr(err, func(err error) error {
			return fmt.Errorf("add explanation here, err=%v", err)
		})
	}
	return nil
}

func b() error {
	return ltsvlog.Err(errors.New("some error")).String("key1", "value1").Stack("")
}

An example output:

time:2017-06-01T16:52:33.959833Z	level:Debug	msg:This is a debug message	str:foo	int:234
time:2017-06-01T16:52:33.959862Z	level:Info	float1:3.14
time:2017-06-01T16:52:33.959914Z	level:Error	err:add explanation here, err=some error       key1:value1     stack:main.b github.com/hnakamur/ltsvlog/example/main.go:43,main.a github.com/hnakamur/ltsvlog/example/main.go:33,main.main github.com/hnakamur/ltsvlog/example/main.go:21,runtime.main runtime/proc.go:194,runtime.goexit runtime/asm_amd64.s:2338

Since these log lines ar long, please scroll horizontally to the right to see all the output.

Benchmark result

hnakamur/go-log-benchmarks

License

MIT

Documentation

Overview

Package ltsvlog is a minimalist logging library for writing logs in LTSV (Labeled Tab-separated Value) format. See http://ltsv.org/ for LTSV.

This logging library has three log levels: Debug, Info and Error. The Info and Error levels are always enabled. You can disable the Debug level but only when you create a logger.

Each log record is printed as one line. A line has multiple fields separated by a tab character. Each field has a label and a value which are separated by a colon ':' character.

So you must not contain a colon character in labels. This is not checked in this library for performance reason, so it is your responsibility not to contain a colon character in labels.

Newline, tab, and backslach characters in values are escaped with "\\n", "\\t", and "\\\\" respectively. Show the example for Event.String.

Index

Examples

Constants

This section is empty.

Variables

Logger is the global logger. You can change this logger like ltsvlog.Logger = ltsvlog.NewLTSVLogger(os.Stdout, false) You can change the global logger safely only before writing to the logger. Changing the logger while writing may cause the unexpected behavior.

Functions

This section is empty.

Types

type Discard added in v0.9.3

type Discard struct{}

Discard discards any logging outputs.

func (*Discard) Debug added in v0.9.3

func (*Discard) Debug() *Event

Debug prints nothing. Note there still exists the cost of evaluating argument values, even though they are not used. Guarding with if and DebugEnabled is recommended.

func (*Discard) DebugEnabled added in v0.9.3

func (*Discard) DebugEnabled() bool

DebugEnabled always return false

func (*Discard) Err added in v1.5.0

func (*Discard) Err(err error)

Err prints nothing.

func (*Discard) Info added in v0.9.3

func (*Discard) Info() *Event

Info prints nothing. Note there still exists the cost of evaluating argument values, even though they are not used.

type Error

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

Error is an error with label and value pairs. *Error implements the error interface so you can return *Error as an error.

This is useful when you would like to log an error with additional labeled values later at the higher level of the callstack.

Error frees lower level functions from depending on loggers since Error is just a data structure which holds an error, a stacktrace and labeled values.

Please see the example at LTSVLogger.Err for an example usage.

func Err added in v1.5.0

func Err(err error) *Error

Err creates an Error with the specified error.

func WrapErr added in v1.5.2

func WrapErr(err error, wrapper func(err error) error) *Error

WrapErr wraps an Error or a plain error and returns a new error.

func (*Error) AppendErrorWithValues

func (e *Error) AppendErrorWithValues(buf []byte) []byte

AppendErrorWithValues appends the error string with labeled values to a byte buffer.

func (*Error) Bool

func (e *Error) Bool(label string, value bool) *Error

Bool appends a labeled bool value to Error.

func (*Error) Byte

func (e *Error) Byte(label string, value byte) *Error

Byte appends a labeled byte value to Error.

func (*Error) Bytes

func (e *Error) Bytes(label string, value []byte) *Error

Bytes appends a labeled bytes value in hex format to Error.

func (*Error) Error

func (e *Error) Error() string

Error returns the error string without labeled values.

func (*Error) Float32

func (e *Error) Float32(label string, value float32) *Error

Float32 appends a labeled float32 value to Error.

func (*Error) Float64

func (e *Error) Float64(label string, value float64) *Error

Float64 appends a labeled float64 value to Error.

func (*Error) Fmt

func (e *Error) Fmt(label, format string, a ...interface{}) *Error

Fmt appends a labeled formatted string value to Event.

func (*Error) Format

func (e *Error) Format(s fmt.State, c rune)

Format formats the error. With "%v" and "%s", just the error string is returned. With "%+v", the error string with labeled values in LTSV format is returned. With "%q", just the quoted error string is returned. With "%+q", the quoted error string with labled values in LTSV format is returned.

func (*Error) Int

func (e *Error) Int(label string, value int) *Error

Int appends a labeled int value to Error.

func (*Error) Int16

func (e *Error) Int16(label string, value int16) *Error

Int16 appends a labeled int16 value to Error.

func (*Error) Int32

func (e *Error) Int32(label string, value int32) *Error

Int32 appends a labeled int32 value to Error.

func (*Error) Int64

func (e *Error) Int64(label string, value int64) *Error

Int64 appends a labeled int64 value to Error.

func (*Error) Int8

func (e *Error) Int8(label string, value int8) *Error

Int8 appends a labeled int8 value to Error.

func (*Error) OriginalError

func (e *Error) OriginalError() error

OriginalError returns the original error.

func (*Error) Sprintf

func (e *Error) Sprintf(label, format string, a ...interface{}) *Error

DEPRECATED: Use Fmt instead.

Sprintf appends a labeled formatted string value to Error.

func (*Error) Stack

func (e *Error) Stack(label string) *Error

Stack appends a stacktrace with label "stack" to Error. If label is empty, "stack" is used.

func (*Error) String

func (e *Error) String(label string, value string) *Error

String appends a labeled string value to Error.

func (*Error) Stringer

func (e *Error) Stringer(label string, value fmt.Stringer) *Error

Stringer appends a labeled string value to Error. The value will be converted to a string with String() method.

func (*Error) Time

func (e *Error) Time(label string, value time.Time, format string) *Error

Time appends a labeled formatted time value to Error. The format is the same as that in the Go standard time package. If the format is empty, time.RFC3339 is used.

func (*Error) UTCTime

func (e *Error) UTCTime(label string, value time.Time) *Error

UTCTime appends a labeled time value to Error. The time value is converted to UTC and then printed in the same format as the log time field, that is the ISO8601 format with microsecond precision and the timezone "Z".

func (*Error) Uint

func (e *Error) Uint(label string, value uint) *Error

Uint appends a labeled uint value to Error.

func (*Error) Uint16

func (e *Error) Uint16(label string, value uint16) *Error

Uint16 appends a labeled uint16 value to Error.

func (*Error) Uint32

func (e *Error) Uint32(label string, value uint32) *Error

Uint32 appends a labeled uint32 value to Error.

func (*Error) Uint64

func (e *Error) Uint64(label string, value uint64) *Error

Uint64 appends a labeled uint64 value to Error.

func (*Error) Uint8

func (e *Error) Uint8(label string, value uint8) *Error

Uint8 appends a labeled uint8 value to Error.

type Event added in v1.5.0

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

Event is a temporary object for building a log record of Debug or Info level.

func (*Event) Bool added in v1.5.0

func (e *Event) Bool(label string, value bool) *Event

Bool appends a labeled bool value to Event.

func (*Event) Byte added in v1.5.0

func (e *Event) Byte(label string, value byte) *Event

Byte appends a labeled byte value to Event.

func (*Event) Bytes added in v1.5.0

func (e *Event) Bytes(label string, value []byte) *Event

Bytes appends a labeled bytes value in hex format to Event.

func (*Event) Float32 added in v1.5.0

func (e *Event) Float32(label string, value float32) *Event

Float32 appends a labeled float32 value to Event.

func (*Event) Float64 added in v1.5.0

func (e *Event) Float64(label string, value float64) *Event

Float64 appends a labeled float64 value to Event.

func (*Event) Fmt

func (e *Event) Fmt(label, format string, a ...interface{}) *Event

Fmt appends a labeled formatted string value to Event.

func (*Event) Format

func (e *Event) Format(s fmt.State, c rune)

Format formats the error. With "%v" and "%s", labeled values are appended to the message in LTSV format. With "%q", quoted LTSV format string is returned.

func (*Event) Int added in v1.5.0

func (e *Event) Int(label string, value int) *Event

Int appends a labeled int value to Event.

func (*Event) Int16 added in v1.5.0

func (e *Event) Int16(label string, value int16) *Event

Int16 appends a labeled int16 value to Event.

func (*Event) Int32 added in v1.5.0

func (e *Event) Int32(label string, value int32) *Event

Int32 appends a labeled int32 value to Event.

func (*Event) Int64 added in v1.5.0

func (e *Event) Int64(label string, value int64) *Event

Int64 appends a labeled int64 value to Event.

func (*Event) Int8 added in v1.5.0

func (e *Event) Int8(label string, value int8) *Event

Int8 appends a labeled int8 value to Event.

func (*Event) Log added in v1.5.0

func (e *Event) Log()

Log writes this event if the logger which created this event is enabled, and puts the event back to the event pool.

func (*Event) Sprintf added in v1.5.0

func (e *Event) Sprintf(label, format string, a ...interface{}) *Event

DEPRECATED: Use Fmt instead.

Sprintf appends a labeled formatted string value to Event.

func (*Event) String added in v1.5.0

func (e *Event) String(label string, value string) *Event

String appends a labeled string value to Event.

Example
package main

import (
	"github.com/hnakamur/ltsvlog"
)

func main() {
	jsonStr := "{\n\t\"foo\": \"bar\\nbaz\"\n}\n"
	ltsvlog.Logger.Info().String("json", jsonStr).Log()

	// Output example:
	// time:2017-06-10T10:22:48.083226Z        level:Info      json:{\n\t"foo": "bar\\nbaz"\n}\n
	
Output:

func (*Event) Stringer added in v1.5.1

func (e *Event) Stringer(label string, value fmt.Stringer) *Event

Stringer appends a labeled string value to Event. The value will be converted to a string with String() method.

func (*Event) Time added in v1.5.0

func (e *Event) Time(label string, value time.Time, format string) *Event

Time appends a labeled formatted time value to Event. The format is the same as that in the Go standard time package. If the format is empty, time.RFC3339 is used.

func (*Event) UTCTime added in v1.5.0

func (e *Event) UTCTime(label string, value time.Time) *Event

UTCTime appends a labeled UTC time value to Event. The time value is converted to UTC and then printed in the same format as the log time field, that is the ISO8601 format with microsecond precision and the timezone "Z".

func (*Event) Uint added in v1.5.0

func (e *Event) Uint(label string, value uint) *Event

Uint appends a labeled uint value to Event.

func (*Event) Uint16 added in v1.5.0

func (e *Event) Uint16(label string, value uint16) *Event

Uint16 appends a labeled uint16 value to Event.

func (*Event) Uint32 added in v1.5.0

func (e *Event) Uint32(label string, value uint32) *Event

Uint32 appends a labeled uint32 value to Event.

func (*Event) Uint64 added in v1.5.0

func (e *Event) Uint64(label string, value uint64) *Event

Uint64 appends a labeled uint64 value to Event.

func (*Event) Uint8 added in v1.5.0

func (e *Event) Uint8(label string, value uint8) *Event

Uint8 appends a labeled uint8 value to Event.

type LTSVLogger

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

LTSVLogger is a LTSV logger.

func NewLTSVLogger

func NewLTSVLogger(w io.Writer, debugEnabled bool, options ...Option) *LTSVLogger

NewLTSVLogger creates a LTSV logger with the default time and value format.

The folloing two values are prepended to each log line.

The first value is the current time, and has the default label "time". The time format is RFC3339 with microseconds in UTC timezone. This format is the same as "2006-01-02T15:04:05.000000Z" in the go time format https://golang.org/pkg/time/#Time.Format

The second value is the log level with the default label "level".

Example
package main

import (
	"os"

	"github.com/hnakamur/ltsvlog"
)

func main() {
	// Change the global logger to a logger which does not print level values.
	ltsvlog.Logger = ltsvlog.NewLTSVLogger(os.Stdout, true, ltsvlog.SetLevelLabel(""))
	
Output:

func (*LTSVLogger) Debug

func (l *LTSVLogger) Debug() *Event

Debug returns a new Event for writing a Debug level log. This Event is returned from the internal event pool, so be sure to call Log() to put this event back to the event pool.

Note there still exists the cost of evaluating argument values if the debug level is disabled, even though those arguments are not used. So guarding with if and DebugEnabled is recommended.

Example
package main

import (
	"github.com/hnakamur/ltsvlog"
)

func main() {
	if ltsvlog.Logger.DebugEnabled() {
		n := 234
		ltsvlog.Logger.Debug().String("msg", "This is a debug message").
			String("key", "key1").Int("intValue", n).Log()
	}

	// Output example:
	// time:2017-05-20T19:12:10.883958Z	level:Debug	msg:This is a debug message	key:key1	intValue:234
	
Output:

func (*LTSVLogger) DebugEnabled

func (l *LTSVLogger) DebugEnabled() bool

DebugEnabled returns whether or not the debug level is enabled. You can avoid the cost of evaluation of arguments passed to Debug like:

if ltsvlog.Logger.DebugEnabled() {
    ltsvlog.Logger.Debug().String("label1", someSlowFunction()).Log()
}

func (*LTSVLogger) Err added in v1.5.0

func (l *LTSVLogger) Err(err error)

Err writes a log for an error with the error level. If err is a *Error, this logs the error with labeled values. If err is not a *Error, this logs the error with the label "err".

Example
package main

import (
	"errors"
	"fmt"

	"github.com/hnakamur/ltsvlog"
)

func main() {
	b := func() error {
		return ltsvlog.Err(errors.New("some error")).String("key1", "value1").Stack("")
	}
	a := func() error {
		err := b()
		if err != nil {
			return ltsvlog.WrapErr(err, func(err error) error {
				return fmt.Errorf("add explanation here, err=%v", err)
			}).String("key2", "value2")
		}
		return nil

	}
	err := a()
	if err != nil {
		ltsvlog.Logger.Err(err)
	}

	// Output example:
	// time:2017-06-10T13:40:38.344079Z	level:Error	err:add explanation here, err=some error	key1:value1	stack:main.main.func1 github.com/hnakamur/ltsvlog/example/err/main.go:12,main.main.func2 github.com/hnakamur/ltsvlog/example/err/main.go:15,main.main github.com/hnakamur/ltsvlog/example/err/main.go:24,runtime.main runtime/proc.go:194,runtime.goexit runtime/asm_amd64.s:2338	key2:value2
	
Output:

func (*LTSVLogger) Info

func (l *LTSVLogger) Info() *Event

Info returns a new Event for writing a Info level log. This Event is returned from the internal event pool, so be sure to call Log() to put this event back to the event pool.

Example
package main

import (
	"github.com/hnakamur/ltsvlog"
)

func main() {
	ltsvlog.Logger.Info().String("msg", "goodbye, world").String("foo", "bar").
		Sprintf("nilValue", "%v", nil).Bytes("bytes", []byte("a/b")).Log()

	// Output example:
	// time:2017-05-20T19:16:11.798840Z	level:Info	msg:goodbye, world	foo:bar	nilValue:<nil>	bytes:0x612f62
	
Output:

type LogWriter added in v0.9.3

type LogWriter interface {
	DebugEnabled() bool
	Debug() *Event
	Info() *Event
	Err(err error)
}

LogWriter is a LTSV logger interface

type Option added in v1.0.0

type Option func(l *LTSVLogger)

Option is the function type to set an option of LTSVLogger

func SetLevelLabel added in v1.0.0

func SetLevelLabel(label string) Option

SetLevelLabel returns the option function to set the level label. If the label is empty, loggers do not print level values.

func SetTimeLabel added in v1.0.0

func SetTimeLabel(label string) Option

SetTimeLabel returns the option function to set the time label. If the label is empty, loggers do not print time values.

Jump to

Keyboard shortcuts

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