xylog

package module
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Jan 13, 2023 License: MIT Imports: 14 Imported by: 3

README

xybor founder Go Reference GitHub Repo stars GitHub top language GitHub go.mod Go version GitHub release (release name instead of tag name) Codacy Badge Codacy Badge Go Report

Introduction

Package xylog is designed for leveled and structured logging, dynamic fields, high performance, zone management, simple configuration, and readable syntax.

The library is combined by python logging design and zap encoding approach.

Quick start

You can easily configure a logger with SimpleConfig.

There are some fields you can modify with this way (note that all fields are optional):

  • Name is the name of Logger. It can be used later with GetLogger function. Default to an empty name (the root logger).

  • Encoding to format the output. Default to TextEncoding.

  • Filename specifies that Logger will write the output to a file. Do NOT use together with Writer.

  • Filemode specifies the mode to open file. Default to APPEND | CREATE | WRONLY.

  • Fileperm specifies the permission when creating the file. Default to 0666.

  • Level specifies the logging level. Default to WARNING.

  • TimeLayout when format the time string. Default to RFC3339Nano.

  • Writer specifies that Logger will write the output to a file. Do NOT use together with Filename.

var config = &xylog.SimpleConfig{
    Name:   "simple-logger",
    Level:  xylog.DEBUG,
    Writer: os.Stdout,
}

var logger, err = config.AddMacro("level", "levelname").Apply()
if err != nil {
    fmt.Println("An error occurred:", err)
    os.Exit(1)
}
defer xylog.Flush()

logger.Debug("logging message")
logger.Event("create-user").Field("username", "foo").
    Field("email", "bar@buzz.com").Field("Age", 25).Info()

// Output:
// level=DEBUG messsage="logging message"
// level=INFO event=create-user username=foo email=bar@buzz.com Age=25

Full configuration

Logger is directly used by application code. Logger names are dot-separated hierarchical names, such as "a", "a.b", "a.b.c" or similar. For "a.b.c", its parents are "a" and "a.b".

A Logger is obtained using GetLogger method. If the Logger with that name didn't exist before, the method will create a new one. The Logger with empty name is the root one.

var logger = xylog.GetLogger("example")
defer xylog.Flush()

Handler is responsible for generating logging messages. Like Logger, Handler is also identified by its name, however, the name is not hierarchical. Every GetHandler call with the same name gives the same Handler.

Exception: Handlers with the empty names are always different.

var handler = xylog.GetHandler("handler")

Emitter writes logging messages to the specified output. Currently, only StreamEmitter is supported. You can use any Writer in this Emitter type.

var emitter = xylog.NewStreamEmitter(os.Stdout)

When a logging method is called, the Logger creates a LogRecord and sends it to underlying Handlers. Handlers convert LogRecord to text and send it to Emitters.

A Logger can have multiple Handlers, and a Handler can have multiple Emitters.

handler.AddEmitter(emitter)
logger.AddHandler(handler)

After preparing Logger, Handler, and Emitter, you can log the first messages.

logger.Debug("foo") // This message is blocked by Logger's preferred level.
logger.Warning("bar")

// Output:
// message=bar

Logging level

Both Logger and Handler has its own preferred level. If a logging level is lower than the preferred one, the message will not be logged.

By default:

  • Handler's preferred level is NOTSET (it logs all logging levels).
  • Logger's preferred level depends on its parents. When a Logger is newly created, its preferred level is the nearest parent's one. The root logger's preferred level is WARNING.

You can set a new preferred level for both Logger and Handler.

logger.SetLevel(xylog.DEBUG)

logger.Debug("foo")
logger.Warning("bar")

// Output:
// message=foo
// message=bar

In the following example, however, the first message with DEBUG can bypass the Logger, but will be prevented by Handler.

logger.SetLevel(xylog.DEBUG)
handler.SetLevel(xylog.INFO)

logger.Debug("foo")
logger.Warning("bar")

// Output:
// message=bar

The numeric values of logging levels are given in the following table. If you define a level with the same numeric value, it overwrites the predefined value.

