README

This project is considered stable Build Status codecov GoDoc

Go logging library. Canonical import path: zgo.at/zlog. You will need Go 1.11 or newer.

The main goal is to offer a friendly and ergonomic API. Getting the maximum possible amount of performance or zero-allocations are not goals, although simple benchmarks show it should be more than Fast Enough™ for most purposes (if not, there are a few max-performance libraries already).

Usage

Basics:

zlog.Print("foo")                  // 15:55:17 INFO: foo
zlog.Printf("foo %d", 1)           // 15:55:17 INFO: foo 1
zlog.Error(errors.New("oh noes"))  // 15:55:17 ERROR: oh noes
                                   //          main.main
                                   //                  /home/martin/code/zlog/_example/basic.go:11
                                   //          runtime.main
                                   //                  /usr/lib/go/src/runtime/proc.go:203
                                   //          runtime.goexit
                                   //                  /usr/lib/go/src/runtime/asm_amd64.s:1357
zlog.Errorf("foo %d", 1)           // 15:55:17 ERROR: foo 1
                                   //          ..stack trace omitted..

This does what you expect: output a message to stdout or stderr. The Error() functions automatically print a stack trace. You'll often want to filter that trace to include just frames that belong to your app:

zlog.Config.StackFilter = errorutil.FilterPattern(
    errorutil.FilterTraceInclude, "zlog/_example")

zlog.Error(errors.New("oh noes"))  // 15:55:17 ERROR: oh noes
                                   //          main.main
                                   //                  /home/martin/code/zlog/_example/basic.go:16

You can add module information and fields for extra information:

log := zlog.Module("test")
log.Print("foo")                    // 15:56:12 test: INFO: foo

log = log.Fields(zlog.F{"foo": "bar"})
log.Print("foo")                    // 15:56:55 test: INFO: foo {foo="bar"}

Debug logs are printed only for modules marked as debug:

zlog.Module("bar").Debug("w00t")    // Prints nothing (didn't enable module "bar").
log := zlog.SetDebug("bar")         // Enable debug logs only for module "bar".
log.Module("bar").Debug("w00t")     // 15:56:55 bar: DEBUG: w00t

Trace logs are like debug logs, but are also printed when there is an error, even when debug is disabled for the module:

log := zlog.Module("foo")
log = log.Trace("useful info")
log.Error(errors.New("oh noes"))   // 19:44:26 foo: TRACE: useful info
                                   // 19:44:26 foo: ERROR: oh noes
                                   //          ..stack trace omitted..
log = log.ResetTrace()             // Remove all traces.

This is pretty useful for adding context to errors without clobbering your general log with mostly useless info.

You can also easily record timings; this is printed for modules marked as debug:

log := zlog.SetDebug("zzz").Module("zzz")

time.Sleep(1 * time.Second)
log = log.Since("one")             // zzz  1000ms  one

time.Sleep(20*time.Millisecond)
log.Since("two")                   // zzz    20ms  two

// Add timing as fields, always works regardless of Debug.
log.FieldsSince().Print("done")    // 19:48:15 zzz: INFO: done {one="1000ms" two="20ms"}

Many functions return a Log object. It's important to remember that Log objects are never modified in-place, so using log.Trace(..) without assigning it is does nothing. This also applies to SetDebug(), Module(), Since(), etc.

The Recover() helper function makes it easier to recover from panics in goroutines:

go func() {
    defer zlog.Recover()           // Recover panics and report with Error().
    panic("oh noes!")
}()

See godoc for the full reference.

Configuration

Configuration is done by setting the zlog.Config variable usually during initialisation of your app.

It's not possible to configure individual logger instances, as it's rarely needed (but I might change my mind if someone presents a good use-case).

See LogConfig godoc for docs.

Expand ▾ Collapse ▴

Documentation

Overview

    Package zlog is a logging library.

    Index

    Constants

    View Source
    const (
    	LevelInfo  = 0
    	LevelErr   = 1
    	LevelDbg   = 2
    	LevelTrace = 3
    )

      Log levels.

      Variables

      This section is empty.

      Functions

      func Error

      func Error(err error)

      func Errorf

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

      func Print

      func Print(v ...interface{})

      func Printf

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

      func ProfileCPU

      func ProfileCPU(path string) func()

        ProfileCPU writes a memory if the path is non-empty. This should be called on start and the returned function on end (e.g. defer):

        func main() {
            defer zlog.ProfileCPU("cpu.prof")()
        
            // ..work..
        }
        

        func ProfileHeap

        func ProfileHeap(path string)

          ProfileHeap writes a memory if the path is non-empty. This is usually called just before the program exits:

          func main() {
              // ..work..
          
              zlog.ProfileHeap("mem.prof")
          }
          

          func Recover

          func Recover(cb ...func(Log) Log)

            Recover from a panic.

            Any panics will be recover()'d and reported with Error():

            go func() {
                defer zlog.Recover()
                // ... do work...
            }()
            

            The first callback will be called before the Error() call, and can be used to modify the Log instance, for example to add fields:

            defer zlog.Recover(func(l Log) Log {
                return l.Fields(zlog.F{"id": id})
            })
            

            Any other callbacks will be called after the Error() call. Modifying the Log instance has no real use.

            Types

            type F

            type F map[string]interface{}

              F are log fields.

              type Log

              type Log struct {
              	Ctx          context.Context
              	Msg          string   // Log message; set with Print(), Debug(), etc.
              	Err          error    // Original error, set with Error().
              	Level        int      // 0: print, 1: err, 2: debug, 3: trace
              	Modules      []string // Modules added to the logger.
              	Data         F        // Fields added to the logger.
              	DebugModules []string // List of modules to debug.
              	Traces       []string // Traces added to the logger.
              	// contains filtered or unexported fields
              }

                Log module.

                func Field

                func Field(k string, v interface{}) Log

                func Fields

                func Fields(f F) Log

                func FieldsLocation

                func FieldsLocation() Log

                  FieldsLocation records the caller location.

                  func FieldsRequest

                  func FieldsRequest(r *http.Request) Log

                    FieldsRequest adds information from a HTTP request as fields.

                    func Module

                    func Module(m string) Log

                      Module adds a module to this Log entry.

                      You can add multiple Modules.

                      func SetDebug

                      func SetDebug(m ...string) Log

                      func (Log) Context

                      func (l Log) Context(ctx context.Context)

                        Context adds a context to the Log entry.

                        This isn't used by zlog, and mostly so that outputs can use it if needed.

                        func (Log) Debug

                        func (l Log) Debug(v ...interface{})

                          Debug records debugging information. This won't do anything if the current module isn't beind debugged.

                          func (Log) Debugf

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

                            Debugf records debugging information. This won't do anything if the current module isn't beind debugged.

                            func (Log) Error

                            func (l Log) Error(err error)

                              Error prints an error.

                              func (Log) Errorf

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

                                Errorf prints an error.

                                func (Log) Field

                                func (l Log) Field(k string, v interface{}) Log

                                  Field sets one data field.

                                  func (Log) Fields

                                  func (l Log) Fields(f F) Log

                                    Fields append data to the Log object.

                                    func (Log) FieldsLocation

                                    func (l Log) FieldsLocation() Log

                                      FieldsLocation records the caller location.

                                      func (Log) FieldsRequest

                                      func (l Log) FieldsRequest(r *http.Request) Log

                                        FieldsRequest adds information from a HTTP request as fields.

                                        func (Log) FieldsSince

                                        func (l Log) FieldsSince() Log

                                          FieldsSince adds timing information recorded with Since as fields.

                                          func (Log) Module

                                          func (l Log) Module(m string) Log

                                          func (Log) Print

                                          func (l Log) Print(v ...interface{})

                                            Print an informational error.

                                            func (Log) Printf

                                            func (l Log) Printf(f string, v ...interface{})

                                              Printf an informational error.

                                              func (Log) ResetTrace

                                              func (l Log) ResetTrace() Log

                                                ResetTrace removes all trace logs added with Trace() and Tracef().

                                                func (Log) SetDebug

                                                func (l Log) SetDebug(m ...string) Log

                                                func (Log) Since

                                                func (l Log) Since(msg string) Log

                                                  Since records the duration since the last Since() or Module() call with the given message.

                                                  The result will be printed to stderr if this module is in the debug list. It can also be added to a Log with FieldsSince().

                                                  func (Log) Trace

                                                  func (l Log) Trace(v ...interface{}) Log

                                                  func (Log) Tracef

                                                  func (l Log) Tracef(f string, v ...interface{}) Log

                                                  type LogConfig

                                                  type LogConfig struct {
                                                  	// Outputs for a Log entry.
                                                  	//
                                                  	// The default is to print to stderr for errors, and stdout for everything
                                                  	// else. Generally you want to keep this as a backup and add additional
                                                  	// outputs, instead of replacing this. For example:
                                                  	//
                                                  	//    zlog.Config.Outputs = append(zlog.Config.Outputs, func(l Log) {
                                                  	//        if l.Level != LevelErr { // Only process errors.
                                                  	//            return
                                                  	//        }
                                                  	//
                                                  	//        // .. send to external error notification service ..
                                                  	//    })
                                                  	//
                                                  	//    zlog.Config.Outputs = append(zlog.Config.Outputs, func(l Log) {
                                                  	//        if l.Level == LevelErr { // Only process non-errors.
                                                  	//            return
                                                  	//        }
                                                  	//
                                                  	//        // .. send to external logging service ..
                                                  	//    })
                                                  	Outputs []OutputFunc
                                                  
                                                  	// Filter stack traces, only used if the error is a github.com/pkg/errors
                                                  	// with a stack trace. Useful to filter out HTTP middleware and other
                                                  	// useless stuff.
                                                  	//
                                                  	// Example:
                                                  	//
                                                  	//   zlog.Config.StackFilter = errorutil.FilterPattern(
                                                  	// 	     errorutil.FilterTraceInclude, "example.com/import")
                                                  	StackFilter *errorutil.Patterns
                                                  
                                                  	// Always print debug information for these modules. Debug will be enabled
                                                  	// for all modules with the special word "all".
                                                  	Debug []string
                                                  
                                                  	// Format function used by the default stdout/stderr output. This takes a
                                                  	// Log entry and formats it for output.
                                                  	//
                                                  	// TODO: the boundary between "outputs" and "zlog internals" are kinda leaky
                                                  	// here; it's used for Trace() logs now. Should think about refactoring
                                                  	// re-doing this in another way.
                                                  	//
                                                  	// Maybe add type OutputConfig{ .. } for this (and FmtTime)?
                                                  	Format func(Log) string
                                                  
                                                  	// Time/date format as accepted by time.Format(); used in the default
                                                  	// Format() function.
                                                  	//
                                                  	// The default is to just print the time, which works well in development.
                                                  	// For production you probably want to use time.RFC3339 or some such.
                                                  	//
                                                  	// This is used in the standard format() function, not not elsewhere.
                                                  	FmtTime string
                                                  }

                                                    LogConfig is the configuration struct.

                                                    var Config LogConfig

                                                      Config for this package.

                                                      func (LogConfig) RunOutputs

                                                      func (c LogConfig) RunOutputs(l Log)

                                                      func (*LogConfig) SetDebug

                                                      func (c *LogConfig) SetDebug(d string)

                                                        SetDebug sets the Debug field from a comma-separated list of module names.

                                                        type OutputFunc

                                                        type OutputFunc func(Log)

                                                          OutputFunc is an output function, used in Config.Outputs.