log

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

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

Go to latest
Published: Aug 8, 2021 License: MIT Imports: 4 Imported by: 1

README

Log

PkgGoDev

It's not a "real" library for logging. There are so many log library out there, and each of them have their own methods.
What this library provides are:

  • Simple but consistent log interface methods
  • Contextual log. Log based on some context can be an event / a process, or anything, the main point is we can manage our log more specific and detail. Contextual log also provide logging metadata and also time measurement. Metadata will printed out only if an error happened, using Warn. If you are using contextual logging, all logging's level will be enabled except for Debug level, there are no options to set minimal logging level if you are using ContextualLog.

We are not try to create a "new log writer", we are using adapter for that purpose.

Interfaces

This library provide basic methods for logging.

// Logger is main abstraction
type Logger interface {
    Debug(msg string)
    Debugf(format string, v ...interface{})
    Warn(msg string)
    Warnf(format string, v ...interface{})
    Info(msg string)
    Infof(format string, v ...interface{})
    Error(msg string)
    Errorf(format string, v ...interface{})
    Fatal(msg string)
    Fatalf(format string, v ...interface{})
}

Adapter

Main responsibility of adapter is to format the message and the send it to their writer. The format can be anything, json, string, or maybe even a bytes (well i dont know if this idea is exist or not), depends on used adapater.

Available adapters:

If you want to create another adapter, you have to make sure your adapter implement Logger interface. You can create an adapter with your own options / configurations, as long as implement same interface.

Level

You can set minimal log level :

// adapter using zerolog , this log only enabled if current activity using Info
logger = log.New(adapter.Zerolog(), "mylogger", log.WithOptionLevel(log.LevelInfo))
logger.Info("hello world")

Hierarchy :

Debug -> Info -> Warn -> Error -> Fatal

Available levels:

log.LevelDebug
log.LevelInfo
log.LevelWarn
log.LevelError
log.LevelFatal

This log level only applied for standard logging and not for ContextualLog.

Installation

go get -v -u github.com/quadroops/pkg/log

Usages (Standard logging)

An example :

// adapter using zerolog 
logger = log.New(adapter.NewZerolog(), "mylogger")
logger.Info("hello world")

// chaining
logger = log.New(adapter.NewZerolog(), "mylogger")
logger.Info("log some variable").Info("another variable").Error("error here")

Options available :

type Option struct {
    Level   int     // set minimal log level, by default: LevelDebug
    IsAsync bool    // if this option is enable, all logging method from an adapter will run in another goroutines, by default: false
}

Example using options :

// adapter using zerolog , this log only enabled if current activity using Info
logger = log.New(adapter.Zerolog(), "mylogger", log.WithOptionLevel(log.LevelInfo))
logger.Info("hello world")

// set async
logger = log.New(adapter.Zerolog(), "mylogger", log.WithAsyncEnabled())
logger.Info("hello world") // logging will run in another goroutine 

// setup both
logger = log.New(adapter.Zerolog(), "mylogger", log.WithAsyncEnabled(), log.WithOptionLevel(log.LevelInfo))
logger.Info("hello world") // logging will run in another goroutine 

Usages (Contextual logging)

The main concept of our "contextual log" is about how we manage / grouping our log based on some specific context. A "context" can be an event , a process or anything relate with your application's domain activities.

The differences with "common log" is, contextual used for more detail and specific analytical log. If you need to analyze your data log, sometimes you need a "context" for that data.

Example:

// process1
logger := log.Contextual(adapter.NewZerolog(), "process1")
logc := logger.Meta(log.KV("requestID", "xid"), log.KV("token", "token"))

// Measure must be called in the end of process, it will calculate time current process
// from the beginning
logc.Info("Incoming request...").Info("Running service logic...").Measure()


// create 'process2' contextual log from previous instance of 'process1' using same adapter
// if you want to use other adapter you'll need to use log.Contextual(...)
logger = logc.NewContextual("process2")
logc = logger.Meta(log.KV("payload", &SomeStruct{}))

// you can get time measurement per log level
logc.Info("Save to database").Measure()
logc.Info("Processing...").Measure()

// do something

// when error happened, all saved metadata will be printed out using Warn
logc.Errorf("Error msg: %s", err.Error()).Measure()

An example output:

2020-12-05T12:06:01+07:00 INF [process1]: Starting process...
2020-12-05T12:06:01+07:00 INF [process2]: Starting new process...
2020-12-05T12:06:03+07:00 INF [process2]: Process success...
2020-12-05T12:06:03+07:00 INF [process2]: Starting second process...
2020-12-05T12:06:03+07:00 INF [process1]: End porcess...
2020-12-05T12:06:03+07:00 INF [process1]: Measurement: 2.0022325s
2020-12-05T12:06:03+07:00 INF [process1]: Start another process...
2020-12-05T12:06:05+07:00 WRN [process2]: [meta] key1: 1
2020-12-05T12:06:05+07:00 WRN [process2]: [meta] key2: 2
2020-12-05T12:06:05+07:00 WRN [process2]: [meta] key3: 3
2020-12-05T12:06:05+07:00 ERR [process2]: Something went wrong...
2020-12-05T12:06:05+07:00 INF [process2]: Measurement: 4.0050952s
2020-12-05T12:06:08+07:00 WRN [process1]: [meta] requestID: random-id
2020-12-05T12:06:08+07:00 WRN [process1]: [meta] key1: val1
2020-12-05T12:06:08+07:00 WRN [process1]: [meta] key2: 2
2020-12-05T12:06:08+07:00 ERR [process1]: Then error...
2020-12-05T12:06:08+07:00 INF [process1]: Measurement: 7.0059645s