Level Numeric value
CRITICAL 50
ERROR/FATAL 40
WARN/WARNING 30
INFO 20
DEBUG 10
NOTSET 0

Structured logging

If the logging message has more than one field, EventLogger can help.

logger.Event("add-user").Field("name", "david").Field("email", "david@dad.com").Info()

// Output:
// event=add-user name=david email=david@dad.com

You also add a field to Logger or Handler permanently. All logging messages will always include permanent fields.

logger.AddField("host", "localhost")
handler.AddField("port", 3333)

logger.Info("start server")

// Output:
// host=localhost port=3333 message="start server"

NOTE: Fixed fields added to Handler will log faster than the one added to Logger

Handler can support different encoding types. By default, it is TextEncoding.

You can log the message with JSON format too.

import "github.com/xybor-x/xylog/encoding"

handler.SetEncoding(encoding.NewJSONEncoding())

logger.Warning("this is a message")
logger.Event("failed").Field("id", 1).Error()

// Output:
// {"message":"this is a message"}
// {"event":"failed","id": 1}

Macros

You can log special fields whose values change every time you log. These fields called macros.

Only the Handler can add macros.

handler.AddMacro("level", "levelname")

logger.Warning("this is a warning message")

// Output:
// level=WARNING message="this is a warning message"

The following table shows supported macros.

MACRO DESCRIPTION
asctime Textual time when the LogRecord was created.
created Time when the LogRecord was created (time.Now().Unix() return value).
filename* Filename portion of pathname.
funcname* Function name logged the record.
levelname Text logging level for the message ("DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL").
levelno Numeric logging level for the message (DEBUG, INFO, WARNING, ERROR, CRITICAL).
lineno* Source line number where the logging call was issued.
module* The module called log method.
msecs Millisecond portion of the creation time.
name Name of the logger.
pathname Full pathname of the source file where the logging call was issued.
process Process ID.
relativeCreated Time in milliseconds between the time LogRecord was created and the time the logging module was loaded.

* These are macros that are only available if xylog.SetFindCaller is called with true.

Filter

Filter can be used by Handlers and Loggers for more sophisticated filtering than is provided by levels.

A Filter instance needs to define Filter(LogRecord) method, which returns true if it allows logging the LogRecord, and vice versa.

type NameFilter struct {
    name string
}

func (f *NameFilter) Filter(record xylog.LogRecord) bool {
    return f.name == record.Name
}

handler.AddFilter(&NameFilter{"example.user"})

var userLogger = xylog.GetLogger("example.user")
var serviceLogger = xylog.GetLogger("example.service")

userLogger.Warning("this is the user logger")
serviceLogger.Warning("this is the service logger")

// Output:
// message="this is the user logger"

Hierarchical logger

As the first section mentioned, the Logger's name is hierarchical. With this feature, you can setup a common Logger with a specified configuration and uses in different application zones.

// common/setup.go
func init() {
    var emitter = xylog.NewStreamEmitter(os.Stderr)
    var handler = xylog.GetHandler("")
    handler.AddEmitter(emitter)
    handler.SetEncoding(encoding.NewJSONEncoding())
    handler.AddMacro("time", "asctime")
    handler.AddMacro("level", "levelname")

    var logger = xylog.GetLogger("parent")
    logger.AddHandler(handler)
    logger.SetLevel(xylog.WARNING)
}
// user/foo.go
import _ "common"

var logger = xylog.GetLogger("parent.user")
defer xylog.Flush()
logger.SetLevel(xylog.INFO)
logger.AddField("module", "user")

logger.Info("this is user module")
logger.Debug("this is a not logged message")

// Output:
// time=[time] level=INFO module=user message="this is user module"
// service/bar.go
import _ "common"

var logger = xylog.GetLogger("parent.service")
defer xylog.Flush()
logger.AddField("module", "service")
logger.AddField("service", "bar")

logger.Warning("this is service module")

// Output:
// time=[time] level=INFO module=service service=bar message="this is service module"

