log

package module
v3.0.0+incompatible Latest Latest
Warning

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

Go to latest
Published: Jun 6, 2016 License: MIT Imports: 6 Imported by: 108

README

log

![Project status](https://img.shields.io/badge/version-3.0.0-green.svg) [![Build Status](https://semaphoreci.com/api/v1/joeybloggs/log/branches/master/badge.svg)](https://semaphoreci.com/joeybloggs/log) [![Coverage Status](https://coveralls.io/repos/github/go-playground/log/badge.svg?branch=master)](https://coveralls.io/github/go-playground/log?branch=master) [![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/log)](https://goreportcard.com/report/github.com/go-playground/log) [![GoDoc](https://godoc.org/github.com/go-playground/log?status.svg)](https://godoc.org/github.com/go-playground/log) ![License](https://img.shields.io/dub/l/vibe-d.svg)

Log is a simple,highly configurable, Structured Logging that is a near drop in replacement for the std library log

Why another logging library?

There's allot of great stuff out there, but also thought a log library could be made easier to use, more efficient by reusing objects and more performant using channels.

Features

  • Logger is simple, only logic to create the log entry and send it off to the handlers and they take it from there.
  • Sends the log entry to the handlers asynchronously, but waits for all to complete; meaning all your handlers can be dealing with the log entry at the same time, but log will wait until all have completed before moving on.
  • Ability to specify which log levels get sent to each handler
  • Built-in console, syslog, http and email handlers
  • Handlers are simple to write + easy to register
  • Logger is a singleton ( one of the few instances a singleton is desired ) so the root package registers which handlers are used and any libraries just follow suit.

Installation

Use go get

go get github.com/go-playground/log

Replacing std log

change import from

import "log"

to

import "github.com/go-playground/log"

Usage

import the log package, setup at least one handler

package main

import (
	"github.com/go-playground/log"
	"github.com/go-playground/log/handlers/console"
)

func main() {

	cLog := console.New()

	log.RegisterHandler(cLog, log.AllLevels...)

	// Trace
	defer log.Trace("trace").End()

	log.Debug("debug")
	log.Info("info")
	log.Notice("notice")
	log.Warn("warn")
	log.Error("error")
	// log.Panic("panic") // this will panic
	log.Alert("alert")
	// log.Fatal("fatal") // this will call os.Exit(1)

	// logging with fields can be used with any of the above
	log.WithFields(log.F("key", "value")).Info("test info")
}

Adding your own Handler

package main

import (
	"bytes"
	"fmt"

	"github.com/go-playground/log"
)

// CustomHandler is your custom handler
type CustomHandler struct {
	// whatever properties you need
	buffer uint // channel buffer
}

// Run starts the logger consuming on the returned channed
func (c *CustomHandler) Run() chan<- *log.Entry {

	// in a big high traffic app, set a higher buffer
	ch := make(chan *log.Entry, c.buffer)

	// can run as many consumers on the channel as you want,
	// depending on the buffer size or your needs
	go func(entries <-chan *log.Entry) {

		// below prints to os.Stderr but could marshal to JSON
		// and send to central logging server
		//																						       ---------
		// 				                                                                 |----------> | console |
		//                                                                               |             ---------
		// i.e. -----------------               -----------------     Unmarshal    -------------       --------
		//     | app log handler | -- json --> | central log app | --    to    -> | log handler | --> | syslog |
		//      -----------------               -----------------       Entry      -------------       --------
		//      																         |             ---------
		//                                  									         |----------> | DataDog |
		//          																	        	   ---------
		var e *log.Entry
		b := new(bytes.Buffer)

		for e = range entries {

			b.Reset()
			b.WriteString(e.Message)

			for _, f := range e.Fields {
				fmt.Fprintf(b, " %s=%v", f.Key, f.Value)
			}

			fmt.Println(b.String())
			e.Consumed() // done writing the entry
		}

	}(ch)

	return ch
}

func main() {

	cLog := &CustomHandler{
		buffer: 0,
	}

	log.RegisterHandler(cLog, log.AllLevels...)

	// Trace
	defer log.Trace("trace").End()

	log.Debug("debug")
	log.Info("info")
	log.Notice("notice")
	log.Warn("warn")
	log.Error("error")
	// log.Panic("panic") // this will panic
	log.Alert("alert")
	// log.Fatal("fatal") // this will call os.Exit(1)

	// logging with fields can be used with any of the above
	log.WithFields(log.F("key", "value")).Info("test info")
}

Log Level Definitions

DebugLevel - Info useful to developers for debugging the application, not useful during operations.

TraceLevel - Info useful to developers for debugging the application and reporting on possible bottlenecks.

InfoLevel - Normal operational messages - may be harvested for reporting, measuring throughput, etc. - no action required.

NoticeLevel - Normal but significant condition. Events that are unusual but not error conditions - might be summarized in an email to developers or admins to spot potential problems - no immediate action required.

WarnLevel - Warning messages, not an error, but indication that an error will occur if action is not taken, e.g. file system 85% full - each item must be resolved within a given time.

ErrorLevel - Non-urgent failures, these should be relayed to developers or admins; each item must be resolved within a given time.

PanicLevel - A "panic" condition usually affecting multiple apps/servers/sites. At this level it would usually notify all tech staff on call.

AlertLevel - Action must be taken immediately. Should be corrected immediately, therefore notify staff who can fix the problem. An example would be the loss of a primary ISP connection.

FatalLevel - Should be corrected immediately, but indicates failure in a primary system, an example is a loss of a backup ISP connection. ( same as SYSLOG CRITICAL )

More Handlers

Pull requests for new handlers are welcome, please provide test coverage is all I ask.

Package Versioning

I'm jumping on the vendoring bandwagon, you should vendor this package as I will not be creating different version with gopkg.in like allot of my other libraries.

Why? because my time is spread pretty thin maintaining all of the libraries I have + LIFE, it is so freeing not to worry about it and will help me keep pouring out bigger and better things for you the community.

Benchmarks

Run on MacBook Pro (Retina, 15-inch, Late 2013) 2.6 GHz Intel Core i7 16 GB 1600 MHz DDR3 using Go version go1.6.2 darwin/amd64

NOTE: only putting benchmarks at others request, by no means does the number of allocations make one log library better than another!

go test -cpu=4 -bench=. -benchmem=true

PASS
BenchmarkLogConsoleTenFieldsParallel-4	 1000000	      1985 ns/op	    1113 B/op	      35 allocs/op
BenchmarkLogConsoleSimpleParallel-4   	 3000000	       455 ns/op	      88 B/op	       4 allocs/op
BenchmarkLogrusText10Fields-4         	  300000	      4179 ns/op	    4291 B/op	      63 allocs/op
BenchmarkLogrusTextSimple-4           	 2000000	       655 ns/op	     672 B/op	      15 allocs/op
BenchmarkLog1510Fields-4              	  100000	     16376 ns/op	    4378 B/op	      92 allocs/op
BenchmarkLog15Simple-4                	 1000000	      1983 ns/op	     320 B/op	       9 allocs/op
ok  	github.com/go-playground/log/benchmarks	10.716s

Special Thanks

Special thanks to the following libraries that inspired

  • logrus - Structured, pluggable logging for Go.
  • apex log - Structured logging package for Go.

Documentation

Overview

Package log is a simple, highly configurable, structured logging that is a near drop in replacement for the std library log.

Usage

package main

import (
    "github.com/go-playground/log"
    "github.com/go-playground/log/handlers/console"
)

func main() {

    cLog := console.New()

    log.RegisterHandler(cLog, log.AllLevels...)

    // Trace
    defer log.Trace("trace").End()

    log.Debug("debug")
    log.Info("info")
    log.Notice("notice")
    log.Warn("warn")
    log.Error("error")
    // log.Panic("panic") // this will panic
    log.Alert("alert")
    // log.Fatal("fatal") // this will call os.Exit(1)

    // logging with fields can be used with any of the above
    log.WithFields(log.F("key", "value")).Info("test info")
}

Adding your own Handler

package main

import (
    "bytes"
    "fmt"

    "github.com/go-playground/log"
)

// CustomHandler is your custom handler
type CustomHandler struct {
    // whatever properties you need
    buffer uint // channel buffer
}

// Run starts the logger consuming on the returned channed
func (c *CustomHandler) Run() chan<- *log.Entry {

    // in a big high traffic app, set a higher buffer
    ch := make(chan *log.Entry, c.buffer)

    // can run as many consumers on the channel as you want,
    // depending on the buffer size or your needs
    go func(entries <-chan *log.Entry) {

        // below prints to os.Stderr but could marshal to JSON
        // and send to central logging server
        var e *log.Entry
        b := new(bytes.Buffer)

        for e = range entries {

            b.Reset()
            b.WriteString(e.Message)

            for _, f := range e.Fields {
                fmt.Fprintf(b, " %s=%v", f.Key, f.Value)
            }

            fmt.Println(b.String())
            e.WG.Done() // done writing the entry
        }

    }(ch)

    return ch
}

func main() {

    cLog := &CustomHandler{
        buffer: 0,
    }

    log.RegisterHandler(cLog, log.AllLevels...)

    // Trace
    defer log.Trace("trace").End()

    log.Debug("debug")
    log.Info("info")
    log.Notice("notice")
    log.Warn("warn")
    log.Error("error")
    // log.Panic("panic") // this will panic
    log.Alert("alert")
    // log.Fatal("fatal") // this will call os.Exit(1)

    // logging with fields can be used with any of the above
    log.WithFields(log.F("key", "value")).Info("test info")
}

Log Level Definitions

DebugLevel - Info useful to developers for debugging the application, not useful during
             operations.

TraceLevel - Info useful to developers for debugging the application and reporting on
             possible bottlenecks.

InfoLevel - Normal operational messages - may be harvested for reporting, measuring
            throughput, etc. - no action required.

NoticeLevel - Normal but significant condition. Events that are unusual but not error
              conditions - might be summarized in an email to developers or admins to
              spot potential problems - no immediate action required.

WarnLevel - Warning messages, not an error, but indication that an error will occur if
            action is not taken, e.g. file system 85% full - each item must be resolved
            within a given time.

ErrorLevel - Non-urgent failures, these should be relayed to developers or admins; each
             item must be resolved within a given time.

PanicLevel - A "panic" condition usually affecting multiple apps/servers/sites. At this
             level it would usually notify all tech staff on call.

AlertLevel - Action must be taken immediately. Should be corrected immediately,
             therefore notify staff who can fix the problem. An example would be the
             loss of a primary ISP connection.

FatalLevel - Should be corrected immediately, but indicates failure in a primary
             system, an example is a loss of a backup ISP connection.
             ( same as SYSLOG CRITICAL )

Index

Constants

View Source
const (
	Black        ANSIEscSeq = "\x1b[30m"
	DarkGray                = "\x1b[30;1m"
	Blue                    = "\x1b[34m"
	LightBlue               = "\x1b[34;1m"
	Green                   = "\x1b[32m"
	LightGreen              = "\x1b[32;1m"
	Cyan                    = "\x1b[36m"
	LightCyan               = "\x1b[36;1m"
	Red                     = "\x1b[31m"
	LightRed                = "\x1b[31;1m"
	Magenta                 = "\x1b[35m"
	LightMagenta            = "\x1b[35;1m"
	Brown                   = "\x1b[33m"
	Yellow                  = "\x1b[33;1m"
	LightGray               = "\x1b[37m"
	White                   = "\x1b[37;1m"
	Underscore              = "\x1b[4m"
	Blink                   = "\x1b[5m"
	Inverse                 = "\x1b[7m"
	Reset                   = "\x1b[0m"
)

ANSI escape sequences NOTE: in an standard xterm terminal the light colors will appear BOLD instead of the light variant

View Source
const (
	// DefaultTimeFormat is the default time format when parsing Time values.
	// it is exposed to allow handlers to use and not have to redefine
	DefaultTimeFormat = "2006-01-02T15:04:05.000000000Z07:00"
)

Variables

AllLevels is an array of all log levels, for easier registering of all levels to a handler

View Source
var (
	Logger *logger
)

Logger is the default instance of the log package

Functions

func Alert

func Alert(v ...interface{})

Alert level formatted message.

func Alertf

func Alertf(msg string, v ...interface{})

Alertf level formatted message.

func Debug

func Debug(v ...interface{})

Debug level formatted message.

func Debugf

func Debugf(msg string, v ...interface{})

Debugf level formatted message.

func Error

func Error(v ...interface{})

Error level formatted message.

func Errorf

func Errorf(msg string, v ...interface{})

Errorf level formatted message.

func Fatal

func Fatal(v ...interface{})

Fatal level formatted message, followed by an exit.

func Fatalf

func Fatalf(msg string, v ...interface{})

Fatalf level formatted message, followed by an exit.

func Fatalln

func Fatalln(v ...interface{})

Fatalln level formatted message, followed by an exit.

func HandleEntry

func HandleEntry(e *Entry)

HandleEntry send the logs entry out to all the registered handlers

func HasHandlers

func HasHandlers() bool

HasHandlers returns if any handlers have been registered.

func Info

func Info(v ...interface{})

Info level formatted message.

func Infof

func Infof(msg string, v ...interface{})

Infof level formatted message.

func Notice

func Notice(v ...interface{})

Notice level formatted message.

func Noticef

func Noticef(msg string, v ...interface{})

Noticef level formatted message.

func Panic

func Panic(v ...interface{})

Panic logs an Panic level formatted message and then panics it is here to let this log package be a drop in replacement for the standard logger

func Panicf

func Panicf(msg string, v ...interface{})

Panicf logs an Panic level formatted message and then panics it is here to let this log package be a near drop in replacement for the standard logger

func Panicln

func Panicln(v ...interface{})

Panicln logs an Panic level formatted message and then panics it is here to let this log package be a near drop in replacement for the standard logger

func Print

func Print(v ...interface{})

Print logs an Info level formatted message

func Printf

func Printf(msg string, v ...interface{})

Printf logs an Info level formatted message

func Println

func Println(v ...interface{})

Println logs an Info level formatted message

func RegisterDurationFunc

func RegisterDurationFunc(fn DurationFormatFunc)

RegisterDurationFunc registers a custom duration function for Trace events

func RegisterHandler

func RegisterHandler(handler Handler, levels ...Level)

RegisterHandler adds a new Log Handler and specifies what log levels the handler will be passed log entries for

func SetApplicationID

func SetApplicationID(id string)

SetApplicationID tells the logger to set a constant application key that will be set on all log Entry objects. log does not care what it is, the application name, app name + hostname.... that's up to you it is needed by many logging platforms for separating logs by application and even by application server in a distributed app.

func SetCallerInfoLevels

func SetCallerInfoLevels(levels ...Level)

SetCallerInfoLevels tells the logger to gather and set file and line number information on Entry objects for the provided log levels. By defaut all but TraceLevel, InfoLevel and NoticeLevel are set to gather information.

func SetCallerSkipDiff

func SetCallerSkipDiff(diff uint8)

SetCallerSkipDiff adds the provided diff to the caller SkipLevel values. This is used when wrapping this library, you can set ths to increase the skip values passed to Caller that retrieves the file + line number info.

func SetTimeFormat

func SetTimeFormat(format string)

SetTimeFormat sets the time format used for Trace events

func Warn

func Warn(v ...interface{})

Warn level formatted message.

func Warnf

func Warnf(msg string, v ...interface{})

Warnf level formatted message.

Types

type ANSIEscSeq

type ANSIEscSeq string

ANSIEscSeq is a predefined ANSI escape sequence

type DurationFormatFunc

type DurationFormatFunc func(time.Duration) string

DurationFormatFunc is the function called for parsing Trace Duration

type Entry

type Entry struct {
	ApplicationID string    `json:"appId"`
	Level         Level     `json:"level"`
	Timestamp     time.Time `json:"timestamp"`
	Message       string    `json:"message"`
	Fields        []Field   `json:"fields"`
	File          string    `json:"file"`
	Line          int       `json:"line"`
	// contains filtered or unexported fields
}

Entry represents a single log entry.

func (*Entry) Alert

func (e *Entry) Alert(v ...interface{})

Alert level message.

func (*Entry) Alertf

func (e *Entry) Alertf(msg string, v ...interface{})

Alertf level formatted message.

func (*Entry) Consumed

func (e *Entry) Consumed()

Consumed lets the Entry and subsequently the Logger instance know that it has been used by a handler

func (*Entry) Debug

func (e *Entry) Debug(v ...interface{})

Debug level message.

func (*Entry) Debugf

func (e *Entry) Debugf(msg string, v ...interface{})

Debugf level formatted message.

func (*Entry) Error

func (e *Entry) Error(v ...interface{})

Error level message.

func (*Entry) Errorf

func (e *Entry) Errorf(msg string, v ...interface{})

Errorf level formatted message.

func (*Entry) Fatal

func (e *Entry) Fatal(v ...interface{})

Fatal level message, followed by an exit.

func (*Entry) Fatalf

func (e *Entry) Fatalf(msg string, v ...interface{})

Fatalf level formatted message, followed by an exit.

func (*Entry) Info

func (e *Entry) Info(v ...interface{})

Info level message.

func (*Entry) Infof

func (e *Entry) Infof(msg string, v ...interface{})

Infof level formatted message.

func (*Entry) Notice

func (e *Entry) Notice(v ...interface{})

Notice level formatted message.

func (*Entry) Noticef

func (e *Entry) Noticef(msg string, v ...interface{})

Noticef level formatted message.

func (*Entry) Panic

func (e *Entry) Panic(v ...interface{})

Panic logs an Error level formatted message and then panics

func (*Entry) Panicf

func (e *Entry) Panicf(msg string, v ...interface{})

Panicf logs an Error level formatted message and then panics

func (*Entry) StackTrace

func (e *Entry) StackTrace() LeveledLogger

StackTrace adds a field with stack trace to the current log Entry.

func (*Entry) Trace

func (e *Entry) Trace(v ...interface{}) Traceable

Trace starts a trace & returns Traceable object to End + log

func (*Entry) Tracef

func (e *Entry) Tracef(msg string, v ...interface{}) Traceable

Tracef starts a trace & returns Traceable object to End + log

func (*Entry) Warn

func (e *Entry) Warn(v ...interface{})

Warn level message.

func (*Entry) Warnf

func (e *Entry) Warnf(msg string, v ...interface{})

Warnf level formatted message.

func (*Entry) WithFields

func (e *Entry) WithFields(fields ...Field) LeveledLogger

WithFields adds the provided fieldsto the current entry

type Field

type Field struct {
	Key   string      `json:"key"`
	Value interface{} `json:"value"`
}

Field contains a single key + value for structured logging.

func F

func F(key string, value interface{}) Field

F creates a new field key + value entry

type FilenameDisplay

type FilenameDisplay uint8

FilenameDisplay is the type of file display output

const (
	Lshortfile FilenameDisplay = iota
	Llongfile
)

FilenameDisplay options

type Handler

type Handler interface {
	Run() chan<- *Entry
}

Handler interface for log handlers

type HandlerChannels

type HandlerChannels []chan<- *Entry

HandlerChannels is an array of handler channels

type Level

type Level uint8

Level of the log

const (
	DebugLevel Level = iota
	TraceLevel
	InfoLevel
	NoticeLevel
	WarnLevel
	ErrorLevel
	PanicLevel
	AlertLevel
	FatalLevel // same as syslog CRITICAL
)

Log levels.

func (Level) String

func (l Level) String() string

type LevelHandlerChannels

type LevelHandlerChannels map[Level]HandlerChannels

LevelHandlerChannels is a group of Handler channels mapped by Level

type LeveledLogger

type LeveledLogger interface {
	Debug(v ...interface{})
	Trace(v ...interface{}) Traceable
	Info(v ...interface{})
	Notice(v ...interface{})
	Warn(v ...interface{})
	Error(v ...interface{})
	Panic(v ...interface{})
	Alert(v ...interface{})
	Fatal(v ...interface{})
	Debugf(msg string, v ...interface{})
	Tracef(msg string, v ...interface{}) Traceable
	Infof(msg string, v ...interface{})
	Noticef(msg string, v ...interface{})
	Warnf(msg string, v ...interface{})
	Errorf(msg string, v ...interface{})
	Panicf(msg string, v ...interface{})
	Alertf(msg string, v ...interface{})
	Fatalf(msg string, v ...interface{})
	WithFields(...Field) LeveledLogger
	StackTrace() LeveledLogger
}

LeveledLogger interface for logging by level

func StackTrace

func StackTrace() LeveledLogger

StackTrace creates a new log Entry with pre-populated field with stack trace.

func WithFields

func WithFields(fields ...Field) LeveledLogger

WithFields returns a log Entry with fields set

type TraceEntry

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

TraceEntry is an object used in creating a trace log entry

func (*TraceEntry) End

func (t *TraceEntry) End()

End completes the trace and logs the entry

type Traceable

type Traceable interface {
	End()
}

Traceable interface for a traceable object

func Trace

func Trace(v ...interface{}) Traceable

Trace starts a trace & returns Traceable object to End + log. Example defer log.Trace(...).End()

func Tracef

func Tracef(msg string, v ...interface{}) Traceable

Tracef starts a trace & returns Traceable object to End + log

Directories

Path Synopsis
examples
handlers

Jump to

Keyboard shortcuts

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