Question

Plusieurs travaux exécutés simultanément doivent utiliser les mêmes informations de configuration pour log4j. Ils déchargent tous les journaux dans un seul fichier en utilisant le même appender. Existe-t-il un moyen de nommer chaque fichier de manière dynamique dans son journal afin qu'il reste séparé?

Merci
Tom

Était-ce utile?

La solution

Pouvez-vous transmettre une propriété système Java pour chaque travail? Si oui, vous pouvez paramétrer comme ceci:

java -Dmy_var=somevalue my.job.Classname

Et ensuite dans votre log4j.properties:

log4j.appender.A.File=${my_var}/A.log

Vous pouvez renseigner la propriété système Java avec une valeur de l'environnement de l'hôte (par exemple) identifiant de manière unique l'instance du travail.

Autres conseils

Si les noms de travail sont connus à l'avance, vous pouvez l'inclure lors de l'appel getLogger (). Vous pouvez ensuite lier différents appenders à différents enregistreurs, avec des noms de fichier distincts (ou d'autres destinations).

Si vous ne pouvez pas connaître le nom du travail à l'avance, vous pouvez configurer le consignateur au moment de l'exécution au lieu d'utiliser un fichier de configuration:

FileAppender appender = new FileAppender();
appender.setFileName(...);
appender.setLayout(...);
Logger logger = Logger.getLogger("com.company.job."+jobName);
logger.addAppender(appender);

Nous avons mis en place quelque chose de similaire dans notre système. Nous stockons les enregistreurs spécifiques dans une carte de hachage et initialisons les appenders pour chacun d’eux selon les besoins.

Voici un exemple:

public class JobLogger {
private static Hashtable<String, Logger> m_loggers = new Hashtable<String, Logger>();
private static String m_filename = "...";  // Root log directory

public static synchronized void logMessage(String jobName, String message)
{
    Logger l = getJobLogger(jobName);
    l.info(message);
}

public static synchronized void logException(String jobName, Exception e)
{
    Logger l = getJobLogger(partner);
    l.info(e.getMessage(), e);
}

private static synchronized Logger getJobLogger(String jobName)
{
    Logger logger = m_loggers.get(jobName);
    if (logger == null) {
        Layout layout = new PatternLayout("...");
        logger = Logger.getLogger(jobName);
        m_loggers.put(jobName, logger);
        logger.setLevel(Level.INFO);
        try {
            File file = new File(m_filename);
            file.mkdirs();
            file = new File(m_filename + jobName + ".log");
            FileAppender appender = new FileAppender(layout, file.getAbsolutePath(), false);
            logger.removeAllAppenders();
            logger.addAppender(appender);
    }
        catch (Exception e)
    { ... }
    }
    return logger;
}
}

Ensuite, pour utiliser ceci dans votre travail, il vous suffit d'utiliser une entrée d'une ligne comme celle-ci:

JobLogger.logMessage(jobName, logMessage);

Ceci créera un fichier journal pour chaque nom de travail et le déposera dans son propre fichier avec ce nom de travail dans le répertoire que vous spécifiez.

Vous pouvez manipuler d’autres types d’appendeurs et autres, car, tel qu’il a été rédigé, l’ajout se poursuivra jusqu’à ce que la JVM soit redémarrée. Cette opération risque de ne pas fonctionner si vous exécutez le même travail sur un serveur toujours actif, mais cela donne comment cela peut fonctionner.

Vous pouvez avoir chaque travail défini NDC ou MDC, puis écrire un appender qui modifie le nom en fonction de la valeur NDC ou MDC. Créer un nouvel appender n'est pas trop difficile. Il peut également y avoir un ajout qui correspondra à la facture dans le bac à sable log4j. Commencez à chercher dans http://svn.apache.org/viewvc/logging/ log4j / trunk / contributions /

Vous pouvez écrire votre propre correcteur qui constitue son propre nom de fichier, éventuellement en utilisant le [File.createTempFile] ( http://java.sun.com/j2se/1.5.0/docs/ api / java / io / File.html # createTempFile (java.lang.String,% 20java.lang.String)) . Si la classe FileAppender a été écrite correctement, vous devriez pouvoir l'étendre - ou RollingFileAppender - et remplacer la méthode getFile pour en renvoyer un choisissez en fonction des nouvelles propriétés que vous souhaitez ajouter.

Mise à profit de la shadit . Si chaque travail peut être identifié par la méthode principale de la classe qui a été démarrée, vous pouvez utiliser la propriété système sun.java.command qui contient le nom complet de la classe démarrée. Par exemple, comme ceci:

log4j.appender.LOGFILE.File=${sun.java.command}.log

Je l'utilise avec un TimestampFileAppender comme ceci:

log4j.appender.LOGFILE=TimestampFileAppender
log4j.appender.LOGFILE.TimestampPattern=yyyy_MM_dd__HH_mm
log4j.appender.LOGFILE.File=${sun.java.command}_{timestamp}.log

Ainsi, lorsque je développe sous Eclipse, je reçois un nouveau fichier journal pour chaque nouveau processus que je lance, identifié par le nom de la classe de la classe avec la méthode principale et l'heure à laquelle il a été lancé.

Tom, vous devez spécifier et ajouter des ajouts pour chaque travail. Supposons que vous ayez 2 travaux correspondant à deux paquets java différents, com.tom.firstbatch et com.tom.secondbatch, vous obtiendriez quelque chose comme ceci dans log4j.xml:

   <category name="com.tom.firstbatch">
      <appender-ref ref="FIRST_APPENDER"/>
   </category>
   <category name="com.tom.secondtbatch">
      <appender-ref ref="SECOND_APPENDER"/>
   </category>

Vous pouvez configurer log4j par programme lorsque vous initialisez le travail.

Vous pouvez également définir le fichier log4j.properties au moment de l'exécution via une propriété système. Du manuel :

  

Définissez la variable de chaîne de ressource sur la valeur de la propriété système log4j.configuration . La méthode recommandée pour spécifier le fichier d'initialisation par défaut consiste à utiliser la propriété système log4j.configuration. Si la propriété système log4j.configuration n'est pas définie, définissez la ressource de variable chaîne sur sa valeur par défaut "log4j.properties".

En supposant que vous exécutiez les travaux à partir de différentes commandes Java, cela leur permettra d'utiliser différents fichiers log4j.properties et des noms de fichiers différents pour chaque fichier.

Sans une connaissance précise de la manière dont vos tâches sont exécutées, il est difficile de le dire!

vous pouvez implémenter les éléments suivants:

  • Un titulaire ThreadLocal pour l'identité de votre travail.
  • Etendre FileAppender, votre FileAppender doit conserver une carte contenant un QuietWriter pour chaque identité de travail. Dans la méthode subendend, vous obtenez l’identité de votre travail auprès du ThreadLocal, vous recherchez (ou créez) le QuietWriter et vous y écrivez ...

Je peux vous envoyer du code par mail si vous le souhaitez ...

log4j.logger.com.foo.admin =, AdminFileAppender log4j.logger.com.foo.report =, ReportFileAppender

C’est une autre façon de faire cette tâche .. ici com.foo.admin est le nom complet du paquet

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