Remove BPA from Makefile
[icn.git] / cmd / bpa-operator / vendor / go.uber.org / zap / FAQ.md
1 # Frequently Asked Questions
2
3 ## Design
4
5 ### Why spend so much effort on logger performance?
6
7 Of course, most applications won't notice the impact of a slow logger: they
8 already take tens or hundreds of milliseconds for each operation, so an extra
9 millisecond doesn't matter.
10
11 On the other hand, why *not* make structured logging fast? The `SugaredLogger`
12 isn't any harder to use than other logging packages, and the `Logger` makes
13 structured logging possible in performance-sensitive contexts. Across a fleet
14 of Go microservices, making each application even slightly more efficient adds
15 up quickly.
16
17 ### Why aren't `Logger` and `SugaredLogger` interfaces?
18
19 Unlike the familiar `io.Writer` and `http.Handler`, `Logger` and
20 `SugaredLogger` interfaces would include *many* methods. As [Rob Pike points
21 out][go-proverbs], "The bigger the interface, the weaker the abstraction."
22 Interfaces are also rigid — *any* change requires releasing a new major
23 version, since it breaks all third-party implementations.
24
25 Making the `Logger` and `SugaredLogger` concrete types doesn't sacrifice much
26 abstraction, and it lets us add methods without introducing breaking changes.
27 Your applications should define and depend upon an interface that includes
28 just the methods you use.
29
30 ### Why sample application logs?
31
32 Applications often experience runs of errors, either because of a bug or
33 because of a misbehaving user. Logging errors is usually a good idea, but it
34 can easily make this bad situation worse: not only is your application coping
35 with a flood of errors, it's also spending extra CPU cycles and I/O logging
36 those errors. Since writes are typically serialized, logging limits throughput
37 when you need it most.
38
39 Sampling fixes this problem by dropping repetitive log entries. Under normal
40 conditions, your application writes out every entry. When similar entries are
41 logged hundreds or thousands of times each second, though, zap begins dropping
42 duplicates to preserve throughput.
43
44 ### Why do the structured logging APIs take a message in addition to fields?
45
46 Subjectively, we find it helpful to accompany structured context with a brief
47 description. This isn't critical during development, but it makes debugging
48 and operating unfamiliar systems much easier.
49
50 More concretely, zap's sampling algorithm uses the message to identify
51 duplicate entries. In our experience, this is a practical middle ground
52 between random sampling (which often drops the exact entry that you need while
53 debugging) and hashing the complete entry (which is prohibitively expensive).
54
55 ### Why include package-global loggers?
56
57 Since so many other logging packages include a global logger, many
58 applications aren't designed to accept loggers as explicit parameters.
59 Changing function signatures is often a breaking change, so zap includes
60 global loggers to simplify migration.
61
62 Avoid them where possible.
63
64 ### Why include dedicated Panic and Fatal log levels?
65
66 In general, application code should handle errors gracefully instead of using
67 `panic` or `os.Exit`. However, every rule has exceptions, and it's common to
68 crash when an error is truly unrecoverable. To avoid losing any information
69 — especially the reason for the crash — the logger must flush any
70 buffered entries before the process exits.
71
72 Zap makes this easy by offering `Panic` and `Fatal` logging methods that
73 automatically flush before exiting. Of course, this doesn't guarantee that
74 logs will never be lost, but it eliminates a common error.
75
76 See the discussion in uber-go/zap#207 for more details.
77
78 ### What's `DPanic`?
79
80 `DPanic` stands for "panic in development." In development, it logs at
81 `PanicLevel`; otherwise, it logs at `ErrorLevel`. `DPanic` makes it easier to
82 catch errors that are theoretically possible, but shouldn't actually happen,
83 *without* crashing in production.
84
85 If you've ever written code like this, you need `DPanic`:
86
87 ```go
88 if err != nil {
89   panic(fmt.Sprintf("shouldn't ever get here: %v", err))
90 }
91 ```
92
93 ## Installation
94
95 ### What does the error `expects import "go.uber.org/zap"` mean?
96
97 Either zap was installed incorrectly or you're referencing the wrong package
98 name in your code.
99
100 Zap's source code happens to be hosted on GitHub, but the [import
101 path][import-path] is `go.uber.org/zap`. This gives us, the project
102 maintainers, the freedom to move the source code if necessary. However, it
103 means that you need to take a little care when installing and using the
104 package.
105
106 If you follow two simple rules, everything should work: install zap with `go
107 get -u go.uber.org/zap`, and always import it in your code with `import
108 "go.uber.org/zap"`. Your code shouldn't contain *any* references to
109 `github.com/uber-go/zap`.
110
111 ## Usage
112
113 ### Does zap support log rotation?
114
115 Zap doesn't natively support rotating log files, since we prefer to leave this
116 to an external program like `logrotate`.
117
118 However, it's easy to integrate a log rotation package like
119 [`gopkg.in/natefinch/lumberjack.v2`][lumberjack] as a `zapcore.WriteSyncer`.
120
121 ```go
122 // lumberjack.Logger is already safe for concurrent use, so we don't need to
123 // lock it.
124 w := zapcore.AddSync(&lumberjack.Logger{
125   Filename:   "/var/log/myapp/foo.log",
126   MaxSize:    500, // megabytes
127   MaxBackups: 3,
128   MaxAge:     28, // days
129 })
130 core := zapcore.NewCore(
131   zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()),
132   w,
133   zap.InfoLevel,
134 )
135 logger := zap.New(core)
136 ```
137
138 ## Extensions
139
140 We'd love to support every logging need within zap itself, but we're only
141 familiar with a handful of log ingestion systems, flag-parsing packages, and
142 the like. Rather than merging code that we can't effectively debug and
143 support, we'd rather grow an ecosystem of zap extensions.
144
145 We're aware of the following extensions, but haven't used them ourselves:
146
147 | Package | Integration |
148 | --- | --- |
149 | `github.com/tchap/zapext` | Sentry, syslog |
150 | `github.com/fgrosse/zaptest` | Ginkgo |
151 | `github.com/blendle/zapdriver` | Stackdriver |
152
153 [go-proverbs]: https://go-proverbs.github.io/
154 [import-path]: https://golang.org/cmd/go/#hdr-Remote_import_paths
155 [lumberjack]: https://godoc.org/gopkg.in/natefinch/lumberjack.v2