WildFly 日志记录:不要从 war 文件输出类名(以保留日志消息缩进)

WildFly logging: don't output classname (to preseve log message indentation) from a war file

要求

OptaPlanner 日志具有 保留的缩进:

更易读
10:34:46,442 INFO  Solving started: time spent (11), best score (-72init/0hard/0medium/0soft), environment mode (REPRODUCIBLE), random (JDK with seed 0).
10:34:46,467 DEBUG     CH step (0), time spent (36), score (-71init/0hard/-1000medium/0soft), selected move count (7), picked move (Day-0(0) {null -> Micha}).
10:34:46,474 DEBUG     CH step (1), time spent (43), score (-70init/0hard/-1414medium/-1000soft), selected move count (7), picked move (Day-0(1) {null -> Angelika}).
                       ... // 70 lines
10:34:46,608 DEBUG     CH step (71), time spent (177), score (0hard/-27239medium/-23706soft), selected move count (7), picked move (Day-17(3) {null -> Katrin}).
10:34:46,610 INFO  Construction Heuristic phase (0) ended: time spent (179), best score (0hard/-27239medium/-23706soft), score calculation speed (3023/sec), step total (72).
10:34:46,624 DEBUG     LS step (0), time spent (193), score (0hard/-27239medium/-23706soft),     best score (0hard/-27239medium/-23706soft), accepted/selected move count (1/25), picked move (Day-9(1) {Irene} <-> Day-15(1) {Susi}).
10:34:46,628 DEBUG     LS step (1), time spent (197), score (0hard/-27239medium/-23706soft),     best score (0hard/-27239medium/-23706soft), accepted/selected move count (1/17), picked move (Day-6(1) {Irene} <-> Day-6(2) {Kristina}).
                       ... // 643 lines
10:34:47,486 DEBUG     LS step (644), time spent (1055), score (-1hard/-27239medium/-23748soft),     best score (0hard/-27239medium/-23706soft), accepted/selected move count (0/1), picked move (Day-7(0) {Tobias} <-> Day-1(1) {Angelika}).
10:34:47,486 INFO  Local Search phase (1) ended: time spent (1055), best score (0hard/-27239medium/-23706soft), score calculation speed (14085/sec), step total (645).
10:34:47,487 INFO  Solving ended: time spent (1056), best score (0hard/-27239medium/-23706soft), score calculation speed (12124/sec), phase total (2), environment mode (REPRODUCIBLE).

上面的缩进可视化了外循环的开始和结束。使用上面示例中的缩进,很难识别每个阶段何时结束等。使用 TRACE 日志记录时情况更糟,它还显示内部循环缩进得更深。

因此我的 logback.xml 模式使用 <pattern>%d [%t] %-5p %m%n</pattern>.

问题

WildFly(和其他应用程序服务器)忽略我的 logback 依赖项和我的 logback.xml 文件并 强制 我一个包含类名的日志记录模式,它打破我的缩进:

10:50:51,317 INFO  [org.optaplanner.core.impl.solver.DefaultSolver] (EE-ManagedExecutorService-default-Thread-1) Solving started: time spent (60), best score (-62init/0hard/0soft), environment mode (REPRODUCIBLE), random (JDK with seed 0).
10:50:51,368 INFO  [org.optaplanner.openshift.employeerostering.server.solver.WannabeSolverManager] (EE-ManagedExecutorService-default-Thread-1)   New best solution found for rosterId (-1).
10:50:51,368 INFO  [org.optaplanner.core.impl.constructionheuristic.DefaultConstructionHeuristicPhase] (EE-ManagedExecutorService-default-Thread-1) Construction Heuristic phase (0) ended: time spent (112), best score (0hard/0soft), score calculation speed (42568/sec), step total (62).
10:50:58,986 INFO  [org.optaplanner.core.impl.localsearch.DefaultLocalSearchPhase] (EE-ManagedExecutorService-default-Thread-1) Local Search phase (1) ended: time spent (7730), best score (0hard/0soft), score calculation speed (331097/sec), step total (2520642).
10:50:58,986 INFO  [org.optaplanner.core.impl.solver.DefaultSolver] (EE-ManagedExecutorService-default-Thread-1) Solving ended: time spent (7730), best score (0hard/0soft), score calculation speed (326366/sec), phase total (2), environment mode (REPRODUCIBLE).

我看不懂,对我来说太冗长了在我阅读唯一真正重要的内容之前,最后一行有 113 个字符的开销 "Solving ended"。 向右滚动以查看它。

如何更改我的应用程序的 war 文件中的日志记录模式? 我正在使用 OpenShift(它为我提供了一个 WildFly 实例),所以我不能乱用 Wildfly 配置本身。


错误解

