Estoy creando un java.util.logging.FileHandler
que puede recorrer los archivos. Cuando se ejecutan varias instancias de mi aplicación, se crea un nuevo archivo de registro para cada instancia de la aplicación. Necesito saber qué archivo está utilizando la aplicación porque quiero subir el archivo de registro a mis servidores para su posterior revisión. ¿Cómo puedo saber qué archivo está usando un determinado FileHandler?Determine el archivo que está utilizando FileHandler
Respuesta
La manera más fácil es colocar algún tipo de identificador en el nombre del archivo, es decir, el argumento pattern
al crear el FileHandler. Como estas son instancias de la misma aplicación, una forma de distinguirlas es mediante su identificación de proceso, por lo que podría hacer esa parte del patrón. Un mejor enfoque es pasar un identificador a través de la línea de comando y usarlo para crear su nombre de archivo. De esta forma, usted controla los archivos que se crean en algún sentido. Finalmente, si su aplicación tiene algún conocimiento de por qué es diferente de todas las demás, por ejemplo, se conecta a un servidor de base de datos en particular, entonces podría simplemente usar ese nombre de servidor de base de datos como parte del nombre del archivo.
EDITAR: Parece que no hay ninguna API para obtener el nombre del archivo que está utilizando un FileHandler. Yo sugeriría mirar en las extensiones de explotación forestal en x4juli (los puertos que una gran cantidad de la funcionalidad log4j a las especificaciones java.util.logging):
usted debería ser capaz de sustituir una instancia de su FileHandler que proporciona un método getFile():
Bien, tengo que decir que FileHandler no proporciona una forma de determinar el archivo de registro. Es realmente tonto.
Terminé escribiendo una función llamada "chooseFile()" que busca/tmp para el siguiente nombre de archivo de registro disponible y devuelve ese archivo. A continuación, puede pasar el nombre de ese archivo al nuevo FileHandler().
/**
* 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 realidad, puede hacer esto mucho más simple simplemente extendiendo FileHandler usted mismo. Por ejemplo ...
MyFileHandler.java:
import java.io.IOException;
import java.util.logging.FileHandler;
public class MyFileHandler extends FileHandler {
protected String _MyFileHandler_Patern;
public MyFileHandler(String pattern) throws IOException {
_MyFileHandler_Patern = pattern;
}
public String getMyFileHandlerPattern() {
return _MyFileHandler_Patern;
}
}
DeleteMe.java:
import java.io.IOException;
import java.util.logging.Handler;
import java.util.logging.Logger;
public class DeleteMe {
public static void main(String[] args) throws IOException {
Logger log = Logger.getLogger(DeleteMe.class.getName());
MyFileHandler output = new MyFileHandler("output.log");
log.addHandler(output);
for (Handler handler : log.getHandlers()) {
if (handler instanceof MyFileHandler) {
MyFileHandler x = (MyFileHandler) handler;
if ("output.log".equals(x.getMyFileHandlerPattern())) {
System.out.println("found hanlder writing to output.log");
}
}
}
}
}
El problema con esto es si usó patrones ¿cómo sabe el archivo real que se utiliza? – PhoneixS
También necesita agregar una llamada a super (patrón) en el controlador MyFileHandler, de lo contrario, el archivo no se usa para escribir los registros. Excelente enfoque, funciona como un encanto. –
Aquí es mi manera bastante hacky alrededor de ella. Funciona de manera predeterminada si no usa cadenas de formato, y debería funcionar si utiliza las cadenas de formato g y u en nombre de archivo, pero no las demás.
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();
}
}
}
- 1. Determine qué proceso está bloqueando el portapapeles
- 2. Determine si la página actual está utilizando SSL en Rails
- 3. Mercurial: determine dónde se eliminó el archivo.
- 4. Determine qué punto final wcf se está utilizando en el servidor
- 5. Determine el tipo de archivo con C#
- 6. Determine el tipo de archivo en Ruby
- 7. ¿Está utilizando el doble más rápido que el flotador?
- 8. Ruta de archivo dinámica y nombre de archivo para FileHandler en el archivo de configuración del registrador en python
- 9. python: determine si una clase está anidada
- 10. Utilizando el archivo .RData
- 11. Cómo configurar las propiedades de un FileHandler específico
- 12. Determine el tipo de archivo de una imagen
- 13. Cómo probar el servicio de unidad que está utilizando PetaPoco.Database
- 14. Determine el nombre de un archivo para descargar
- 15. Determine el número de páginas en un archivo PDF
- 16. Determine la clave primaria de una tabla utilizando TSQL
- 17. Script Bash: determine si se modificó el archivo.
- 18. Determine el dispositivo del usuario utilizando iOS SDK y el código Cocoa Touch/Objective-C completo
- 19. ¿Está utilizando extensiones paralelas?
- 20. ¿Está utilizando Better?
- 21. archivo fue creado para el archivo que no es la arquitectura que se está vinculando (i386)
- 22. Linux de programación: el dispositivo que un archivo está en
- 23. Ruby: obtener el archivo que se está ejecutando
- 24. Determine si una subvista está visible en un UIScrollView
- 25. al leer el archivo utilizando fgets
- 26. Determine el motivo de System.AccessViolationException
- 27. Lea la imagen y determine si está corrupta C#
- 28. Determine si CGPoint está dentro del área de la imagen
- 29. Determine el tamaño de un InputStream
- 30. Jquery: utilizando una solicitud POST, que no está permitida Error
Bueno, cada vez que se ejecuta una nueva instancia, el archivo de registro se incrementa de modo que: primera instancia - log.0 segunda instancia - log.1 tercera instancia - log.2 –
Tal vez he malentendido tu pregunta Parece que ya puedes asociar una instancia con un archivo, ¿qué más necesitas? Si necesita más información de identificación, como qué significa la instancia 1, 2 o 3, entonces debe mejorarla de la manera que he especificado anteriormente. Si no, entonces aclare. – ars
Digamos que tengo 3 instancias ejecutándose, y cada una tiene su propio archivo de registro, como se indica en mi último comentario.La instancia 2 encuentra un error y registra el error en su archivo de registro (log.1), luego deberá cargar el archivo de registro en un servidor, pero para poder cargarlo, debe saber a qué archivo de registro acaba de escribir, que ser el mismo que subirá –