]>
Commit | Line | Data |
---|---|---|
15c0b25d AP |
1 | # go-hclog |
2 | ||
3 | [![Go Documentation](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)][godocs] | |
4 | ||
5 | [godocs]: https://godoc.org/github.com/hashicorp/go-hclog | |
6 | ||
7 | `go-hclog` is a package for Go that provides a simple key/value logging | |
8 | interface for use in development and production environments. | |
9 | ||
10 | It provides logging levels that provide decreased output based upon the | |
11 | desired amount of output, unlike the standard library `log` package. | |
12 | ||
107c1cdb | 13 | It provides `Printf` style logging of values via `hclog.Fmt()`. |
15c0b25d AP |
14 | |
15 | It provides a human readable output mode for use in development as well as | |
16 | JSON output mode for production. | |
17 | ||
18 | ## Stability Note | |
19 | ||
20 | While this library is fully open source and HashiCorp will be maintaining it | |
21 | (since we are and will be making extensive use of it), the API and output | |
22 | format is subject to minor changes as we fully bake and vet it in our projects. | |
23 | This notice will be removed once it's fully integrated into our major projects | |
24 | and no further changes are anticipated. | |
25 | ||
26 | ## Installation and Docs | |
27 | ||
28 | Install using `go get github.com/hashicorp/go-hclog`. | |
29 | ||
30 | Full documentation is available at | |
31 | http://godoc.org/github.com/hashicorp/go-hclog | |
32 | ||
33 | ## Usage | |
34 | ||
35 | ### Use the global logger | |
36 | ||
37 | ```go | |
38 | hclog.Default().Info("hello world") | |
39 | ``` | |
40 | ||
41 | ```text | |
42 | 2017-07-05T16:15:55.167-0700 [INFO ] hello world | |
43 | ``` | |
44 | ||
45 | (Note timestamps are removed in future examples for brevity.) | |
46 | ||
47 | ### Create a new logger | |
48 | ||
49 | ```go | |
50 | appLogger := hclog.New(&hclog.LoggerOptions{ | |
51 | Name: "my-app", | |
52 | Level: hclog.LevelFromString("DEBUG"), | |
53 | }) | |
54 | ``` | |
55 | ||
56 | ### Emit an Info level message with 2 key/value pairs | |
57 | ||
58 | ```go | |
59 | input := "5.5" | |
60 | _, err := strconv.ParseInt(input, 10, 32) | |
61 | if err != nil { | |
62 | appLogger.Info("Invalid input for ParseInt", "input", input, "error", err) | |
63 | } | |
64 | ``` | |
65 | ||
66 | ```text | |
67 | ... [INFO ] my-app: Invalid input for ParseInt: input=5.5 error="strconv.ParseInt: parsing "5.5": invalid syntax" | |
68 | ``` | |
69 | ||
70 | ### Create a new Logger for a major subsystem | |
71 | ||
72 | ```go | |
73 | subsystemLogger := appLogger.Named("transport") | |
74 | subsystemLogger.Info("we are transporting something") | |
75 | ``` | |
76 | ||
77 | ```text | |
78 | ... [INFO ] my-app.transport: we are transporting something | |
79 | ``` | |
80 | ||
81 | Notice that logs emitted by `subsystemLogger` contain `my-app.transport`, | |
82 | reflecting both the application and subsystem names. | |
83 | ||
84 | ### Create a new Logger with fixed key/value pairs | |
85 | ||
86 | Using `With()` will include a specific key-value pair in all messages emitted | |
87 | by that logger. | |
88 | ||
89 | ```go | |
90 | requestID := "5fb446b6-6eba-821d-df1b-cd7501b6a363" | |
91 | requestLogger := subsystemLogger.With("request", requestID) | |
92 | requestLogger.Info("we are transporting a request") | |
93 | ``` | |
94 | ||
95 | ```text | |
96 | ... [INFO ] my-app.transport: we are transporting a request: request=5fb446b6-6eba-821d-df1b-cd7501b6a363 | |
97 | ``` | |
98 | ||
99 | This allows sub Loggers to be context specific without having to thread that | |
100 | into all the callers. | |
101 | ||
107c1cdb ND |
102 | ### Using `hclog.Fmt()` |
103 | ||
104 | ```go | |
105 | var int totalBandwidth = 200 | |
106 | appLogger.Info("total bandwidth exceeded", "bandwidth", hclog.Fmt("%d GB/s", totalBandwidth)) | |
107 | ``` | |
108 | ||
109 | ```text | |
110 | ... [INFO ] my-app: total bandwidth exceeded: bandwidth="200 GB/s" | |
111 | ``` | |
112 | ||
15c0b25d AP |
113 | ### Use this with code that uses the standard library logger |
114 | ||
115 | If you want to use the standard library's `log.Logger` interface you can wrap | |
116 | `hclog.Logger` by calling the `StandardLogger()` method. This allows you to use | |
117 | it with the familiar `Println()`, `Printf()`, etc. For example: | |
118 | ||
119 | ```go | |
120 | stdLogger := appLogger.StandardLogger(&hclog.StandardLoggerOptions{ | |
121 | InferLevels: true, | |
122 | }) | |
123 | // Printf() is provided by stdlib log.Logger interface, not hclog.Logger | |
124 | stdLogger.Printf("[DEBUG] %+v", stdLogger) | |
125 | ``` | |
126 | ||
127 | ```text | |
128 | ... [DEBUG] my-app: &{mu:{state:0 sema:0} prefix: flag:0 out:0xc42000a0a0 buf:[]} | |
129 | ``` | |
130 | ||
131 | Notice that if `appLogger` is initialized with the `INFO` log level _and_ you | |
132 | specify `InferLevels: true`, you will not see any output here. You must change | |
133 | `appLogger` to `DEBUG` to see output. See the docs for more information. |