2013년 1월 7일 월요일

Scala 용 Slf4j Logging

Scala에서 직접 Slf4j 를 사용해도 가능하지만,  좀 더 편하게 사용할 수 기존 Logger를 Scala 용으로 Wrapping 하였습니다.

package kr.kth.commons.slf4j
import org.slf4j.{Logger => Slf4jLogger, Marker}
import annotation.varargs
/**
* Scala를 위한 Logger 입니다.
* User: sunghyouk.bae@gmail.com
* Date: 13. 1. 6.
*/
class Logger(val log: Slf4jLogger) {
import scala.language.implicitConversions
private implicit def _any2String(msg: Any): String =
msg match {
case null => "<null>"
case _ => msg.toString
}
lazy val name = log.getName
lazy val isTraceEnabled = log.isTraceEnabled
@inline final def isTraceEnabled(marker: Marker) = log.isTraceEnabled(marker)
@inline final def trace(msg: String, t: Throwable) {
if (isTraceEnabled)
log.trace(msg, t)
}
@inline final def trace(marker: Marker, msg: String, t: Throwable) {
if (isTraceEnabled(marker))
log.trace(marker, msg, t)
}
@inline
@varargs final def trace(format: Any, arguments: Any*) {
if (isTraceEnabled)
log.trace(format.toString, arguments.map(_.asInstanceOf[AnyRef]): _*)
}
@inline
@varargs final def trace(marker: Marker, format: Any, arguments: Any*) {
if (isTraceEnabled(marker))
log.trace(marker, format.toString, arguments.map(_.asInstanceOf[AnyRef]): _*)
}
lazy val isDebugEnabled = log.isDebugEnabled
@inline final def isDebugEnabled(marker: Marker) = log.isDebugEnabled(marker)
@inline final def debug(msg: String, t: Throwable) {
if (isDebugEnabled)
log.debug(msg, t)
}
@inline final def debug(marker: Marker, msg: String, t: Throwable) {
if (isDebugEnabled(marker))
log.debug(marker, msg, t)
}
@inline
@varargs final def debug(format: Any, arguments: Any*) {
if (isDebugEnabled)
log.debug(format.toString, arguments.map(_.asInstanceOf[AnyRef]): _*)
}
@inline
@varargs final def debug(marker: Marker, format: Any, arguments: Any*) {
if (isDebugEnabled(marker))
log.debug(marker, format.toString, arguments.map(_.asInstanceOf[AnyRef]): _*)
}
lazy val isInfoEnabled = log.isInfoEnabled
@inline final def isInfoEnabled(marker: Marker) = log.isInfoEnabled(marker)
@inline final def info(msg: String, t: Throwable) {
if (isInfoEnabled)
log.info(msg, t)
}
@inline final def info(marker: Marker, msg: String, t: Throwable) {
if (isInfoEnabled(marker))
log.info(marker, msg, t)
}
@inline
@varargs final def info(format: Any, arguments: Any*) {
if (isInfoEnabled)
log.info(format.toString, arguments.map(_.asInstanceOf[AnyRef]): _*)
}
@inline
@varargs final def info(marker: Marker, format: Any, arguments: Any*) {
if (isInfoEnabled(marker))
log.info(marker, format.toString, arguments.map(_.asInstanceOf[AnyRef]): _*)
}
lazy val isWarnEnabled = log.isWarnEnabled
@inline final def isWarnEnabled(marker: Marker) = log.isWarnEnabled(marker)
@inline final def warn(msg: String, t: Throwable) {
if (isWarnEnabled)
log.warn(msg, t)
}
@inline final def warn(marker: Marker, msg: String, t: Throwable) {
if (isWarnEnabled(marker))
log.warn(marker, msg, t)
}
@inline
@varargs final def warn(format: Any, arguments: Any*) {
if (isWarnEnabled)
log.warn(format.toString, arguments.map(_.asInstanceOf[AnyRef]): _*)
}
@inline
@varargs final def warn(marker: Marker, format: Any, arguments: Any*) {
if (isWarnEnabled(marker))
log.warn(marker, format.toString, arguments.map(_.asInstanceOf[AnyRef]): _*)
}
lazy val isErrorEnabled = log.isErrorEnabled
@inline final def isErrorEnabled(marker: Marker) = log.isErrorEnabled(marker)
@inline final def error(msg: String, t: Throwable) {
if (isErrorEnabled)
log.error(msg, t)
}
@inline final def error(marker: Marker, msg: String, t: Throwable) {
if (isErrorEnabled(marker))
log.error(marker, msg, t)
}
@inline
@varargs final def error(format: Any, arguments: Any*) {
if (isErrorEnabled)
log.error(format.toString, arguments.map(_.asInstanceOf[AnyRef]): _*)
}
@inline
@varargs final def error(marker: Marker, format: Any, arguments: Any*) {
if (isErrorEnabled(marker))
log.error(marker, format.toString, arguments.map(_.asInstanceOf[AnyRef]): _*)
}
}
object Logger {
import scala.reflect.{classTag, ClassTag}
lazy val RootLoggerName = Slf4jLogger.ROOT_LOGGER_NAME
/**
* 지정된 이름을 Logger 이름으로 사용합니다. 예: Logger("LoggerName")
*/
def apply(name: String): Logger = new Logger(org.slf4j.LoggerFactory.getLogger(name))
/**
* 지정한 클래스 수형에 맞는 Logger를 반환합니다. 예: Logger(this.type)
*/
def apply(cls: Class[_]): Logger = apply(cls.getName)
/**
* 특정 클래스에 맞는 Logger 를 반환합니다. 예: Logger[classOf[MyClass]]
*/
def apply[C: ClassTag](): Logger = apply(classTag[C].runtimeClass.getName)
/**
* Root Logger
*/
def rootLogger = apply(RootLoggerName)
}
view raw Logger.scala hosted with ❤ by GitHub

Scala 의 Mixin 방식으로 사용하기 위해서 Logging trait 을 구현했습니다.

package kr.kth.commons.slf4j
import org.slf4j.Marker
import annotation.varargs
/**
* 로그를 사용할 클래스에서 MixIn 방식으로 상속해서 사용하면 됩니다. ( class A extends Logger ... )
* User: sunghyouk.bae@gmail.com
* Date: 13. 1. 6.
*/
trait Logging {
protected lazy val log: Logger = Logger(getClass)
protected def loggerName = log.name
protected lazy val isTranceEnabled = log.isTraceEnabled
protected def trace(msg: String, t: Throwable) {
log.trace(msg, t)
}
protected def trace(marker: Marker, msg: String, t: Throwable) {
log.trace(marker, msg, t)
}
@varargs
protected def trace(format: Any, arguments: Any*) {
log.trace(format, arguments)
}
@varargs
protected def trace(marker: Marker, format: Any, arguments: Any*) {
log.trace(marker, format, arguments)
}
protected lazy val isDebugEnabled = log.isDebugEnabled
protected def debug(msg: String, t: Throwable) {
log.debug(msg, t)
}
protected def debug(marker: Marker, msg: String, t: Throwable) {
log.debug(marker, msg, t)
}
@varargs
protected def debug(format: Any, arguments: Any*) {
log.debug(format, arguments)
}
@varargs
protected def debug(marker: Marker, format: Any, arguments: Any*) {
log.debug(marker, format, arguments)
}
protected lazy val isInfoEnabled = log.isInfoEnabled
protected def info(msg: String, t: Throwable) {
log.info(msg, t)
}
protected def info(marker: Marker, msg: String, t: Throwable) {
log.info(marker, msg, t)
}
@varargs
protected def info(format: Any, arguments: Any*) {
log.info(format, arguments)
}
@varargs
protected def info(marker: Marker, format: Any, arguments: Any*) {
log.info(marker, format, arguments)
}
protected lazy val isWarnEnabled = log.isWarnEnabled
protected def warn(msg: String, t: Throwable) {
log.warn(msg, t)
}
protected def warn(marker: Marker, msg: String, t: Throwable) {
log.warn(marker, msg, t)
}
@varargs
protected def warn(format: Any, arguments: Any*) {
log.warn(format, arguments)
}
@varargs
protected def warn(marker: Marker, format: Any, arguments: Any*) {
log.warn(marker, format, arguments)
}
protected lazy val isErrorEnabled = log.isErrorEnabled
protected def error(msg: String, t: Throwable) {
log.error(msg, t)
}
protected def error(marker: Marker, msg: String, t: Throwable) {
log.error(marker, msg, t)
}
@varargs
protected def error(format: Any, arguments: Any*) {
log.error(format, arguments)
}
@varargs
protected def error(marker: Marker, format: Any, arguments: Any*) {
log.error(marker, format, arguments)
}
}
view raw Logging.scala hosted with ❤ by GitHub


Logging trait 을 사용하여 MixIn 방식으로 사용하는 예입니다.

package kr.kth.commons.slf4j
import org.junit.Test
/**
* User: sunghyouk.bae@gmail.com
* Date: 13. 1. 8
*/
class LoggingTest extends Logging {
@Test
def printString() {
log.trace("Trace Simple String")
log.debug("Debug Simple String")
log.info("Info Simple String")
log.warn("Warn Simple String")
log.error("Error Simple String")
}
@Test
def printAnyVal() {
log.debug("print 1")
log.debug(1)
}
case class Card(val name: String, val year: Int)
@Test
def printAnyRef() {
log.debug("print Card object (name=Credit, year=2006)")
log.debug(new Card("Credit", 2006))
}
@Test
def printFormatString() {
log.trace("Format String. Card=[{}]", new Card("Format", 2013))
log.debug("Format String. Card=[{}]", new Card("Format", 2013))
log.info("Format String. Card=[{}]", new Card("Format", 2013))
log.warn("Format String. Card=[{}]", new Card("Format", 2013))
log.error("Format String. Card=[{}]", new Card("Format", 2013))
}
@Test
def printException() {
log.debug("Print exception", new RuntimeException("for test"))
}
}


댓글 없음: