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.