Jakarta ee 根据日志级别,使用Facelets、Seam和Logback在错误页面上有条件地打印堆栈跟踪
我想打印pages.xml捕获的异常的堆栈跟踪,但我只想在最精细的日志记录级别比Jakarta ee 根据日志级别,使用Facelets、Seam和Logback在错误页面上有条件地打印堆栈跟踪,jakarta-ee,websphere,seam,facelets,logback,Jakarta Ee,Websphere,Seam,Facelets,Logback,我想打印pages.xml捕获的异常的堆栈跟踪,但我只想在最精细的日志记录级别比warn更精细的情况下这样做。通过这种方式,测试人员可以复制/粘贴堆栈跟踪,但最终用户永远不会看到它 环境详情: IBM WebSphere Application Server 7() JBoss Seam 2.2.0.GA JSF Facelets 1.1.15 0.9.21 1.6.0 以下是当前处理异常的方式 从pages.xml: <?xml version="1.0" encodin
warn
更精细的情况下这样做。通过这种方式,测试人员可以复制/粘贴堆栈跟踪,但最终用户永远不会看到它
环境详情:
- IBM WebSphere Application Server 7()
- JBoss Seam 2.2.0.GA
- JSF Facelets 1.1.15
- 0.9.21
- 1.6.0
- 1.6.0
<?xml version="1.0" encoding="UTF-8"?>
<pages xmlns="http://jboss.com/products/seam/pages"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jboss.com/products/seam/pages http://jboss.com/products/seam/pages-2.2.xsd">
<!-- ... -->
<exception class="javax.faces.application.ViewExpiredException">
<end-conversation />
<redirect view-id="/exceptionSessionTimeout.xhtml" />
</exception>
<!--
Prevent the Facelets error page from appearing.
This is where I want to conditionally print the stack trace.
Currently it's more or less just a generic error page.
-->
<exception>
<end-conversation />
<redirect view-id="/exception.xhtml" />
</exception>
</pages>
<logger name="com.example" level="trace" />
从web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- ... -->
<!-- Fallback static HTML page -->
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/unhandledException.html</location>
</error-page>
</web-app>
java.lang.Exception
/unhandledException.html
从logback.xml:
<?xml version="1.0" encoding="UTR-8"?>
<configuration scan="true">
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%date] [%thread] [%level] [%mdc] [%logger:%method:%line]: %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/path/to/app-logs-dir/AppName.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>/path/to/app-logs-dir/AppName.%d{yyyy-MM-dd-a}.gz</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>[%date] [%thread] [%level] [%mdc] [%logger:%method:%line]: %msg%n</pattern>
</encoder>
</appender>
<logger name="com.example" level="trace" />
<logger name="com.example.auth" level="error" />
<root level="warn">
<appender-ref ref="FILE" />
<appender-ref ref="CONSOLE" />
</root>
</configuration>
[%date][%thread][%level][%mdc][%logger:%method:%line]:%msg%n
/path/to/app logs dir/AppName.log
/path/to/app logs dir/AppName.%d{yyyyy-MM-dd-a}.gz
[%date][%thread][%level][%mdc][%logger:%method:%line]:%msg%n
对于这个问题的理想解决方案,这将导致在/error.xhtml(来自pages.xml)上打印堆栈跟踪:
鉴于这不会:
<logger name="com.example" level="warn" />
在Seam中使用Facelets,有没有办法确定Logback的日志级别?如果没有Seam,则可以使用错误处理程序servlet:
web.xml
:
<servlet>
<servlet-name>ErrorHandlerServlet</servlet-name>
<servlet-class>com.example.ErrorHandlerServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ErrorHandlerServlet</servlet-name>
<url-pattern>/ErrorHandlerServlet</url-pattern>
</servlet-mapping>
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/ErrorHandlerServlet</location>
</error-page>
ErrorHandlerServlet
com.example.ErrorHandlerServlet
ErrorHandlerServlet
/ErrorHandlerServlet
java.lang.Exception
/ErrorHandlerServlet
'ErrorHandlerServlet.java':
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ErrorHandlerServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final Logger logger = LoggerFactory
.getLogger(ErrorHandlerServlet.class);
@Override
protected void doGet(final HttpServletRequest request,
final HttpServletResponse response)
throws ServletException, IOException {
logger.info("handler");
final Object errorMessage = request
.getAttribute(RequestDispatcher.ERROR_MESSAGE);
final Object throwableObj = request
.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
logger.warn("error message: {}", errorMessage, throwableObj);
final Logger appLogger = LoggerFactory
.getLogger("com.example");
if (!appLogger.isInfoEnabled()) {
final RequestDispatcher requestDispatcher =
request.getRequestDispatcher("/error.html");
requestDispatcher.forward(request, response);
return;
}
final PrintWriter writer = response.getWriter();
writer.println("<pre>");
if (throwableObj != null && throwableObj instanceof Throwable) {
final Throwable throwable = (Throwable) throwableObj;
throwable.printStackTrace(writer);
}
writer.println("</pre>");
}
}
import java.io.IOException;
导入java.io.PrintWriter;
导入javax.servlet.RequestDispatcher;
导入javax.servlet.ServletException;
导入javax.servlet.http.HttpServlet;
导入javax.servlet.http.HttpServletRequest;
导入javax.servlet.http.HttpServletResponse;
导入org.slf4j.Logger;
导入org.slf4j.LoggerFactory;
公共类ErrorHandlerServlet扩展了HttpServlet{
私有静态最终长serialVersionUID=1L;
专用静态最终记录器记录器=记录器工厂
.getLogger(ErrorHandlerServlet.class);
@凌驾
受保护的无效数据集(最终HttpServletRequest请求,
最终HttpServletResponse(响应)
抛出ServletException、IOException{
logger.info(“handler”);
最终对象errorMessage=请求
.getAttribute(RequestDispatcher.ERROR_消息);
最终对象throwableObj=请求
.getAttribute(RequestDispatcher.ERROR\u异常);
logger.warn(“错误消息:{}”,errorMessage,throwableObj);
最终记录器appLogger=记录器工厂
.getLogger(“com.example”);
如果(!appLogger.IsInfo已启用()){
最终请求分派器请求分派器=
getRequestDispatcher(“/error.html”);
转发(请求、响应);
返回;
}
最终PrintWriter=response.getWriter();
writer.println(“”);
if(throwableObj!=null&&throwableObj Throwable实例){
最终可丢弃的可丢弃=(可丢弃的)可丢弃的;
可丢弃。printStackTrace(写入程序);
}
writer.println(“”);
}
}
无论如何,我认为这不是一个好的实践,很少有人认为更改日志配置会影响应用程序的行为。在生产环境中产生这种副作用可能会有问题。show stacktraces
web.xml
上下文参数可能是更好的方法