Benchmark

CPU: AMD Ryzen 7 5800H (3.2Ghz)

These benchmark of xylog are measured with SetFindCaller is called with false.

NOTE: The benchmarks are run on a different CPU from the origin, so the benchmark values may be different too.

Log a message and 10 fields:

Package Time Time % to zap Objects Allocated
⚡ zap 1707 ns/op +0% 5 allocs/op
⚡ zap (sugared) 2043 ns/op +20% 10 allocs/op
zerolog 884 ns/op -48% 1 allocs/op
go-kit 6255 ns/op +266% 58 allocs/op
logrus 8384 ns/op +391% 80 allocs/op
apex/log 22707 ns/op +1230% 65 allocs/op
log15 25461 ns/op +1391% 75 allocs/op
🚀 xylog 3518 ns/op +106% 77 allocs/op

Log a message with a logger that already has 10 fields of context:

Package Time Time % to zap Objects Allocated
⚡ zap 140 ns/op +0% 0 allocs/op
⚡ zap (sugared) 181 ns/op +29% 1 allocs/op
zerolog 89 ns/op -36% 0 allocs/op
go-kit 5963 ns/op +4159% 57 allocs/op
logrus 6590 ns/op +4607% 69 allocs/op
apex/log 21777 ns/op +15455% 54 allocs/op
log15 15124 ns/op +10702% 71 allocs/op
🚀 xylog 416 ns/op +197% 6 allocs/op

Log a static string, without any context or printf-style templating:

Package Time Time % to zap Objects Allocated
⚡ zap 154 ns/op +0% 0 allocs/op
⚡ zap (sugared) 195 ns/op +27% 1 allocs/op
zerolog 87 ns/op -44% 0 allocs/op
go-kit 382 ns/op +148% 10 allocs/op
logrus 1008 ns/op +554% 24 allocs/op
apex/log 1744 ns/op +1032% 6 allocs/op
log15 4246 ns/op +2657% 21 allocs/op
🚀 xylog 447 ns/op +190% 6 allocs/op

Documentation

Overview

Package xylog is designed for leveled and structured logging, dynamic fields, high performance, zone management, simple configuration, and readable syntax.

Index

Examples

Constants

View Source
const (
	NOTLOG   = 1000
	CRITICAL = 50
	ERROR    = 40
	WARNING  = 30
	WARN     = WARNING
	INFO     = 20
	DEBUG    = 10
	NOTSET   = 0
)

Default levels, these can be replaced with any positive set of values having corresponding names. There is a pseudo-level, NOTSET, which is only really there as a lower limit for user-defined levels. Handlers and loggers are initialized with NOTSET so that they will log all messages, even at user-defined levels.

Variables

This section is empty.

Functions

func AddLevel

func AddLevel(level int, levelName string)

AddLevel associates a log level with name. It can overwrite other log levels. Default log levels:

NOTSET       0
DEBUG        10
INFO         20
WARN/WARNING 30
ERROR/FATAL  40
CRITICAL     50

func CheckLevel added in v0.2.0

func CheckLevel(level int) int

CheckLevel validates if the given level is associated or not.

func Flush added in v0.3.0

func Flush()

Flush writes unflushed buffered data to outputs.

func GetLevelName added in v0.2.0

func GetLevelName(level int) string

GetLevelName returns a name associated with the given level.

func SetFindCaller added in v0.2.0

func SetFindCaller(b bool)

SetFindCaller with true to find caller information including filename, line number, function name, and module.

func SetSkipCall

func SetSkipCall(skip int)

SetSkipCall sets the new skipCall value which dertermine the depth call of Logger.log method.

func SetTimeLayout

func SetTimeLayout(layout string)

SetTimeLayout sets the time layout to print asctime. It is time.RFC3339Nano by default.

Types

type Emitter

type Emitter interface {
	// Emit will be called after a record was decided to log.
	Emit([]byte)

	// Flush writes unflushed buffered data to destination, then closes the
	// Emitter.
	Flush()
}

Emitter instances dispatch logging events to specific destinations.

type EventLogger

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

EventLogger is a logger wrapper supporting to compose logging message with key-value structure.

Example
package main

import (
	"os"

	"github.com/xybor-x/xylog"
)

func main() {
	var emitter = xylog.NewStreamEmitter(os.Stdout)
	var handler = xylog.GetHandler("")
	handler.AddEmitter(emitter)

	var logger = xylog.GetLogger("example.EventLogger")
	defer xylog.Flush()
	logger.AddHandler(handler)
	logger.SetLevel(xylog.DEBUG)

	logger.Event("create").Field("product", 1235).Debug()

}
Output:

event=create product=1235

func (*EventLogger) Critical

func (e *EventLogger) Critical()

Critical calls Log with CRITICAL level.

func (*EventLogger) Debug

func (e *EventLogger) Debug()

Debug calls Log with DEBUG level.

func (*EventLogger) Error

func (e *EventLogger) Error()

Error calls Log with ERROR level.

func (*EventLogger) Fatal

func (e *EventLogger) Fatal()

Fatal calls Log with CRITICAL level, then followed by a call to os.Exit(1).

func (*EventLogger) Field

func (e *EventLogger) Field(key string, value any) *EventLogger

Field adds a key-value pair to logging message.

func (*EventLogger) Info

func (e *EventLogger) Info()

Info calls Log with INFO level.

func (*EventLogger) Log

func (e *EventLogger) Log(level int)

Log logs with a custom level.

func (*EventLogger) Panic added in v0.5.0

func (e *EventLogger) Panic()

Panic calls Log with CRITICAL level, then followed by a call to panic().

func (*EventLogger) Warn

func (e *EventLogger) Warn()

Warn calls Log with WARN level.

func (*EventLogger) Warning

func (e *EventLogger) Warning()

Warning calls Log with WARNING level.

type Filter

type Filter interface {
	Filter(record LogRecord) bool
}

Filter instances are used to perform arbitrary filtering of LogRecord.

Example
package main

import (
	"os"

	"github.com/xybor-x/xylog"
	"github.com/xybor-x/xylog/test"
)

func main() {
	var emitter = xylog.NewStreamEmitter(os.Stdout)
	var handler = xylog.GetHandler("")
	handler.AddEmitter(emitter)
	handler.AddFilter(&test.LoggerNameFilter{Name: "example.filter.chat"})

	var logger = xylog.GetLogger("example.filter")
	defer xylog.Flush()
	logger.AddHandler(handler)
	logger.SetLevel(xylog.DEBUG)

	xylog.GetLogger("example.filter.auth").Debug("auth foo")
	xylog.GetLogger("example.filter.chat").Debug("chat foo")

}
Output:

messsage="chat foo"

type Handler

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

Handler handles logging events. Do NOT instantiated directly this struct.

Any Handler with a not-empty name will be associated with its name.

Example
package main

import (
	"fmt"

	"github.com/xybor-x/xylog"
)

func main() {
	// You can use a Handler throughout program because all Handlers can be
	// identified by their names.
	var handlerA = xylog.GetHandler("example.Handler")
	var handlerB = xylog.GetHandler("example.Handler")
	if handlerA == handlerB {
		fmt.Println("handlerA == handlerB")
	} else {
		fmt.Println("handlerA != handlerB")
	}

	// In case the name is an empty string, it creates different Handlers every
	// call.
	var handlerC = xylog.GetHandler("")
	var handlerD = xylog.GetHandler("")
	if handlerC == handlerD {
		fmt.Println("handlerC == handlerD")
	} else {
		fmt.Println("handlerC != handlerD")
	}

}
Output:

handlerA == handlerB
handlerC != handlerD

func GetHandler

func GetHandler(name string) *Handler

GetHandler gets a handler with the specified name, creating it if it doesn't yet exist.

Leave the name as empty if you want to create an anonymous Handler.

func (*Handler) AddEmitter added in v0.2.0

func (h *Handler) AddEmitter(e Emitter)

