powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Нетормозящее логирование в Джаве.
72 сообщений из 72, показаны все 3 страниц
Нетормозящее логирование в Джаве.
    #39103628
Dymytry
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем хороших выходных!

Решил на досуге изучить вопрос влияния логгирования на производительность.

Имею простой пустой цикл..
Код: java
1.
2.
        for (i = 0; i<Integer.MAX_VALUE; i++) {
        }


... и хочу максимально подробно логгировать переменную i, с минимальным импактом на производительность.

1) просто вставить system.out.println() в цикл. замедляет очень сильно.
2) создать надзирающий daemon поток который печатает эту переменную, она должна быть volatile как по учебнику, замедляет прилично.
3) то же, но переменная без volatile. Ухудшение раз в 10 меньше чем в п.2. Оно почти не связано с потоком, а связано что переменная теперь не локальная.

Что я узнать-то хотел.

1) Какой оптимальный алгоритм для реализации этой задачи? Лучше все-таки логгировать из основного потока, или из наблюдающего потока? Предполагаю, библиотеки логгирования решают эту задачу, или есть смысл делать как я?
2) Оказалось, что запись в статическую переменную класса относительно записи в локальную переменную замедляет данный код раз в тыщу. Где бы почитать про Джаву на таком уровне?

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
package performance.simple;
public class PerformanceCheck {

    private static int i = 0; //volatile hits performance

    private static final Thread t = new Thread() {
        public void run() {
            while(true) {
                if (i % 100000000 == 0) {
                    System.out.println(i);
                }
            }
        }
    };

    public static void main(String[] args) {

        System.out.println("start execution....");

        t.setDaemon(true);
        t.start();

        long start = System.currentTimeMillis();

        for (i = 0; i<Integer.MAX_VALUE; i++) {
        }

        long end = System.currentTimeMillis();

        System.out.println(end - start);

        System.out.println("end execution....");
    }
}
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39103678
Фотография Dmitry.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вынести условие
Код: java
1.
if (i % 100000000 == 0) 

в основной цикл
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39103724
rfq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39103786
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
условие i % 100000000 не совместимо с "максимально подробно логгировать"

Кроме того, такое логгирование, когда другой поток "смотрит" в сырые данные - это вообще как правило, не есть правильно. Так можно логгировать искусственную задачу, в реальном проекте это скорей всего будет плохо.

Принцип может быть такой. Данные логов кладутся в очередь в том же потоке, а потом (через время или по достижении порогового размера) другой поток их забирает и пишет в лог.
при этом, до некоторой величины граничного потока данных, оно тормозить не будет - пока старая порция будет успевать залоггироваться. Когда поток данных превысит эту величину, то все начнет тормозить - но это уже будет подход к границе производительности.

насчет волатильных переменных, скоростей записи, чтения, публикации в др потоки - смотрите на ютуб ранние видео с канала JUGRuVideo, а так же поиском пробивайте имена людей, которые эти доклады делают.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39104032
Фотография Dmitry.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забавно.

следующий код у меня отрабатывает примерно за 13 миллисекунд.
но если заменить
Код: plaintext
if(j==0)j++;
на
Код: plaintext
if(j==0)i++;
то код отрабатывает около 10 секунд.
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
public class A {
	
	public static void main(String[] args) {
		System.out.println("start execution....");
		long start = System.currentTimeMillis();
		
		int i=0;
		for (i=0; i<2000000000; i++ ) {
			int j=i%1000000000;
			if(j==0)j++;
		}

		long end = System.currentTimeMillis();
		System.out.println(end - start);
		System.out.println("end execution.... i="+i);
	}
}
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39104110
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dymytry1) просто вставить system.out.println() в цикл. замедляет очень сильно.

System.out.println() может выводить в GUI, текстовую консоль, в файл или вообще вникуда. Производительность каждого варианта разная.

Dymytry2) создать надзирающий daemon поток который печатает эту переменную, она должна быть volatile как по учебнику, замедляет прилично.
При чем тут учебник? volatile решает определенную задачу, но для вашей существуют и другие решения, просто вы о них ещё не знаете. Начните хотя бы с ExecutorService

Dymytry3) то же, но переменная без volatile. Ухудшение раз в 10 меньше чем в п.2. Оно почти не связано с потоком, а связано что переменная теперь не локальная.
Понятно что ничего не понятно.

Dymytry1) Какой оптимальный алгоритм для реализации этой задачи?

На сколько я знаю, очереди с буферизированой записью в файл. Логируемое сообщение создаётся в рабочем потоке, никаких volatile для этого не нужно. Сообщение складывается в очередь. Фоновый поток логгера выгребает сообщения и пачкой пишет их в файл.

DymytryЛучше все-таки логгировать из основного потока, или из наблюдающего потока?

Почему именно "наблюдающего"? Других вариантов нет?

DymytryПредполагаю, библиотеки логгирования решают эту задачу, или есть смысл делать как я?

Смысла делать как вы нет. Даже самый древний log4j спокойно пишет сотни мегабайт логов в течении максимум пары секунд (в зависимости от устройства IO)

Dymytry2) Оказалось, что запись в статическую переменную класса относительно записи в локальную переменную замедляет данный код раз в тыщу. Где бы почитать про Джаву на таком уровне?

Ключевые слова для Google
JIT, microbenchmarking, JMH, client JVM, server JVM
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39104435
Partisan M
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DymytryРешил на досуге изучить вопрос влияния логгирования на производительность.

Имею простой пустой цикл..

for (i = 0; i<Integer.MAX_VALUE; i++) {
}


... и хочу максимально подробно логгировать переменную i, с минимальным импактом на производительность.

Лучше на досуге поизучайте русский язык. Ваше изучение импакта не имеет смысла (нот хавает нифига тхе сенсе), поскольку пример не имеет отношения к реальным задачам. Если они у вас есть, то изучайте на них. Но в общем можно сказать, что и в крупных программах это обычно не проблема, однако есть средства предотвращения излишней нагрузки от логирования, их и надо изучить.
А именно:
1) Разделить сообщения на уровни. В настройках логирования (лучше в отдельном файле, а не в и исходном коде программы) для обычной эксплуатации указать более высокий уровень (меньше сообщений), а при обнаружении ошибок сменить его на менее высокий. в популярной библиотеке log4j надо использовать как минимум 2 уровня - ERROR и DEBUG. В других посмотреть, какие там есть уровни.
2) Задать, чтобы команды логирования срабатывали только при достаточном уровне.
Например, в log4j (или LogBack) это будет выглядеть как:

Код: java
1.
2.
3.
if (logger.isDebugEnabled()) {
    logger.debug(какое-то сообщение);
}



Эта предосторжность может иметь смысл, если для создания сообщения требуется существенная работа.
3) Вместо log4j (самая популярная библиотека) по возможности использовать LogBack (автор log4j и LogBack утверждает, что LogBack быстрее. Я не проверял).
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39104459
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Partisan Mпоскольку пример не имеет отношения к реальным задачам. Если они у вас есть, то изучайте на них
+1
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39104574
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DymytryВсем хороших выходных!
... и хочу максимально подробно логгировать переменную i, с минимальным импактом на производительность.

1) просто вставить system.out.println() в цикл. замедляет очень сильно.
2) создать надзирающий daemon поток который печатает эту переменную, она должна быть volatile как по учебнику, замедляет прилично.
3) то же, но переменная без volatile. Ухудшение раз в 10 меньше чем в п.2. Оно почти не связано с потоком, а связано что переменная теперь не локальная.

Что я узнать-то хотел.

1) Какой оптимальный алгоритм для реализации этой задачи? Лучше все-таки логгировать из основного потока, или из наблюдающего потока? Предполагаю, библиотеки логгирования решают эту задачу, или есть смысл делать как я?
2) Оказалось, что запись в статическую переменную класса относительно записи в локальную переменную замедляет данный код раз в тыщу. Где бы почитать про Джаву на таком уровне?

