Как настроить Logback для печати имени класса

Я использую Play 2.1. Я использую logger play.api.Logger по умолчанию. Я смущен тем, как это работает.

В моем scala коде, строка в классе "com.myapp.tickets" в методе "getPayment()", как этот

Logger.info("getTickets")

генерирует сообщение журнала, подобное этому.

14:58:58.005 INFO  application play.api.LoggerLike$class info  getTickets

Мой шаблон application-logger.xml

%d{HH:mm:ss.SSS} %-5level %logger %class %method  %msg%n

Проблема заключается в том, что% logger сообщает мне "приложение",% class говорит мне "play.api.LoggerLike $class и% method сообщает мне" info ". Я знаю все это. Я, конечно, хочу избежать добавление более крутого в само сообщение (например, имя класса или метод).

Если я распечатаю стек вызовов (% caller), то уровень 2 имеет то, что я хочу, но это не кажется жизнеспособным способом создания журнала.

Как мне настроить его для вывода класса и метода приложения, а не класса и метода самого журнала?

Ответ 1

Обратный шаблон:

%d{HH:mm:ss.SSS} [%thread] %-5level %class{36}.%M %L - %msg%n

Результат:

14:53:47.816 [http-bio-8080-exec-3] DEBUG  c.f.s.w.s.i.example.ExServiceImpl.getStatus 993 - blocked-->0
  • [http-bio-8080-exec-3] - это имя потока

  • c.f.s.w.s.i.example - это имя пакета

  • ExServiceImpl - это имя класса

  • getStatus - имя метода

  • 993 - номер строки

Ответ 2

%class{0} выводит только имя класса, поэтому вместо:

com.something.MyClass

Вы получите:

MyClass

Вот как обычно выглядит мой шаблон для журнала:

%d{HH:mm:ss} [%thread] %-5p %class{0} - %m%n

Вы также можете добавить метод и строку, если вы заинтересованы:

%d{HH:mm:ss} [%thread] %-5p %class{0}.%method:%L - %m%n

Ответ 3

Старый поток, но общая проблема. В Play используется обертка вокруг slf4j, которая заставляет все записывать как [Logger $ALogger] или [application]. Существует несколько способов регистрации фактического имени класса.

Поместите это в свой класс:

private static org.slf4j.Logger logger = play.logger.underlying();

И поместите это в свои методы:

logger.info("Your message");

Другой вариант - заменить все ваши вызовы Logger этим, но он добавит служебные данные, поскольку он должен извлекать базовый объект каждый раз, когда вы хотите что-то записывать:

Logger.underlying().info("Your message");

Ответ 4

Я не уверен, что это действительно то, что ты хочешь, но попробуешь?

Logger (this.getClass()). Информация ( "getTickets" )

Ответ 5

Я в процессе отказа от единственного подхода application.log, который, по-видимому, по умолчанию работает с его Logger. Мое приложение требует такого рода мелкозернистой регистрации и настройки времени выполнения, что корректный логин делает так хорошо, когда имя_файла == Имя регистратора. У меня был довольно хороший успех, и я просто стал "старой школой" в моих контроллерах, таких как...

package controllers
import play.api._
import play.api.mvc._
import org.slf4j.LoggerFactory

object Application extends Controller {
  val log = LoggerFactory.getLogger(getClass())

  def index = Action {
    log.trace("index")
    NotFound
  }

  def hb = Action {
    log.trace("hb")
    val message = makeMessage()
    log.info(message)
    Ok(message)
  }

  def makeMessage(): String = {
    val version = "@[email protected]"
    val tag = "@[email protected]"
    val timestamp = "@[email protected]"
    val status = makeStatus()
    return "DM2 [Version: %s] [Build: %s] [Date: %s] [Status: %s]".format(version, tag, timestamp, status)
  }

  def makeStatus(): String = {
    // TODO: Implement datastore healthcheck
    return "TODO"
  }
}

Для любого разработчика, используемого для slf4j/logback или log4j, этот подход будет казаться знакомым. С другой стороны, я сейчас борюсь с запуском оболочки script из "play dist " не удается найти файл logger.xml в JAR файле, где в начале script не используется мой conf/logger.xml, который получает JARed командой" play dist".

Если бы я был немного лучше разработчика Scala, я думаю, что тот же эффект может быть достигнут с чем-то вроде характеристики Logging.

Ответ 6

Поскольку Play Logger обертывает базовые вызовы SLF4J, класс журнала всегда является "приложением":

13:45:21 INFO  application: - Some message

Но есть простой способ обойти это.

Создайте признак:

import play.api.Logger

trait WithLogging {
   val logger: Logger = Logger(this.getClass())
}

И в ваших классах просто смешайте черту:

import WithLogging

class Foobarr extends WithLogging {
   def doFoo = {
      logger.info("Im in foooo")
   }
}

Теперь это должно быть:

13:45:21 INFO  models.Foobarr: - Im in foooo