/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

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