Created
May 12, 2018 14:50
-
-
Save petitviolet/c171e3e1b6e397169077c7bc1a10fd41 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.slf4j.LoggerFactory | |
trait LoggerProvider { | |
protected lazy val logger = new xLogger(this.getClass.getName) | |
} | |
private object xLogger { | |
def apply(name: String): xLogger = new xLogger(name) | |
} | |
class xLogger private (name: String) { | |
private lazy val logger = LoggerFactory.getLogger(name) | |
private lazy val isDebugEnabled: Boolean = logger.isDebugEnabled | |
def debugStackTrace(t: => Throwable) = { | |
if (isDebugEnabled) { | |
logger.debug("---------------------") | |
logger.debug(t.getStackTrace.mkString("\n")) | |
logger.debug("---------------------") | |
} | |
} | |
def debug(msg: => String): Unit = | |
if (isDebugEnabled) { | |
logger.debug(msg) | |
} | |
def info(msg: => String): Unit = | |
if (logger.isInfoEnabled) logger.info(msg) | |
def warn(msg: => String): Unit = | |
if (logger.isWarnEnabled) logger.warn(msg) | |
/** | |
* [[Throwable]]をstack trace出さずにある程度詳細なメッセージを出すための関数 | |
* @param depth メッセージに載せるStackTraceの掘る深さ | |
* @return | |
*/ | |
private def throwableMsg(t: Throwable, depth: Int): String = { | |
@annotation.tailrec | |
def loop(t: Throwable, stacks: List[String] = Nil): List[String] = { | |
def getCause(t: Throwable): String = { | |
val trace = t.getStackTrace | |
.take(depth) | |
.map { x => | |
s"${x.getFileName}:${x.getLineNumber}" | |
} | |
.mkString(" -> ") | |
s"${t.getMessage} => $trace" | |
} | |
Option(t) match { | |
case None => stacks | |
case Some(_) => loop(t.getCause, getCause(t) :: stacks) | |
} | |
} | |
loop(t) | |
.map { msg => | |
s"[$msg]" | |
} | |
.mkString(" ") | |
} | |
def warn(msg: => String, e: => Throwable): Unit = | |
if (logger.isWarnEnabled) { | |
logger.warn(s"$msg\n\t${throwableMsg(e, depth = 10)}") | |
} | |
def error(msg: => String): Unit = | |
if (logger.isErrorEnabled) logger.error(msg) | |
def error(msg: => String, e: => Throwable): Unit = | |
if (logger.isErrorEnabled) logger.error(msg, e) | |
def withTimeTrackLog[T](msg: => String)(snippet: => T): T = { | |
if (isDebugEnabled) { | |
logger.debug(s"[P][START]$msg") | |
val start = System.currentTimeMillis() | |
val _result = snippet | |
val end = System.currentTimeMillis() | |
logger.debug(s"[P][END](${end - start} ms) $msg") | |
_result | |
} else snippet | |
} | |
def withTimeTrackLogWithResult[T](msg: => String)(snippet: => T): T = { | |
if (isDebugEnabled) { | |
logger.debug(s"[P][START]$msg") | |
val start = System.currentTimeMillis() | |
val _result = snippet | |
val end = System.currentTimeMillis() | |
logger.debug(s"[P][END](${end - start} ms) $msg. result = ${_result}") | |
_result | |
} else snippet | |
} | |
private def log(logLevel: LogLevel): (=> String) => Unit = { | |
import LogLevel._ | |
logLevel match { | |
case DEBUG => debug _ | |
case INFO => info _ | |
case WARN => warn _ | |
case ERROR => error | |
} | |
} | |
def withTrackLog[T](msg: => String, logLevel: LogLevel = LogLevel.DEBUG)(snippet: => T): T = { | |
val _msg = msg | |
log(logLevel)(s"[START] ${_msg}") | |
val r = snippet | |
log(logLevel)(s"[END] ${_msg}") | |
r | |
} | |
} | |
sealed abstract class LogLevel(val value: String) | |
object LogLevel { | |
case object DEBUG extends LogLevel("debug") | |
case object INFO extends LogLevel("info") | |
case object WARN extends LogLevel("warn") | |
case object ERROR extends LogLevel("error") | |
val values = DEBUG :: INFO :: WARN :: ERROR :: Nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment