Simple, configurable and scalable Structured Logging for Go.

Overview

log

Project status Build Status Coverage Status Go Report Card GoDoc License Gitter

Log is a simple, highly configurable, Structured Logging library

Why another logging library?

There's allot of great stuff out there, but also thought a log library could be made more configurable using per handler log levels.

Features

  • Logger is simple, only logic to create the log entry and send it off to the handlers and they take it from there.
  • Ability to specify which log levels get sent to each handler
  • Built-in console, syslog, http, HipChat, json and email handlers
  • Handlers are simple to write + easy to register + easy to remove
  • Default logger for quick prototyping and cli applications. It is automatically removed when you register one of your own.
  • 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.
  • Convenient context helpers GetContext & SetContext
  • Works with go-playground/errors extracting types and tags when used with WithError, is the default
  • Works with pkg/errors when used with WithError, must set using SetWithErrFn
  • Works with segmentio/errors-go extracting types and tags when used with WithError, must set using SetWithErrFn

Installation

Use go get

go get -u github.com/go-playground/log/v7

Usage

import the log package, it is recommended to set up at least one handler, but there is a default console logger.

package main

import (
	"errors"

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

func main() {
	// There is a default logger with the same settings
	// once any other logger is registered the default logger is removed.
	cLog := console.New(true)
	log.AddHandler(cLog, log.AllLevels...)

	// Trace
	defer log.WithTrace().Info("time to run")

	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)

	err := errors.New("the is an error")
	// logging with fields can be used with any of the above
	log.WithError(err).WithFields(log.F("key", "value")).Info("test info")

	// predefined global fields
	log.WithDefaultFields(log.Fields{
		{"program", "test"},
		{"version", "0.1.3"},
	}...)

	log.WithField("key", "value").Info("testing default fields")

	// or request scoped default fields
	logger := log.WithFields(
		log.F("request", "req"),
		log.F("scoped", "sco"),
	)

	logger.WithField("key", "value").Info("test")
}

Adding your own Handler

package main

