golog

package module
v0.0.0-...-28640be Latest Latest
Warning

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

Go to latest
Published: Jun 8, 2017 License: MIT Imports: 5 Imported by: 28

README

golog

Build Status

Simple but powerful go logging library

alt text

Example
package main

import "github.com/ivpusic/golog"

func main() {
	// get default logger
	logger := golog.Default

	// default level for all loggers is DEBUG
	// you can easily change it if you want
	logger.Level = golog.WARN

	// log something
	logger.Debug("some message")
}
Features
  • Multiple loggers
  • Logger Context
  • Copying Logger
  • Appenders
    • Stdout appender
    • File appender
    • Mongo appender
  • Simple API for writing custom appenders
  • Enabling/disabling appenders
  • Enabling/disabling loggers
  • Attaching log data
  • Formatting logs
Installation
go get github.com/ivpusic/golog
Levels

Currently supported levels are

  • DEBUG
  • INFO
  • WARN
  • ERROR
  • PANIC (in this case program will panic)
Formatting

Normally you call one of Debug, Info, etc.. methods of logger when you want to log some string. But sometimes you want to format your log, so you want to pass format and parameters related to format. Let's see example:

package main

import "github.com/ivpusic/golog"

func main() {
	logger := golog.Default

	// will output `some cool number 4`
	// the same you can do for other levels
	logger.Debugf("some %s number %d", "cool", 4)
}
Logger Context

Every logger can have it's own context. Later every appender will be able to extract context which is shared between all logs sent by that logger.

package main

import "github.com/ivpusic/golog"

func main() {
  logger := golog.Default

  logger.SetContext(golog.Ctx{
    "field1": 123,
    "field2": "value"
  })

  // Calling copy will make new instance of logger,
  // but with all values copied from original logger.
  // After copy loggers are independent instances.
  logger = logger.Copy().SetContext(golog.Ctx{
    "field1": 123,
    "field2": "value"
  })

  logger.Debug("message")
}
Update Context

If you have some new value which you would like to have in all next logs for logger, you can use AddContextKey function to append single key/value pair to logger context.

Attaching data

You can attach data to log. Be aware that your appender have to support this. Appender will be able to access passed data using Data member of golog.Log type. First argument of logging method is string which is actual log message, and other parameters are data which can be optionally attached to log.

package main

import "github.com/ivpusic/golog"

type SomeType struct {
	Something 		string
	SomethingElse 	int
}

func main() {
	logger := golog.Default

	data1 := SomeType{"blabla", 10}
	data2 := SomeType{"blabla", 10}
	// first parameter is string, and second is ...inteface{}
	// the same you can do for other level
	// once again, appender which you are using should support (save) passed data
	logger.Debug("some log message", data1, data2)
}
Multiple loggers

You can ask golog for logger instance. Logger instances are singletons.

package main

import "github.com/ivpusic/golog"

func main() {
	// get logger with name github.com/someuser/somelib
	// if logged doesn't exists, it will be created
	logger := golog.GetLogger("github.com/someuser/somelib")

	// this can be very useful if library which you are using uses
	// golog too. Then you can control logger level or logger appenders
	logger.Level = golog.DEBUG

	// or you can just log something using that logger
	logger.Debug("some message")
}
Enabling/Disabling loggers

If library which you are using uses golog you can explicitly enable or disable logger. This gives you control over logs which you want to see (in your console for example), and the ones which you don't.

package main

import "github.com/ivpusic/golog"

func main() {
	// you have to provide logger name in order to disable it
	golog.Disable("github.com/someuser/somelib")

	// all loggers are enabled by default
	// if you have case that at some point you disable it,
	// and later you want to enable it again, you can use this method
	golog.Enable("github.com/someuser/somelib")
}
Appenders

Golog provides set of default appenders and ultra simple API for adding new ones.

Stdout

This appender is enabled by default, so by default you should see messages in your terminal with following structure:

{logger_name} {date} {level} {message}
Enabling appenders

As you know stdout appender is enabled by default. You can enable additional appenders using Enable method of logger.

File
package main

import "github.com/ivpusic/golog"
import "github.com/ivpusic/golog/appenders"

