I’ve made a Logging trait which encapsulates the details of a logging implementation, it’s also nice and lazy so is efficient especially when a particular log level is not active.
/**
* A SLF4J based logging trait
*/
trait Log {
import org.slf4j.Logger
import org.slf4j.LoggerFactory
val loggedClazz: Class[_]
lazy val logger: Logger = LoggerFactory.getLogger(loggedClazz.getClass)
def logDebug(codeblock: => String) = {
if (logger.isDebugEnabled) {
logger.debug(codeblock)
}
}
def logError(codeblock: => String) = {
if (logger.isErrorEnabled) {
logger.error(codeblock)
}
}
def logInfo(codeblock: => String) = {
if (logger.isInfoEnabled) {
logger.info(codeblock)
}
}
def logWarn(codeblock: => String) = {
if (logger.isWarnEnabled) {
logger.warn(codeblock)
}
}
}
However it requires the class into which this trait is mixed-in to implement the following..
object MyServer extends Log {
val loggedClazz = MyServer.getClass
}
My question is, is it possible to somehow enable the Trait to know into which class it has been mixed into? Removing the need to do:
val loggedClazz = MyServer.getClass
SOLUTION: Following the provided feedback, I rewrote the class in the following manner.
/**
* A SLF4J based logging trait
*/
trait Log {
import org.slf4j.Logger
import org.slf4j.LoggerFactory
lazy val logger: Logger = LoggerFactory.getLogger(getClass)
def logDebug(codeblock: => String) = {
if (logger.isDebugEnabled) {
logger.debug(codeblock)
}
}
def logError(codeblock: => String) = {
if (logger.isErrorEnabled) {
logger.error(codeblock)
}
}
def logInfo(codeblock: => String) = {
if (logger.isInfoEnabled) {
logger.info(codeblock)
}
}
def logWarn(codeblock: => String) = {
if (logger.isWarnEnabled) {
logger.warn(codeblock)
}
}
}
Totally simple. When you do it right, first time 😉
Your current code won’t work as expected as the returned logger will always be for class
Class[Class[_]], as you’re callinggetClasson aClass[_]object.Use this instead:
lazy val logger: Logger = LoggerFactory.getLogger(getClass)You may also want to have a look SLF4S, a thin wrapper around SLF4J, which is very similar to what you’re doing.