AddEmitter adds a specified Emitter.

func (*Handler) AddField added in v0.2.0

func (h *Handler) AddField(name string, value any)

AddField adds a fixed field to the logging message.

func (*Handler) AddFilter

func (h *Handler) AddFilter(f Filter)

AddFilter adds a specified Filter.

func (*Handler) AddMacro added in v0.2.0

func (h *Handler) AddMacro(name, macro string)

AddMacro adds the macro value to the logging message under a name.

func (*Handler) Emitters added in v0.2.0

func (h *Handler) Emitters() []Emitter

Emitters returns all current Emitters.

func (*Handler) Filters added in v0.2.0

func (h *Handler) Filters() []Filter

Filters returns all current Filters.

func (*Handler) Handle added in v0.2.0

func (h *Handler) Handle(record LogRecord)

Handle checks if a record should be logged or not, then calls Emitters if it is.

func (*Handler) Level added in v0.2.0

func (h *Handler) Level() int

Level returns the current logging level.

func (*Handler) Name added in v0.2.0

func (h *Handler) Name() string

Name returns the current name. An anonymous Handler returns the empty name.

func (*Handler) RemoveEmitter added in v0.2.0

func (h *Handler) RemoveEmitter(e Emitter)

RemoveEmitter remove an existed Emitter.

func (*Handler) RemoveFilter

func (h *Handler) RemoveFilter(f Filter)

RemoveFilter remove an existed Filter.

func (*Handler) SetEncoding added in v0.2.0

func (h *Handler) SetEncoding(e encoding.Encoding)

SetEncoding sets a new Encoding.

func (*Handler) SetLevel

func (h *Handler) SetLevel(level int)

SetLevel sets the new logging level. It is NOTSET by default.

type LogRecord

type LogRecord struct {
	// Textual time when the LogRecord was created.
	Asctime string

	// Time when the LogRecord was created (time.Now().Unix() return value).
	Created int64

	// This a not a macro. Fields are always added to the logging message
	// without calling AddMacro.
	Fields []field

	// Filename is the portion of pathname.
	FileName string

	// Funcname is the name of function which logged the record.
	FuncName string

	// Text logging level for the message ("DEBUG", "INFO", "WARNING", "ERROR",
	// "CRITICAL").
	LevelName string

	// Numeric logging level for the message (DEBUG, INFO, WARNING, ERROR,
	// CRITICAL).
	LevelNo int

	// Source line number where the logging call was issued.
	LineNo int

	// The module called log method.
	Module string

	// Millisecond portion of the creation time.
	Msecs int

	// Name of the logger.
	Name string

	// Full pathname of the source file where the logging call was issued.
	PathName string

	// Process ID.
	Process int

	// Time in milliseconds when the LogRecord was created, relative to the time
	// the logging module was loaded (typically at application startup time).
	RelativeCreated int64
}

A LogRecord instance represents an event being logged.

LogRecord instances are created every time something is logged. They contain all the information pertinent to the event being logged. The main information passed in is Message. The record also includes information as when the record was created or the source line where the logging call was made.

type Logger

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

Logger represents a single logging channel. A "logging channel" indicates an area of an application. Exactly how an "area" is defined is up to the application developer. Since an application can have any number of areas, logging channels are identified by a unique string. Application areas can be nested (e.g. an area of "input processing" might include sub-areas "read CSV files", "read XLS files" and "read Gnumeric files"). To cater for this natural nesting, channel names are organized into a namespace hierarchy where levels are separated by periods. So in the instance given above, channel names might be "input" for the upper level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels. There is no arbitrary limit to the depth of nesting.

Example
package main

import (
	"os"

	"github.com/xybor-x/xylog"
)

func main() {
	var emitter = xylog.NewStreamEmitter(os.Stdout)
	var handler = xylog.GetHandler("")
	handler.AddEmitter(emitter)

	var logger = xylog.GetLogger("example.Logger")
	defer xylog.Flush()
	logger.AddHandler(handler)
	logger.SetLevel(xylog.DEBUG)
	logger.Debugf("foo %s", "bar")

}
Output:

