sistema - ¿Cómo obtengo que la salida de registro java aparezca en una sola línea?
metodo eliminar en java (10)
1) -Djava.util.logging.SimpleFormatter.format
Java 7 admite una propiedad con la sintaxis de cadena de formato java.util.Formatter
.
-Djava.util.logging.SimpleFormatter.format=...
Mira here .
Mi favorito es:
-Djava.util.logging.SimpleFormatter.format=%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS %4$-6s %2$s %5$s%6$s%n
que hace que la salida sea como:
2014-09-02 16:44:57 SEVERE org.jboss.windup.util.ZipUtil unzip: Failed to load: foo.zip
2) Poniéndolo en IDEs
Los IDE generalmente le permiten establecer las propiedades del sistema para un proyecto. Por ejemplo, en NetBeans, en lugar de agregar -D ... = ... en algún lugar, agregue la propiedad en el diálogo de acción, en una forma de java.util.logging.SimpleFormatter.format=%1$tY-%1$tm-...
sin cotizaciones. El IDE debería averiguarlo.
3) Poniéndolo en Maven - Surefire
Para su conveniencia, aquí le mostramos cómo presentarlo a Surefire:
<!-- Surefire -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.17</version>
<configuration>
<systemPropertyVariables>
<!-- Set JUL Formatting -->
<java.util.logging.SimpleFormatter.format>%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS %4$-6s %2$s %5$s%6$s%n</java.util.logging.SimpleFormatter.format>
</systemPropertyVariables>
</configuration>
</plugin>
4) Hecho a mano
Tengo una biblioteca con pocas clases relacionadas con java.util.logging
. Entre ellos, es SingleLineFormatter
. Frasco descargable here .
public class SingleLineFormatter extends Formatter {
Date dat = new Date();
private final static String format = "{0,date} {0,time}";
private MessageFormat formatter;
private Object args[] = new Object[1];
// Line separator string. This is the value of the line.separator
// property at the moment that the SimpleFormatter was created.
//private String lineSeparator = (String) java.security.AccessController.doPrivileged(
// new sun.security.action.GetPropertyAction("line.separator"));
private String lineSeparator = "/n";
/**
* Format the given LogRecord.
* @param record the log record to be formatted.
* @return a formatted log record
*/
public synchronized String format(LogRecord record) {
StringBuilder sb = new StringBuilder();
// Minimize memory allocations here.
dat.setTime(record.getMillis());
args[0] = dat;
// Date and time
StringBuffer text = new StringBuffer();
if (formatter == null) {
formatter = new MessageFormat(format);
}
formatter.format(args, text, null);
sb.append(text);
sb.append(" ");
// Class name
if (record.getSourceClassName() != null) {
sb.append(record.getSourceClassName());
} else {
sb.append(record.getLoggerName());
}
// Method name
if (record.getSourceMethodName() != null) {
sb.append(" ");
sb.append(record.getSourceMethodName());
}
sb.append(" - "); // lineSeparator
String message = formatMessage(record);
// Level
sb.append(record.getLevel().getLocalizedName());
sb.append(": ");
// Indent - the more serious, the more indented.
//sb.append( String.format("% ""s") );
int iOffset = (1000 - record.getLevel().intValue()) / 100;
for( int i = 0; i < iOffset; i++ ){
sb.append(" ");
}
sb.append(message);
sb.append(lineSeparator);
if (record.getThrown() != null) {
try {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
record.getThrown().printStackTrace(pw);
pw.close();
sb.append(sw.toString());
} catch (Exception ex) {
}
}
return sb.toString();
}
}
En este momento, una entrada predeterminada se ve así:
Oct 12, 2008 9:45:18 AM myClassInfoHere
INFO: MyLogMessageHere
¿Cómo lo hago para hacer esto?
Oct 12, 2008 9:45:18 AM myClassInfoHere - INFO: MyLogMessageHere
Aclaración Estoy usando java.util.logging
A partir de Java 7, java.util.logging.SimpleFormatter admite obtener su format de una propiedad del sistema, por lo que agregar algo como esto a la línea de comandos de JVM hará que se imprima en una línea:
-Djava.util.logging.SimpleFormatter.format=''%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS %4$s %2$s %5$s%6$s%n''
Alternativamente, también puede agregar esto a su logger.properties
:
java.util.logging.SimpleFormatter.format=''%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS %4$s %2$s %5$s%6$s%n''
Como dijo Obediah Stane, es necesario crear su propio método de format
. Pero cambiaría algunas cosas:
Cree una subclase derivada directamente de
Formatter
, no deSimpleFormatter
.SimpleFormatter
ya no tiene nada que agregar.¡Tenga cuidado al crear un nuevo objeto
Date
! Debe asegurarse de representar la fecha deLogRecord
. Al crear una nuevaDate
con el constructor predeterminado, representará la fecha y la hora en que elFormatter
procesa elLogRecord
, no la fecha en que se creó elLogRecord
.
La siguiente clase se puede utilizar como formateador en un Handler
, que a su vez se puede added al Logger
. Tenga en cuenta que ignora toda la información de clases y métodos disponible en LogRecord
.
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Date;
import java.util.logging.Formatter;
import java.util.logging.LogRecord;
public final class LogFormatter extends Formatter {
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
@Override
public String format(LogRecord record) {
StringBuilder sb = new StringBuilder();
sb.append(new Date(record.getMillis()))
.append(" ")
.append(record.getLevel().getLocalizedName())
.append(": ")
.append(formatMessage(record))
.append(LINE_SEPARATOR);
if (record.getThrown() != null) {
try {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
record.getThrown().printStackTrace(pw);
pw.close();
sb.append(sw.toString());
} catch (Exception ex) {
// ignore
}
}
return sb.toString();
}
}
Este registro es específico de su aplicación y no una característica general de Java. ¿Qué aplicación (s) está ejecutando?
Puede ser que esto provenga de una biblioteca de registro específica que está utilizando dentro de su propio código. De ser así, publique los detalles de cuál está utilizando.
Esto es lo que estoy usando.
public class VerySimpleFormatter extends Formatter {
private static final String PATTERN = "yyyy-MM-dd''T''HH:mm:ss.SSSXXX";
@Override
public String format(final LogRecord record) {
return String.format(
"%1$s %2$-7s %3$s/n",
new SimpleDateFormat(PATTERN).format(
new Date(record.getMillis())),
record.getLevel().getName(), formatMessage(record));
}
}
Obtendrás algo como ...
2016-08-19T17:43:14.295+09:00 INFO Hey~
2016-08-19T17:43:16.068+09:00 SEVERE Seriously?
2016-08-19T17:43:16.068+09:00 WARNING I''m warning you!!!
He descubierto una forma que funciona. Puede crear una subclase de SimpleFormatter y anular el método de formato
public String format(LogRecord record) {
return new java.util.Date() + " " + record.getLevel() + " " + record.getMessage() + "/r/n";
}
Un poco sorprendido con esta API, pensé que se podría haber proporcionado una mayor funcionalidad / flexibilidad.
Si inicia sesión en una aplicación web con Tomcat, agregue:
-Djava.util.logging.ConsoleHandler.formatter = org.apache.juli.OneLineFormatter
En argumentos de VM
Similar a Tervor, pero me gusta cambiar la propiedad en tiempo de ejecución.
Tenga en cuenta que esto debe establecerse antes de que se cree el primer SimpleFormatter, tal como se escribió en los comentarios.
System.setProperty("java.util.logging.SimpleFormatter.format",
"%1$tF %1$tT %4$s %2$s %5$s%6$s%n");
si está utilizando java.util.logging, entonces hay un archivo de configuración que está haciendo esto para registrar los contenidos (a menos que esté usando la configuración programática). Entonces, tus opciones son
1) ejecutar postprocesador que elimina los saltos de línea
2) cambie la configuración de registro Y elimine los saltos de línea de la misma. Reinicie su aplicación (servidor) y debería estar bien.
Por captura de pantalla, en Eclipse, seleccione "ejecutar como", luego "Ejecutar configuraciones ..." y agregue la respuesta de Trevor Robinson con comillas dobles en lugar de comillas. Si te pierdes las comillas dobles, obtendrás errores de "no se pudo encontrar o cargar la clase principal".