/scalate-util/src/main/scala/org/fusesource/scalate/util/Logging.scala

http://github.com/scalate/scalate · Scala · 204 lines · 147 code · 31 blank · 26 comment · 22 complexity · 38d0adb6eaa6b330462fcbceed740bbb MD5 · raw file

  1. /**
  2. * Copyright (C) 2009-2011 the original author or authors.
  3. * See the notice.md file distributed with this work for additional
  4. * information regarding copyright ownership.
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. package org.fusesource.scalate.util
  19. import _root_.java.lang.{ Throwable, String }
  20. import org.slf4j.{ MDC, LoggerFactory }
  21. import java.util.concurrent.atomic.AtomicLong
  22. /**
  23. * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
  24. */
  25. object Log {
  26. def apply(name: String): Log = new Log {
  27. override lazy val log = LoggerFactory.getLogger(name)
  28. }
  29. def apply(clazz: Class[_]): Log = apply(clazz.getName.replace("$", "#").stripSuffix("#"))
  30. def apply(clazz: Class[_], suffix: String): Log = apply(clazz.getName.replace("$", "#").stripSuffix("#") + "." + suffix)
  31. val exception_id_generator = new AtomicLong(System.currentTimeMillis)
  32. def next_exception_id = exception_id_generator.incrementAndGet.toHexString
  33. }
  34. /**
  35. * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
  36. */
  37. trait Log {
  38. import Log._
  39. lazy val log = LoggerFactory.getLogger(getClass.getName.replace("$", "#").stripSuffix("#"))
  40. private def with_throwable(e: Throwable)(func: => Unit) = {
  41. if (e != null) {
  42. val stack_ref = if (log.isDebugEnabled) {
  43. val id = next_exception_id
  44. MDC.put("stackref", id.toString)
  45. Some(id)
  46. } else {
  47. None
  48. }
  49. func
  50. stack_ref.foreach { id =>
  51. log.debug("stack trace: " + id, e)
  52. MDC.remove("stackref")
  53. }
  54. } else {
  55. func
  56. }
  57. }
  58. private def format(message: String, args: Seq[Any]) = {
  59. if (args.isEmpty) {
  60. message
  61. } else {
  62. message.format(args.map(_.asInstanceOf[AnyRef]): _*)
  63. }
  64. }
  65. def error(m: => String, args: Any*): Unit = {
  66. if (log.isErrorEnabled) {
  67. log.error(format(m, args.toSeq))
  68. }
  69. }
  70. def error(e: Throwable, m: => String, args: Any*): Unit = {
  71. if (log.isErrorEnabled) {
  72. with_throwable(e) {
  73. log.error(format(m, args.toSeq))
  74. }
  75. }
  76. }
  77. def error(e: Throwable): Unit = {
  78. if (log.isErrorEnabled) {
  79. with_throwable(e) {
  80. log.error(e.getMessage)
  81. }
  82. }
  83. }
  84. def warn(m: => String, args: Any*): Unit = {
  85. if (log.isWarnEnabled) {
  86. log.warn(format(m, args.toSeq))
  87. }
  88. }
  89. def warn(e: Throwable, m: => String, args: Any*): Unit = {
  90. if (log.isWarnEnabled) {
  91. with_throwable(e) {
  92. log.warn(format(m, args.toSeq))
  93. }
  94. }
  95. }
  96. def warn(e: Throwable): Unit = {
  97. if (log.isWarnEnabled) {
  98. with_throwable(e) {
  99. log.warn(e.getMessage)
  100. }
  101. }
  102. }
  103. def info(m: => String, args: Any*): Unit = {
  104. if (log.isInfoEnabled) {
  105. log.info(format(m, args.toSeq))
  106. }
  107. }
  108. def info(e: Throwable, m: => String, args: Any*): Unit = {
  109. if (log.isInfoEnabled) {
  110. with_throwable(e) {
  111. log.info(format(m, args.toSeq))
  112. }
  113. }
  114. }
  115. def info(e: Throwable): Unit = {
  116. with_throwable(e) {
  117. if (log.isInfoEnabled) {
  118. log.info(e.getMessage)
  119. }
  120. }
  121. }
  122. def debug(m: => String, args: Any*): Unit = {
  123. if (log.isDebugEnabled) {
  124. log.debug(format(m, args.toSeq))
  125. }
  126. }
  127. def debug(e: Throwable, m: => String, args: Any*): Unit = {
  128. if (log.isDebugEnabled) {
  129. log.debug(format(m, args.toSeq), e)
  130. }
  131. }
  132. def debug(e: Throwable): Unit = {
  133. if (log.isDebugEnabled) {
  134. log.debug(e.getMessage, e)
  135. }
  136. }
  137. def trace(m: => String, args: Any*): Unit = {
  138. if (log.isTraceEnabled) {
  139. log.trace(format(m, args.toSeq))
  140. }
  141. }
  142. def trace(e: Throwable, m: => String, args: Any*): Unit = {
  143. if (log.isTraceEnabled) {
  144. log.trace(format(m, args.toSeq), e)
  145. }
  146. }
  147. def trace(e: Throwable): Unit = {
  148. if (log.isTraceEnabled) {
  149. log.trace(e.getMessage, e)
  150. }
  151. }
  152. }
  153. /**
  154. * A Logging trait you can mix into an implementation class without affecting its public API
  155. */
  156. trait Logging {
  157. protected val log = Log(getClass)
  158. protected def error(message: => String): Unit = log.error(message)
  159. protected def error(message: => String, e: Throwable): Unit = log.error(e, message)
  160. protected def error(e: Throwable): Unit = log.error(e)
  161. protected def warn(message: => String): Unit = log.warn(message)
  162. protected def warn(message: => String, e: Throwable): Unit = log.warn(e, message)
  163. protected def warn(e: Throwable): Unit = log.warn(e)
  164. protected def info(message: => String): Unit = log.info(message)
  165. protected def info(message: => String, e: Throwable): Unit = log.info(e, message)
  166. protected def info(e: Throwable): Unit = log.info(e)
  167. protected def debug(message: => String): Unit = log.debug(message)
  168. protected def debug(message: => String, e: Throwable): Unit = log.debug(e, message)
  169. protected def debug(e: Throwable): Unit = log.debug(e)
  170. protected def trace(message: => String): Unit = log.trace(message)
  171. protected def trace(message: => String, e: Throwable): Unit = log.trace(e, message)
  172. protected def trace(e: Throwable): Unit = log.trace(e)
  173. }