Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 272 lines (214 sloc) 10.255 kB
7bcf044 @Vagabond Initial import
Vagabond authored
1 * Overview
7e68976 @Vagabond Try to improve M:F(A) printing a little
Vagabond authored
2 Lager (as in the beer) is a logging framework for Erlang. Its purpose is
7bcf044 @Vagabond Initial import
Vagabond authored
3 to provide a more traditional way to perform logging in an erlang application
4 that plays nicely with traditional UNIX logging tools like logrotate and
5 syslog.
6
ec60541 @seancribbs Fix build status badge [ci skip]
seancribbs authored
7 [[http://travis-ci.org/basho/lager][Travis-CI]] :: [[https://secure.travis-ci.org/basho/lager.png]]
b5f7361 @seancribbs Add Travis CI hook and build status.
seancribbs authored
8
9 * Features
7bcf044 @Vagabond Initial import
Vagabond authored
10 - Finer grained log levels (debug, info, notice, warning, error, critical,
11 alert, emergency)
12 - Logger calls are transformed using a parse transform to allow capturing
13 Module/Function/Line/Pid information
14 - When no handler is consuming a log level (eg. debug) no event is even sent
15 to the log handler
de705e4 @Vagabond Corrections to README
Vagabond authored
16 - Supports multiple backends, including console and file. More are planned.
7bcf044 @Vagabond Initial import
Vagabond authored
17
18 * Usage
19 To use lager in your application, you need to define it as a rebar dep or have
20 some other way of including it in erlang's path. You can then add the
21 following option to the erlang compiler flags
22
d4b06a0 @Vagabond Adventures in org mode
Vagabond authored
23 #+BEGIN_EXAMPLE
7bcf044 @Vagabond Initial import
Vagabond authored
24 {parse_transform, lager_transform}
d4b06a0 @Vagabond Adventures in org mode
Vagabond authored
25 #+END_EXAMPLE
7bcf044 @Vagabond Initial import
Vagabond authored
26
de21911 @Vagabond Typo
Vagabond authored
27 Alternately, you can add it to the module you wish to compile with logging
7bcf044 @Vagabond Initial import
Vagabond authored
28 enabled:
29
d4b06a0 @Vagabond Adventures in org mode
Vagabond authored
30 #+BEGIN_EXAMPLE
7bcf044 @Vagabond Initial import
Vagabond authored
31 -compile([{parse_transform, lager_transform}]).
d4b06a0 @Vagabond Adventures in org mode
Vagabond authored
32 #+END_EXAMPLE
7bcf044 @Vagabond Initial import
Vagabond authored
33
3a1579a Added lager:start() to the README
Joe DeVivo authored
34 Before logging any messages, you'll need to start the lager application. The
35 lager module's start function takes care of loading and starting any dependencies
36 lager requires.
37
38 #+BEGIN_EXAMPLE
39 lager:start().
40 #+END_EXAMPLE
41
42 Once you have built your code with lager and started the lager application,
43 you can then generate log messages by doing the following:
7bcf044 @Vagabond Initial import
Vagabond authored
44
d4b06a0 @Vagabond Adventures in org mode
Vagabond authored
45 #+BEGIN_EXAMPLE
7bcf044 @Vagabond Initial import
Vagabond authored
46 lager:error("Some message")
d4b06a0 @Vagabond Adventures in org mode
Vagabond authored
47 #+END_EXAMPLE
7bcf044 @Vagabond Initial import
Vagabond authored
48
49 Or:
50
d4b06a0 @Vagabond Adventures in org mode
Vagabond authored
51 #+BEGIN_EXAMPLE
7bcf044 @Vagabond Initial import
Vagabond authored
52 lager:warning("Some message with a term: ~p", [Term])
d4b06a0 @Vagabond Adventures in org mode
Vagabond authored
53 #+END_EXAMPLE
7bcf044 @Vagabond Initial import
Vagabond authored
54
55 The general form is lager:Severity() where Severity is one of the log levels
56 mentioned above.
57
58 * Configuration
9d48bae @Vagabond More README
Vagabond authored
59 To configure lager's backends, you use an application variable (probably in
60 your app.config):
61
62 #+BEGIN_EXAMPLE
5554103 @muxspace Fixed syntax error in config example
muxspace authored
63 {lager, [
9d48bae @Vagabond More README
Vagabond authored
64 {handlers, [
f45f9c9 @Vagabond Typo in config example
Vagabond authored
65 {lager_console_backend, info},
6eb8240 @Vagabond Crash log rotation & documentation on rotation
Vagabond authored
66 {lager_file_backend, [
81d4aea @Vagabond Finish implementing time based log rotation
Vagabond authored
67 {"error.log", error, 10485760, "$D0", 5},
68 {"console.log", info, 10485760, "$D0", 5}
6eb8240 @Vagabond Crash log rotation & documentation on rotation
Vagabond authored
69 ]}
9d48bae @Vagabond More README
Vagabond authored
70 ]}
5554103 @muxspace Fixed syntax error in config example
muxspace authored
71 ]}.
9d48bae @Vagabond More README
Vagabond authored
72 #+END_EXAMPLE
73
74 The available configuration options for each backend are listed in their
75 module's documentation.
76
0415d21 @nialscorva Changed the messages sent to the backends to include metadata and sep…
nialscorva authored
77 * Custom Formatting
78 All loggers have a default formatting that can be overriden. A formatter is any module that
79 exports format(#lager_log_message{},Config#any()). It is specified as part of the configuration
80 for the backend:
81
82 #+BEGIN_EXAMPLE
83 {lager, [
84 {handlers, [
85 {lager_console_backend, [info, {lager_default_formatter, [time," [",severity,"] ", message, "\n"]}},
86 {lager_file_backend, [
87 [{"error.log", error, 10485760, "$D0", 5,{lager_default_formatter,[date, " ", time," [",severity,"] ",pid, " ", message, "\n"]}],
88 {"console.log", info, 10485760, "$D0", 5}
89 ]}
90 ]}
91 ]}.
92 #+END_EXAMPLE
93
94 Included is lager_default_formatter. This provides a generic, default formatting for log messages using a "semi-iolist"
95 as configuration. Any iolist allowed elements in the configuration are printed verbatim. Atoms in the configuration
96 are treated as metadata properties and extracted from the log message.
97 The metadata properties date,time, message, and severity will always exist.
98 The properties pid, file, line, module, and function will always exist if the parser transform is used.
99
100 #+BEGIN_EXAMPLE
101 ["Foo"] -> "Foo", regardless of message content.
102 [message] -> The content of the logged message, alone.
103 [{pid,"Unknown Pid"}] -> "<?.?.?>" if pid is in the metadata, "Unknown Pid" if not.
104 [date, " ", time," [",severity,"] ",pid, " ", message, "\n"] -> default formatting if none is provided
105 #+END_EXAMPLE
106
107 Optionally, a tuple of {atom(),semi-iolist()}
108 can be used. The atom will look up the property, but if not found it will use the semi-iolist() instead. These fallbacks
109 can be nested or refer to other properties.
110
111 #+BEGIN_EXAMPLE
112 [{pid,"Unknown Pid"}] -> "<?.?.?>" if pid is in the metadata, "Unknown Pid" if not.
113 [{server,[$(,{pid,"Unknown Server"},$)]}}] -> user provided server metadata, otherwise "(<?.?.?>)", otherwise "(Unknown Server)"
114 #+END_EXAMPLE
115
9d48bae @Vagabond More README
Vagabond authored
116 * Error logger integration
117 Lager is also supplied with a error_logger handler module that translates
118 traditional erlang error messages into a friendlier format and sends them into
0859c90 @Vagabond Default the error_logger redirect to be on, log to the 'log' dir
Vagabond authored
119 lager itself to be treated like a regular lager log call. To disable this, set
120 the lager application variable `error_logger_redirect' to `false'.
121
122 The error_logger handler will also log more complete error messages (protected
123 with use of trunc_io) to a "crash log" which can be referred to for further
61ae86f @Vagabond Minor documentation tweaks
Vagabond authored
124 information. The location of the crash log can be specified by the crash_log
125 application variable. If undefined it is not written at all.
9d48bae @Vagabond More README
Vagabond authored
126
6eb8240 @Vagabond Crash log rotation & documentation on rotation
Vagabond authored
127 Messages in the crash log are subject to a maximum message size which can be
128 specified via the crash_log_msg_size application variable.
129
9d48bae @Vagabond More README
Vagabond authored
130 * Runtime loglevel changes
131 You can change the log level of any lager backend at runtime by doing the
132 following:
133
134 #+BEGIN_EXAMPLE
135 lager:set_loglevel(lager_console_backend, debug).
136 #+END_EXAMPLE
137
138 Or, for the backend with multiple handles (files, mainly):
139
140 #+BEGIN_EXAMPLE
5793dfe @dreverri Fix typo in README
dreverri authored
141 lager:set_loglevel(lager_file_backend, "console.log", debug).
9d48bae @Vagabond More README
Vagabond authored
142 #+END_EXAMPLE
143
144 Lager keeps track of the minium log level being used by any backend and
145 supresses generation of messages lower than that level. This means that debug
146 log messages, when no backend is consuming debug messages, are effectively
de705e4 @Vagabond Corrections to README
Vagabond authored
147 free. A simple benchmark of doing 1 million debug log messages while the
9d48bae @Vagabond More README
Vagabond authored
148 minimum threshold was above that takes less than half a second.
81d4aea @Vagabond Finish implementing time based log rotation
Vagabond authored
149
150 * Internal log rotation
151 Lager can rotate its own logs or have it done via an external process. To
152 use internal rotation, use the last 3 values in the file backend's
153 configuration tuple. For example
154
155 #+BEGIN_EXAMPLE
156 {"error.log", error, 10485760, "$D0", 5}
157 #+END_EXAMPLE
158
159 This tells lager to log error and above messages to "error.log" and to
160 rotate the file at midnight or when it reaches 10mb, whichever comes first
161 and to keep 5 rotated logs, in addition to the current one. Setting the
162 count to 0 does not disable rotation, it instead rotates the file and keeps
163 no previous versions around. To disable rotation set the size to 0 and the
164 date to "".
165
166 The "$D0" syntax is taken from the syntax newsyslog uses in newsyslog.conf.
167 The relevant extract follows:
168
169 #+BEGIN_EXAMPLE
170 Day, week and month time format: The lead-in character
171 for day, week and month specification is a `$'-sign.
172 The particular format of day, week and month
173 specification is: [Dhh], [Ww[Dhh]] and [Mdd[Dhh]],
174 respectively. Optional time fields default to
175 midnight. The ranges for day and hour specifications
176 are:
177
178 hh hours, range 0 ... 23
179 w day of week, range 0 ... 6, 0 = Sunday
180 dd day of month, range 1 ... 31, or the
181 letter L or l to specify the last day of
182 the month.
183
184 Some examples:
185 $D0 rotate every night at midnight
186 $D23 rotate every day at 23:00 hr
187 $W0D23 rotate every week on Sunday at 23:00 hr
188 $W5D16 rotate every week on Friday at 16:00 hr
189 $M1D0 rotate on the first day of every month at
190 midnight (i.e., the start of the day)
191 $M5D6 rotate on every 5th day of the month at
192 6:00 hr
193 #+END_EXAMPLE
194
195 To configure the crash log rotation, the following application variables are
196 used:
197 - crash_log_size
198 - crash_log_date
199 - crash_log_count
200
201 See the .app.src file for further details.
f85ea9e @Vagabond Add note on syslog backend
Vagabond authored
202
203 * Syslog Support
5fd47ad @Vagabond Typo
Vagabond authored
204 Lager syslog output is provided as a separate application;
f85ea9e @Vagabond Add note on syslog backend
Vagabond authored
205 [[https://github.com/basho/lager_syslog][lager_syslog]]. It is packaged as a
206 separate application so Lager itself doesn't have an indirect dependancy on a
207 port driver. Please see the lager_syslog README for configuration information.
0e70e68 @Vagabond Add documentation & function to clear all traces
Vagabond authored
208
570d6cb @Vagabond Add link to AMQP backend
Vagabond authored
209 * AMQP Support
210 Jon Brisbin has written a lager backend to send lager messages into AMQP, so
211 you can aggregate logs from a cluster into a central point. You can find it
212 under the [[https://github.com/jbrisbin/lager_amqp_backend][lager_amqp_backend]]
213 project on github.
214
0e70e68 @Vagabond Add documentation & function to clear all traces
Vagabond authored
215 * Tracing
216 Lager supports basic support for redirecting log messages based on log message
ed7bc9a @Vagabond Add pid to the list of attributes automatically captured for tracing
Vagabond authored
217 attributes. Lager automatically captures the pid, module, function and line at the
0e70e68 @Vagabond Add documentation & function to clear all traces
Vagabond authored
218 log message callsite. However, you can add any additional attributes you wish:
219
220 #+BEGIN_EXAMPLE
221 lager:warning([{request, RequestID},{vhost, Vhost}], "Permission denied to ~s", [User])
222 #+END_EXAMPLE
223
224 Then, in addition to the default trace attributes, you'll be able to trace
225 based on request or vhost:
226
227 #+BEGIN_EXAMPLE
228 lager:trace_file("logs/example.com.error", [{vhost, "example.com"}], error)
229 #+END_EXAMPLE
230
231 You can also omit the final argument, and the loglevel will default to
232 'debug'.
233
234 Tracing to the console is similar:
235
236 #+BEGIN_EXAMPLE
237 lager:trace_console([{request, 117}])
238 #+END_EXAMPLE
239
240 In the above example, the loglevel is omitted, but it can be specified as the
241 second argument if desired.
242
243 You can also specify multiple expressions in a filter, or use the '*' atom as
244 a wildcard to match any message that has that attribute, regardless of its
245 value.
246
247 Tracing to an existing logfile is also supported, if you wanted to log
248 warnings from a particular module to the default error.log:
249
250 #+BEGIN_EXAMPLE
251 lager:trace_file("log/error.log", [{module, mymodule}], warning)
252 #+END_EXAMPLE
253
254 To view the active log backends and traces, you can use the lager:status()
255 function. To clear all active traces, you can use lager:clear_all_traces().
c619263 @Vagabond Cleanup unused handlers when a trace is removed, documentation
Vagabond authored
256
257 To delete a specific trace, store a handle for the trace when you create it,
258 that you later pass to lager:stop_trace/1:
259
260 #+BEGIN_EXAMPLE
261 {ok, Trace} = lager:trace_file("log/error.log", [{module, mymodule}]),
262 ...
263 lager:stop_trace(Trace)
264 #+END_EXAMPLE
ed7bc9a @Vagabond Add pid to the list of attributes automatically captured for tracing
Vagabond authored
265
266 Tracing to a pid is somewhat of a special case, since a pid is not a
267 data-type that serializes well. To trace by pid, use the pid as a string:
268
269 #+BEGIN_EXAMPLE
270 lager:trace_console([{pid, "<0.410.0>"}])
271 #+END_EXAMPLE
Something went wrong with that request. Please try again.