github.com/rohankumardubey/proxyfs@v0.0.0-20210108201508-653efa9ab00e/logger/README.md (about) 1 # logger 2 Logging package for ProxyFS 3 4 5 ## About 6 7 This package is implemented on top of the [logrus](https://github.com/sirupsen/logrus) package to provide structured logging functionality for ProxyFS. It uses logrus's log fields functionality to generate logs that are easily parsed by log tools. 8 9 The purpose of this package is to provide a front-end to the Logrus package to provide standard field-based logging for ProxyFS. 10 11 12 13 ## Features 14 - The package and function name of the caller are automatically added to the log's fields. See the [Log fields section](#log-fields) for more detailed information about how log fields are used internal to this package. 15 - Logging of commonly-used fields is standardized to make log searches easier. 16 - Provides per-calling-package control (in one place) of whether Trace and Debug logs are emitted. 17 - Logger is API-compatible with many **logrus** APIs. 18 19 20 21 22 ## Logging Levels 23 24 Logger has seven logging levels, one more (Trace level) than Logrus. 25 26 Each Logger level maps to a particular Logrus logging level. Trace logs are sent to Logrus at the Info level. 27 28 The intent is to have the ability to have more logging levels than Logrus, with the verbosity controlled by the Logger package. While Logrus has log level controls, we do not use them. Instead we have our own logging controls. 29 30 | Level | Description | 31 | ----- | ----------- | 32 | Debug | Logs intended to debug internal package behaviour. These are not normally enabled by default. | 33 | **Trace** | Logs intended to trace the success path through a package. These may or may not be enabled in production code. | 34 | Info | Logs intended record something that might be useful. | 35 | Warning | Logs intended to call attention to something. | 36 | Error | Logs intended to capture an error. This level should only be used for things that the top-level caller would consider an error. | 37 | Fatal | Log a fatal condition. This will cause the calling process to exit, without a clean shutdown. Should be used very sparingly. | 38 | Panic | Log a panic condition. This will cause the calling process to panic. Note that golang panics do not generate a core, so put as much information as possible into the log text. | 39 40 41 ## Logging verbosity control 42 43 Logs at Info, Warning, Error, Fatal and Panic levels are always on. 44 45 Logs at Trace and Debug levels have per-package controls. 46 47 The emission of trace logs can be set to true or false on a per-calling-package basis. If a trace setting for the logged package cannot be found, trace logging for that package is considered to be **turned off**. 48 49 **NOTE:** 50 51 **TODO: Add support for setting trace and debug logging configuration via .conf files** 52 53 54 ### Trace logs 55 56 The `packageTraceSettings` map controls whether tracing is enabled for particular packages. If a package is in this map and is set to "true", then tracing for that package is considered to be enabled and trace logs for that package will be emitted. If the package is in this list and is set to "false", OR if the package is not in this list, trace logs for that package will NOT be emitted. 57 58 59 ### Debug logs 60 61 The `packageDebugSettings` map controls which debug logs are enabled for particular packages. Unlike trace settings, debug settings are stored as a list of enabled debug tags. 62 63 The intent of using a map of tags like this is to be able to turn on/off debug logs for subsets of functionality within a package so that one doesn't have to turn on traces that aren't needed. 64 65 Bear in mind that these tags are evaluated on a package + tag basis, so the same tag can be used on different packages without conflict. 66 67 68 69 ## Example 70 71 The simplest way to use Logger is as a replacement for the stdlib logger: 72 73 ``` 74 package main 75 76 import ( 77 "github.com/swiftstack/ProxyFS/logger" 78 ) 79 80 func main() { 81 receivedSignal := <-signalChan 82 logger.Infof("Received signal %v", receivedSignal) 83 } 84 ``` 85 86 ## Caveats 87 - **Logger APIs should not be called if one has not started up the logger package by calling logger.Up().** 88 89 90 91 92 ## APIs 93 94 95 | API | Description | 96 | --- | ----------- | 97 | `Error`,`Info` | Same as the Logrus version of these APIs, except function and package fields are added | 98 | `Errorf`, `Fatalf`, `Infof`, `Warnf` | Same as the Logrus version of these APIs, except function and package fields are added | 99 |`Tracef` | Behaves like `*f` APIs, at Trace level. Function and package fields are added.| 100 | `ErrorWithError`, `FatalWithError`, `InfoWithError`, `WarnWithError` | Adds support to error field. Otherwise functionally equivalent to the non-`WithError` versions of these APIs | 101 | `TraceWithError` | Behaves like `*WithError` APIs, at Trace level. | 102 | `ErrorfWithError`, `FatalfWithError`, `InfofWithError`, `PanicfWithError`, `WarnfWithError` | A combination of the `*f` and `*WithError` APIs | 103 |`TracefWithError` | `*fWithError` API at Trace level. | 104 |`ErrorfWithErrorTxnID`, `InfofWithErrorTxnID` | Adds support for a transaction ID field to `*fWithError` APIs. | 105 |`DebugID` | Adds support for a debug ID field to the `Debug` API. Debug IDs are how we control whether debug logs are emitted. | 106 |`DebugfID` | Adds support for a debug ID field to the `Debugf` API. Debug IDs are how we control whether debug logs are emitted. | 107 |`DebugfIDWithTxnID` | Adds support for a transaction ID field to `DebugfID` API. | 108 |`DebugfIDWithError` | Adds support for the error field to `DebugfID` API.| 109 |`TraceEnter`, `TraceEnterDeferred` | APIs for tracing function entry. | 110 |`TraceExit`, `TraceExitErr` | APIs for tracing function exit. | 111 112 113 ** The following debug-related APIs are intentionally not supported ** 114 115 The following plain Debug* APIs are not supported, since all Debug logging must be done using a debug ID. 116 117 118 | Not supported API | Suggested Alternative API | 119 | ----------------- | ------------------------- | 120 | `Debug` | `DebugID` | 121 | `Debugf` | `DebugfID` | 122 | `DebugWithError` | `DebugIDWithError` | 123 | `DebugfWithError` | `DebugfIDWithError` | 124 125 126 # Internal design notes 127 128 ## [Log Fields](log-fields) 129 130 As described in 131 [logrus fields documentation](https://github.com/sirupsen/logrus/blob/master/README.md#fields), the use of log fields allows careful, structured logging instead of long, hard-to-parse error messages. 132 133 For example, instead of: 134 135 log.Infof("%s: (txn = %v) error = %v", utils.GetFnName(), scc.hc.transID, err) 136 137 (with the corresponding log) 138 139 time="2016-08-16T22:41:49Z" level=info msg="inode.Close: (txn = 45362) error = hc.setupPutChunkedBegin error" 140 141 we now do 142 143 logger.InfofWithErrorTxnID(err, scc.hc.transIDStr(), "error") 144 145 (with the corresponding log) 146 147 time="2016-08-16T22:41:49Z" level=info msg="error" error="hc.setupPutChunkedBegin error" function=Close package=inode ss_transid=45362 148 149 150 151 The use of log fields make it much easier to parse log files, either manually or with log parsing tools. 152 153 154 The log fields that are currently supported by this package are: 155 156 * **package**: the package of the calling function 157 * **function**: the calling function 158 * **error** 159 * **ss_transid**: swift transaction ID for inode/sock_swift logic 160 161 162 ## Function context 163 `FuncCtx` is a context structure that is used by some of the Logger APIs. This struct is an optimization so that package and function are only extracted once per function. 164 165 The package, function and other fields are stored in the `FuncCtx` in a `logrus.Entry*`. 166 167 This construct is mainly used inside the logger package, but is used by `TraceExit`/`TraceExitErr` as well.