func main() {
	logger := golog.Default

	// make instance of file appender and enable it
	logger.Enable(appenders.File(golog.Conf{
		// file in which logs will be saved
		"path": "/path/to/log.txt",
	}))

	logger.Debug("some message")
}
Mongo
package main

import "github.com/ivpusic/golog"
import "github.com/ivpusic/golog/appenders"

func main() {
	logger := golog.Default

	// make instance of mongo appender and enable it
	logger.Enable(appenders.Mongo(golog.Conf{
		// host and database port of target mongo database
		// where logs will be saved
		"host":       "127.0.0.1:27017",
		// target database in which logs will be saved
		"db":         "somedb",
		// target collection in which logs will be saved
		"collection": "logs",
		// database username (if exists)
		"username":   "myusername",
		// database password (if exists)
		"password":   "mypassword",
	}))

	logger.Debug("some message")
}
Disabling appenders

You can disable appender by calling Disable method of logger.

package main

import "github.com/ivpusic/golog"
import "github.com/ivpusic/golog/appenders"

func main() {
	logger := golog.Default

	appender := appenders.File(golog.Conf{
		"path": "/path/to/log.txt",
	})

	// let we say that we first enabled appender
	logger.Enable(appender)

	// and at the some point we want to disable it
	logger.Disable(appender)

	// you can also disable appender by passing appender id
	// in this case we are disabling file appender, so we will pass it's id
	logger.Disable("github.com/ivpusic/golog/appender/file")

  	// this log won't go to disabled appender
	logger.Debug("some message")
}
Custom appenders

Writing your own appender to really simple. You have to implement Id and Append methods. In Append method you will receive log instance, and you can do with it wathever you want.

package main

import "github.com/ivpusic/golog"

type CustomAppender struct {
}

func (s *CustomAppender) Append(log golog.Log) {
	// do something with log
	// for example you can save it to database
	// send it to some service, etc.
}

func (s *CustomAppender) Id() string {
	return "id/of/custom/appender"
}

func main() {
	logger := golog.Default

	// make custom appender instance
	appender := &CustomAppender{}

	// enable custom appender
	logger.Enable(appender)

	// log something
	logger.Debug("this will go to custom appender also")
}
Conventions

We should name propperly our loggers and appenders if we want that others don't have troubles when they want to use them.

Logger names

Logger name should be go get path of your library. So for example if you have library hosted on github, and users are getting library with go get github.com/someuser/somelibrary, then you shold use logger:

logger := golog.GetLogger("github.com/someuser/somelibrary")

On this way users will easily get logger of your library, change its level, enable it or disable it.

Appender names

Let we say that you hosted your appender on github, and whole repo is reserved only for that appender, so users will get your appender with go get github.com/someuser/someappender. In this case ID of appender should be github.com/someuser/someappender.

In case that you have one repo and in that repo you have multiple appenders available, then you append appender name to go get path. So if your repository is github.com/someuser/appenders, and you have appender A and appender B available in that repo, then ID of appender A should be github.com/someuser/appenders/A and ID of appender B should be github.com/someuser/appenders/B.

GoDoc

For additional documentation and detailed info about package structures please visit this link.

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	DEBUG = Level{
		Value: 10,

		Name: "DEBUG",
		// contains filtered or unexported fields
	}

	INFO = Level{
		Value: 20,

		Name: "INFO",
		// contains filtered or unexported fields
	}

	WARN = Level{
		Value: 30,

		Name: "WARN",
		// contains filtered or unexported fields
	}

	ERROR = Level{
		Value: 40,

		Name: "ERROR",
		// contains filtered or unexported fields
	}

	PANIC = Level{
		Value: 50,

		Name: "PANIC",
		// contains filtered or unexported fields
	}
)

Functions

func Disable

func Disable(name string)

Will disable all logs comming from logger with provided name

func Enable

func Enable(name string)

Will enable all logs comming to logger with provided name

Types

type Appender

type Appender interface {
	// method for injecting log to some source
	// when appender receives Log instance through this method,
	// it should decide what to do with log
	Append(log Log)

	// method will return appender ID
	// it will be used for disabling appenders
	Id() string
}

Interface for implementing custom appenders.

type Conf

type Conf map[string]string