Оптимизацию логгирования я-бы начал со следующего.
1) Выбор библиотеки логгирования. Что есть? Тут сравнение по перформансу. Log4j, LogBack, Log4j2
https://logging.apache.org/log4j/2.x/performance.html
Обрати внимание на "Asynchronous Logging Performance Improvements".

Можно также посмотреть какие стоят Appenders. Файловые - достаточно быстры.
Но JDBCAppender, SNMPAppender, и пищущие в сислог операционки будут скорее
всего буферизироваться а по заполнении буфера тормозить и блокировать нормальный
flow алгоритма.

2) Пересмотреть смысл самой задачи. Если ты борешся с проблемой то ее надо "вычленить".
Незачем логгировать простыню трафика типа "entry-exit" в каждый codeblock, callback, или сеттер.
Что потом делать с такой аналиткой? Не хватит никаких терабайтов чтобы это хранить.

Имеет смысл сделать логгирование избирательным. Логгировать СОБЫТИЕ.
Например

Код: java
1.
if (i==...) { logger.trace(....) }.



3) Убрать строковые операции и лишнее форматирование. В старых библиотеках. Мы делали конкатенацию

Код: java
1.
javaUtilLogger.fine("i = "+i); 



И чтобы отсекать конкатенацию для level > fine от более строгих нужно было оборачивать вызов логгирования
проверкой условия.

В новых библиотеках есть гарантия того что строковая операция и форматирование не будет
работать для "отсекаемых" уровней если мы используем специальный синтаксис с multiple arguments и bracers.

Код: java
1.
slf4jLogger.trace("i = {}",i); 
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39104870
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Test.java
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
import org.apache.log4j.Logger;
import org.apache.log4j.Level;
public class Test
{
  public static void main(String[] args)
  {
    int count = 100;
    try {
      count = Integer.parseInt(args[0]);
    }
    catch (RuntimeException ex) {};
    long start = System.currentTimeMillis();
    Logger log = Logger.getLogger(Test.class);
    for (int i = 0; i < count; i++) {
      log.trace(Level.TRACE + ": " + i);
      log.debug(Level.DEBUG + ": " + i);
      log.info(Level.INFO + " : " + i);
      log.warn(Level.WARN + " : " + i);
      log.error(Level.ERROR + ": " + i);
      log.fatal(Level.FATAL + ": " + i);
    }
    start = System.currentTimeMillis() - start;
    log.fatal("===========");
    log.fatal("Test run in " + start + " msec.");
    log.shutdown();
  }
}


log4.xml
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
<?xml version="1.0" encoding="windows-1251"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">

<log4j:configuration debug="false">

  <appender name="console" class="org.apache.log4j.ConsoleAppender">
    <param name="Threshold" value="fatal" />
    <layout class="org.apache.log4j.EnhancedPatternLayout">
      <param name="ConversionPattern" value="|%d{yyyy-MM-dd HH:mm:ss.SSS Z}|%-5p|%t|%c|%m%n%throwable{short}" />
    </layout>
  </appender>

  <appender name="null" class="org.apache.log4j.varia.NullAppender">
    <layout class="org.apache.log4j.EnhancedPatternLayout">
      <param name="ConversionPattern" value="|%d{yyyy-MM-dd HH:mm:ss.SSS Z}|%-5p|%t|%c|%m%n" />
    </layout>
  </appender>

  <appender name="file" class="org.apache.log4j.FileAppender">
    <param name="File" value="Test.log" />
    <param name="Append" value="false" />
    <layout class="org.apache.log4j.EnhancedPatternLayout">
      <param name="ConversionPattern" value="|%d{yyyy-MM-dd HH:mm:ss.SSS Z}|%-5p|%c|%t|%m%n" />
    </layout>
  </appender>

  <appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
    <appender-ref ref="null" />
    <appender-ref ref="file" />
    <appender-ref ref="console"/>
  </appender>

  <root>
    <priority value="trace"/>
    <appender-ref ref="ASYNC"/>
  </root>

</log4j:configuration>


Сотня итераций, вывод на экран (FATAL), в файл и nullAppender (TRACE):
Код: plaintext
1.
2.
...
|2015-11-16 23:22:39.040 +0800|FATAL|main|Test|===========
|2015-11-16 23:22:39.040 +0800|FATAL|main|Test|Test run in 267 msec.

Всё тоже самое, кроме уровня (везде FATAL):
Код: plaintext
1.
2.
...
|2015-11-16 23:23:39.136 +0800|FATAL|main|Test|===========
|2015-11-16 23:23:39.136 +0800|FATAL|main|Test|Test run in 187 msec.

P.S. AsyncLogger настраивается только через xml-конфигурацию.
Создаётся (перезаписывается) файл Test.log в текущем каталоге.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39104926
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Лучше так (без предупреждений об устаревшем API):
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
public class Test
{
  final static LogManager logMan = new LogManager();
  public static void main(String[] args)
  {
    int count = 100;
    try {
      count = Integer.parseInt(args[0]);
    }
    catch (RuntimeException ex) {};
    long start = System.currentTimeMillis();
    Logger log = logMan.getLogger(Test.class);
    for (int i = 0; i < count; i++) {
      log.trace(Level.TRACE + ": " + i);
      log.debug(Level.DEBUG + ": " + i);
      log.info(Level.INFO + " : " + i);
      log.warn(Level.WARN + " : " + i);
      log.error(Level.ERROR + ": " + i);
      log.fatal(Level.FATAL + ": " + i);
    }
    start = System.currentTimeMillis() - start;
    log.fatal("===========");
    log.fatal("Test run in " + start + " msec.");
    logMan.shutdown();
  }
}


Ну и замеры времени более "честные" - исключены (фиксированные) затраты времени на создание конфигурации и получение логгеров.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39104933
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну и совсем косметика:
Test.java
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
public class Test
{
  final static LogManager logMgr = new LogManager();
  final static Logger log = logMgr.getLogger(Test.class);
  public static void main(String[] args)
  {
    int count = 100;
    try {
      count = Integer.parseInt(args[0]);
    }
    catch (RuntimeException ex) {};
    long start = System.currentTimeMillis();
    for (int i = 0; i < count; i++) {
      log.trace(Level.TRACE + ": " + i);
      log.debug(Level.DEBUG + ": " + i);
      log.info(Level.INFO + " : " + i);
      log.warn(Level.WARN + " : " + i);
      log.error(Level.ERROR + ": " + i);
      log.fatal(Level.FATAL + ": " + i);
    }
    start = System.currentTimeMillis() - start;
    log.fatal("===========");
    log.fatal("Test run in " + start + " msec.");
    logMgr.shutdown();
  }
}

...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39104936
scf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rfq,

О да, всё придумано до нас.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39104939
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Консоль штука медленная, поэтому запускать лучше так (windows):
Код: plaintext
1.
2.
3.
4.
> java ... 1000|find "|Test run "
|2015-11-17 00:33:02.403 +0800|FATAL|main|Test|Test run 1000 iteration in 63 msec.

> java ... Test 1000|find "|Test run "
|2015-11-17 00:33:27.818 +0800|FATAL|main|Test|Test run 1000 iteration in 109 msec.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39105037
Фотография grasoff.net
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dymytryс минимальным импактомс чем? о_О
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39105834
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Более содержательный пример
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
import java.util.concurrent.atomic.AtomicInteger;

public class Test
{
  private final static int
    THREADS_MIN = 1
  , THREADS_MAX = 5000
  , THREADS_DEFAULT = 10
  , COUNTER_MIN = 1000
  , COUNTER_MAX = 1000000
  , COUNTER_DEFAULT = COUNTER_MAX;
  
