简体   繁体   English

scala 自我意识特征

[英]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.我制作了一个 Logging trait,它封装了日志实现的细节,它也很好而且很懒,所以特别是在特定日志级别不活动时非常有效。

/**
* 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..但是,它需要混入此特征的 class 来实现以下功能。

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?我的问题是,是否有可能让 Trait 知道它混入了哪个 class ? Removing the need to do:无需执行以下操作:

   val loggedClazz = MyServer.getClass

SOLUTION: Following the provided feedback, I rewrote the class in the following manner.解决方案:根据提供的反馈,我以以下方式重写了 class。

/**
 * 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 .您可以将val loggedClazz: Class[_]替换为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.您当前的代码将无法按预期工作,因为返回的记录器将始终用于 class Class[Class[_]] ,因为您在Class[_] object 上调用getClass

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.您可能还想看看SLF4S ,一个围绕 SLF4J 的薄包装,它与您正在做的非常相似。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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