/src/main/scala/com/codahale/logula/Logging.scala
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}