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

Я использую Play 2.1. Я использую регистратор по умолчанию 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 сообщает мне «информацию». Я все это знаю. Я, конечно, не хочу добавлять больше бесполезности. в само сообщение (например, имя класса или метод).

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

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


person user2141729    schedule 06.03.2013    source источник


Ответы (6)


Шаблон журнала:

%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 это номер строки

person Dinesh Appuhami    schedule 13.11.2013
comment
На самом деле это не решает первоначальную проблему, поскольку по-прежнему просто отображает тот же беспорядок класса play.api.LoggerLike$. - person Matt R; 01.03.2014
comment
То же самое, не помогает. play.api.LoggerLike$class отображается. %logger действительно отображает правильный кластер - person Capacytron; 15.06.2016

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

com.something.MyClass

Ты получишь:

MyClass

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

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

Вы также можете добавить метод и строку, если вам интересно, выполнив следующие действия:

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

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

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

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

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

logger.info("Your message");

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

Logger.underlying().info("Your message");
person bitstream    schedule 02.03.2015
comment
Наконец-то что-то сработало. Нет ли способа сделать это прямо из игры? - person saurabheights; 01.10.2016

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

Регистратор(this.getClass()).info("getTickets")

person Maxime Calmels    schedule 08.03.2013
comment
Это близко, но не совсем то, что я искал. Я получаю это 06:24:52.907 INFO com.myapp.tickets$ play.api.LoggerLike$class info getTickets Таким образом, %logger получает правильную строку, с которой я согласен. Это улучшение. Но %class и %method по-прежнему получают бесполезные значения из игры. Учитывая, что %logger имеет правильный класс, %class не так важен и может быть удален. Метод % - это то, чего все еще не хватает. Есть ли способ получить реальный метод getPayments вместо информации? - person user2141729; 12.03.2013

Я нахожусь в процессе отказа от единого подхода application.log, который Play, по-видимому, использует по умолчанию со своим Logger. Мое приложение требует мелкозернистого ведения журнала и настройки во время выполнения, что так хорошо получается при прямом журналировании, когда classname == Logger name. Я добился довольно больших успехов в использовании «старой школы» в своих контроллерах, например...

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 = "@buildsig.version@"
    val tag = "@buildsig.tag@"
    val timestamp = "@buildsig.timestamp@"
    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, этот подход покажется знакомым. С другой стороны, в настоящее время я борюсь с скрипт запуска оболочки из play dist не может найти файл logger.xml в файле JAR, где скрипт запуска не может использовать мой conf/logger.xml, который получает JAR-файл с помощью "play dist" команда.

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

person Bob Kuhar    schedule 03.06.2013

Поскольку Logger в Play оборачивает базовые вызовы 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
person flurdy    schedule 20.06.2017