2009-11-25 3 views
1

Lorsque notre application émet des erreurs que nous attrapons, nous mettons le message et stacktrace dans un fichier journal créé spécifiquement pour notre application (myapp.log). Par exemple:Utilisation de log4j avec conteneur Web (partie du serveur J2EE)

public class SomeClass { 
    OurLogger log = OurLogger.getLogger ("myapp", SomeClass.class); 
    public void someMethod { 
     try { 
     //code 
     } 
     catch (DataAccessException e) 
     { 
      log.error(e.getMessage(), e); 
     } 
    } 
} 

Nous faisons cela parce que depuis que nous sommes dans un environnement où plusieurs applications résident sur un serveur d'applications ... la nôtre et tous les autres journaux d'applications doit être séparé de la server.log.

Cependant, pour certains cas où nous n'attrapons pas l'erreur ... la trace de la pile est en cours d'écriture server.log Dans ces cas également, nous aimerions envoyer des erreurs de pile à myapp.log. Je sais que nous pouvons définir une exception dans web.xml et la rediriger vers une page jsp mais est-il possible, dans ce cas, de ne pas envoyer la trace de la pile à server.log mais plutôt à myapp.log? Autre que d'attraper l'exception par changement de code bien sûr.

+0

Quel serveur d'applications utilisez-vous? –

+0

glassfish v2. mais nous avons un groupe qui gère la configuration du serveur. donc il ne sera pas facile pour moi de leur demander de faire un changement ... à moins que je puisse le sauvegarder :) – Omnipresent

+0

Ok. En passant, GlassFish utilise Java Logging (pas log4j). –

Répondre

1

Cependant, dans certains cas où nous ne rattrapent pas l'erreur ... la trace de la pile est en cours d'écriture sur server.log

Pour moi, c'est un comportement normal. Certaines exceptions, par exemple RuntimeException, sont interceptées par le serveur d'applications et consignées dans le fichier journal du serveur d'applications (qui est global pour un domaine avec GlassFish). Et vous ne regardez pas pour tous les attraper, vous voulez que le conteneur fasse son travail dans une telle situation, par exemple en annulant une transaction, ou vous obtiendrez des bogues méchants.

Dans ces cas également, nous aimerions envoyer des erreurs de pile à myapp.log. Je sais que nous pouvons définir une exception dans le web.xml et redirige vers une page jsp mais est-il possible, dans ce cas, de ne pas envoyer la trace de la pile à server.log mais plutôt à myapp.log?

À ma connaissance, ce n'est pas possible. Et même si vous ajoutez un <error-page>, c'est toujours le serveur de l'application qui va attraper l'exception, donc cela ne résoudra pas votre "problème". Et même si vous utilisez un filtre de servlet pour attraper Throwable (je ne ferais pas cela) et que vous le connectez au niveau de l'application, vous devrez le relancer pour laisser le conteneur faire son travail comme je l'ai mentionné ci-dessus. Donc, cela ne résoudra pas entièrement votre «problème».

À part attraper l'exception par changement de code bien sûr.

Ne le faites pas, vous ne pas veulent les attraper tous!

0

La réponse dépend du serveur d'applications/du conteneur Web. Cela va au-delà de la spécification Java EE. Vous devez consulter le chapitre 'Connexion' de sa documentation pour plus de détails. Certains peuvent soutenir la construction comme vous voulez, mais d'autres ne le peuvent pas.

La meilleure solution est d'avoir un gestionnaire d'exception global, tel que le <error-page> que vous avez mentionné vous-même. Laissez-le écouter java.lang.Exception ou peut-être Throwable. Alternativement, vous pouvez avoir (ou réutiliser) un Filter qui écoute sur /* et juste mettre le chain.doFilter(request, response) à l'intérieur d'un bloc try-catch sur Exception ou peut-être Throwable.

Editer: Voici quelques exemples de code comme demandé dans les commentaires. D'abord le Filter qui écoute sur /*. La façon dont je l'ai expliqué avant écrit presque code lui-même:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { 
    try { 
     chain.doFilter(request, response); 
    } catch (Exception e) { 
     logger.error("Caught an uncaught exception.", e); 
     HttpServletRequest req = (HttpServletRequest) request; 
     HttpServletResponse res = (HttpServletResponse) response; 
     req.getRequestDispatcher("error.jsp").forward(req, res); 
    } 
} 

Notez que je recommande plus à mettre dans le « contrôleur avant » Servlet de votre application web. Je ne sais pas si vous en utilisez (il aurait été trop évident de le mettre là, cependant) et je ne sais pas si vous utilisez un cadre existant qui pourrait déjà fournir hors de la ... boîtes de solutions pour cela.

Et la page d'erreur, eh bien, vous ne pouvez pas contourner un scriptlet laid pour enregistrer l'exception.

<% logger.error("Caught an uncaught exception", exception); %> 

Notez que cette encore logs l'exception à la server.log. À ce stade, il est déjà trop tard pour tourner.

+0

Si j'ajoute dans web.xml, les journaux sont écrits dans server.log. J'utilise GlassFish v2 en passant. – Omnipresent

+0

J'aurais dû ajouter, dans la page d'erreur particulière, vous avez la possibilité de vous connecter l'exception vous-même. Il est disponible dans la portée de la page JSP en tant que variable implicite nommée 'exception'. – BalusC

+0

Et, si vous ** ne ** voulez pas vous connecter à 'server.log', alors je passerais à l'approche du filtre et j'appellerais un renvoi à la page d'erreur dans le bloc catch. – BalusC

Questions connexes