Open Liberty 22.0.0.6-beta提供了一个新的测试版功能(连同所有的GA功能),它提供了新的日志功能,将日志中的堆栈痕迹连接起来,使它们作为一个单一的日志事件输出。
Open Liberty22.0.0.6-beta包括以下测试版功能(以及所有GA功能)。、:
新的日志功能:将堆栈跟踪合并为一个单一的日志事件
当在Open Liberty中记录堆栈跟踪时,通常是来自应用程序的Throwable.printStackTrace() 调用,现在你可以把发出的堆栈跟踪作为一个单一的日志事件输出。如果你把你的日志转发到下游的第三方日志分析技术,如Elastic Logstash Kibana(ELK)栈,这个更新是有影响的。它影响到控制台输出、控制台日志、消息日志和跟踪日志。在这次更新之前,堆栈跟踪的每一行都被打印为一个单独的事件。
例子
没有加入堆栈跟踪的控制台输出:
[err] java.lang.ArithmeticException: divide by zero
[err] at com.ibm.demo.MyResource.ex(MyResource.java:86)
[err] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[err] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[err] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[err] at java.base/java.lang.reflect.Method.invoke(Method.java:566)
[err] at com.ibm.ws.jaxrs20.server.LibertyJaxRsServerFactoryBean.performInvocation(LibertyJaxRsServerFactoryBean.java:656)
[err] at [internal classes]
[err] at javax.servlet.http.HttpServlet.service(HttpServlet.java:686)
[err] at com.ibm.websphere.jaxrs.server.IBMRestServlet.service(IBMRestServlet.java:96)
[err] at [internal classes]
[err] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
[err] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
[err] at java.base/java.lang.Thread.run(Thread.java:831)
加入堆栈跟踪后的控制台输出:
[err] java.lang.ArithmeticException: divide by zero
at com.ibm.demo.MyResource.ex(MyResource.java:86)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at com.ibm.ws.jaxrs20.server.LibertyJaxRsServerFactoryBean.performInvocation(LibertyJaxRsServerFactoryBean.java:656)
at [internal classes]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:686)
at com.ibm.websphere.jaxrs.server.IBMRestServlet.service(IBMRestServlet.java:96)
at [internal classes]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:831)
messages.log 没有加入堆栈跟踪的输出:
2022-04-06, 15:50:22:246 EDT] 00000047 SystemErr R java.lang.ArithmeticException: divide by zero
[2022-04-06, 15:50:22:247 EDT] 00000047 SystemErr R at com.ibm.demo.MyResource.ex(MyResource.java:86)
[2022-04-06, 15:50:22:248 EDT] 00000047 SystemErr R at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[2022-04-06, 15:50:22:249 EDT] 00000047 SystemErr R at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[2022-04-06, 15:50:22:250 EDT] 00000047 SystemErr R at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[2022-04-06, 15:50:22:251 EDT] 00000047 SystemErr R at java.base/java.lang.reflect.Method.invoke(Method.java:566)
[2022-04-06, 15:50:22:251 EDT] 00000047 SystemErr R at com.ibm.ws.jaxrs20.server.LibertyJaxRsServerFactoryBean.performInvocation(LibertyJaxRsServerFactoryBean.java:656)
...
messages.log 加入了堆栈痕迹的输出:
[2022-04-06, 15:52:38:586 EDT] 00000077 SystemErr R java.lang.ArithmeticException: divide by zero
at com.ibm.demo.MyResource.ex(MyResource.java:86)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at com.ibm.ws.jaxrs20.server.LibertyJaxRsServerFactoryBean.performInvocation(LibertyJaxRsServerFactoryBean.java:656)
...
messages.log 使用 记录,JSON 没有加入堆栈痕迹的输出:
{"type":"liberty_message","host":"LAPTOP-JU4FJ7TJ","ibm_userDir":"C:\/devdir\/LibertiesFeb18\/open-liberty\/dev\/build.image\/wlp\/usr\/","ibm_serverName":"sj","message":"java.lang.ArithmeticException: divide by zero","ibm_threadId":"00000034","ibm_datetime":"2022-04-20T13:41:37.605-0400","module":"SystemErr","loglevel":"SystemErr","ibm_methodName":"","ibm_className":"","ibm_sequence":"1650476497605_0000000000069","ext_thread":"Default Executor-thread-2"}
{"type":"liberty_message","host":"LAPTOP-JU4FJ7TJ","ibm_userDir":"C:\/devdir\/LibertiesFeb18\/open-liberty\/dev\/build.image\/wlp\/usr\/","ibm_serverName":"sj","message":"\tat com.ibm.demo.MyResource.ex(MyResource.java:86)","ibm_threadId":"00000034","ibm_datetime":"2022-04-20T13:41:37.616-0400","module":"SystemErr","loglevel":"SystemErr","ibm_methodName":"","ibm_className":"","ibm_sequence":"1650476497616_000000000006A","ext_thread":"Default Executor-thread-2"}
{"type":"liberty_message","host":"LAPTOP-JU4FJ7TJ","ibm_userDir":"C:\/devdir\/LibertiesFeb18\/open-liberty\/dev\/build.image\/wlp\/usr\/","ibm_serverName":"sj","message":"\tat java.base\/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)","ibm_threadId":"00000034","ibm_datetime":"2022-04-20T13:41:37.626-0400","module":"SystemErr","loglevel":"SystemErr","ibm_methodName":"","ibm_className":"","ibm_sequence":"1650476497626_000000000006B","ext_thread":"Default Executor-thread-2"}
...
messages.log 使用 日志,加入堆栈痕迹JSON 的输出:
{"type":"liberty_message","host":"LAPTOP-JU4FJ7TJ","ibm_userDir":"C:\/devdir\/LibertiesFeb18\/open-liberty\/dev\/build.image\/wlp\/usr\/","ibm_serverName":"sj","message":"java.lang.ArithmeticException: divide by zero\r\n\tat com.ibm.demo.MyResource.ex(MyResource.java:86)\r\n\tat java.base\/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\r\n\tat java.base\/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\r\n\tat java.base\/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\r\n\tat java.base\/java.lang.reflect.Method.invoke(Method.java:566)\r\n\tat com.ibm.ws.jaxrs20.server.LibertyJaxRsServerFactoryBean.performInvocation(LibertyJaxRsServerFactoryBean.java:656)\r\n\tat com.ibm.ws.jaxrs20.server.LibertyJaxRsInvoker.performInvocation(LibertyJaxRsInvoker.java:160)\r\n\tat org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:101)\r\n\tat com.ibm.ws.jaxrs20.server.LibertyJaxRsInvoker.invoke(LibertyJaxRsInvoker.java:273)\r\n\tat org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:213)\r\n\tat com.ibm.ws.jaxrs20.server.LibertyJaxRsInvoker.invoke(LibertyJaxRsInvoker.java:444)\r\n\tat org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:112)\r\n\tat org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59)\r\n\tat org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:96)\r\n\tat org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)\r\n\tat org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:123)\r\n\tat org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:277)\r\n\tat com.ibm.ws.jaxrs20.endpoint.AbstractJaxRsWebEndpoint.invoke(AbstractJaxRsWebEndpoint.java:137)\r\n\tat com.ibm.websphere.jaxrs.server.IBMRestServlet.handleRequest(IBMRestServlet.java:146)\r\n\tat com.ibm.websphere.jaxrs.server.IBMRestServlet.doGet(IBMRestServlet.java:112)\r\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:686)\r\n\tat com.ibm.websphere.jaxrs.server.IBMRestServlet.service(IBMRestServlet.java:96)\r\n\tat com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1258)\r\n\tat com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:746)\r\n\tat com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:443)\r\n\tat com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1227)\r\n\tat com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1011)\r\n\tat com.ibm.ws.webcontainer.servlet.CacheServletWrapper.handleRequest(CacheServletWrapper.java:75)\r\n\tat com.ibm.ws.webcontainer40.servlet.CacheServletWrapper40.handleRequest(CacheServletWrapper40.java:85)\r\n\tat com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:938)\r\n\tat com.ibm.ws.webcontainer.osgi.DynamicVirtualHost$2.run(DynamicVirtualHost.java:281)\r\n\tat com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink$TaskWrapper.run(HttpDispatcherLink.java:1184)\r\n\tat com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink.wrapHandlerAndExecute(HttpDispatcherLink.java:453)\r\n\tat com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink.ready(HttpDispatcherLink.java:412)\r\n\tat com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:566)\r\n\tat com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.handleNewRequest(HttpInboundLink.java:500)\r\n\tat com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.processRequest(HttpInboundLink.java:360)\r\n\tat com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.ready(HttpInboundLink.java:327)\r\n\tat com.ibm.ws.tcpchannel.internal.NewConnectionInitialReadCallback.sendToDiscriminators(NewConnectionInitialReadCallback.java:167)\r\n\tat com.ibm.ws.tcpchannel.internal.NewConnectionInitialReadCallback.complete(NewConnectionInitialReadCallback.java:75)\r\n\tat com.ibm.ws.tcpchannel.internal.WorkQueueManager.requestComplete(WorkQueueManager.java:514)\r\n\tat com.ibm.ws.tcpchannel.internal.WorkQueueManager.attemptIO(WorkQueueManager.java:584)\r\n\tat com.ibm.ws.tcpchannel.internal.WorkQueueManager.workerRun(WorkQueueManager.java:968)\r\n\tat com.ibm.ws.tcpchannel.internal.WorkQueueManager$Worker.run(WorkQueueManager.java:1057)\r\n\tat com.ibm.ws.threading.internal.ExecutorServiceImpl$RunnableWrapper.run(ExecutorServiceImpl.java:245)\r\n\tat java.base\/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)\r\n\tat java.base\/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)\r\n\tat java.base\/java.lang.Thread.run(Thread.java:831)","ibm_threadId":"00000060","ibm_datetime":"2022-04-20T13:42:26.365-0400","module":"SystemErr","loglevel":"SystemErr","ibm_methodName":"","ibm_className":"","ibm_sequence":"1650476546365_0000000000099","ext_thread":"Default Executor-thread-38"}
这个新功能是通过配置引导属性、环境变量或通过server.xml 文件启用的。如果在所有这些选项中都有配置,那么配置的优先级是server.xml > 环境变量 > bootstrap属性。
配置
bootstrap.properties:
`com.ibm.ws.logging.stackJoin=true
server.env:
WLP_LOGGING_STACK_JOIN=true
server.xml:
<logging stackJoin="true" />
现在就试试吧
要尝试这些功能,只需更新你的构建工具,拉出Open Liberty所有测试版功能包,而不是主版本。该测试版适用于Java SE 18、Java SE 17、Java SE 11和Java SE 8。
如果你使用Maven,这里有坐标:
<dependency>
<groupId>io.openliberty.beta</groupId>
<artifactId>openliberty-runtime</artifactId>
<version>22.0.0.6-beta</version>
<type>pom</type>
</dependency>
或者对于Gradle:
dependencies {
libertyRuntime group: 'io.openliberty.beta', name: 'openliberty-runtime', version: '[22.0.0.6-beta,)'
}
或者看一下我们的下载页面。