PageRenderTime 16ms CodeModel.GetById 1ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 1ms

/src/main/scala/com/codahale/logula/Logging.scala

http://github.com/codahale/logula
Scala | 184 lines | 83 code | 30 blank | 71 comment | 5 complexity | 895498bc1fbf26b5330cbd7575fa48ce MD5 | raw file
  1package com.codahale.logula
  2
  3import scala.collection.mutable
  4import management.ManagementFactory
  5import javax.management.{InstanceAlreadyExistsException, ObjectName}
  6import org.apache.log4j.net.SyslogAppender
  7import org.apache.log4j._
  8
  9/**
 10 * A singleton class for configuring logging in a JVM process.
 11 */
 12object Logging {
 13  class LoggingConsoleConfig {
 14    /**
 15     * Whether or not logged statements should be output to standard out.
 16     * Defaults to {@code true}.
 17     */
 18    var enabled = true
 19
 20    /**
 21     * The minimum logging level which will be written to console.
 22     */
 23    var threshold = Level.ALL
 24  }
 25
 26  class LoggingFileConfig {
 27    /**
 28     * Whether or not logged statements should be output to a file.
 29     * Defaults to  {@code false}.
 30     */
 31    var enabled = false
 32
 33    /**
 34     * The minimum logging level which will be written to the file.
 35     */
 36    var threshold = Level.ALL
 37
 38    /**
 39     * The log filename.
 40     */
 41    var filename = ""
 42
 43    /**
 44     * The maximum log file in kilobytes, before it's rolled over.
 45     */
 46    var maxSize = 10 * 1024 //10MB
 47
 48    /**
 49     * The number of old log files to retain.
 50     */
 51    var retainedFiles = 5
 52  }
 53
 54  class LoggingSyslogConfig {
 55    /**
 56     * Whether or not logged statements should be output to syslog.
 57     * Defaults to  {@code false}.
 58     */
 59    var enabled = false
 60
 61    /**
 62     * The minimum logging level which will be written to syslog.
 63     */
 64    var threshold = Level.ALL
 65
 66    /**
 67     * The syslog host.
 68     */
 69    var host = "localhost"
 70
 71    /**
 72     * The syslog facility.
 73     */
 74    var facility = "local0"
 75
 76    /**
 77     * The syslog pattern.
 78     */
 79    var pattern = "%c: %m"
 80  }
 81
 82  class LoggingConfig {
 83    /**
 84     * Console logging configuration.
 85     */
 86    val console = new LoggingConsoleConfig
 87
 88    /**
 89     * File logging configuration.
 90     */
 91    val file = new LoggingFileConfig
 92
 93    /**
 94     * Syslog logging configuration.
 95     */
 96    val syslog = new LoggingSyslogConfig
 97
 98    /**
 99     * A map of logger names to default levels.
100     */
101    val loggers = new mutable.HashMap[String, Level]()
102
103    /**
104     * Whether or not Logula should register a JMX MBean which allows you to
105     * dynamically modify logger levels. Defaults to {@code true}.
106     */
107    var registerWithJMX = true
108
109    /**
110     * The default level for all loggers.
111     */
112    var level = Level.INFO
113  }
114
115  /**
116   * Configure Logula using all defaults
117   */
118  def configure() {
119    configure { _ => }
120  }
121
122  /**
123   * Configure Logula.
124   */
125  def configure(f: LoggingConfig => Any) {
126    val config = new LoggingConfig
127    f(config)
128
129    val root = Logger.getRootLogger
130    root.getLoggerRepository.resetConfiguration()
131    root.setLevel(config.level)
132
133    for ((name, level) <- config.loggers) {
134      Logger.getLogger(name).setLevel(level)
135    }
136
137    val appender = new AsyncAppender
138    root.addAppender(appender)
139
140    if (config.console.enabled) {
141      val console = new ConsoleAppender(new Formatter)
142      console.setThreshold(config.console.threshold)
143      appender.addAppender(console)
144    }
145
146    if (config.file.enabled) {
147      val rollingLog = new RollingFileAppender()
148      rollingLog.setLayout(new Formatter)
149      rollingLog.setAppend(true)
150      rollingLog.setFile(config.file.filename)
151      rollingLog.setMaximumFileSize(config.file.maxSize * 1024)
152      rollingLog.setMaxBackupIndex(config.file.retainedFiles)
153      rollingLog.activateOptions()
154      rollingLog.setThreshold(config.file.threshold)
155
156      appender.addAppender(rollingLog)
157    }
158
159    if (config.syslog.enabled) {
160      val layout = new PatternLayout(config.syslog.pattern)
161      val syslog = new SyslogAppender(layout, config.syslog.host, SyslogAppender.getFacility(config.syslog.facility))
162      syslog.setThreshold(config.syslog.threshold)
163      appender.addAppender(syslog)
164    }
165
166    if (config.registerWithJMX) {
167      try {
168        val mbeans = ManagementFactory.getPlatformMBeanServer
169        val name = new ObjectName("com.codahale.logula:type=Logging")
170        mbeans.registerMBean(LoggingMXBean, name)
171      } catch {
172        case e: InstanceAlreadyExistsException => // THANKS
173      }
174    }
175  }
176}
177
178/**
179 * A mixin trait which provides subclasses with a Log instance keyed to the
180 * subclass's name.
181 */
182trait Logging {
183  protected lazy val log: Log = Log.forClass(getClass)
184}