Skip to content
Branch: master
Find file History
Permalink
Type Name Latest commit message Commit time
..
Failed to load latest commit information.
deprecated_levels
level log/level: improve examples (#845) Mar 5, 2019
logrus
syslog Fix build (#917) Oct 3, 2019
term log: Fix build tags Jul 31, 2018
zap
README.md
benchmark_test.go log: Unexport Context and change With and WithPrefix to top level fun… Mar 5, 2017
concurrency_test.go Improve log.testConcurrency to check errors and control total event c… Jul 20, 2016
doc.go log: Update docs to reflect unexporting context and newContext. Mar 6, 2017
example_test.go log: Update docs to reflect unexporting context and newContext. Mar 6, 2017
json_logger.go Disable HTML escaping in JSON Logger (#914) Oct 7, 2019
json_logger_test.go Disable HTML escaping in JSON Logger (#914) Oct 7, 2019
log.go log: Update docs to reflect unexporting context and newContext. Mar 6, 2017
log_test.go log: Update docs to reflect unexporting context and newContext. Mar 6, 2017
logfmt_logger.go Update package docs and examples. Jul 20, 2016
logfmt_logger_test.go Improve log.testConcurrency to check errors and control total event c… Jul 20, 2016
nop_logger.go Unify logging idioms Nov 22, 2015
nop_logger_test.go log: Unexport Context and change With and WithPrefix to top level fun… Mar 5, 2017
stdlib.go Change default file key string to caller Jan 17, 2017
stdlib_test.go Change default file key string to caller Jan 17, 2017
sync.go Run gofmt on code Jul 12, 2017
sync_test.go Run gofmt on code Jul 12, 2017
value.go Remove dependency on github.com/go-stack/stack Aug 31, 2018
value_test.go log: Add TimestampFormat. Apr 20, 2017

README.md

package log

package log provides a minimal interface for structured logging in services. It may be wrapped to encode conventions, enforce type-safety, provide leveled logging, and so on. It can be used for both typical application log events, and log-structured data streams.

Structured logging

Structured logging is, basically, conceding to the reality that logs are data, and warrant some level of schematic rigor. Using a stricter, key/value-oriented message format for our logs, containing contextual and semantic information, makes it much easier to get insight into the operational activity of the systems we build. Consequently, package log is of the strong belief that "the benefits of structured logging outweigh the minimal effort involved".

Migrating from unstructured to structured logging is probably a lot easier than you'd expect.

// Unstructured
log.Printf("HTTP server listening on %s", addr)

// Structured
logger.Log("transport", "HTTP", "addr", addr, "msg", "listening")

Usage

Typical application logging

w := log.NewSyncWriter(os.Stderr)
logger := log.NewLogfmtLogger(w)
logger.Log("question", "what is the meaning of life?", "answer", 42)

// Output:
// question="what is the meaning of life?" answer=42

Contextual Loggers

func main() {
	var logger log.Logger
	logger = log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr))
	logger = log.With(logger, "instance_id", 123)

	logger.Log("msg", "starting")
	NewWorker(log.With(logger, "component", "worker")).Run()
	NewSlacker(log.With(logger, "component", "slacker")).Run()
}

// Output:
// instance_id=123 msg=starting
// instance_id=123 component=worker msg=running
// instance_id=123 component=slacker msg=running

Interact with stdlib logger

Redirect stdlib logger to Go kit logger.

import (
	"os"
	stdlog "log"
	kitlog "github.com/go-kit/kit/log"
)

func main() {
	logger := kitlog.NewJSONLogger(kitlog.NewSyncWriter(os.Stdout))
	stdlog.SetOutput(kitlog.NewStdlibAdapter(logger))
	stdlog.Print("I sure like pie")
}

// Output:
// {"msg":"I sure like pie","ts":"2016/01/01 12:34:56"}

Or, if, for legacy reasons, you need to pipe all of your logging through the stdlib log package, you can redirect Go kit logger to the stdlib logger.

logger := kitlog.NewLogfmtLogger(kitlog.StdlibWriter{})
logger.Log("legacy", true, "msg", "at least it's something")

// Output:
// 2016/01/01 12:34:56 legacy=true msg="at least it's something"

Timestamps and callers

var logger log.Logger
logger = log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr))
logger = log.With(logger, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller)

logger.Log("msg", "hello")

// Output:
// ts=2016-01-01T12:34:56Z caller=main.go:15 msg=hello

Levels

Log levels are supported via the level package.

Supported output formats

Enhancements

package log is centered on the one-method Logger interface.

type Logger interface {
	Log(keyvals ...interface{}) error
}

This interface, and its supporting code like is the product of much iteration and evaluation. For more details on the evolution of the Logger interface, see The Hunt for a Logger Interface, a talk by Chris Hines. Also, please see #63, #76, #131, #157, #164, and #252 to review historical conversations about package log and the Logger interface.

Value-add packages and suggestions, like improvements to the leveled logger, are of course welcome. Good proposals should

  • Be composable with contextual loggers,
  • Not break the behavior of log.Caller in any wrapped contextual loggers, and
  • Be friendly to packages that accept only an unadorned log.Logger.

Benchmarks & comparisons

There are a few Go logging benchmarks and comparisons that include Go kit's package log.

You can’t perform that action at this time.