  final static LogManager logMgr = new LogManager();
  private final static Logger log = logMgr.getLogger(Test.class);
  
  static int threads = THREADS_DEFAULT;
  static int count = COUNTER_DEFAULT;
  static AtomicInteger counter = new AtomicInteger(0);

  public static void main(String[] args) throws InterruptedException
  {
    try { threads = Integer.parseInt(args[0]); }
    catch (RuntimeException e) {};
    if (threads < THREADS_MIN) threads = THREADS_MIN;
    if (threads > THREADS_MAX) threads = THREADS_MAX;

    try { count = Integer.parseInt(args[1]); }
    catch (RuntimeException e) {};
    if (count < COUNTER_MIN) count = COUNTER_MIN;
    if (count > COUNTER_MAX) count = COUNTER_MAX;
    
    Thread[] loggers = new Thread[threads];
    for (int i = 0; i < threads; i++) loggers[i] = new Thread(new LogPlain());
    long timer = System.currentTimeMillis();
    for (Thread logger : loggers) logger.start();
    for (Thread logger : loggers) logger.join();
    timer = System.currentTimeMillis() - timer;
    log.fatal("Test run " + count + " iteration on " + threads + " threads in " + timer + " msec");
    logMgr.shutdown();
  }
  
  private static class LogPlain implements Runnable
  {
    private final static Logger log = logMgr.getLogger(LogPlain.class);
    @Override public void run()
    {
      int i;
      for (;;)
      {
        if (count < (i = counter.incrementAndGet())) return;
        log.fatal(Level.FATAL + ": " + i + " " + Thread.currentThread());
        if (count < (i = counter.incrementAndGet())) return;
        log.error(Level.ERROR + ": " + i);
        if (count < (i = counter.incrementAndGet())) return;
        log.warn (Level.WARN + " : " + i);
        if (count < (i = counter.incrementAndGet())) return;
        log.info (Level.INFO + " : " + i);
        if (count < (i = counter.incrementAndGet())) return;
        log.debug(Level.DEBUG + ": " + i);
        if (count < (i = counter.incrementAndGet())) return;
        log.trace(Level.TRACE + ": " + i);
      }
    }
  }
}

Результаты:

Код: plaintext
1.
2.
3.
4.
5.
 (for %A in (1 10 50 100 500) do @java -cp bin;classes Test %A)|find "|Test run "
2015-11-17 22:39:57.535 +0800|FATAL|main|Test|Test run 1000000 iteration on 1 threads in 6396 msec
2015-11-17 22:40:05.527 +0800|FATAL|main|Test|Test run 1000000 iteration on 10 threads in 6429 msec
2015-11-17 22:40:13.657 +0800|FATAL|main|Test|Test run 1000000 iteration on 50 threads in 6583 msec
2015-11-17 22:40:22.225 +0800|FATAL|main|Test|Test run 1000000 iteration on 100 threads in 7067 msec
2015-11-17 22:40:30.246 +0800|FATAL|main|Test|Test run 1000000 iteration on 500 threads in 6474 msec

Если я нигде не накосячил (судя по файловому логу - не накосячил), то, в нулевом приближении, AsycnLogger - вполне эффективен.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39106025
Dymytry
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем большое спасибо!

Пойду изучать исходники библиотек логгирования.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39106650
Сергей Арсеньев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IMHO логгирование показывает весь блеск и нищету кофе-машины.

С одной стороны JIT. Казалось бы сделай макросы условную компиляции управляемые из Runtime. И при их изменении инвалидируй скомпилированный код использовавший их и компилируй заново.

Ан нет.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39106712
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей АрсеньевIMHO логгирование показывает весь блеск и нищету кофе-машины.

С одной стороны JIT. Казалось бы сделай макросы условную компиляции управляемые из Runtime. И при их изменении инвалидируй скомпилированный код использовавший их и компилируй заново.

Ан нет.
Тут кофеварка непричём. Подобный антипаттерн еще легче воспроизводить в языках и системах с двухэтапной компилляцией.
А как вариант можно сделать как в ojdbc. Собрать два варианта библиотек. ojdbc_g где включено JUL и ojdbc где вызовы
логгеров отсутствуют. В конце-концов манипулирование логами уровня трейс это достаточно специфичная задача
и ее можно вынести в цикл конфигурирования приложения.

Управляемая компилляция из Runtime это мега-круто но ненужно. Это ... как ипошить по птичкам из САУ.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39106738
Сергей Арсеньев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonТут кофеварка непричём. Подобный антипаттерн еще легче воспроизводить в языках и системах с двухэтапной компилляцией.

Ну рвет твои шаблоны экстремальное логгирование. Но это не значит, что это что-то не реализуемое.

В принципе, при наличии многопоточного логгера и независимого вввода-вывода для лога. Можно добиться того, что основной поток будет испытывать минимальные осложнения от включения-выключения логгирования на лету. Основной оверхед будет в генерации параметров для log.debug(...) и т.п.

Собственно есть некоторый плюс от этого - меньше возмущений при включении, проще поймать плавающий баг.

Но если нужна максимальная производительность, то надо убирать генерацию параметров. А это без динамического компилирования - только компиляцией для всех уровней. Каждого класса. И соответствующего class loader.

Самое смешное, что в кофемашине, обычно, есть динамическая компиляция. Но программиста до нее не допускают. :)
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39106833
Partisan M
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DymytryПойду изучать исходники библиотек логгирования.

Значит, слова на объяснения потрачены зря, потому что у афтара желание заниматься фигнёй не пропало.
Надо изучать руководства по библиотекам логирования, из них можно много чего узнать для пользования. Нет большого смысла в изучении исходников, т.к. можно смело предположить, что авторы популярных библиотек умеют программировать не хуже, чем афтар ненужного теста для их изобличения, раз логирование для него непривычно.

Сергей АрсеньевIMHO логгирование показывает весь блеск и нищету кофе-машины.
Мне оно показывает только результат логирования. Блеск и нищета если и есть, то не интересуют.


Да, забыл. При выводе по формату на скорость может влиять выбор форматов.
Например, в log4j для даты (%d) автор рекомендует один из форматов - ABSOLUTE, DATE, ISO8601. Можно задать любой, представимый с помощью SimpleDateFormat, но другие по мнению автора медленнее. Он очевидно измерял, а я нет и эту рекомендацию соблюдаю не всегда, больше обращаю внимание на удобство.

Также он предупреждает о возможной медлительности элементов формата C, F, l, L, M.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39107032
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей АрсеньевОсновной оверхед будет в генерации параметров для log.debug(...) и т.п.Можно озвучить экзотическую конфигурацию, где ввод-вывод перестал быть узким местом?Самое смешное, что в кофемашине, обычно, есть динамическая компиляция. Но программиста до нее не допускают. :)А вы уже научились использовать серверную JVM?
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39107070
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
К вопросу об охрененных затратах на обработку параметров:
Код: plaintext
1.
2.
3.
4.
5.
6.
> for %A in (1 50 100 500 1000 5000) do @java -cp bin;classes Test %A
Test run 1000000 iteration on 1 threads in 1357 msec
Test run 1000000 iteration on 50 threads in 1420 msec
Test run 1000000 iteration on 100 threads in 1466 msec
Test run 1000000 iteration on 500 threads in 1513 msec
Test run 1000000 iteration on 1000 threads in 1327 msec
Test run 1000000 iteration on 5000 threads in 2605 msec
Test.java
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
import java.util.concurrent.atomic.AtomicInteger;

public class Test
{
  private final static int
    THREADS_MIN = 1
  , THREADS_MAX = 5000
  , THREADS_DEFAULT = 10
  , COUNTER_MIN = 1000
  , COUNTER_MAX = 1000000
  , COUNTER_DEFAULT = COUNTER_MAX;
  
