blammo

package module
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Apr 27, 2020 License: BSD-3-Clause Imports: 10 Imported by: 0

README

Blammo

This is a simple console logger for Go which supports:

  • High performance logging (zero allocations)
  • An API modeled on zerolog
  • Human readable output, not JSON
  • Logging errors to stderr and everything else to stdout
  • Optional logging to files
  • Not much code

I liked zerolog's API and speed, but its console logging was slow, it lacked stdout/stderr separation, and it was a lot of code -- mostly because it implemented lots of functionality I didn't need.

If you want to log to systemd, JSON APIs or binary files, use zerolog. If you just want logging for humans at high speed with minimal code, this is a smaller and faster option.

Simple usage:

import "github.com/lpar/blammo/log"

// turn on debug output for default logger at runtime
log.SetDebug(true)

log.Info().Msg("Hello sailor")
log.Debug().Int("x", 6).Msg("Debug info")

Hopefully you'll agree that it's better than bad, it's good.

Design notes

I believe in minimizing the number of logging levels. Over many years, these are the ones I've found I use:

  • Info: Normal information, progress messages, job output.
  • Error: Something has definitely gone wrong.
  • Warning: Something has happened which may be a program error or may be a human error, and could be worth investigating.
  • Debug: Trace information to be turned on when debugging.

An example of a situation where a warning is appropriate might be an invalid digital signature on a JSON Web Token. It could indicate an error in the decoding, but it could also be caused by someone trying to bypass security using a JWT with a fake signature.

There's no Fatal level in my world, because it's almost never appropriate to crash out in an uncontrolled fashion after detecting an error. If you're in one of the situations where it is appropriate, just do something like:

log.Error().Msg("fatal error")
log.Close()
os.Exit(1)

Errors and warnings are sent to a separate stream by default because that's the Unix convention since time immemorial. Also, on the cloud hosting I use, output to stderr gets highlighted to distinguish it from normal logging output. I'm aware that you can't reliably reconstruct the message sequence from stderr and stdout when they're separated like this; that's why we have timestamps on every line, right?

I haven't implemented the whole zerolog API. For example, if you want to dump out a slice or array of anything other than a few bytes, you'll have to write a loop,as there's no equivalent of zerolog's Array type. I think this makes sense from the point of view of line length and simplicity. I also haven't implemented special message appenders for types which are Stringers, such as IP addresses; just use their .String() method.

An added option zerolog lacks is the Msgf() method. This works like fmt.Printf, and is consequently relatively slow, but is there to make it easy to migrate code from other loggers that use a Printf-style interface It's also convenient for user-visible error messages where speed isn't a major concern.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Event

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

Event represents the text collected for output to a given log Writer.

func (*Event) Bool

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

Bool adds a key (variable name) and boolean to the logging event.

func (*Event) Bytes

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

Bytes adds a key (variable name) and slice of bytes to the logging event in hex.

func (*Event) CallStack added in v1.1.0

func (e *Event) CallStack() *Event

CallStack() writes a call stack as @file_0..@file_n and @line_0..@line_n. The number of levels written is limited by the value of Logger.MaxCallLevels.

func (*Event) Caller

func (e *Event) Caller() *Event

Caller writes the line number and file of the source code that the current function was called from, as the @line_1 and @file_1 keys, as well as the current line and file as @line_0 and @file_0.

func (*Event) Err

func (e *Event) Err(err error) *Event

Err adds an error message as the @error key

func (*Event) Float32

func (e *Event) Float32(key string, f float32) *Event

Float32 adds a key (variable name) and float32 to the logging event.

func (*Event) Float64

func (e *Event) Float64(key string, f float64) *Event

Float64 adds a key (variable name) and float64 to the logging event.

func (*Event) Int

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

Int adds a key (variable name) and integer to the logging event.

func (*Event) Int16

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

Int16 adds a key (variable name) and integer to the logging event.

func (*Event) Int32

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

Int32 adds a key (variable name) and integer to the logging event.

func (*Event) Int64

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

Int64 adds a key (variable name) and integer to the logging event.

func (*Event) Int8

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

Int8 adds a key (variable name) and integer to the logging event.

func (*Event) Line

func (e *Event) Line() *Event

Line writes the current line number and file of the source code as the @line_0 and @file_0 keys.

func (*Event) Msg

func (e *Event) Msg(msg string)

Msg writes the accumulated log entry to the log, along with the message provided.

func (*Event) Msgf

func (e *Event) Msgf(fmtstr string, vals ...interface{})

Msgf writes a message formatted as per fmt.Sprintf. It's likely to be slower than any other log event method.

func (*Event) Str

func (e *Event) Str(key string, value string) *Event

Str adds a key (variable name) and string to the logging event.

func (*Event) Time

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

Time adds a key (variable name) and time to the logging event.

func (*Event) Uint16

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

Uint16 adds a key (variable name) and integer to the logging event.

func (*Event) Uint32

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

Uint32 adds a key (variable name) and integer to the logging event.

func (*Event) Uint64

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

Uint64 adds a key (variable name) and integer to the logging event.

func (*Event) Uint8

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

Uint8 adds a key (variable name) and integer to the logging event.

type Logger

type Logger struct {
	ErrorWriter io.Writer // where to send Error() events
	InfoWriter  io.Writer // where to send Info() events
	DebugWriter io.Writer // where to send Debug() events

	Timestamp string // format string for timestamps
	UTC       bool   // whether to write timestamps in UTC

	MaxCallLevels      int  // how many call levels CallStack() should write
	IncludeSystemFiles bool // whether to include system source files in the call stack

	ErrorTag []byte
	WarnTag  []byte
	InfoTag  []byte
	DebugTag []byte
	KeyStart []byte
	KeyEnd   []byte

	Closer func()
}

Logger represents an object you can create log events from.

func NewCloudLogger added in v1.0.3

func NewCloudLogger() *Logger

NewCloudLogger creates a new logger with output to stdout and stderr, no ANSI codes or timestamps. Suitable for Cloud Foundry, OpenShift, etc.

func NewConsoleLogger

func NewConsoleLogger() *Logger

NewConsoleLogger creates a new logger with output to stdout and stderr, ANSI colored logging level tags, and timestamps to 1 second precision.

func NewFileLogger

func NewFileLogger(errlog string, infolog string) (*Logger, error)

NewFileLogger creates a new logger with output to the error and info log filenames provided, no ANSI codes, and timestamps to 1 second precision.

func NewLogger added in v1.0.3

func NewLogger() *Logger

NewLogger attempts to determine whether stdout is connected to the console. If so, it returns a ConsoleLogger; if not, it looks for the PORT environment variable to determine whether to return a CloudLogger. If that isn't found, it returns a PipeLogger.

func NewPipeLogger added in v1.0.3

func NewPipeLogger() *Logger

NewPipeLogger creates a new logger with output to stdout and stderr, no ANSI codes, and timestamps to 1 second precision.

func (*Logger) Close

func (l *Logger) Close()

Close closes any open log files.

func (*Logger) Debug

func (l *Logger) Debug() *Event

Debug returns a debug level logging event you can add values and messages to

func (*Logger) Error

func (l *Logger) Error() *Event

Error returns an error level logging event you can add values and messages to

func (*Logger) Info

func (l *Logger) Info() *Event

Info returns an info level logging event you can add values and messages to

func (*Logger) Warn

func (l *Logger) Warn() *Event

Warn returns a warning level logging event you can add values and messages to

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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