Je crée un java.util.logging.filehandler code> autorisé à parcourir les fichiers. Lorsque plusieurs instances de mon application sont exécutées, un nouveau fichier journal est créé pour chaque instance de l'application. J'ai besoin de savoir quel fichier est utilisé par l'application, car je souhaite télécharger le fichier journal sur mes serveurs pour un examen plus approfondi. Comment puis-je dire quel fichier est utilisé par un certain fichierHandlerler? P>
4 Réponses :
Le moyen le plus simple consiste à placer une sorte d'identifiant dans le nom de fichier lui-même, c'est-à-dire l'argument code> modèle code> lorsque vous créez le fichierHandler. Comme ce sont des instances de la même application, une façon de les distinguer est de leur identifiant de processus, de sorte que vous puissiez faire cette partie du motif. Une meilleure approche consiste à adopter un identifiant via la ligne de commande et à utiliser cela pour effectuer votre nom de fichier. De cette façon, vous contrôlez les fichiers créés dans un sens. Enfin, si votre demande a une connaissance de la raison pour laquelle il est différent de tous les autres, il se connecte par exemple à un serveur de base de données particulier, vous pouvez simplement utiliser ce nom du serveur de base de données dans le cadre du nom de fichier. p>
Edit: Il ne semble y avoir aucune API pour obtenir le nom du fichier utilisé par un fichierHandler. Je suggère de regarder dans les extensions de journalisation dans X4JULI (qui porte beaucoup de la fonctionnalité Log4J aux spécifications Java.Util.logging): P>
Vous devriez être capable de remplacer une instance de leur fichierHandler qui fournit une méthode getfile (): p>
Eh bien, chaque fois qu'une nouvelle instance est exécutée, le fichier journal est incrémenté comme suit: 1st Instance - log.0 2nd instance - log.fr.1 3ème instance - Log.2
Peut-être que j'ai mal compris votre question. Il semble que vous puissiez déjà associer une instance avec un fichier - que avez-vous besoin d'autre? Si vous avez besoin d'informations d'identification supplémentaires, comme ce que signifie l'instance 1, 2 ou 3 signifie, vous devez l'améliorer de la manière dont j'ai spécifié ci-dessus. Sinon, veuillez clarifier.
Disons que j'ai 3 instances en cours d'exécution et chacune a son propre fichier journal, comme indiqué dans mon dernier commentaire. Instance 2 rencontre une erreur et enregistre l'erreur à son fichier journal (log.1), il aura alors besoin de télécharger le journal sur un serveur, mais pour le télécharger, il doit savoir quel logfile il vient d'écrire, ce qui sera Soyez le même qu'il sera téléchargé.
Merci, la bibliothèque que vous avez mentionnée m'a permis d'utiliser le même logfile pour plusieurs instances, ce qui ne nécessite plus de trouver le fichier journal de logfile, ce qui est encore meilleur. :)
Malheureusement, x4juli.org n'existe plus.
OK, je dois dire que le fichierHandler ne permettant pas de déterminer le fichier journal est sérieusement mutile.
J'ai chuté écrit une fonction appelée "Choisir ()" qui recherche / TMP pour le fichier journal disponible suivant Nom et renvoie ce fichier. Vous pouvez ensuite transmettre le nom de ce fichier en New FileHandler (). P>
/** * Utility: select a log file. File is created immediately to reserve * its name. */ static public File chooseFile(final String basename) throws IOException { final int nameLen = basename.length(); File tmpDir = new File(System.getProperty("java.io.tmpdir")); String[] logs = tmpDir.list(new FilenameFilter() { public boolean accept(File d, String f) { return f.startsWith(basename); } }); int count = 0; if (logs.length > 0) { for (String name : logs) { int n = atoi(name.substring(nameLen)); if (n >= count) count = n + 1; } } String filename = String.format("%s%d.log", basename, count); File logFile = new File(tmpDir, filename); logFile.createNewFile(); return logFile; }
En réalité, vous pouvez le faire beaucoup plus simple en étendant simplement le fichierHandler vous-même. Par exemple ...
myfileHandler.java: p> deleteme.java: p>
Le problème avec ceci est si vous avez utilisé des modèles comment connaissez-vous le fichier réel qui est utilisé?
Vous devez également ajouter un appel à Super (motif) dans le contrôleur MyFileHandler, sinon le fichier n'est pas utilisé pour écrire les journaux. Excellente approche, fonctionne comme un charme.
Voici mon chemin plutôt hacky autour de cela. Il fonctionne pour la valeur par défaut si vous n'utilisez aucune chaîne de format et que vous devez travailler si vous utilisez les chaînes de format G et U dans le nom de fichier, mais pas les autres.
public class FriendlyFileHandler extends FileHandler { /*** * In order to ensure the most recent log file is the file this one owns, * we flush before checking the directory for most recent file. * * But we must keep other log handlers from flushing in between and making * a NEW recent file. */ private static Object[] flushLock = new Object[0]; private String pattern; public FriendlyFileHandler(String pattern, int maxLogLengthInBytes, int count) throws IOException, SecurityException { super(pattern, maxLogLengthInBytes, count); this.pattern = pattern; } /*** * Finds the most recent log file matching the pattern. * This is just a guess - if you have a complicated pattern * format it may not work. * * IMPORTANT: This log file is still in use. You must * removeHandler() on the logger first, .close() this handler, * then add a NEW handler to your logger. THEN, you can read * the file. * * Currently supported format strings: g, u * * @return A File of the current log file, or null on error. */ public synchronized File getCurrentLogFile() { synchronized(flushLock) { // so the file has the most recent date on it. flush(); final String patternRegex = // handle incremental number formats pattern.replaceAll("%[gu]", "\\d*") + // handle default case where %g is appended to end "(\\.\\d*)?$"; final Pattern re = Pattern.compile(patternRegex); final Matcher matcher = re.matcher(""); // check all files in the directory where this log would be final File basedir = new File(pattern).getParentFile(); final File[] logs = basedir.listFiles(new FileFilter() { @Override public boolean accept(final File pathname) { // only get files that are part of the pattern matcher.reset(pathname.getAbsolutePath()); return matcher.find(); } }); return findMostRecentLog(logs); } } private File findMostRecentLog(File[] logs) { if (logs.length > 0) { long mostRecentDate = 0; int mostRecentIdx = 0; for (int i = 0; i < logs.length; i++) { final long d = logs[i].lastModified(); if (d >= mostRecentDate) { mostRecentDate = d; mostRecentIdx = i; } } return logs[mostRecentIdx]; } else { return null; } } @Override public synchronized void flush() { // only let one Handler flush at a time. synchronized(flushLock) { super.flush(); } } }