messsage="foo bar"

func GetLogger

func GetLogger(name string) *Logger

GetLogger gets a logger with the specified name, creating it if it doesn't yet exist. This name is a dot-separated hierarchical name, such as "a", "a.b", "a.b.c", or similar.

Leave name as empty string to get the root logger.

func (*Logger) AddField added in v0.1.0

func (lg *Logger) AddField(key string, value any)

AddField adds a fixed field to all logging message of this logger.

func (*Logger) AddFilter

func (lg *Logger) AddFilter(f Filter)

AddFilter adds a specified Filter.

func (*Logger) AddHandler

func (lg *Logger) AddHandler(h *Handler)

AddHandler adds a new handler.

func (*Logger) Children added in v0.2.0

func (lg *Logger) Children() []*Logger

Children returns direct children logger.

func (*Logger) Critical

func (lg *Logger) Critical(s string)

Critical logs default formatting objects with CRITICAL level.

func (*Logger) Criticalf

func (lg *Logger) Criticalf(s string, a ...any)

Criticalf logs a formatting message with CRITICAL level.

func (*Logger) Debug

func (lg *Logger) Debug(s string)

Debug logs default formatting objects with DEBUG level.

func (*Logger) Debugf

func (lg *Logger) Debugf(s string, a ...any)

Debugf logs a formatting message with DEBUG level.

func (*Logger) Error

func (lg *Logger) Error(s string)

Error logs default formatting objects with ERROR level.

func (*Logger) Errorf

func (lg *Logger) Errorf(s string, a ...any)

Errorf logs a formatting message with ERROR level.

func (*Logger) Event

func (lg *Logger) Event(e string) *EventLogger

Event creates an EventLogger which logs key-value pairs.

func (*Logger) Fatal

func (lg *Logger) Fatal(s string)

Fatal logs default formatting objects with CRITICAL level, then followed by a call to os.Exit(1).

func (*Logger) Fatalf

func (lg *Logger) Fatalf(s string, a ...any)

Fatalf logs a formatting message with CRITICAL level, then followed by a call to os.Exit(1).

func (*Logger) Filters added in v0.2.0

func (lg *Logger) Filters() []Filter

Filters returns all current Filters.

func (*Logger) Handlers added in v0.2.0

func (lg *Logger) Handlers() []*Handler

Handlers returns all current Handlers.

func (*Logger) Info

func (lg *Logger) Info(s string)

Info logs default formatting objects with INFO level.

func (*Logger) Infof

func (lg *Logger) Infof(s string, a ...any)

Infof logs a formatting message with INFO level.

func (*Logger) Level added in v0.2.0

func (lg *Logger) Level() int

Level returns the current logging level.

func (*Logger) Log

func (lg *Logger) Log(level int, s string)

Log logs default formatting objects with a custom level.

func (*Logger) Logf

func (lg *Logger) Logf(level int, s string, a ...any)

Logf logs a formatting message with a custom level.

func (*Logger) Name added in v0.2.0

func (lg *Logger) Name() string

Name returns the full name.

func (*Logger) Panic added in v0.5.0

func (lg *Logger) Panic(s string)

Panic logs default formatting objects with CRITICAL level, then followed by a call to panic().

func (*Logger) Panicf added in v0.5.0

func (lg *Logger) Panicf(s string, a ...any)

Panicf logs a formatting message with CRITICAL level, then followed by a call to panic().

func (*Logger) Parent added in v0.2.0

func (lg *Logger) Parent() *Logger

Parent returns the parent logger. If there is no parent, return nil instead.

func (*Logger) RemoveAllHandlers added in v0.2.0

func (lg *Logger) RemoveAllHandlers()

RemoveAllHandlers removes all existed Handlers.

func (*Logger) RemoveFilter

func (lg *Logger) RemoveFilter(f Filter)

RemoveFilter removes an existed Filter.

func (*Logger) RemoveHandler

func (lg *Logger) RemoveHandler(h *Handler)