  final static LogManager logMgr = new LogManager();
  private final static Logger log = logMgr.getLogger(Test.class);
  
  static int threads = THREADS_DEFAULT;
  static int count = COUNTER_DEFAULT;
  static AtomicInteger counter = new AtomicInteger(0);

  public static void main(String[] args) throws InterruptedException
  {
    try { threads = Integer.parseInt(args[0]); }
    catch (RuntimeException e) {};
    if (threads < THREADS_MIN) threads = THREADS_MIN;
    if (threads > THREADS_MAX) threads = THREADS_MAX;

    try { count = Integer.parseInt(args[1]); }
    catch (RuntimeException e) {};
    if (count < COUNTER_MIN) count = COUNTER_MIN;
    if (count > COUNTER_MAX) count = COUNTER_MAX;
    
    Thread[] loggers = new Thread[threads];
    for (int i = 0; i < threads; i++) loggers[i] = new Thread(new LogPlain());
    long timer = System.currentTimeMillis();
    for (Thread logger : loggers) logger.start();
    for (Thread logger : loggers) logger.join();
    timer = System.currentTimeMillis() - timer;
    logMgr.shutdown();
    System.err.println("Test run " + count + " iteration on " + threads + " threads in " + timer + " msec");
  }
  
  private static class LogPlain implements Runnable
  {
    private final static Logger log = logMgr.getLogger(LogPlain.class);
    @Override public void run()
    {
      int i;
      for (;;)
      {
        if (count < (i = counter.incrementAndGet())) return;
        Thread.yield();
        log.fatal(Level.FATAL + ": " + i + " " + Thread.currentThread());
        if (count < (i = counter.incrementAndGet())) return;
        log.error(Level.ERROR + ": " + i);
        if (count < (i = counter.incrementAndGet())) return;
        log.warn (Level.WARN + " : " + i);
        if (count < (i = counter.incrementAndGet())) return;
        log.info (Level.INFO + " : " + i);
        if (count < (i = counter.incrementAndGet())) return;
        log.debug(Level.DEBUG + ": " + i);
        if (count < (i = counter.incrementAndGet())) return;
        log.trace(Level.TRACE + ": " + i);
      }
    }
  }
}

log4j.xml
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
<?xml version="1.0" encoding="windows-1251"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">

<log4j:configuration debug="false">

  <appender name="console" class="org.apache.log4j.ConsoleAppender">
    <param name="Threshold" value="fatal" />
    <layout class="org.apache.log4j.EnhancedPatternLayout">
      <param name="ConversionPattern" value="|%d{yyyy-MM-dd HH:mm:ss.SSS Z}|%-5p|%t|%c|%m%n%throwable{short}" />
    </layout>
  </appender>

  <appender name="null" class="org.apache.log4j.varia.NullAppender">
    <layout class="org.apache.log4j.EnhancedPatternLayout">
      <param name="ConversionPattern" value="|%d{yyyy-MM-dd HH:mm:ss.SSS Z}|%-5p|%t|%c|%m%n" />
    </layout>
  </appender>

  <appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
    <appender-ref ref="null" />
    <!-- appender-ref ref="file" / -->
    <!-- appender-ref ref="console"/ -->
  </appender>

  <appender name="file" class="org.apache.log4j.FileAppender">
    <param name="File" value="Test.log" />
    <param name="Append" value="false" />
    <layout class="org.apache.log4j.EnhancedPatternLayout">
      <param name="ConversionPattern" value="|%d{yyyy-MM-dd HH:mm:ss.SSS Z}|%-5p|%c|%t|%m%n" />
    </layout>
  </appender>

  <root>
    <priority value="trace"/>
    <appender-ref ref="ASYNC"/>
  </root>

</log4j:configuration>

...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39107074
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В предыдущем примере уровень логирования был "trace", ставим "off" ничего более не меняя:
Код: plaintext
1.
2.
3.
4.
5.
6.
> for %A in (1 50 100 500 1000 5000) do @java -cp bin;classes Test %A
Test run 1000000 iteration on 1 threads in 343 msec
Test run 1000000 iteration on 50 threads in 437 msec
Test run 1000000 iteration on 100 threads in 515 msec
Test run 1000000 iteration on 500 threads in 702 msec
Test run 1000000 iteration on 1000 threads in 983 msec
Test run 1000000 iteration on 5000 threads in 1763 msec
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39107413
Сергей Арсеньев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovМожно озвучить экзотическую конфигурацию, где ввод-вывод перестал быть узким местом?
Если вывод в журнал идет на отдельный канал ввода-вывода с независимым массивом дисков и основной поток занят работой, а не только сбросом информации в журнал. То могут быть ситуации, когда ввод-вывод журнала не будет узким местом. Но конечно не панацея.
Basil A. SidorovСамое смешное, что в кофемашине, обычно, есть динамическая компиляция. Но программиста до нее не допускают. :)А вы уже научились использовать серверную JVM?
Нет. Я конечно представляю себе как встроить препроцессор который будет высматривать в коде макросы условной компиляции перед передачей их javac и как устроить инвалидацию загруженных классов в класслоадере и подсовывание прошедших компиляцию через препроцессор. Но чисто теоретически. На практике до такой фигни руки не доходили. И вряд ли дойдут.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39107900
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей АрсеньевЕсли вывод в журнал идет на отдельный канал ввода-вывода с независимым массивом дисков и основной поток занят работой, а не только сбросом информации в журнал... то в этом случае логирование нас вряд ли нагружает и без выкрутасов.Нет. Я конечно представляю себе как встроить препроцессор который будет высматривать в коде макросы условной компиляции перед передачей их javac и как устроить инвалидацию загруженных классов в класслоадере и подсовывание прошедших компиляцию через препроцессор. Но чисто теоретически. На практике до такой фигни руки не доходили. И вряд ли дойдут.Когда мне захотелось сделать так, чтобы отладочная версия приложения собиралась отдельно, чтобы я определил "public final static" флаги и сделал обёртку, которая начиналась с "if (глобально | локально) return;".
Это позволяло глобально включить отладку или глобально отключить, но включить в отдельной иерархии классов.
Обёртка делала, разумеется, делала несколько больше, чем (примитивное) управление сборкой и однострочная выдача.
Не так кошерно, как препроцессор и сохраняет все недостатки раздельной сборки realease/debug, но имеет право на жизнь и не требует никаких извращений.

Это я всё к тому, что иногда "желание странного" должно наказываться. Чтобы не желали.

P.S. Серверная JVM умеет генерировать более оптимальный (машинный) код, а не то, что вы подумали.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39108033
Сергей Арсеньев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovКогда мне захотелось сделать так, чтобы отладочная версия приложения собиралась отдельно
Это то понятно.

Я про вариант включить отладку в каком-нибудь наборе классов, назовем его драйвером, на лету. И выключить, когда стало понятно в чем дело.

Вариант 1. Статический - логгер всегда вызывается и ему передаются параметры, а уж он сам внутри разбирает, надо или нет отсюда принимать сообщения.

Вариант 2. Динамический. Часть кода вызывающая логгер включается и выключается. Блеск джавы в том, что это можно провернуть практически из коробки, в отличии от статически компилирующих систем. А нищета в том, что это "моветон" и поэтому надо очень постараться, чтобы такое провернуть.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39108129
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей АрсеньевЯ про вариант включить отладку в каком-нибудь наборе классов, назовем его драйвером, на лету. И выключить, когда стало понятно в чем дело"... ты только не обижайся" (ц) х/ф "Мимино".
Не знаю почему это не сделано искаропки, но достаточно дёрнуть configureAndWatch и настройки протоколирования будут меняться по мере надобности.
Насколько мне известно, log4j 1.x может терять сообщения при такой перенастройке, но не факт, что это критично.
Т.е. мы опять приходим к тому, что есть рабочее решение, но хочется изобрести своё.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39108371
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Странно что в топике никто не вспомнил про шаблон Strategy.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39108713
Сергей Арсеньев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovТ.е. мы опять приходим к тому, что есть рабочее решение, но хочется изобрести своё.
Еще раз в log4j есть коробочное решение позволяющее в этом фрагменте кода
Код: java
1.
logger.debug("i="+i);


не выполнять
Код: java
1.
"i="+i


если установлен уровень, при котором debug игнорируется?
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39109239
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей АрсеньевЕще раз в log4j есть коробочное решение позволяющее в этом фрагменте кодаЕщё раз - вы уже продемонстрировали, что это критично?

P.S. Я, как бы, шесть лет администрировал промышленную систему, где на практически каждую ошибку разработчики отвечали "требуются отладочные логи".
И всего один раз, когда им требовалось прикрыть честь мундира, среди прочих придирок было указано, что их волшебный пузырёк в виде собственного аппендера не использовался и это, якобы, создало фатальные проблемы.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39110947
Сергей Арсеньев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. Sidorov,

Мы рассматриваем теоретическую возможность или практику.
На практике чаще всего, если не перегибать палку с полным протоколированием каждого чиха это действительно редко важно.
Ну разве что сериализация объекта i в методе toString() не занимает пол часа. :)

С точки зрения большинства реальных задач, не требующих максимальной производительности, как я уже писал, гораздо лучше, чтобы логгер не изменял своего влияния на работающую систему, чем не оказывал его, когда не надо. Поэтому задача ТС про нетормозящее логгирование, для меня больше академическая, чем реальная.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39111012
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На самом деле логгирование высоконагруженных участков кода - это
в корне неверная идея. Что там ловим?

Я-бы предложил завести целочисленные счетчики в code-blocks и вести учёт количества
событий. Тоесть если ставится вопрос - а были ли исключения класса Х или ошибки типа
Y или срабатывал ли кейс Z - то этот вариант успешно работает.

Сбрасывать состояние счётчиков можно в обычный лог по времени (раз в сутки),
по финализатору или по спец-методам деструкции для контейнеров
или по "кнопке" если есть JMX.

Мой вариант отчёта - всегда компактен не флудит простынями текстовых файлов и
самое главное - он не ударяет по производительности.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39111039
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonНа самом деле логгирование высоконагруженных участков кода - это
в корне неверная идея
+1
Хотя это противоречит теме)).
ЗЫ. Например в SSO сервере шибболе, есть замечательная возможность в рантайме включить нужный уровень логирования.
И через минут 10 у вас побегут более подробные логи.
Подебажили и выключили.
Да, противоречит топику, но ...красиво.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39111054
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я готов удивиться вместе с вами. И поцокать языком. Но обычно
у меня подобные задачи возникали всего пару раз в жизни.
Первое - была проверка гипотезы. Заходим-ли мы в if- блок
хотя-бы раз в месяц. Это был баг безопасности. И я его подтвердил.
За месяц было 2-3 события.

Второе - был сбор статистики. Нужно было учесть каких событий
в процентном соотношении больше. События не фиксировались в БД
и был вариант реализовать это только в java-коде. Реализовал.
Посчитали. Фиксировать в логах было невыгодно т.к. high-лоад
и админы паниковали. Насчёт места.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39111124
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonНа самом деле логгирование высоконагруженных участков кода - это
в корне неверная идеяНа самом деле неверной является идея, что некоторые участки кода табуированы для протоколирования.
У протоколирования есть вполне конкретные практические задачи.
Конкретно программистов, обычно, касается задача "найти ошибку постфактум".Что там ловим?Что надо, то и ловим.
И это может быть и заранее предусмотренный сценарий и "затычка по месту на конкретную проблему".Мой вариант отчёта - всегда компактен не флудит простынями текстовых файлов и самое главное - он не ударяет по производительности."Маша наклеила девяносто марок, а профессор - только десять. Но зато все правильно" (ц) Е.Успенский, "Двадцать пять профессий Маши Филипенко".
Компактным должен быть тот протокол, по которому персонал, эксплуатирующий систему получает информацию о работе этой системы.
А вот если ищем ошибку, то компактность отходит на второй план.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39111137
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей АрсеньевМы рассматриваем теоретическую возможность или практикуПрактику.гораздо лучше, чтобы логгер не изменял своего влияния на работающую систему, чем не оказывал его, когда не надо"Мы пойдём простым логическим ходом".
Максимально возможный уровень детализации, обычно, trace. Изредка - all.
Предлагаете сохранить все накладные расходы на трассировку для уровня info?
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39111149
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
тут несколько моментов :

1) Это разные подходы между :

Код: java
1.
2.
3.
      
System.out.println("");
System.err.println("");



разное потоки - разное выполнение ...
2) кошерное оформление теста :


Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
  import java.util.concurrent.TimeUnit;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.infra.Blackhole;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import ru.stoloto.isalnikov.benchmarkfactorial.Factorial;



@Warmup(iterations = 5)
@Measurement(iterations = 10)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
@Fork(2)
public class Test
{
  final static LogManager logMgr = new LogManager();
  final static Logger log = logMgr.getLogger(Test.class);
  
  
  
    @Param({"10", "100", "1000", "10000", "50000", "100000"})
    private int n;
   
   
    public int logger(int n) {

        for (int i = 0; i < n; i++) {
            log.trace(Level.TRACE + ": " + i);
            log.debug(Level.DEBUG + ": " + i);
            log.info(Level.INFO + " : " + i);
            log.warn(Level.WARN + " : " + i);
            log.error(Level.ERROR + ": " + i);
            log.fatal(Level.FATAL + ": " + i);
        }

        logMgr.shutdown();
        return 0;
    }
  
    @Benchmark
    public void log(Blackhole bh) {
        bh.consume(logger(n));
    }
   
   
  public static void main(String[] args)  throws RunnerException 
  {

   
              
      Options opt = new OptionsBuilder()
              .include(Factorial.class.getSimpleName())
              .forks(1)
              .build();

      new Runner(opt).run();
      
  }
}
     




# Run progress: 83,33% complete, ETA 00:00:15
# Fork: 1 of 1
# Warmup Iteration 1: log4j:WARN No appenders could be found for logger (ru.stoloto.isalnikov.benchmarkfactorial.AATest).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
91,891 ms/op
# Warmup Iteration 2: 66,285 ms/op
# Warmup Iteration 3: 73,935 ms/op
# Warmup Iteration 4: 62,913 ms/op
# Warmup Iteration 5: 63,678 ms/op
Iteration 1: 61,813 ms/op
Iteration 2: 63,478 ms/op
Iteration 3: 62,874 ms/op
Iteration 4: 63,440 ms/op
Iteration 5: 62,798 ms/op
Iteration 6: 63,161 ms/op
Iteration 7: 63,945 ms/op
Iteration 8: 63,840 ms/op
Iteration 9: 66,408 ms/op
Iteration 10: 63,668 ms/op


Result "log":
63,543 ±(99.9%) 1,791 ms/op [Average]
(min, avg, max) = (61,813, 63,543, 66,408), stdev = 1,185
CI (99.9%): [61,752, 65,333] (assumes normal distribution)


# Run complete. Total time: 00:01:32

Benchmark (n) Mode Cnt Score Error Units
AATest.log 10 avgt 10 0,007 ± 0,002 ms/op
AATest.log 100 avgt 10 0,057 ± 0,002 ms/op
AATest.log 1000 avgt 10 0,591 ± 0,076 ms/op
AATest.log 10000 avgt 10 5,968 ± 0,144 ms/op
AATest.log 50000 avgt 10 31,255 ± 0,839 ms/op
AATest.log 100000 avgt 10 63,543 ± 1,791 ms/op



