Как я могу получить вывод журнала Java в одну строку? - PullRequest
117 голосов
/ 12 октября 2008

На данный момент запись по умолчанию выглядит примерно так:

Oct 12, 2008 9:45:18 AM myClassInfoHere
INFO: MyLogMessageHere

Как мне это сделать?

Oct 12, 2008 9:45:18 AM myClassInfoHere - INFO: MyLogMessageHere

Уточнение Я использую java.util.logging

Ответы [ 10 ]

76 голосов
/ 22 мая 2012

Начиная с Java 7, java.util.logging.SimpleFormatter поддерживает получение его формата из системного свойства, поэтому добавление чего-либо подобного в командную строку JVM приведет к печать в одну строку:

-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'

Кроме того, вы также можете добавить это к вашему 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'
70 голосов
/ 09 мая 2011

1) -Djava.util.logging.SimpleFormatter.format

Java 7 поддерживает свойство с синтаксисом строки формата java.util.Formatter.

-Djava.util.logging.SimpleFormatter.format=... 

См. здесь .

Мой любимый это:

-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

который выводит как:

2014-09-02 16:44:57 SEVERE org.jboss.windup.util.ZipUtil unzip: Failed to load: foo.zip

2) Помещение в IDE

Среды IDE обычно позволяют задавать системные свойства для проекта. Например. в NetBeans вместо добавления -D ... = ... куда-нибудь добавьте свойство в диалоге действий в виде java.util.logging.SimpleFormatter.format=%1$tY-%1$tm-... - без кавычек. IDE должна выяснить.

3) Помещение в Maven - Surefire

Для вашего удобства, вот как это сделать в 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) Ручная работа

У меня есть библиотека с несколькими java.util.logging связанными классами . Среди них это SingleLineFormatter. Загружаемый jar здесь .

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();
  }
}
45 голосов
/ 11 декабря 2015

Похоже на Tervor, но мне нравится менять свойство во время выполнения.

Обратите внимание, что это необходимо установить до создания первого SimpleFormatter - как было написано в комментариях.

    System.setProperty("java.util.logging.SimpleFormatter.format", 
            "%1$tF %1$tT %4$s %2$s %5$s%6$s%n");
35 голосов
/ 13 октября 2008

Как сказал Обедия Стейн, необходимо создать собственный метод format. Но я бы изменил несколько вещей:

  • Создайте подкласс, непосредственно полученный из Formatter, а не из SimpleFormatter. SimpleFormatter больше нечего добавить.

  • Будьте осторожны с созданием нового Date объекта! Вы должны обязательно указать дату LogRecord. При создании нового Date с конструктором по умолчанию он будет представлять дату и время, когда Formatter обрабатывает LogRecord, а не дату создания LogRecord.

Следующий класс может быть использован в качестве средства форматирования в Handler, что в свою очередь может быть добавлено к Logger. Обратите внимание, что он игнорирует всю информацию о классе и методе, доступную в 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();
    }
}
9 голосов
/ 19 августа 2016

Это то, что я использую.

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));
    }
}

Вы получите что-то вроде ...

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!!!
7 голосов
/ 20 марта 2013

Eclipse config

За снимок экрана в Eclipse выберите «Запустить как», затем «Запустить конфигурации ...» и добавьте ответ Тревора Робинсона с двойными кавычками вместо кавычек. Если вы пропустите двойные кавычки, вы получите сообщение об ошибке «не удалось найти или загрузить основной класс».

4 голосов
/ 12 октября 2008

Я понял, как это работает. Вы можете создать подкласс SimpleFormatter и переопределить метод формата

    public String format(LogRecord record) {
        return new java.util.Date() + " " + record.getLevel() + " " + record.getMessage() + "\r\n";
    }

Немного удивленный этим API, я бы подумал, что больше функциональности / гибкости было бы обеспечено из коробки

0 голосов
/ 03 октября 2016

Если вы входите в веб-приложение с помощью tomcat, добавьте:

-Djava.util.logging.ConsoleHandler.formatter = org.apache.juli.OneLineFormatter

О аргументах виртуальной машины

0 голосов
/ 12 октября 2008

если вы используете java.util.logging, то есть файл конфигурации, который делает это для регистрации содержимого (если вы не используете программную конфигурацию). Итак, ваши варианты
1) запустить постпроцессор, удаляющий разрывы строк
2) изменить конфигурацию журнала и удалить из него разрывы строк. Перезапустите приложение (сервер), и у вас все получится.

0 голосов
/ 12 октября 2008

Это ведение журнала специально для вашего приложения, а не общая функция Java. Какие приложения вы используете?

Возможно, это происходит из определенной библиотеки журналов, которую вы используете в своем собственном коде. Если это так, пожалуйста, опубликуйте информацию о том, какой из них вы используете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...