README.md 8.83 KB
Newer Older
Duncan M. McGreggor's avatar
Duncan M. McGreggor committed
1
# logjam
Duncan M. McGreggor's avatar
Duncan M. McGreggor committed
2

3 4 5 6
[![Build Status][travis badge]][travis]
[![LFE Versions][lfe badge]][lfe]
[![Erlang Versions][erlang badge]][versions]
[![Tags][github tags badge]][github tags]
7
[![Downloads][hex downloads]][hex package]
8

Duncan McGreggor's avatar
Duncan McGreggor committed
9
[![Project Logo][logo]][logo-large]
10

11
*A Logging Library for LFE*
Duncan M. McGreggor's avatar
Duncan M. McGreggor committed
12 13


14
##### Table of Contents
15 16

* [Introduction](#introduction-)
17
* [Dependencies](#dependencies-)
18 19
* [Installation](#installation-)
* [Setup](#setup-)
20 21 22
  * [Basic Configuration](#basic-configuration-)
  * [Colour Support](#colour-support-)
  * [Starting Logjam](#starting-logjam-)
23 24
* [Usage](#usage-)
  * [Log-level Functions](#log-level-functions-)
Duncan M. McGreggor's avatar
Duncan M. McGreggor committed
25
  * [Dynamically Updating Log Levels](#dynamically-updating-log-levels-)
26
* [License](#license-)
27 28 29


## Introduction [↟](#table-of-contents)
Duncan M. McGreggor's avatar
Duncan M. McGreggor committed
30 31 32 33 34 35

The preferred logging library in Erlang is
[lager](https://github.com/basho/lager). However, it doesn't work
out of the box with LFE, due to the fact that it uses parse transforms (the LFE
compiler uses Core Erlang and does not generate Erlang abstract terms, which
are how Erlang parse transforms work).
Duncan M. McGreggor's avatar
Duncan M. McGreggor committed
36

Duncan M. McGreggor's avatar
Duncan M. McGreggor committed
37
As such, we needed a way to easily use lager from LFE. So here you have it: a
Duncan McGreggor's avatar
Duncan McGreggor committed
38
a pile of logs for the LFE community, in a river of LFE code ...
Duncan M. McGreggor's avatar
Duncan M. McGreggor committed
39

40 41
[![][screenshot]][screenshot]

Duncan M. McGreggor's avatar
Duncan M. McGreggor committed
42

43
## Dependencies [↟](#table-of-contents)
44 45

As of version 0.3.0, this project assumes that you have
46
[rebar3](https://github.com/rebar/rebar3) installed somwhere in your `$PATH`.
47 48 49 50
It no longer uses the old version of rebar. If you do not wish to use rebar3,
you may use the most recent rebar2-compatible release of logjam: 0.2.0.


51
## Installation [↟](#table-of-contents)
Duncan M. McGreggor's avatar
Duncan M. McGreggor committed
52

53
Just add it to your `rebar.config` deps:
Duncan M. McGreggor's avatar
Duncan M. McGreggor committed
54 55

```erlang
56 57 58 59 60
{deps, [
  ...
  {logjam, ".*",
    {git, "[email protected]:lfex/logjam.git", "master"}}
    ]}.
Duncan M. McGreggor's avatar
Duncan M. McGreggor committed
61 62 63 64 65
```

And then do the usual:

```bash
66
$ make compile
Duncan M. McGreggor's avatar
Duncan M. McGreggor committed
67 68 69
```


70
## Setup [↟](#table-of-contents)
71

72 73 74

### Basic Configuration [↟](#table-of-contents)

75
First things first, make sure you have an `lfe.config` file with the
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
appropriate lager configuration options set. For instance:

```cl
#(logging (
   #(log-level info)
   #(backend lager)
   #(options (#(lager_console_backend info)
              #(lager_file_backend (
                #(file "log/error.log")
                #(level error)
                #(size 10485760)
                #(date "$D0")
                #(count 5)))
              #(lager_file_backend (
                #(file "log/console.log")
                #(level info)
                #(size 10485760)
                #(date "$D0")
                #(count 5)))))))
```

Duncan McGreggor's avatar
Duncan McGreggor committed
97
Any legal lager configuration will work (as long as you translate it into LFE
98 99
syntax first!).

100 101
If you'd like to use use the custom log formatter (modeled after logging
formats common in Clojure applications), you can configure your handler like
102
the following:
103 104

```cl
105 106 107 108 109 110 111 112 113 114
#(logging (
   #(log-level debug)
   #(colored true)
   #(backend lager)
   #(options (#(lager_console_backend (
                debug
                #(logjam-formatter
                  (date " " time " [" pid "] [" severity "] " message "\n"))))
               ...))))
```
115

Cinova Dev Team's avatar
Cinova Dev Team committed
116

117
### Color Support [↟](#table-of-contents)
Cinova Dev Team's avatar
Cinova Dev Team committed
118

119
Logjam supports colourd logging -- you just need to enable it in your
120
project's `lfe.config` file. See the logjam `lfe.config` for example
121
configuration.
122

123
To not have ANSI colors as part of the output, be sure to use `#(colored false)`.
Cinova Dev Team's avatar
Cinova Dev Team committed
124

125
If you'd like to use your own colors, you can start with this template:
Cinova Dev Team's avatar
Cinova Dev Team committed
126

127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
```cl
#(logging (
   #(log-level debug)
   #(colored true)
   #(colors (#(timestamp (color green))
             #(process (color cyan))
             #(date (color green))
             #(time (color green))
             #(modfunc (color yellow))
             #(message (color green))
             #(debug (color greenb))
             #(info (color blue))
             #(notice (color cyan))
             #(warning (color yellow))
             #(error (color red))
             #(critical (color yellowb))
             #(alert (color magentab))
             #(emergency (color redb))))
  ...))
146
```
147 148 149 150 151 152 153

The confguration value for the color is a list of module and func that will be called to wrap color around the log text indicated by the configuration's key (e.g., timestamp, debug, etc.)


### Starting Logjam [↟](#table-of-contents)

Next, start the logjam application (which will perform additional setup and start lager):
154 155

```cl
156 157 158
> (logjam:start)
ok
2015-12-17 13:08:04.163 [<0.7.0>] [info] Application lager started on ...
159 160
```

161
You may or may not see a message logged to the console, depending upon your log-level setting in `lfe.config`.
162 163 164


## Usage [&#x219F;](#table-of-contents)
165

166
The `logjam` module includes all the logging functions you may be used to in other logging frameworks. These allow you do make calls like the following:
Cinova Dev Team's avatar
Cinova Dev Team committed
167 168

```cl
169 170 171 172
(logjam:info "An informative message")
(logjam:info "A ~p message" '(great))
(logjam:info 'my-mod 'my-func/2 "Message from function ...")
(logjam:info 'my-mod 'my-func/2 "Message from a ~p function ..." '(simple))
Cinova Dev Team's avatar
Cinova Dev Team committed
173
```
174

175 176 177 178 179 180 181 182 183 184
If you would like to have your module and function populated in the log more or less automatically, you can call logjam log functions with the "caller" tuple:

```cl
(logjam:info `#(c ,(logjam:caller)) "An informative message")
(logjam:info `#(c ,(logjam:caller)) "A ~p message" '(great))
```

More details on the logging functions are given below.


185
### Log-level Functions [&#x219F;](#table-of-contents)
Duncan M. McGreggor's avatar
Duncan M. McGreggor committed
186

187
Now you'll be able to use logjam. The following log types are defined:
188 189 190
 * `debug`
 * `info`
 * `notice`
191
 * `warning` (supported with `warn` alias)
192 193 194
 * `error` (supported by both sets of `error` and `err` functions)
 * `critical`
 * `alert`
195
 * `emergency` (supported with `fail` and `faiulre` aliases)
196

Duncan McGreggor's avatar
Duncan McGreggor committed
197
Each of these has arity 1, 2, 3, and 4 functions of the same name:
198
* arity 1: pass a message
199
* arity 2: pass an `(io_lib:format ...)` format string and arguments for the
200 201
  format string OR pass a caller tuple and a message
* arity 3: pass a module, a function, and a message OR pass a caller tuple, a format string, and args
202
* arity 4: pass a module, a function, an `(io_lib:format ...)` format string,
203 204 205 206 207
  and arguments for the format string

Examples:

```cl
208 209 210 211 212 213 214
> (logjam:info "wassup?")
ok
> 2015-12-17 13:44:06.912 [<0.46.0>] [info] wassup?
```

```cl
> (logjam:critical "~s~shey!" '("a " "critical thing, hey-"))
215
ok
216
> 2015-12-17 13:44:31.412 [<0.46.0>] [critical] a critical thing, hey-hey!
217 218 219
```

```cl
220
> (logjam:notice `#(c ,(logjam:caller)) "You better check this out ...")
221
ok
222 223 224 225 226 227 228 229
> 2015-12-17 13:49:10.235 [<0.46.0>] [notice] lists:map/2 You better check this out ...

```

```cl
> (logjam:notice (MODULE) 'my-func "You better check this out ...")
ok
> 2015-12-17 13:45:12.158 [<0.46.0>] [notice] -no-module:my-func You better check this out ...
230 231 232
```

```cl
233
> (logjam:alert `#(c ,(logjam:caller)) "~s~shey!" '("whoa! " "red alert, "))
234
ok
235
> 2015-12-17 13:48:08.277 [<0.46.0>] [alert] lists:map/2 whoa! red alert, hey!
236 237 238
```

```cl
239
> (logjam:alert (MODULE) 'my-func "~s~shey!" '("whoa! " "red alert, "))
240
ok
241
> 2015-12-17 13:45:31.196 [<0.46.0>] [alert] -no-module:my-func whoa! red alert, hey!
242
```
243 244 245 246 247


### Dynamically Updating Log Levels [&#x219F;](#table-of-contents)

logjam provides the following wrappers for this same functionality in lager:
248 249 250
 * `logjam:set-level/1` - set the level of the console backend
 * `logjam:set-level/2` - set the log level of a given backend
 * `logjam:set-level/3` - set the log level of a given backend's' logfile
251

252
Examples:
253

254
```cl
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
> (logjam:set-level 'debug)
ok
 ```

```cl
> (logjam:set-level 'lager_console_backend 'debug)
ok
```

```cl
> (logjam:set-level 'lager_file_backend "log/console.log" 'debug)
21:32:03.894 [notice] Changed loglevel of log/console.log to debug
ok
```

```cl
(logjam:set-level 'lager_file_backend "log/error.log" 'warning)
21:34:32.131 [notice] Changed loglevel of log/error.log to warning
ok
```
275 276 277 278 279 280 281 282 283


## License [&#x219F;](#table-of-contents)

Apache Version 2 License

Copyright © 2015-2016, Duncan McGreggor <[email protected]>


284
[](Named page links below ...)
285 286 287

[logo]: priv/images/logjam-crop-small.png
[logo-large]: priv/images/logjam.jpg
Duncan McGreggor's avatar
Duncan McGreggor committed
288
[screenshot]: priv/images/screenshot.png
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303
[org]: https://github.com/lfex
[github]: https://github.com/lfex/logjam
[gitlab]: https://gitlab.com/lfex/logjam
[travis]: https://travis-ci.org/lfex/logjam
[travis badge]: https://img.shields.io/travis/lfex/logjam.svg
[lfe]: https://github.com/rvirding/lfe
[lfe badge]: https://img.shields.io/badge/lfe-1.2.0-blue.svg
[erlang badge]: https://img.shields.io/badge/erlang-R15%20to%2019.1-blue.svg
[versions]: https://github.com/lfex/logjam/blob/master/.travis.yml
[github tags]: https://github.com/lfex/logjam/tags
[github tags badge]: https://img.shields.io/github/tag/lfex/logjam.svg
[github downloads]: https://img.shields.io/github/downloads/lfex/logjam/total.svg
[hex badge]: https://img.shields.io/hexpm/v/logjam.svg?maxAge=2592000
[hex package]: https://hex.pm/packages/logjam
[hex downloads]: https://img.shields.io/hexpm/dt/logjam.svg