Динамически выбирайте реализацию логгера в Scala - PullRequest
2 голосов
/ 28 мая 2019

У меня есть библиотека, в которой я использую log4j для записи вещей.Для некоторых конкретных классов моей библиотеки (все классы, расширяющие Component) я хочу, чтобы оператор log в начале содержал суффикс [component_name].

Я не хочу изменять то, как обычно выглядит оператор logлайк.Следовательно, внутри одного из этих специальных компонентов с именем 'foo' оператор log.info("message") должен выводить [foo] message в системе ведения журнала.

Это то, что я делал до сих пор и где я застрял:

object Logging {
   val logger = Logger.getLogger("my_logger_name")
}

Это базовый логгер, который я вызываю по всему коду, используя Logging.logger.info("message")

Я подумал, что лучше всего было бы создать обогащенный логгер, используя черту

trait WithEnrichedLogger {
   this: Component =>
   val logger = new EnrichedLogger(this.name)
}

class EnrichedLogger(name: String) {
   def info(msg: String): Unit = Logging.logger.info(s"[${name}] $msg")
}

и мой компонент просто выглядит как

abstract class Component with WithEnrichedLogger {
     def name: String
     ....

     def some_method: Unit = { 
        logger.info("log statement") \\ it should print the '[name]' at the beginning 
     }
 } 

Проблема в этой настройке заключается в том, что в момент создания Component черта WithEnrichedLogger инициализируется и значение name равновсе еще ноль.По этой причине утверждение «null log Statement»

Это решение показалось мне наиболее элегантным, но, пожалуйста, предложите мне другие, если лучше

1 Ответ

4 голосов
/ 28 мая 2019

Вам просто нужно сделать значение logger lazy:

trait WithEnrichedLogger {
  this: Component =>
  lazy val logger = new EnrichedLogger(this.name)
}

Теперь logger не будет создано до тех пор, пока оно не будет впервые использовано, к этому времени значение name будет действительным.

...