Documentation

Index

Constants

View Source
const (
	// LevelDebug .
	LevelDebug = iota

	// LevelInfo .
	LevelInfo

	// LevelWarn .
	LevelWarn

	// LevelError .
	LevelError

	// LevelFatal .
	LevelFatal
)

Variables

This section is empty.

Functions

This section is empty.

Types

type ContextualLog

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

ContextualLog is main object for contextual logging

func Contextual

func Contextual(adapter Logger, name string) *ContextualLog

Contextual used to create new instance of ContextualLog

func (*ContextualLog) Error

func (c *ContextualLog) Error(msg string) *ContextualLog

Error used to log something with Error level, and also print out all saved metadata

func (*ContextualLog) Errorf

func (c *ContextualLog) Errorf(format string, v ...interface{}) *ContextualLog

Errorf used to log formatted string with Error level, and also print out all saved metadata

func (*ContextualLog) Fatal

func (c *ContextualLog) Fatal(msg string) *ContextualLog

Fatal used to log something with Fatal level, and also print out all saved metadata

func (*ContextualLog) Fatalf

func (c *ContextualLog) Fatalf(format string, v ...interface{}) *ContextualLog

Fatalf used to log something with Fatal level, and also print out all saved metadata

func (*ContextualLog) Info

func (c *ContextualLog) Info(msg string) *ContextualLog

Info used to log something with Info level

func (*ContextualLog) Infof

func (c *ContextualLog) Infof(format string, v ...interface{}) *ContextualLog

Infof used to log formatted string with Info level

func (*ContextualLog) Measure

func (c *ContextualLog) Measure()

Measure used to setup time measurement. This method should not return current object's instance.

func (*ContextualLog) Meta

func (c *ContextualLog) Meta(kv ...KeyValue) *ContextualLog

Meta used to setup metadata contains of key value objects

func (*ContextualLog) NewContextual

func (c *ContextualLog) NewContextual(name string) *ContextualLog

NewContextual used to create new instance from current instance but only need to define context name

func (*ContextualLog) Warn

func (c *ContextualLog) Warn(msg string) *ContextualLog

Warn used to log something with Warn level

func (*ContextualLog) Warnf

func (c *ContextualLog) Warnf(format string, v ...interface{}) *ContextualLog

Warnf used to log formatted string with Warn level

type KeyValue

type KeyValue struct {
	Key   string
	Value interface{}
}

KeyValue used to save all metadata

func KV

func KV(key string, val interface{}) KeyValue

KV used to setup new object KeyValue

type Log

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

Log is main object for our logging methods

func New

func New(adapter Logger, name string, options ...Optional) *Log

New used to create Log instance

func (*Log) Debug

func (l *Log) Debug(msg string) *Log

Debug .

func (*Log) Debugf

func (l *Log) Debugf(format string, v ...interface{}) *Log

Debugf .

func (*Log) Error

func (l *Log) Error(msg string) *Log

Error .

func (*Log) Errorf

func (l *Log) Errorf(format string, v ...interface{}) *Log

Errorf .

func (*Log) Fatal

func (l *Log) Fatal(msg string) *Log

Fatal is a final level, there are no process to checking log's level here

func (*Log) Fatalf

func (l *Log) Fatalf(format string, v ...interface{}) *Log

Fatalf same with Fatal, but it's use formatting message

func (*Log) Info

func (l *Log) Info(msg string) *Log

Info .

func (*Log) Infof

func (l *Log) Infof(format string, v ...interface{}) *Log

Infof .

func (*Log) Warn

func (l *Log) Warn(msg string) *Log

Warn .

func (*Log) Warnf

func (l *Log) Warnf(format string, v ...interface{}) *Log

Warnf .

type Logger

type Logger interface {
	Debug(msg string)
	Debugf(format string, v ...interface{})
	Warn(msg string)
	Warnf(format string, v ...interface{})
	Info(msg string)
	Infof(format string, v ...interface{})
	Error(msg string)
	Errorf(format string, v ...interface{})
	Fatal(msg string)
	Fatalf(format string, v ...interface{})
}

Logger is main abstraction

type Option

type Option struct {
	Level   int
	IsAsync bool
}

Option used to setup logging level and flag if we need to run it in another goroutine or not

type Optional

type Optional func(o *Option)

Optional used as functional options to our logging

func WithAsyncEnabled

func WithAsyncEnabled() Optional

WithAsyncEnabled enable async

func WithOptionLevel

func WithOptionLevel(level int) Optional

WithOptionLevel set logging level

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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