简体   繁体   中英

scala self aware trait

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;)

You could replace val loggedClazz: Class[_] with val loggedClazz = getClass .

Your current code won't work as expected as the returned logger will always be for class Class[Class[_]] , as you're calling getClass on a Class[_] 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM