PageRenderTime 40ms CodeModel.GetById 19ms app.highlight 17ms RepoModel.GetById 2ms app.codeStats 0ms

/README.md

http://github.com/codahale/logula
Markdown | 181 lines | 137 code | 44 blank | 0 comment | 0 complexity | 61fcf4636a172cd6df0db90711a3a401 MD5 | raw file
  1Logula
  2======
  3
  4*Bwah ah ah ah.*
  5
  6[Logula](http://github.com/codahale/logula) is a Scala library which provides a
  7sane log output format and an easy-to-use mixin for adding logging to your code.
  8
  9It's a thin front-end for [log4j 1.2](http://logging.apache.org/log4j/1.2/)
 10because `java.util.logging` was a pain in the neck to deal with.
 11
 12
 13Requirements
 14------------
 15
 16* Java SE 6
 17* Scala 2.8.1 or 2.9.0-1
 18* log4j 1.2
 19
 20
 21How To Use
 22----------
 23
 24**First**, specify Logula as a dependency:
 25
 26```xml
 27<repositories>
 28  <repository>
 29    <id>repo.codahale.com</id>
 30    <url>http://repo.codahale.com</url>
 31  </repository>
 32</repositories>
 33
 34<dependencies>
 35  <dependency>
 36    <groupId>com.codahale</groupId>
 37    <artifactId>logula_${scala.version}</artifactId>
 38    <version>2.1.3</version>
 39  </dependency>
 40</dependencies>
 41```
 42
 43**Second**, configure the logging system:
 44
 45```scala
 46import com.codahale.logula.Logging
 47import org.apache.log4j.Level
 48
 49Logging.configure { log =>
 50  log.registerWithJMX = true
 51
 52  log.level = Level.INFO
 53  log.loggers("com.myproject.weebits") = Level.OFF
 54
 55  log.console.enabled = true
 56  log.console.threshold = Level.WARN
 57
 58  log.file.enabled = true
 59  log.file.filename = "/var/log/myapp/myapp.log"
 60  log.file.maxSize = 10 * 1024 // KB
 61  log.file.retainedFiles = 5 // keep five old logs around
 62
 63  // syslog integration is always via a network socket
 64  log.syslog.enabled = true
 65  log.syslog.host = "syslog-001.internal.example.com"
 66  log.syslog.facility = "local3"
 67}
 68```
 69
 70**Third**, add some logging to your classes:
 71
 72```scala
 73class MyThing extends Logging {
 74  def complicatedManoeuvre() {
 75    try {
 76      log.warn("This is about to get complicated...")
 77      log.info("Trying to do %d backflips", backflipsToAttempt)
 78      // complicated bit elided
 79    } catch {
 80      case e: Exception => log.error(e, "Horrible things have happened.")
 81    }
 82  }
 83}
 84```
 85
 86Notice that the logging statements use Scala's formatting syntax, and that
 87logged exceptions are passed as the first argument.
 88
 89
 90Statement Arguments
 91-------------------
 92
 93Unlike a lot of Scala logging libraries, Logula doesn't use pass-by-name
 94semantics (e.g., `f: => A`) for its logging statements, which means two things:
 95
 961. The Scala compiler doesn't have to create one-off closure objects for each
 97   logging statement. This should reduce the amount of garbage collection
 98   pressure.
 992. If your logging arguments are complex to create, that price will be paid
100   regardless of whether or not the statement is logged.
101
102For example:
103
104```scala
105log.debug("A huge collection: %s", things.mkString(", "))
106```
107
108The `mkString` call will happen every time. To prevent this, either keep your
109arguments simple:
110
111```scala
112log.debug("A huge collection: %s", things)
113```
114
115or only conditionally log them:
116
117```scala
118if (log.isDebugEnabled) {
119  log.debug("A huge collection: %s", things.mkString(", "))
120}
121```
122
123In most cases, it's simple enough to just log basic values.
124
125
126The Log Format
127--------------
128
129Logula's log format has a few specific goals.
130
131* Be roughly human readable. You shouldn't need another program to make sense of
132  your program.
133* Be machine parsable. You shouldn't need another human to make sense of your
134  program. (Shush.)
135* Make it easy for sleepy ops folks to figure out why things are pear-shaped at
136  o'dark-thirty using standard UNIXy tools like `tail`, `grep`, and `fortune`.
137
138An example of logging output looks like this:
139
140    TRACE [2010-04-06 06:42:35,271] com.codahale.logula.examples.ThingDoer: Contemplating doing a thing.
141    DEBUG [2010-04-06 06:42:35,274] com.codahale.logula.examples.ThingDoer: About to do a thing.
142    INFO  [2010-04-06 06:42:35,274] com.codahale.logula.examples.ThingDoer: Doing a thing
143    WARN  [2010-04-06 06:42:35,275] com.codahale.logula.examples.ThingDoer: Doing a thing
144    ERROR [2010-04-06 06:42:35,275] com.codahale.logula.examples.ThingDoer: This may get ugly.
145    FATAL [2010-04-06 06:42:35,275] com.codahale.logula.examples.ThingDoer: The thing has gone horribly wrong.
146    ! java.lang.RuntimeException: oh noes!
147    ! 	at scala.Predef$.error(Predef.scala:74)
148    ! 	at com.codahale.logula.examples.ThingDoer.run(ExampleLoggingRun.scala:16)
149    ! 	at com.codahale.logula.examples.ExampleLoggingRun$.main(ExampleLoggingRun.scala:40)
150    ! 	at com.codahale.logula.examples.ExampleLoggingRun.main(ExampleLoggingRun.scala)
151    ! 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
152    ! 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
153    ! 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
154    ! 	at java.lang.reflect.Method.invoke(Method.java:597)
155    ! 	at sbt.Run.run0(Run.scala:60)
156    ! 	at sbt.Run.execute$1(Run.scala:47)
157    ! 	at sbt.Run$$anonfun$run$2.apply(Run.scala:50)
158    ! 	at sbt.Run$$anonfun$run$2.apply(Run.scala:50)
159    ! 	at sbt.TrapExit$.executeMain$1(TrapExit.scala:33)
160    ! 	at sbt.TrapExit$$anon$1.run(TrapExit.scala:42)
161    ! 
162
163A few items of note:
164
165  * All timestamps are in UTC and ISO 8601 format. This really should be OK with
166    you.
167  * You can grep for messages of a specific level really easily:
168    `tail -f logula.log | grep '^WARN'`
169  * You can grep for messages from a specific class or package really easily:
170    `tail -f logula.log | grep 'ThingDoer'`
171  * You can even pull out full exception stack traces, plus the accompanying
172    log message: `tail -f logula.log | grep -B 1 '^\!'`
173  * If you squint, you can still make out the actual log messages.
174
175
176License
177-------
178
179Copyright (c) 2010-2011 Coda Hale
180
181Published under The MIT License, see LICENSE