Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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