2010-06-29 32 views
3

je voudrais imprimer la trace de la pile pour l'exception qui a été pris par pages.xml, mais je veux seulement le faire si le plus le niveau d'enregistrement granulaire est plus granulaire que warn. De cette façon, les testeurs peuvent copier/coller la trace de la pile, mais les utilisateurs finaux ne la verront jamais.conditionnellement Imprimer Trace de la pile sur la page d'erreur En fonction du niveau de journal à l'aide Facelets, Seam, et Logback

détails Environnement:

Voilà comment les exceptions sont actuellement traitées ...

De pages.xml:

<?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> 

De 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> 

De logback.xml: Avec la solution idéale à ce problème

<?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> 

, cela provoquerait une trace de la pile à imprimer /error.xhtml (de pages.xml):

<logger name="com.example" level="trace" /> 

Alors que ce ne serait pas:

<logger name="com.example" level="warn" /> 

U Sing Facelets avec Seam, est-il un moyen de déterminer les niveaux de log de Logback?

Répondre

2

Sans Seam il est possible avec un servlet gestionnaire d'erreur:

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.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>"); 
    } 
} 

Quoi qu'il en soit, je ne pense pas que ce serait bonne pratique, très peu de personnes s'attendent à ce que la modification de la configuration de journalisation influence le comportement de l'application. Il pourrait être problématique d'avoir ce genre d'effets secondaires dans un environnement de production. Un paramètre de contexte show-stacktracesweb.xml peut-être une meilleure approche.