Convinient type for representing appender configuration

type Ctx

type Ctx map[string]interface{}

type Level

type Level struct {
	// level priority value
	// bigger number has bigger priority
	Value int `json:"value"`

	// level name
	Name string `json:"name"`
	// contains filtered or unexported fields
}

Representing log level

type Log

type Log struct {
	// date and time of log
	Time time.Time `json:"time"`

	// logged message
	Message string `json:"message"`

	// log level
	Level Level `json:"level"`

	// additional data sent to log
	// this part should be handled by appenders
	// appender can decide to ignore data or to store it on specific way
	Data []interface{} `json:"data"`

	// represents data bound to contextual logger
	Ctx Ctx `json:"ctx"`

	// id of process which made log
	Pid int `json:"pid"`

	// logger instance
	Logger *Logger `json:"logger"`
}

Representing one Log instance

type Logger

type Logger struct {

	// name of logger
	// logger name will be shown in stdout appender output
	// also it can be used to enable/disable logger
	Name string `json:"name"`

	// minimum level of log to be shown
	Level Level `json:"-"`

	// if this flag is set to true, in case any errors in appender
	// appender should panic. This also depends on appender implementation,
	// so appender can decide to ignore or to accept information in this flag
	DoPanic bool `json:"-"`
	// contains filtered or unexported fields
}

Representing one logger instance Logger can have multiple appenders, it can enable it, or disable it. Also you can define level which will be specific to this logger.

var (
	// instance of default logger
	Default *Logger
)

func GetLogger

func GetLogger(name string) *Logger

Function for getting logger instance. Method returns singleton logger instance.

func (*Logger) AddContextKey

func (l *Logger) AddContextKey(key string, value interface{}) *Logger

func (*Logger) Copy

func (l *Logger) Copy() *Logger

Will copy current logger and return instance of new one.

func (*Logger) Debug

func (l *Logger) Debug(msg interface{}, data ...interface{})

Making log with DEBUG level.

func (*Logger) Debugf

func (l *Logger) Debugf(msg string, params ...interface{})

Making formatted log with DEBUG level.

func (*Logger) Disable

func (l *Logger) Disable(target interface{})

If you want to disable logs from some appender you can use this method. You have to call method either with appender instance, or you can pass appender Id as argument. If appender is found, it will be removed from list of appenders of this logger, and all other further logs won't be received by this appender.

func (*Logger) Enable

func (l *Logger) Enable(appender Appender)

When you want to send logs to another appender, you should create instance of appender and call this method. Method is expecting appender instance to be passed to this method. At the end passed appender will receive logs

func (*Logger) Error

func (l *Logger) Error(msg interface{}, data ...interface{})

Making log with ERROR level.

func (*Logger) Errorf

func (l *Logger) Errorf(msg string, params ...interface{})

Making formatted log with ERROR level.

func (*Logger) Info

func (l *Logger) Info(msg interface{}, data ...interface{})

Making log with INFO level.

func (*Logger) Infof

func (l *Logger) Infof(msg string, params ...interface{})

Making formatted log with INFO level.

func (*Logger) Panic

func (l *Logger) Panic(msg interface{}, data ...interface{})

Making log with PANIC level.

func (*Logger) Panicf

func (l *Logger) Panicf(msg string, params ...interface{})

Making formatted log with PANIC level.

func (*Logger) SetContext

func (l *Logger) SetContext(ctx Ctx) *Logger

Will set context to current logger. Later appenders will be able to extract context from Log instance.

func (*Logger) Warn

func (l *Logger) Warn(msg interface{}, data ...interface{})

Making log with WARN level.

func (*Logger) Warnf

func (l *Logger) Warnf(msg string, params ...interface{})

Making formatted log with WARN level.

type Stdout

type Stdout struct {
	DateFormat string
}

Representing stdout appender.

func StdoutAppender

func StdoutAppender() *Stdout

Function for creating and returning new stdout appender instance.

func (*Stdout) Append

func (s *Stdout) Append(log Log)

Appending logs to stdout.

func (*Stdout) Id

func (s *Stdout) Id() string

Getting Id of stdout appender Id of default stdout appender is "github.com/ivpusic/golog/stdout"

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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