Skip to content

hashicorp/go-hclog

Repository files navigation

go-hclog

Go Documentation

go-hclog is a package for Go that provides a simple key/value logging interface for use in development and production environments.

It provides logging levels that provide decreased output based upon the desired amount of output, unlike the standard library log package.

It provides Printf style logging of values via hclog.Fmt().

It provides a human readable output mode for use in development as well as JSON output mode for production.

Stability Note

This library has reached 1.0 stability. Its API can be considered solidified and promised through future versions.

Installation and Docs

Install using go get github.com/hashicorp/go-hclog.

Full documentation is available at http://godoc.org/github.com/hashicorp/go-hclog

Usage

Use the global logger

hclog.Default().Info("hello world")
2017-07-05T16:15:55.167-0700 [INFO ] hello world

(Note timestamps are removed in future examples for brevity.)

Create a new logger

appLogger := hclog.New(&hclog.LoggerOptions{
	Name:  "my-app",
	Level: hclog.LevelFromString("DEBUG"),
})

Emit an Info level message with 2 key/value pairs

input := "5.5"
_, err := strconv.ParseInt(input, 10, 32)
if err != nil {
	appLogger.Info("Invalid input for ParseInt", "input", input, "error", err)
}
... [INFO ] my-app: Invalid input for ParseInt: input=5.5 error="strconv.ParseInt: parsing "5.5": invalid syntax"

Create a new Logger for a major subsystem

subsystemLogger := appLogger.Named("transport")
subsystemLogger.Info("we are transporting something")
... [INFO ] my-app.transport: we are transporting something

Notice that logs emitted by subsystemLogger contain my-app.transport, reflecting both the application and subsystem names.

Create a new Logger with fixed key/value pairs

Using With() will include a specific key-value pair in all messages emitted by that logger.

requestID := "5fb446b6-6eba-821d-df1b-cd7501b6a363"
requestLogger := subsystemLogger.With("request", requestID)
requestLogger.Info("we are transporting a request")
... [INFO ] my-app.transport: we are transporting a request: request=5fb446b6-6eba-821d-df1b-cd7501b6a363

This allows sub Loggers to be context specific without having to thread that into all the callers.

Using hclog.Fmt()

totalBandwidth := 200
appLogger.Info("total bandwidth exceeded", "bandwidth", hclog.Fmt("%d GB/s", totalBandwidth))
... [INFO ] my-app: total bandwidth exceeded: bandwidth="200 GB/s"

Use this with code that uses the standard library logger

If you want to use the standard library's log.Logger interface you can wrap hclog.Logger by calling the StandardLogger() method. This allows you to use it with the familiar Println(), Printf(), etc. For example:

stdLogger := appLogger.StandardLogger(&hclog.StandardLoggerOptions{
	InferLevels: true,
})
// Printf() is provided by stdlib log.Logger interface, not hclog.Logger
stdLogger.Printf("[DEBUG] %+v", stdLogger)
... [DEBUG] my-app: &{mu:{state:0 sema:0} prefix: flag:0 out:0xc42000a0a0 buf:[]}

Alternatively, you may configure the system-wide logger:

// log the standard logger from 'import "log"'
log.SetOutput(appLogger.StandardWriter(&hclog.StandardLoggerOptions{InferLevels: true}))
log.SetPrefix("")
log.SetFlags(0)

log.Printf("[DEBUG] %d", 42)
... [DEBUG] my-app: 42

Notice that if appLogger is initialized with the INFO log level, and you specify InferLevels: true, you will not see any output here. You must change appLogger to DEBUG to see output. See the docs for more information.

If the log lines start with a timestamp you can use the InferLevelsWithTimestamp option to try and ignore them. Please note that in order for InferLevelsWithTimestamp to be relevant, InferLevels must be set to true.