3) когда вывод в лог пишется как конкатенация - такой код всегда будет выполняться - даже если перед ним будет стоять условие if( тут нужно проверить ) в отличии от форматного кода ... через % - который выполняется в момент вызова -

замените :
Код: java
1.
logger.debug("i="+i);



на

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
  log.debug("i= %d", i);

или String.format("i= %d", 5) ;

+  добавить для наглядности 

if(log.isDebugEnabled()){
}




перепишите заново тесты и будет вам счастье :) + результаты тестов сюда - на обозрение ;)
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39111155
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
4) логгирование через аспекты (АОП / Proxy ) (+ включение/выключение логгирования , когда это требуется )
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39111157
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Atum13) когда вывод в лог пишется как конкатенация - такой код всегда будет выполняться - даже если перед ним будет стоять условие if( тут нужно проверить )Вы уверены:
Код: sql
1.
if (false) синтаксически.корректная.фигня(разная, фигня);

?
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39111188
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovКомпактным должен быть тот протокол, по которому персонал, эксплуатирующий систему получает информацию о работе этой системы.А вот если ищем ошибку, то компактность отходит на второй план.
Вася. Я совершенно не понял твой сарказм.
И я буду настаивать на своей правоте в рамках
решаемых в этом форуме задач. Давай побольше
примеров (хороших и разных) и непредвзятых
и я буду думать как с помощью учёта вхождений в
codeblocks получить любую ценную для тебя и для нас
информацию по ошибкам.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39111218
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovAtum13) когда вывод в лог пишется как конкатенация - такой код всегда будет выполняться - даже если перед ним будет стоять условие if( тут нужно проверить )Вы уверены:
Код: sql
1.
if (false) синтаксически.корректная.фигня(разная, фигня);

?

Где то был тест на сам if - (как вариант - задачка на n мерные матрицы
с кучей вложенных форов и проверками на if / сложности n3 и выше)

так вот сам тест на if - (сама операция сравнения , тоже может сильно тормозить , иногда кто то предлагаю вместо if бросать исключение - но оно кажись тормозит еще больше ... сам if так же писать нужно правильно - раньше советовали сравнивать с 0 как самый быстрый if ... )

ps

конечно я не уверен ... искать нужно ... и проверять ... где то давным давно читал ... но если и наврал то без обид ...

но очень похоже на правду ...


if - тормозит
и тормозит конкатенация это 100% - которую нужно заменить на формат ... - который даёт первоманс ...
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39111265
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Atum1, припомни плиз условие этой задачки. Там суть наверное не в if была а в изменении
сложности.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39111286
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonAtum1, припомни плиз условие этой задачки. Там суть наверное не в if была а в изменении
сложности.

не именно в if - просто когда if ов много - это реально они реально торомозят т.к. это такты , это лишние проверки итд ...
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39111301
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Atum1просто когда if ов много - это реально они реально торомозят
не верю.
Раз уж у нас академический спор)).
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39111320
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мне тоже не верится.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39111361
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonДавай побольше примеров (хороших и разных) и непредвзятыхНе я заявил об этом баге на вебовском форуме, но наткнувшись на условия, при которых ошибка стабильно воспроизводилась я смог:
1. Доказать, что ошибка вообще есть;
2. Доказать, что ошибка есть в коде, в правильности которого разработчик поначалу не сомневался.
И то и другое потребовало вдумчивого ковыряния в отладочных логах .

На прошлом месте работы было два случая, когда наличие предупреждения "запрос бла-бла-бла исполняется столько-то секунд" позволило выявить и решить две проблемы. Не критичные, но всё-таки.
Был случай когда, наоборот, я просил убрать бессмысленное предупреждение, а несколько позднее точно выяснил , что код, где это предупреждение выдавалось - содержал ошибку.
Про то, что на практически любую ошибку от меня требовали отладочных логов - я уже упоминал.
Это, что вспомнилось, так сказать, с ходу.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39111362
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonМне тоже не верится.

завтра что нибудь придумаю .... :) если вы не троллите :)?!

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.Blackhole;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

@Warmup(iterations = 5)
@Measurement(iterations = 10)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
@Fork(2)
public class IfTest {

    @Param({"1000", "2500"})
    private int n;

    public static int iftest1(int n) {
        int result = 0;
        for (int i = 0; i < n; i++) {
            if (i < n) {
                for (int j = 0; j < n; j++) {
                    if (j < n) {
                        for (int k = 0; k < n; k++) {
                            if (i == j) {
                                if (j == k) {
                                    result++;
                                }
                            }

                        }
                    }

                }
            }

        }
        return result;
    }


    public static int iftest2(int n) {
        int result = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                for (int k = 0; k < n; k++) {
                    if (i == j) {
                        if (j == k) {
                            result++;
                        }
                    }

                }
            }

        }
        return result;
    }
    
    
        public static int iftest3(int n) {
        int result = 0;
        for (int i = 0; i < n; i++) {
            if (i - i == 0) {
                for (int j = 0; j < n; j++) {
                    if (j -j == 0) {
                        for (int k = 0; k < n; k++) {
                            if (i == j) {
                                if (j == k) {
                                    result++;
                                }
                            }

                        }
                    }

                }
            }

        }
        return result;
    }

    @Benchmark
    public void testIftest1(Blackhole bh) {
        bh.consume(iftest1(n));
    }

    @Benchmark
    public void testIftest2(Blackhole bh) {
        bh.consume(iftest2(n));
    }
    @Benchmark
    public void testIftest3(Blackhole bh) {
        bh.consume(iftest3(n));
    }

    public static void main(String[] args) throws RunnerException {

        Options opt = new OptionsBuilder()
                .include(IfTest.class.getSimpleName())
                .forks(1)
                .build();

        new Runner(opt).run();
    }

}



тут самое главное понять выбросит компилятор проверки или нет ...
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39111366
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
# Run complete. Total time: 00:03:02

Benchmark (n) Mode Cnt Score Error Units
IfTest.testIftest1 1000 avgt 10 1,306 ± 0,023 ms/op
IfTest.testIftest1 2500 avgt 10 8,069 ± 0,359 ms/op
IfTest.testIftest2 1000 avgt 10 1,009 ± 0,015 ms/op
IfTest.testIftest2 2500 avgt 10 6,235 ± 0,218 ms/op
IfTest.testIftest3 1000 avgt 10 1,000 ± 0,009 ms/op
IfTest.testIftest3 2500 avgt 10 6,083 ± 0,058 ms/op
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39111367
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Atum1просто когда if ов много - это реально они реально торомозятВы, блин, контекст не теряйте - чтобы условный оператор тормозил на фоне тормозов ввода-вывода ...
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39111369
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Atum1тут самое главное понять выбросит компилятор проверки или нет ...В чём проблема глянуть байт код через (уже) ява-пюре JD-GUI ?
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39111454
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Atum1, дык... здесь не if тормозит а его тело. Ну ты шутник блин.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39111555
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. Sidorov, примеры хорошие. Но я акцентировал внимание когда
код-под нагрузкой. События генерируются миллионы раз в секунду.
Либо нет места куда писать (прошивка сетевого устройства).

P.S. Я не против логов вообще. Я даже их большой любитель.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39111595
uid unique
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot Partisan M]DymytryРешил на досуге изучить вопрос влияния логгирования на производительность.

2) Задать, чтобы команды логирования срабатывали только при достаточном уровне.
Например, в log4j (или LogBack) это будет выглядеть как:

Код: java
1.
2.
3.
if (logger.isDebugEnabled()) {
    logger.debug(какое-то сообщение);
}