import (
	"bytes"
	"fmt"

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

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

// Log accepts log entries to be processed
func (c *CustomHandler) Log(e 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 |
	//          																	        	   ---------
	b := new(bytes.Buffer)
	b.Reset()
	b.WriteString(e.Message)

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

func main() {

	cLog := new(CustomHandler)

	log.AddHandler(cLog, log.AllLevels...)

	// Trace
	defer log.WithTrace().Info("took this long")

	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.WithField("key", "value").Info("test info")
}

Log Level Definitions

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

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 )

Handlers

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

Handler Description Docs
console Allows for log messages to be sent to a any writer, default os.Stderr GoDoc
syslog Allows for log messages to be sent via syslog, includes TLS support. GoDoc
http Allows for log messages to be sent via http. Can use the HTTP handler as a base for creating other handlers requiring http transmission. GoDoc
email Allows for log messages to be sent via email. GoDoc
hipchat Allows for log messages to be sent to a hipchat room. GoDoc
json Allows for log messages to be sent to any wrtier in json format. GoDoc

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 15-inch 2017 using go version go1.9.4 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 --bench=. -benchmem=true
goos: darwin
goarch: amd64
pkg: github.com/go-playground/log/benchmarks
BenchmarkLogConsoleTenFieldsParallel-8           2000000               946 ns/op            1376 B/op         16 allocs/op
BenchmarkLogConsoleSimpleParallel-8              5000000               296 ns/op             200 B/op          4 allocs/op

Special Thanks

Special thanks to the following libraries that inspired

  • logrus - Structured, pluggable logging for Go.
  • apex log - Structured logging package for Go.
Comments
  • New Redis & HTTP handlers

    New Redis & HTTP handlers

    @joeybloggs I've added these two new handlers. Please note this is an initial version and I'd like to improve them both in the near future by adding a feature that allows multiple items to be buffered and sent in a MULTI command to Redis, and allow the option for multiple events to be buffered and sent at once for the HTTP handler.

    I haven't added any tests for the HTTP handler as I'm not completely certain how to test for that yet. Would it be reasonable to have spawn a local HTTP server listening for events for this test?

    I also plan on adding a file handler, which allows you to log events to a specified file. Let me know if this code is reasonable, and let me know if you have any suggestions for improvements/modifications!

    opened by hartfordfive 9
  • Synchronization

    Synchronization

    but synchronization of the change is still the user's responsibility

    Sorry to make another issue, but I just noticed that, and I'm a bit new to Go in general. How would I synchronize the changes in the email handler (or log itself?), for instance? I can't seem to find any way.

    opened by Chiiruno 7
  • Sharing fields between entries

    Sharing fields between entries

    What is the recommended way to use one collection of fields to log multiple entries? The obvious way:

    func respond(requestID string) {
        l := log.WithFields(
            log.F("requestID", requestID),
        )
        l.Info("Everything goes ok")
        l.Warn("Something's wrong")
    }
    

    But it's completely wrong because of the way the package works -- each time I call WithFields(...), I get an Entry from pool, and when I call Info(...) or Warn(...) I put Entry back into pool. There's no guarantee that I get the same Entry next time I log with the same "context".

    I tried to approach this problem from a different angle by aliasing a slice and implementing LeveledLogger, so I can mutate and copy fields as I like:

    type Fields []log.Field
    
    func (fs Fields) Info(v ...interface{}) {
        log.WithFields(fs...).Info(v...)
    }
    
    func (fs Fields) WithFields(other ...log.Field) log.LeveledLogger {
        return append(fs, other...)
    }
    
    ...
    
    func respond(requestID string) {
        l := Fields{
            log.F("requestID", requestID),
        }
        l.Info("Everything goes ok")
        l[:].WithFields(log.F("temperature", 100)).Warn("Something's wrong")
        l.Info("Back to normal") // no "temperature" field
    }
    

    I wonder if I missed something and there's a simpler solution.

    enhancement 
    opened by Perlence 7
  • Go playground issue

    Go playground issue

    it seems there is a problem with the Go playground- when I try to run this from the Golang tutorial https://go.dev/tour/flowcontrol/12 I get an error ("can't connect to server) but when I copy and paste the code to another playground window, it works. Also obviously the tutorial /playground environment is being changed by the development team - when will it be stable?

    opened by giteeup12 4
  • group entries

    group entries

    Hi there,

    there is possible group log entries? Im trying to print multiple log entries for a unique action, eg:

    INFO running command 1
    INFO output is bla
    INFO running command 2
    INFO output is bla
    

    but when I use the same logic in multiple goroutines, become insane:

    INFO running command 1
    INFO running command 1
    INFO running command 1
    INFO output is bla
    INFO running command 1
    INFO running command 1
    INFO output is bla
    INFO output is bla
    ERROR error for command is : foo bar
    INFO output is bla
    INFO running command 2
    INFO running command 2
    INFO output is bla
    INFO output is bla
    INFO running command 2
    INFO output is bla
    

    Any ideia about this issue?

    Thanks

    question 
    opened by sebastianwebber 4
  • SetFormatFunc is useless

    SetFormatFunc is useless

    Though SetFormatFunc method is exported in every handler, users actually can do nothing with this. Since none of the handlers' struct have any exported field, users can't customize their own format function.

    Either making some fields exported or adding some getters to make this method usable. What do you think about it?

    enhancement 
    opened by dengshuan 4
  • cannot use syscall.Stdout as type int in argument to terminal.IsTerminal

    cannot use syscall.Stdout as type int in argument to terminal.IsTerminal

    $ go get -v github.com/go-playground/log
    github.com/go-playground/log
    # github.com/go-playground/log
    C:\Users\Steven\go\src\github.com\go-playground\log\log.go:24:24: cannot use
    syscall.Stdout (type syscall.Handle) as type int in argument to
    terminal.IsTerminal
    
    bug 
    opened by ghost 3
  • Ability to change or disable log levels

    Ability to change or disable log levels

    Being able to disable or change the log levels for a handler is important for projects which may rely on toggle-able features.

    Related: bakape/meguca#730

    opened by Chiiruno 3
  • Cannot use in a module based project

    Cannot use in a module based project

    Essentially, the go.mod definition is malformed and causes projects attempting to consume the module by importing the latest version using import "github.com/go-playground/log/v7". Also, the sub-modules need to be updated to use the proper import path. Otherwise they will be importing the v6.3.0 version of the module.

    opened by SinisterMinister 2
  • Windows color

    Windows color

    Using this file:

    package main
    import "github.com/go-playground/log"
    func main() {
       log.Warn("aaaaa bbbbb")   
    }
    

    I get this result:

    2019-05-21 06:52:06.780406600-05:00  [33;1m  WARN [0m aaaaa bbbbb
    
    opened by ghost 2
  • Unable to remove handlers

    Unable to remove handlers

    addHandlers just keeps the handler there forever with no way to remove it or change it. removeHandlers would be a great method for this. Consider servers where you can change the error email live, the only thing you can do right now is change and restart the program.

    opened by Chiiruno 2
Releases(v8.0.1)
  • v8.0.0-rc8(Jun 8, 2022)

  • v8.0.0-rc7(Jun 3, 2022)

  • v8.0.0-rc6(Jun 2, 2022)

  • v8.0.0-rc5(Jun 2, 2022)

  • v8.0.0-rc4(May 31, 2022)

  • v8.0.0-rc3(May 31, 2022)

  • v8.0.0-rc2(May 31, 2022)

  • v8.0.0-rc1(May 31, 2022)

  • v8.0.0-rc.2(May 31, 2022)

  • v7.0.2(Nov 11, 2019)

  • v7.0.1(May 21, 2019)

  • v7.0.0(May 12, 2019)

    What's new?

    NOTE: breaking change as now relying on go-playground/pkg/runtime for stack information previously within go-playground/errors and updated to the latest version of the errors package.

    • Added default logger. If you register your own logger, of any kind, the default logger is removed and so is backward compatible. It is only registered when attached to a terminal.
    • Added Close methods to handlers to allow resource cleanup & automatic removal of the logger now that RemoveHandler and AddHandler can be made on the fly.
    • Updated to use go-playground/pkg/runtime.StackLevel(...) previously found int go-playground/errors
    Source code(tar.gz)
    Source code(zip)
  • v6.4.0(Mar 11, 2019)

    What's new?

    • Added the ability to add an remove Handlers and Handler Levels at runtime with the following functions:
      • RemoveHandler(Handler)
      • RemoveHandlerLevels(Handler, level)
    • Tuned performance of the error parsing a bit
    • Updated to use the newest go-playground/errors
    • Fixed some syslog tests
    • Updated to using Go Modules
    Source code(tar.gz)
    Source code(zip)
  • v6.3.0(Jun 28, 2018)

  • v6.2.2(May 24, 2018)

    What was fixed?

    Added resetting of the email template when changing email information, otherwise new values were not reflected. see #23 for details thanks @Chiiruno for the PR

    Source code(tar.gz)
    Source code(zip)
  • v6.2.1(May 22, 2018)

    What was fixed?

    Allowing setting of the email config values individually was racey, updated to use a single method and synchronized with a RWMutex.

    Source code(tar.gz)
    Source code(zip)
  • v6.2.0(May 22, 2018)

    What's new?

    Added ability to change email handler information after initialization, but synchronization of the change is still the user's responsibility. see #19 for details, thanks @Chiiruno for the PR!

    also fixing the versioning, I accidentally cut the last release as 6.0.1 instead of 6.1.1.

    Source code(tar.gz)
    Source code(zip)
  • v6.0.1(Apr 5, 2018)

    What was fixed?

    Fixed error prefixes being extracted from error.Cause and properly appended to the error when using WithError thanks @andreiko for reporting

    Source code(tar.gz)
    Source code(zip)
  • v6.1.0(Apr 2, 2018)

  • v6.0.0(Mar 16, 2018)

    What's new?

    This is a major version bump to v6.0.0, for most there will be no changes at all, but was a possibility for those using pkg/errors so just being cautious.

    • Exposed HandleEntry to allow for centralized logging.
    • Add ability to customize WithError functionality
      • uses go-playground/errors by default as the default WithError function
      • custom pkg/errors WithError function exists under errors/pkg
      • custom segmentio/errors-go WithError function exists under errors/segmentio
    Source code(tar.gz)
    Source code(zip)
  • v5.0.2(Feb 13, 2018)

  • v5.0.1(Feb 13, 2018)

  • v5.0.0(Feb 12, 2018)

    v5.0.0 Released! what's changed/improved?

    • Removing pooling entries
    • Allowing default/global fields you want on all entries
    • Allowing sharing of fields between entries
    • Allowing tracing using WithTrace to be used with any log level
    • Adding convenient methods to store and retrieve the log Entry from a context.Context for request scoped entries.
    • Simplified log Handlers
    • Added WithError method.
    • WithError() has support for errors package, wrapper error info will be used.
    • WithError() if it is not a wrapped error will fetch the program line and file info automatically.

    Why do we not use a map like other loggers for WithFields?

    1. maps have overhead that is not used or helpful.
    2. using a map for fields entries does not guarantee the order of the entries.
    Source code(tar.gz)
    Source code(zip)
  • v4.3.0(May 22, 2017)

    What's new?

    • Added SetExitFunc() for overriding of the exist function called by Fatal() and Fatalf() calls Thanks @sb10
    • Added strconv.AppendFloat(...)
    • Renamed examples to _examples to avoid pulling in dependencies, if any, in the examples.
    Source code(tar.gz)
    Source code(zip)
  • v4.2.0(Nov 16, 2016)

  • v4.1.0(Oct 14, 2016)

  • v4.0.1(Aug 5, 2016)

    What was fixed?

    if there was a $GOPATH defined on the system, but the code wasn't under it an out-of-range exception was thrown, this was identified by @sm3142 in pull request #7 and fix has been made to all handlers.

    Thanks @sm3142 for the pull request!

    Source code(tar.gz)
    Source code(zip)
  • v4.0.0(Jul 21, 2016)

    What's New?

    • updated syslog to use github.com/RackSec/srslog. std lib syslog will no longer be maintained as per comment https://github.com/golang/go/issues/13449#issuecomment-161204716
    • TLS support is now available via new syslog package
    • Simplified Syslog New() function
    • eliminated some data races IN THE TESTS, NOT THE LIBRARY ITSELF
    Source code(tar.gz)
    Source code(zip)
Owner
Go Playgound
multiple packages, libraries and programs to further the advancement of Go!
Go Playgound
Gomol is a library for structured, multiple-output logging for Go with extensible logging outputs

gomol Gomol (Go Multi-Output Logger) is an MIT-licensed structured logging library for Go. Gomol grew from a desire to have a structured logging libra

Kristin Davidson 19 Sep 26, 2022
Simple and configurable Logging in Go, with level, formatters and writers

go-log Logging package similar to log4j for the Golang. Support dynamic log level Support customized formatter TextFormatter JSONFormatter Support mul

Guoqiang Chen 13 Sep 26, 2022
Hierarchical, leveled, and structured logging library for Go

spacelog Please see http://godoc.org/github.com/spacemonkeygo/spacelog for info License Copyright (C) 2014 Space Monkey, Inc. Licensed under the Apach

Space Monkey Go 98 Apr 27, 2021
Structured logging package for Go.

Package log implements a simple structured logging API inspired by Logrus, designed with centralization in mind. Read more on Medium. Handlers apexlog

Apex 1.3k Dec 24, 2022
Structured, composable logging for Go

log15 Package log15 provides an opinionated, simple toolkit for best-practice logging in Go (golang) that is both human and machine readable. It is mo

Alan Shreve 1.1k Dec 18, 2022
Structured, pluggable logging for Go.

Logrus Logrus is a structured logger for Go (golang), completely API compatible with the standard library logger. Logrus is in maintenance-mode. We wi

Simon Eskildsen 21.9k Jan 9, 2023
Structured Logging Made Easy

Structured Logging Made Easy Features Dependency Free Simple and Clean Interface Consistent Writer IOWriter, io.Writer wrapper FileWriter, rotating &

phuslu 465 Jan 3, 2023
Blazing fast, structured, leveled logging in Go.

⚡ zap Blazing fast, structured, leveled logging in Go. Installation go get -u go.uber.org/zap Note that zap only supports the two most recent minor ve

Uber Go 17.8k Jan 7, 2023
Logrus is a structured, pluggable logging for Go.

Logrus is a structured logger for Go (golang), completely API compatible with the standard library logger.

Simon Eskildsen 274 May 25, 2021
Minimal structured logging library for Go

slog slog is a minimal structured logging library for Go. Install go get cdr.dev/slog Features Minimal API First class context.Context support First c

Coder 255 Dec 29, 2022
Fully asynchronous, structured, pluggable logging for Go.

logr Logr is a fully asynchronous, contextual logger for Go. It is very much inspired by Logrus but addresses two issues: Logr is fully asynchronous,

Mattermost 16 Dec 28, 2022
structured logging helper

Logart Logart is a structured logging tool that aims to simplify logging to a database It is not yet in stable state, but is used in production and ac

Karitham 3 Apr 24, 2021
Go-metalog - Standard API for structured logging

Metalog is a standard API for structured logging and adapters for its implementa

Kirill 4 Jan 20, 2022
A simple logging module for go, with a rotating file feature and console logging.

A simple logging module for go, with a rotating file feature and console logging. Installation go get github.com/jbrodriguez/mlog Usage Sample usage W

Juan B. Rodriguez 30 Dec 14, 2022
FactorLog is a logging infrastructure for Go that provides numerous logging functions for whatever your style may be

FactorLog FactorLog is a fast logging infrastructure for Go that provides numerous logging functions for whatever your style may be. It could easily b

Kevin Darlington 55 Aug 3, 2022
Package logging implements a logging infrastructure for Go

Golang logging library Package logging implements a logging infrastructure for Go. Its output format is customizable and supports different logging ba

Luke Zhang 0 Nov 10, 2021
Configurable Logger for Go

Timber! This is a logger implementation that supports multiple log levels, multiple output destinations with configurable formats and levels for each.

DeNA SF 66 Jun 28, 2022
A minimal and extensible structured logger

⚠️ PRE-RELEASE ⚠️ DO NOT IMPORT THIS MODULE YOUR PROJECT WILL BREAK package log package log provides a minimal interface for structured logging in ser

Go kit 135 Jan 7, 2023
Search and analysis tooling for structured logs

Zed The Zed system provides an open-source, cloud-native, and searchable data lake for semi-structured and structured data. Zed lakes utilize a supers

Brim 941 Jan 5, 2023