Question

Comme de nombreux utilisateurs de log4j, nous avons souvent une journalisation du niveau de débogage coûteuse à évaluer. Nous gardons donc ces cas avec un code tel que:

if( _logger.isDebugEnabled )
  _logger.debug("Interesting, my foojes are goofed up: " + getFullDetails())

Cependant, c'est plus laid qu'un simple appel _logger.debug, et parfois le programmeur ne réalise pas que l'évaluation peut coûter cher.

Il semble qu’il devrait être assez simple d’écrire un programme qui prend un fichier jar compilé et protège tous les appels _logger.debug avec la vérification isDebugEnabled. Nous serions probablement disposés à accepter la surcharge supplémentaire liée à la vérification de isDebugEnabled dans tous les cas.

Quelqu'un a-t-il déjà essayé cette approche ou effectué un post-traitement similaire d'un bocal?

Était-ce utile?

La solution

Avez-vous consulté AspectJ ? Cela prend en charge les aspects utilisant le tissage de code-barres, et peut intercepter dans un fichier .jar précédemment compilé .

Autres conseils

Plutôt que de chercher à modifier le pot, je chercherais une solution à l'aide de Instrumentation de code intermédiaire . Le problème consistera à identifier les parties du code que vous souhaitez insérer dans un .isDebugEnabled () - vous devrez identifier les objets utilisés uniquement pour les invocations log4j.

Je pense qu'une bonne solution serait que le code soit efficace tel quel .

Considérez que log4j est obsolète. Son auteur lui-même l'a laissé tel quel pour éviter de rompre la compatibilité, mais il en a créé un nouveau, SLF4J ( http: // www .slf4j.org / ). Il fournit à la fois une façade et une implémentation, selon la distinction commons-logging / log4j, mais sans les défauts de chacun ...

Je pense que, dans cette nouvelle fonction de journalisation, vous pouvez envoyer des paramètres d'objet à la journalisation et que le niveau est évalué avant la conversion des objets (en chaîne ou autrement). L'idée est d'utiliser une chaîne de format et des paramètres.

Notre code n'utilise pas slf4j, mais nous avons des méthodes utilitaires qui font exactement cela. Il est codé comme suit (de mémoire):

    public enum LogLevel {
       FATAL, ERROR, WARNING, INFO, DEBUG;

       public void log(Logger logger, String format, Object... parameters) {
         if (isEnabled(logger)) {
            logImpl(logger, String.format(format, parameters));
         }
       }
       public boolean isEnabled(Logger logger) {
         switch(this) {
           case WARNING : return logger.isWarningEnabled();
           case INFO : return logger.isInfoEnabled();
           case DEBUG : return logger.isDebugEnabled();
           default: return true;
         }
       }
       private void logImpl(Logger logger, String message) {
         switch(this) {
           case WARNING : logger.warn(message);
           // other cases
         }
       }
    }

Il est utilisé comme:

     public void myMethod(Object param) {
       LogLevel.WARNING.log(LOGGER, "What is my message ....", "myMethod", param);
     }

UPDATE : si vous devez appeler une méthode dans le journal ...

  • Une possibilité consiste à utiliser la méthode toString . Ceci est approprié si votre journalisation est "technique" et sera également utilisée lors du débogage.

  • Si votre journalisation est plus fonctionnelle (je ne pense pas au développeur), je suggère de définir une interface (son fonctionnement est correct dans ce cas, il est donc utile de donner un sens). :

    public interface Detailable { // the name could also suggest logging?
      String getFullDetails();
    }
    

    Implémentez cette interface dans tout objet devant être transmis en tant qu'objet de journalisation, avec un calcul complexe pour créer le journal.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top