Эта предосторжность может иметь смысл, если для создания сообщения требуется существенная работа.
3) Вместо log4j (самая популярная библиотека) по возможности использовать LogBack (автор log4j и LogBack утверждает, что LogBack быстрее. Я не проверял).

1. в LogBack есть асинхронное логирование (с кешем) - заметно быстрее при большой нагрузке, но лог файлы обновляются большими кусками;
2. Используйте slf4j фасад от того же автора (он работает и с log4j и с другими логгерами через редиректоры) - в нем не нужно тащить if (logger.isDebugEnabled()) так как поддерживаются темплейты и строка не склеиваться перед вызовом - поддерживается до 4х позиций в темплайте - к примеру - logger.debug("Some param={} and another param={}", param1, param2);
3. Можете попробовать грязный хак - если используете разные билды - для дебаггинга и для продакшн - if(DEBUG_BUILD_STATIC_BOOLEAN) { logger.debug("message"); } - При компиляции javac его может выпилить.

Для таких злобных циклов не вижу смысла логгировать миллион одинаковых строчек с одним полезным словом, удобнее собрать массив и потом уже его вывести в 10 или 16-ричном формате (матрицу), как в excel.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39111784
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonAtum1, дык... здесь не if тормозит а его тело. Ну ты шутник блин.