RemoveHandler removes an existed Handler.

func (*Logger) SetLevel

func (lg *Logger) SetLevel(level int)

SetLevel sets the new logging level.

func (*Logger) Stack added in v0.1.0

func (lg *Logger) Stack(level int)

Stack logs the stack trace.

func (*Logger) Warn

func (lg *Logger) Warn(s string)

Warn logs default formatting objects with WARN level.

func (*Logger) Warnf

func (lg *Logger) Warnf(s string, a ...any)

Warnf logs a formatting message with WARN level.

func (*Logger) Warning

func (lg *Logger) Warning(s string)

Warning logs default formatting objects with WARNING level.

func (*Logger) Warningf

func (lg *Logger) Warningf(s string, a ...any)

Warningf logs a formatting message with WARNING level.

type SimpleConfig added in v0.4.0

type SimpleConfig struct {
	// Name is the name of Logger. It can be used later with GetLogger function.
	// Default to an empty name (the root logger).
	Name string

	// Use the specified encoding to format the output. Default to TextEncoding.
	Encoding encoding.Encoding

	// Specify that Logger will write the output to a file. Do NOT use together
	// with Writer.
	Filename string

	// Specify the mode to open file. Default to APPEND | CREATE | WRONLY.
	Filemode int

	// Specify the permission when creating the file. Default to 0666.
	Fileperm os.FileMode

	// The logging level. Default to WARNING.
	Level int

	// The time layout when format the time string. Default to RFC3339Nano.
	TimeLayout string

	// Specify that Logger will write the output to a file. Do NOT use together
	// with Filename.
	Writer io.Writer
	// contains filtered or unexported fields
}

SimpleConfig supports to quickly create a Logger without configurating Emitter and Handler.

Example
package main

import (
	"fmt"
	"os"

	"github.com/xybor-x/xylog"
)

func main() {
	var config = &xylog.SimpleConfig{
		Name:   "simple-logger",
		Level:  xylog.DEBUG,
		Writer: os.Stdout,
	}

	var logger, err = config.AddMacro("level", "levelname").Apply()
	if err != nil {
		fmt.Println("An error occurred:", err)
	}
	defer xylog.Flush()

	logger.Debug("logging message")
	logger.Event("create-user").Field("username", "foo").
		Field("email", "bar@buzz.com").Field("Age", 25).Info()

}
Output:

level=DEBUG messsage="logging message"
level=INFO event=create-user username=foo email=bar@buzz.com Age=25

func (*SimpleConfig) AddMacro added in v0.4.0

func (cfg *SimpleConfig) AddMacro(name, value string) *SimpleConfig

AddMacro adds a macro value to output format.

func (SimpleConfig) Apply added in v0.4.0

func (cfg SimpleConfig) Apply() (*Logger, error)

Apply creates a Logger based on the configuration.

type StreamEmitter

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

StreamEmitter writes logging message to a stream.

func NewBufferEmitter added in v0.4.1

func NewBufferEmitter(w io.Writer, bufsize int) *StreamEmitter

NewBufferEmitter creates a StreamEmitter which uses a Buffered Writer.

func NewStreamEmitter

func NewStreamEmitter(w io.Writer) *StreamEmitter

NewStreamEmitter creates a StreamEmitter which writes logging message to a stream.

func (*StreamEmitter) Emit

func (e *StreamEmitter) Emit(msg []byte)

Emit will be called after a record was decided to log.

func (*StreamEmitter) Flush added in v0.2.0

func (e *StreamEmitter) Flush()

Flush writes unflushed buffered data to destination.

Directories

Path Synopsis
Package benchmarks is only used to benchmark the xylog.
Package benchmarks is only used to benchmark the xylog.
Package encoding provides a fast encoding approach for xylog.
Package encoding provides a fast encoding approach for xylog.
Package test provides utility test methods and objects for xylog unittest and benchmark.
Package test provides utility test methods and objects for xylog unittest and benchmark.

Jump to

Keyboard shortcuts

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