log: Explain why Logger.Log returns an error and how to work with it.
Chris Hines
7 years ago
89 | 89 | // handled atomically within the wrapped logger, but it typically serializes |
90 | 90 | // both the formatting and output logic. Use a SyncLogger if the formatting |
91 | 91 | // logger may perform multiple writes per log event. |
92 | // | |
93 | // Error Handling | |
94 | // | |
95 | // This package relies on the practice of wrapping or decorating loggers with | |
96 | // other loggers to provide composable pieces of functionality. It also means | |
97 | // that Logger.Log must return an error because some | |
98 | // implementations—especially those that output log data to an io.Writer—may | |
99 | // encounter errors that cannot be handled locally. This in turn means that | |
100 | // Loggers that wrap other loggers should return errors from the wrapped | |
101 | // logger up the stack. | |
102 | // | |
103 | // Fortunately, the decorator pattern also provides a way to avoid the | |
104 | // necessity to check for errors every time an application calls Logger.Log. | |
105 | // An application required to panic whenever its Logger encounters | |
106 | // an error could initialize its logger as follows. | |
107 | // | |
108 | // fmtlogger := log.NewLogfmtLogger(log.NewSyncWriter(os.Stdout)) | |
109 | // logger := log.LoggerFunc(func(keyvals ...interface{}) error { | |
110 | // if err := fmtlogger.Log(keyvals...); err != nil { | |
111 | // panic(err) | |
112 | // } | |
113 | // return nil | |
114 | // }) | |
92 | 115 | package log |