proxygen
proxygen/folly/folly/logging/docs/LogHandlers.md
Go to the documentation of this file.
1 # Log Handlers
2 
3 The `LogHandler` class defines the interface for classes that wish to be
4 notified of log messages.
5 
6 `LogHandler` objects can be attached to specific log categories to be notified
7 about log messages sent to that category or any of its children categories.
8 Attaching a `LogHandler` to the root category will cause it to be notified
9 about every enabled log message.
10 
11 
12 # Built-in Log Handlers
13 
14 The logging library currently provides a few basic built-in `LogHandler`
15 implementations.
16 
17 ## `stream` Handler Type
18 
19 In the [configuration settings](Config.md), you can use the `stream` type to
20 define a log handler that will write to `stdout` or `stderr`. The `stream`
21 property of the log handler specifies which stream to write to. For example,
22 the following defines a handler named `myhandler` that writes to stderr
23 
24 ```
25 myhandler=stream:stream=stderr
26 ```
27 
28 ## `file` Handler Type
29 
30 A `file` handler type is also provided that appends log messages to a file on
31 disk. The `path` option controls which file to write to. For example:
32 
33 ```
34 myhandler=file:path=/var/log/my.log
35 ```
36 
37 However, note that the `file` handler is currently not registered by default by
38 `folly::initLogging()`. This log handler allows appending to arbitrary files
39 based on the configuration settings. You should only enable this handler type
40 if you trust the source of your configuration string. (For instance, this
41 handler is potentially unsafe if your program runs with elevated privileges but
42 users with lower privilege levels can write to your configuration file.)
43 
44 The following code snippet can be used to explicitly enable this log handler
45 type. It can be called before `initLogging()` to support the `file` handler
46 type in the configuration string passed to `initLogging()`.
47 
48 ```
49 folly::LoggerDB::get()->registerHandlerFactory(
50  std::make_unique<folly::FileHandlerFactory>());
51 
52 ```
53 
54 ## Handler Options
55 
56 The built-in handler types also accept several options to control their
57 behavior. These include:
58 
59 ### `async`
60 
61 The `async` option controls whether log messages should be written
62 asynchronously in a separate thread (when `async` is true) or immediately in
63 the thread that generated the log messages (when `async` is false).
64 
65 This mainly affects the behavior when log messages are being generated faster
66 than they can be written to the output file or stream:
67 
68 * Using `async=true` will ensure that your program never blocks waiting to
69  write the messages. Instead, the handler will start dropping log messages
70  when this occurs. When it is able to catch up it will emit a message
71  indicating how many messages were dropped.
72 
73 * Using `async=false` will ensure that no log messages are dropped, at the
74  expense of blocking your program's normal processing until the log messages
75  can be written.
76 
77 One additional consideration is that `async=false` will ensure that all log
78 messages have been flushed if your program crashes. With `async=true` it is
79 possible to lose some recent messages on program crash. For instance, if one
80 thread logs a message and then dereferences a null pointer, `async=false` will
81 ensure that the log message has been flushed before the thread can proceed to
82 dereference the null pointer. However with `async=true` the logging I/O thread
83 may not have flushed the log message by the time the thread that generated the
84 message crashes.
85 
86 With `async=true`, the `max_buffer_size` option controls how much log data may
87 buffered in memory before dropping new log messages. This option specifies the
88 maximum number of bytes of unflushed log data to keep. New log messages that
89 would trigger this limit to be exceeded will be discarded. (Log messages are
90 either entirely kept or discarded; partial messages are never kept.)
91 
92 ### `formatter`
93 
94 The `formatter` parameter controls how log messages should be formatted.
95 
96 Currently the only built-in log formatter is `glog`, which formats log messages
97 similarly to [glog](https://github.com/google/glog). Additional formatters may
98 be added in the future, and it is also possible to implement your own
99 `LogFormatter` class.
100 
101 
102 # Default Handler Configuration
103 
104 By default `initLogging()` creates a single log handler named `default`.
105 This log handler is installed on the root log category, and logs all messages
106 to stderr using a message format similar to that used by
107 [glog](https://github.com/google/glog).
108 
109 This `default` log handler has the `async` option disabled by default. This
110 means that `initLogging()` will not spawn a separate logging I/O thread by
111 default. However, log messages may delay normal program processing if they are
112 being generated faster than they can be written to stderr.
113 
114 High performance programs that want to avoid performance hiccups caused by
115 logging may wish to enable the `async` option on the default log handler.
116 This can easily be changed with the logging configuration string. For
117 instance, the following string sets the root category's log level to `WARN` and
118 enables the `async` option on the default log handler:
119 
120 ```
121 WARN; default:async=true
122 ```
123 
124 
125 # Custom Log Handlers
126 
127 It is possible to define your own custom `LogHandler` class should you choose
128 to. The `LogHandlerFactory` API enables you to create your own custom
129 `LogHandler` types from configuration settings parsed by `parseLogConfig()`.
130 You can use `LoggerDB::get()->registerHandlerFactory()` to register your own
131 custom log handler type.
132 
133 ## `StandardLogHandler`
134 
135 The `StandardLogHandler` class is an implementation of `LogHandler` that
136 splits log message processing into two steps: formatting the message to a
137 string, and then writing that string somewhere.
138 
139 It uses a `LogFormatter` class to perform the message formatting, and a
140 `LogWriter` class to write the formatted message.
141 
142 You can provide only a custom `LogFormatter` or `LogWriter` implementation if
143 you want to customize one of these two steps without providing a full
144 `LogHandler` implementation of your own.
145 
146 The `StandardLogHandlerFactory` class can then be used to implement your own
147 custom `LogHandlerFactory` that creates a `StandardLogHandler` with your custom
148 log formatter or writer type.