=)
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39111916
Сергей Арсеньев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovВы, блин, контекст не теряйте - чтобы условный оператор тормозил на фоне тормозов ввода-вывода ...
Мы же договорились, что ввод-вывод мы выкидываем в отдельный поток на отдельный канал ввода-вывода. :)
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39111922
Сергей Арсеньев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И да - выкидывать логику с проверкой установленного уровня логгирования и подключенных аппендеров на верх, перед вызовом logger.debug(...), это как-то моветон.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39112366
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonНо я акцентировал внимание когда код-под нагрузкойВ очередной раз повторю, что на прошлой работе я администрировал промышленную систему регионального уровня. Регион у нас не особо населённый, система не особо нагруженная, но проблем с производительностью логирования - не было. Проблемы с производительностью системы - были, с производительностью логирования - не было.События генерируются миллионы раз в секунду.Теперь давайте вы приводите практический пример. Брать цифры с потолка и я умею.Либо нет места куда писать (прошивка сетевого устройства)Теоретики вы, блин, теоретики ...
Вот когда практикующий админ публиковал на fido-online "методичку" по удалённому обновлению FreeBSD4 до FreeBSD7 - было интересно: человек многое предусмотрел и продумал, а "шить сетевое устройство" ... Ну обновлял я прошивки пары HP LaserJet разных моделей по сети - вообще ничего волнующего и логи не интересны. Вообще.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39112373
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей АрсеньевМы же договорились, что ввод-вывод мы выкидываем в отдельный поток на отдельный канал ввода-вывода. :)Да хоть в dev/nul - я приводил примеры и с null-appender, да и переназначить вывод в "реальный nul" - не проблема.
Только накладные расходы на ввод-вывод это не убирает. Исчезает (только) запись на физическое устройство, а это далеко не всё.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39112486
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Про прошивку ты не понял. Я вообще не то имел в виду.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39112510
uid unique
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей АрсеньевИ да - выкидывать логику с проверкой установленного уровня логгирования и подключенных аппендеров на верх, перед вызовом logger.debug(...), это как-то моветон.
Моветон конечно если вызов намного дороже получается, в log4j примерно так и было - основная стоимость это не проброс наверх и проверка уровня логирования а склейка строки сообщения. Если же склейки сообщения перед вызовом не происходит то не намного дороже но код намного чище и меньше вероятность Copy/Paste ошибки (не то условие в if(logger.is...). Проверка на уровень логирования и склейка сообщения происходит внутри враппера логгера (slf4j).
На данный момент сижу и выпиливаю if для логеров log4j из старого приложения (перевожу на slf4j wrapper).

Изначально поставлена задача некорректно - логирование нагруженного цикла. В этом случае лучше делать дамп массива данных один раз после цикла (или периодически). Подобные задачи у меня были при обработке графики, там приходилось выкидывать все лишнее из циклов, целочисленное деление сплошь и рядом применять (вместо double), а здесь - логи в Loop на миллион циклов. Кто их читать сможет? В многопоточном приложении будет просто лапша перемешанная на миллионы строчек.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39112535
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonПро прошивку ты не понял. Я вообще не то имел в виду.Я всё ещё жду практический пример.

P.S. Если у сетевого устройства нет устройства хранения, то у него есть syslog/SNMP.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39112536
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uid uniqueа здесь - логи в Loop на миллион циклов. Кто их читать сможет?Их не читают.
Смотрят на итоговую строку при разных настройках логгеров и понимают, что log4j совсем не такой страшный, как его малюют.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39112595
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovmaytonПро прошивку ты не понял. Я вообще не то имел в виду.Я всё ещё жду практический пример.

P.S. Если у сетевого устройства нет устройства хранения, то у него есть syslog/SNMP.
Вот тебе еще пример. Видеокодек. Необходимо фиксировать
пропущенные кадры. Кадры с сбойной контрольной суммой
или ошибки синхронизации для VBR.

Что для этого тоже нужно в лог писать?
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39112606
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonВидеокодек.
Необходимо фиксировать пропущенные кадры.
Кадры с сбойной контрольной суммой или ошибки синхронизации для VBR.

Что для этого тоже нужно в лог писать?Или то, что перечислено или "В чём подвох?"

P.S. Непонятно, каким образом в этом примере возникли "миллионы событий в секунду" и "прошивка сетевого устройства".
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39112617
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Test.java
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;
import org.apache.log4j.xml.DOMConfigurator;
import java.util.concurrent.atomic.AtomicInteger;

public class Test
{
  private final static int
    THREADS_MIN = 1
  , THREADS_MAX = 25000
  , THREADS_DEFAULT = 10
  , COUNTER_MIN = 1000
  , COUNTER_MAX = 50000000
  , COUNTER_DEFAULT = 5000000;
  
  final static LogManager logMgr = new LogManager();
  private final static Logger log = logMgr.getLogger(Test.class);
  
  static int threads = THREADS_DEFAULT;
  static int count = COUNTER_DEFAULT;
  static AtomicInteger counter = new AtomicInteger(0);

  public static void main(String[] args) throws InterruptedException
  {
    try { threads = Integer.parseInt(args[0]); }
    catch (RuntimeException e) {};
    if (threads < THREADS_MIN) threads = THREADS_MIN;
    if (threads > THREADS_MAX) threads = THREADS_MAX;

    try { count = Integer.parseInt(args[1]); }
    catch (RuntimeException e) {};
    if (count < COUNTER_MIN) count = COUNTER_MIN;
    if (count > COUNTER_MAX) count = COUNTER_MAX;
    
    Thread[] loggers = new Thread[threads];
    Reporter.print("Test for " + count + " iterations over " + threads + " threads started - ");
    for (int i = 0; i < threads; i++) loggers = new Thread(new LogPlain());
    for (Thread logger : loggers) logger.start();
    for (Thread logger : loggers) logger.join();
    Reporter.print("Test for " + count + " iterations over " + threads + " threads stopped - ");
    logMgr.shutdown();
  }
  
  private static class Reporter
  {
    private final static Logger log = logMgr.getLogger(Reporter.class);
    private static long timer = System.currentTimeMillis();;
    static void print(String msg)
    {
      long now = System.currentTimeMillis();
      long delta = now - timer;
      timer = now;
      log.info(msg + delta + " msec");
    }
  }
  
  private static class LogPlain implements Runnable
  {
    private final static Logger log = logMgr.getLogger(LogPlain.class);
    @Override public void run()
    {
      int i = 0;
      for (;;)
      {
        log.fatal(Level.FATAL + ": " + i);
        if (count < (i = counter.incrementAndGet())) return;
        log.error(Level.ERROR + ": " + i);
        if (count < (i = counter.incrementAndGet())) return;
        log.warn (Level.WARN + " : " + i);
        if (count < (i = counter.incrementAndGet())) return;
        log.info (Level.INFO + " : " + i);
        if (count < (i = counter.incrementAndGet())) return;
        log.debug(Level.DEBUG + ": " + i);
        if (count < (i = counter.incrementAndGet())) return;
        log.trace(Level.TRACE + ": " + i);
        if (count < (i = counter.incrementAndGet())) return;
      }
    }
  }
}

log4j.xml
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
<?xml version="1.0" encoding="windows-1251"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">

<log4j:configuration debug="false">

  <appender name="console" class="org.apache.log4j.ConsoleAppender">
    <param name="Threshold" value="info" />
    <layout class="org.apache.log4j.EnhancedPatternLayout">
      <param name="ConversionPattern" value="|%d{yyyy-MM-dd HH:mm:ss.SSS Z}|%-5p|%m%n%throwable{short}" />
    </layout>
  </appender>

  <appender name="null" class="org.apache.log4j.varia.NullAppender">
    <layout class="org.apache.log4j.EnhancedPatternLayout">
      <param name="ConversionPattern" value="|%d{yyyy-MM-dd HH:mm:ss.SSS Z}|%-5p|%t|%c|%m%n" />
    </layout>
  </appender>

  <appender name="MAIN" class="org.apache.log4j.AsyncAppender">
    <appender-ref ref="null" />
  </appender>

  <appender name="REPORT" class="org.apache.log4j.AsyncAppender">
    <appender-ref ref="console"/>
    <appender-ref ref="file" />
  </appender>

  <appender name="file" class="org.apache.log4j.FileAppender">
    <param name="File" value="Test.log" />
    <param name="Append" value="true" />
    <layout class="org.apache.log4j.EnhancedPatternLayout">
      <param name="ConversionPattern" value="|%d{yyyy-MM-dd HH:mm:ss.SSS Z}|%-5p|%c|%t|%m%n" />
    </layout>
  </appender>

  <logger name="Test$Reporter">
    <level value="info" />
    <appender-ref ref="REPORT"/>
  </logger>

  <root>
    <priority value="trace"/>
    <appender-ref ref="MAIN"/>
  </root>

</log4j:configuration>

результат с комментариями
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
-- LogLevel - OFF
|2015-11-25 00:36:56.571 +0800|INFO |Test$Reporter|main|Test for 5000000 iterations over 1 threads started - 0 msec
|2015-11-25 00:36:57.335 +0800|INFO |Test$Reporter|main|Test for 5000000 iterations over 1 threads stopped - 764 msec
|2015-11-25 00:36:57.650 +0800|INFO |Test$Reporter|main|Test for 5000000 iterations over 10 threads started - 0 msec
|2015-11-25 00:36:58.914 +0800|INFO |Test$Reporter|main|Test for 5000000 iterations over 10 threads stopped - 1264 msec
|2015-11-25 00:36:59.244 +0800|INFO |Test$Reporter|main|Test for 5000000 iterations over 100 threads started - 0 msec
|2015-11-25 00:37:01.101 +0800|INFO |Test$Reporter|main|Test for 5000000 iterations over 100 threads stopped - 1857 msec
|2015-11-25 00:37:01.431 +0800|INFO |Test$Reporter|main|Test for 5000000 iterations over 1000 threads started - 0 msec
|2015-11-25 00:37:02.976 +0800|INFO |Test$Reporter|main|Test for 5000000 iterations over 1000 threads stopped - 1545 msec
|2015-11-25 00:37:03.322 +0800|INFO |Test$Reporter|main|Test for 5000000 iterations over 10000 threads started - 0 msec
|2015-11-25 00:37:07.146 +0800|INFO |Test$Reporter|main|Test for 5000000 iterations over 10000 threads stopped - 3824 msec

-- LogLevel - TRACE
|2015-11-25 00:37:22.640 +0800|INFO |Test$Reporter|main|Test for 5000000 iterations over 1 threads started - 0 msec
|2015-11-25 00:37:28.303 +0800|INFO |Test$Reporter|main|Test for 5000000 iterations over 1 threads stopped - 5663 msec
|2015-11-25 00:37:28.633 +0800|INFO |Test$Reporter|main|Test for 5000000 iterations over 10 threads started - 0 msec
|2015-11-25 00:37:33.204 +0800|INFO |Test$Reporter|main|Test for 5000000 iterations over 10 threads stopped - 4571 msec
|2015-11-25 00:37:33.566 +0800|INFO |Test$Reporter|main|Test for 5000000 iterations over 100 threads started - 0 msec
|2015-11-25 00:37:38.308 +0800|INFO |Test$Reporter|main|Test for 5000000 iterations over 100 threads stopped - 4742 msec
|2015-11-25 00:37:38.670 +0800|INFO |Test$Reporter|main|Test for 5000000 iterations over 1000 threads started - 0 msec
|2015-11-25 00:37:43.881 +0800|INFO |Test$Reporter|main|Test for 5000000 iterations over 1000 threads stopped - 5211 msec
|2015-11-25 00:37:44.274 +0800|INFO |Test$Reporter|main|Test for 5000000 iterations over 10000 threads started - 0 msec
|2015-11-25 00:37:52.448 +0800|INFO |Test$Reporter|main|Test for 5000000 iterations over 10000 threads stopped - 8174 msec
"LogLevel - OFF" означает, что накладные расходы - исключительно на то самое ужасное "соединение строк".
"LogLevel - TRACE" - соединение строк и вывод в NULL-аппендер. Который, как следует из его названия, никуда и ничего не пишет.

Вроде, всё очевидно - если логирование корректно настроено, то:
1. Составлять строчку для сообщения "плюсиками" - нефатально;
2. Накладные расходы на ввод-вывод - достаточно высоки;
3. Протоколирование из многих потоков заметно только тогда, когда этих потоков [i]действительно много
.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39112620
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ладно. Давай на этом закончим. Я просто хотел подытожить что когда мне нужен
перформанс от логгирования я НЕ ЛОГГИРУЮ вообще а веду учёт событий
класса АНАЛИТИКА от лог-файла. До сегодняшнего дня мне это удавалось.
Кроме тех случаев когда в message толкали текстовый файл построчно или нужно
было фиксировать timestamps. Впрочем последнее было крайне редко.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39112625
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Странные вы, всё-таки, люди ...
"Не логирую вообще" и тут же "аналитика лог-файла".
"timestamp нужен крайне редко", хотя формирование этих штампов делает сама библиотека и думать об этом вообще не надо. Вот измерять интервалы, да - "только хардкор".
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39113196
Atum1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
может бинарный лог попробовать? + ssd диски?
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39161807
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не знаю, было ли уже в данной теме. Наткнулся на интересный документ:

Проверка утверждений (assertions) и условная компиляция

В конце статьи приводится пример с условной компиляции. Лично для меня это было новой информацией. Может еще кому интересно будет.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39161842
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Atum1может бинарный лог попробовать?
На запись они одинаковы.

Бинарность была-бы бонусом если-бы нужно были вычитывать
потом из этого файла records по номерам или индексировать.
...
Рейтинг: 0 / 0
Нетормозящее логирование в Джаве.
    #39163180
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid KudryavtsevЛично для меня это было новой информацией 18441954
...
Рейтинг: 0 / 0
72 сообщений из 72, показаны все 3 страниц
Форумы / Java [игнор отключен] [закрыт для гостей] / Нетормозящее логирование в Джаве.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]