github.com/go-kit/log@v0.2.1/README.md (about) 1 # package log 2 3 [](https://pkg.go.dev/github.com/go-kit/log) 4 [](https://goreportcard.com/report/go-kit/log) 5 [](https://github.com/go-kit/log/actions/workflows/test.yml) 6 [](https://coveralls.io/github/go-kit/log?branch=main) 7 8 `package log` provides a minimal interface for structured logging in services. 9 It may be wrapped to encode conventions, enforce type-safety, provide leveled 10 logging, and so on. It can be used for both typical application log events, 11 and log-structured data streams. 12 13 ## Structured logging 14 15 Structured logging is, basically, conceding to the reality that logs are 16 _data_, and warrant some level of schematic rigor. Using a stricter, 17 key/value-oriented message format for our logs, containing contextual and 18 semantic information, makes it much easier to get insight into the 19 operational activity of the systems we build. Consequently, `package log` is 20 of the strong belief that "[the benefits of structured logging outweigh the 21 minimal effort involved](https://www.thoughtworks.com/radar/techniques/structured-logging)". 22 23 Migrating from unstructured to structured logging is probably a lot easier 24 than you'd expect. 25 26 ```go 27 // Unstructured 28 log.Printf("HTTP server listening on %s", addr) 29 30 // Structured 31 logger.Log("transport", "HTTP", "addr", addr, "msg", "listening") 32 ``` 33 34 ## Usage 35 36 ### Typical application logging 37 38 ```go 39 w := log.NewSyncWriter(os.Stderr) 40 logger := log.NewLogfmtLogger(w) 41 logger.Log("question", "what is the meaning of life?", "answer", 42) 42 43 // Output: 44 // question="what is the meaning of life?" answer=42 45 ``` 46 47 ### Contextual Loggers 48 49 ```go 50 func main() { 51 var logger log.Logger 52 logger = log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr)) 53 logger = log.With(logger, "instance_id", 123) 54 55 logger.Log("msg", "starting") 56 NewWorker(log.With(logger, "component", "worker")).Run() 57 NewSlacker(log.With(logger, "component", "slacker")).Run() 58 } 59 60 // Output: 61 // instance_id=123 msg=starting 62 // instance_id=123 component=worker msg=running 63 // instance_id=123 component=slacker msg=running 64 ``` 65 66 ### Interact with stdlib logger 67 68 Redirect stdlib logger to Go kit logger. 69 70 ```go 71 import ( 72 "os" 73 stdlog "log" 74 kitlog "github.com/go-kit/log" 75 ) 76 77 func main() { 78 logger := kitlog.NewJSONLogger(kitlog.NewSyncWriter(os.Stdout)) 79 stdlog.SetOutput(kitlog.NewStdlibAdapter(logger)) 80 stdlog.Print("I sure like pie") 81 } 82 83 // Output: 84 // {"msg":"I sure like pie","ts":"2016/01/01 12:34:56"} 85 ``` 86 87 Or, if, for legacy reasons, you need to pipe all of your logging through the 88 stdlib log package, you can redirect Go kit logger to the stdlib logger. 89 90 ```go 91 logger := kitlog.NewLogfmtLogger(kitlog.StdlibWriter{}) 92 logger.Log("legacy", true, "msg", "at least it's something") 93 94 // Output: 95 // 2016/01/01 12:34:56 legacy=true msg="at least it's something" 96 ``` 97 98 ### Timestamps and callers 99 100 ```go 101 var logger log.Logger 102 logger = log.NewLogfmtLogger(log.NewSyncWriter(os.Stderr)) 103 logger = log.With(logger, "ts", log.DefaultTimestampUTC, "caller", log.DefaultCaller) 104 105 logger.Log("msg", "hello") 106 107 // Output: 108 // ts=2016-01-01T12:34:56Z caller=main.go:15 msg=hello 109 ``` 110 111 ## Levels 112 113 Log levels are supported via the [level package](https://godoc.org/github.com/go-kit/log/level). 114 115 ## Supported output formats 116 117 - [Logfmt](https://brandur.org/logfmt) ([see also](https://blog.codeship.com/logfmt-a-log-format-thats-easy-to-read-and-write)) 118 - JSON 119 120 ## Enhancements 121 122 `package log` is centered on the one-method Logger interface. 123 124 ```go 125 type Logger interface { 126 Log(keyvals ...interface{}) error 127 } 128 ``` 129 130 This interface, and its supporting code like is the product of much iteration 131 and evaluation. For more details on the evolution of the Logger interface, 132 see [The Hunt for a Logger Interface](http://go-talks.appspot.com/github.com/ChrisHines/talks/structured-logging/structured-logging.slide#1), 133 a talk by [Chris Hines](https://github.com/ChrisHines). 134 Also, please see 135 [#63](https://github.com/go-kit/kit/issues/63), 136 [#76](https://github.com/go-kit/kit/pull/76), 137 [#131](https://github.com/go-kit/kit/issues/131), 138 [#157](https://github.com/go-kit/kit/pull/157), 139 [#164](https://github.com/go-kit/kit/issues/164), and 140 [#252](https://github.com/go-kit/kit/pull/252) 141 to review historical conversations about package log and the Logger interface. 142 143 Value-add packages and suggestions, 144 like improvements to [the leveled logger](https://godoc.org/github.com/go-kit/log/level), 145 are of course welcome. Good proposals should 146 147 - Be composable with [contextual loggers](https://godoc.org/github.com/go-kit/log#With), 148 - Not break the behavior of [log.Caller](https://godoc.org/github.com/go-kit/log#Caller) in any wrapped contextual loggers, and 149 - Be friendly to packages that accept only an unadorned log.Logger. 150 151 ## Benchmarks & comparisons 152 153 There are a few Go logging benchmarks and comparisons that include Go kit's package log. 154 155 - [imkira/go-loggers-bench](https://github.com/imkira/go-loggers-bench) includes kit/log 156 - [uber-common/zap](https://github.com/uber-common/zap), a zero-alloc logging library, includes a comparison with kit/log