添加 jboss-deployment-structure.xml 以排除 <subsystem name="logging" /> 无济于事,因为我得到了这个丑陋的输出,其中提到了我的整个时间戳和线程名称 每行两次 :

10:46:19,236 INFO  [stdout] (EE-ManagedExecutorService-default-Thread-1) 2017-05-22 10:46:19,236 [EE-ManagedExecutorService-default-Thread-1] DEBUG     LS step (95814), time spent (4026), score (0hard/0soft),     best score (0hard/0soft), accepted/selected move count (1/1), picked move (Fort Collins 2017-02-01T06:00-14:00 {Jay Cole} <-> Saint Peter 2017-02-01T06:00-14:00 {Ivy Cole}).
10:46:19,236 INFO  [stdout] (EE-ManagedExecutorService-default-Thread-1) 2017-05-22 10:46:19,236 [EE-ManagedExecutorService-default-Thread-1] DEBUG     LS step (95815), time spent (4026), score (0hard/0soft),     best score (0hard/0soft), accepted/selected move count (1/1), picked move (Saint Peter 2017-02-01T06:00-14:00 {Jay Cole} <-> Santa Barbara 2017-02-01T14:00-22:00 {Flo Li}).
10:46:19,236 INFO  [stdout] (EE-ManagedExecutorService-default-Thread-1) 2017-05-22 10:46:19,236 [EE-ManagedExecutorService-default-Thread-1] DEBUG     LS step (95816), time spent (4026), score (0hard/0soft),     best score (0hard/0soft), accepted/selected move count (1/1), picked move (Los Angeles 2017-02-02T06:00-14:00 {Ivy Cole -> Elsa King}).

使用 WildFly,您可以在 WAR/WEB-INF/classes 目录中的 WAR 中包含一个 logging.properties 文件。不幸的是,属性文件的格式没有很好的记录。有一些unofficial documentation。然而,下面是一个例子。

loggers=

logger.level=INFO
logger.handlers=CONSOLE

handler.CONSOLE=org.jboss.logmanager.handlers.ConsoleHandler
handler.CONSOLE.level=INFO
handler.CONSOLE.formatter=PATTERN
handler.CONSOLE.properties=autoFlush,target,enabled
handler.CONSOLE.autoFlush=true
handler.CONSOLE.target=SYSTEM_OUT
handler.CONSOLE.enabled=true

formatter.PATTERN=org.jboss.logmanager.formatters.PatternFormatter
formatter.PATTERN.properties=pattern
formatter.PATTERN.pattern=%d{HH:mm:ss,SSS} [%t] %-5p %m%n

请注意,[%t] 是线程名称的模式,它可能会稍微偏离您正在寻找的格式。

您可以使用日志子系统的 JBoss 配置轻松地根据自己的喜好调整服务器日志输出。这种方法的优点之一是您可以在运行时 change/update 它而无需重新部署您的应用程序或重新启动服务器,并且您可以从一个地方管理所有日志记录配置。
您没有指定是否要全局更改输出,或者您是否有一个特定的日志文件来存储您的 optaplanner 日志。我建议创建一个具有您请求格式的专用日志,同时仍保留默认日志(具有 class 名称),以备您需要它进行一些故障排除或一些自动日志处理。如果您的要求不同,您可以轻松调整它。为了我们的目的,我们需要设置自定义 handlercategory。类别通常对应于 class 或包和处理程序定义如何处理日志消息(例如,到文件,到控制台,...)。
首先,让我们创建一个处理程序,从消息条目中省略 class 名称。通过 JBoss CLI,我们可以使用以下命令执行此操作:

/subsystem=logging/periodic-rotating-file-handler=OPTAPLANNER:add(append=true,formatter= "%d{HH:mm:ss,SSS} %-5p (%t) %s%e%n", suffix=".yyyy-MM-dd",file={path="opta.log",relative-to="jboss.server.llog.dir"},level=ALL)

此处理程序会将所有消息输出到服务器日志目录中的文件 opta.log。该文件将在每天午夜滚动,并将附加当前日期作为后缀。我们指定的格式化程序完全省略了 class 名称,您可以根据需要轻松自定义它。

现在我们在 org.optaplanner 包中为 classes 创建一个处理程序:通过 JBoss CLI 你可以像这样定义一个自定义类别:

/subsystem=logging/logger=org.optaplanner:add(category=org.optaplanner,level=INFO,handlers=[OPTAPLANNER])

使用此配置,来自 org.optaplanner.* 的所有日志消息都应重定向到专用的 OPTAPLANNER 处理程序,以及两个默认处理程序(FILECONSOLE) .

如果您愿意,所有操作都可以通过基于 web 的 wildfly 管理控制台(在 http://server:9990 上可用)完成。

有关详细信息,请查看 wildfly docs