如何在 Java 中进行日志记录

如何在 Java 中进行日志记录

日志文件

在谈论日志文件时,一种常见的方法是为不同的用例使用单独的文件。这意味着应用程序通常会记录到多个日志文件。

您可能有一个error.log(文件名模式为 ..YYYYMMDD.ZZZ.error.log),由监控和警报系统以及操作人员使用。显然,您只需要该日志文件中的条目,即您想要发出警报的条目,即您的 ERROR 或 WARN 语句。

你可以有另一个日志文件名为info.log建立或status.log(与<应用程序名称>。<实例名称>的文件名模式.YYYYMMDD.ZZZ.status.log),其中包含有关应用进展或用户活动的上述信息,以及例如 trace.log 文件,只要您想对日志记录发疯。

当记录到单独的文件时,有一个命令行实用程序(如log-merger,或只是一个普通的旧 bash 脚本)来动态合并这些单独的日志文件以获得特定的时间戳是有意义的。

假设你有两个文件:

错误日志

2015-08-29 15:49:46,641 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-4) MSC000001: Failed to start service jboss.undertow.listener.default: org.jboss.msc.service.StartException in service jboss.undertow.listener.default: Could not start http listener

at org.wildfly.extension.undertow.ListenerService.start(ListenerService.java:150)

at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1948)

at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1881)

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)

at java.lang.Thread.run(Thread.java:745)

Caused by: java.net.BindException: Die Adresse wird bereits verwendet

at sun.nio.ch.Net.bind0(Native Method)

at sun.nio.ch.Net.bind(Net.java:436)

at sun.nio.ch.Net.bind(Net.java:428)

at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:214)

at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)

at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:67)

at org.xnio.nio.NioXnioWorker.createTcpConnectionServer(NioXnioWorker.java:182)

at org.xnio.XnioWorker.createStreamConnectionServer(XnioWorker.java:243)

at org.wildfly.extension.undertow.HttpListenerService.startListening(HttpListenerService.java:115)

at org.wildfly.extension.undertow.ListenerService.start(ListenerService.java:147)

... 5 more

状态日志

2015-08-29 15:49:46,033 INFO [org.xnio] (MSC service thread 1-3) XNIO version 3.3.1.Final

运行日志合并实用程序后,可以按如下方式即时查看它们:

[1] 2015-08-29 15:49:46,033 INFO [org.xnio] (MSC service thread 1-3) XNIO version 3.3.1.Final

[0] 2015-08-29 15:49:46,641 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-4) MSC000001: Failed to start service jboss.undertow.listener.default: org.jboss.msc.service.StartException in service jboss.undertow.listener.default: Could not start http listener

[0] at org.wildfly.extension.undertow.ListenerService.start(ListenerService.java:150)

[0] at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1948)

[0] at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1881)

[0] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)

[0] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)

[0] at java.lang.Thread.run(Thread.java:745)

[0] Caused by: java.net.BindException: Die Adresse wird bereits verwendet

[0] at sun.nio.ch.Net.bind0(Native Method)

[0] at sun.nio.ch.Net.bind(Net.java:436)

[0] at sun.nio.ch.Net.bind(Net.java:428)

[0] at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:214)

[0] at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)

[0] at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:67)

[0] at org.xnio.nio.NioXnioWorker.createTcpConnectionServer(NioXnioWorker.java:182)

[0] at org.xnio.XnioWorker.createStreamConnectionServer(XnioWorker.java:243)

[0] at org.wildfly.extension.undertow.HttpListenerService.startListening(HttpListenerService.java:115)

[0] at org.wildfly.extension.undertow.ListenerService.start(ListenerService.java:147)

[0] ... 5 more

您当然也可以选择从一开始就将所有内容都记录到一个文件中。

然而,有一个警告:经验表明开发人员经常错误地假设,仅仅因为日志语句具有时间/位置相关性 - 这可能会违反直觉,尤其是当我们刚刚谈到合并日志文件时。

下面是一个示例:假设您有一个使用 Hibernate 的应用程序。它启动到某个点然后挂起,您看不到更多日志消息。该应用程序根本无法启动。

您看到的最后一条日志消息如下:

2018-09-11 09:35:19.166 INFO 14620 --- [ost-startStop-1] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'

很容易假设某些东西必须被 JPA 或 Hibernate 破坏,仅仅因为这是您的最后一条日志消息。事实上,它可能是 Hibernate,但您的应用程序也可能在尝试启动另一个部分/第三方框架时挂起,但尚未将内容注销。

因此,当您快速得出结论时要小心,这通常发生在高压情况下:当生产中出现严重错误时。通过位置/时间戳日志文件关联并不自动意味着它IS相关,只知道它CAN是。

相关推荐