powered by simpleCommunicator - 2.0.30     © 2024 Programmizd 02
Map
Форумы / Java [игнор отключен] [закрыт для гостей] / Новый альтернативный Slf4j логгер Бобина
320 сообщений из 320, показаны все 13 страниц
Новый альтернативный Slf4j логгер Бобина
    #39844881
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Приветствую!

4 года не был на сайте.

Хочу порекламировать свой Опер Сорс.
Если запрещено - сливайте плиз.

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

Slf4j логгер «Бобина».

Отличается:
- адской скоростью и маленьким потреблением памяти
- легкой и простой настройкой (в отличии от невменяемых настроек других логгеров)
- умеет писать одновременно сотни лог файлов
- легко (настраивается) пишет отдельные логи на каждый поток

Также работает отлично со Спрингом.

Есть полная документация на него в Вики.

https://github.com/INFINITE-TECHNOLOGY/BOBBIN

Надеюсь он вам понравится и станет основным логгером для вас.
Лично мне он нравится намного больше logback и log4j2...
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845020
Андрей Панфилов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasSlf4j логгер «Бобина».

Отличается:
- адской скоростью и маленьким потреблением памяти
- легкой и простой настройкой (в отличии от невменяемых настроек других логгеров)
- умеет писать одновременно сотни лог файлов
- легко (настраивается) пишет отдельные логи на каждый потокНужно срочно заявку подавать на включение в реестр российского ПО...

BobbinScriptEngine.groovy
Код: java
1.
2.
3.
4.
5.
6.
7.
    SimpleDateFormat dateFormat = new SimpleDateFormat(getDateFormat())

...

    String getDate() {
        return dateFormat.format(new Date())
    }




Не смущает что SimpleDateFormat нифига не потокобезопасный?


FileDestination.groovy
Код: 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.
    BobbinFile currentBobbinFile
....

    @Override
    protected void store(String finalOutputMessageText, Level level, String className, String date) {
        String newFileName = bobbinScriptEngine.evalFileName(level.value(), className, date)
        refreshCurrentFile(newFileName)
        currentBobbinFile.writer.write(finalOutputMessageText)
        currentBobbinFile.writer.flush()
    }

    void refreshCurrentFile(String newFileName) {
        if (currentBobbinFile == null) {
            currentBobbinFile = initFile(newFileName)
        } else {
            if (currentBobbinFile.fileName != newFileName) {
                currentBobbinFile = initFile(newFileName)
            }
        }
    }

    BobbinFile initFile(String fileName) {
        BobbinFile file = new BobbinFile(fileName)
        file.fileName = fileName
        file.getParentFile().mkdirs()
        file.writer = new FileWriter(file, true)
        return file
    }




Если на время забыть, что файловые дескрипторы утекают в неизвестном направлении, этот код потокобезопасный или нет? не будет такого что логи пишутся куда-то не туда?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845052
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Привет Андрей!

Спасибо что посмотрел этот логгер и прокомментировал.

Я уже начал сдаваться, кажется что никому такие вещи не интересны.
А ведь объективно существующие логгеры это каменный век. Это как использовать в Порше (Spring) сиденья от лады.

Насчёт твоего комметария - simpledateformat только «parse» не потокобезопасный.
Format потокобезопасный в нём, так что норм.

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

Этот логгер в первую очередь ориентирован на многопоточные среды с сотнями одновременных потоков. Всё продуманно и проверенно много раз. За каждой кажущейся простотой здесь всегда стоит рефакторинг.


авторНужно срочно заявку подавать на включение в реестр российского ПО...
Я хотел принять в этом участие (только в ОАЭ), но немного опоздал с million arab coders initiative :)
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845056
Андрей Панфилов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasНасчёт твоего комметария - simpledateformat только «parse» не потокобезопасный.
Format потокобезопасный в нём, так что норм.
как-то с трудом верится...

Код: 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.
    // Called from Format after creating a FieldDelegate
    private StringBuffer format(Date date, StringBuffer toAppendTo,
                                FieldDelegate delegate) {
        // Convert input date to time field list
        calendar.setTime(date);

    /**
     * Private member function that does the real date/time formatting.
     */
    private void subFormat(int patternCharIndex, int count,
                           FieldDelegate delegate, StringBuffer buffer,
                           boolean useDateFormatSymbols)
    {
        int     maxIntCount = Integer.MAX_VALUE;
        String  current = null;
        int     beginOffset = buffer.length();

        int field = PATTERN_INDEX_TO_CALENDAR_FIELD[patternCharIndex];
        int value;
        if (field == CalendarBuilder.WEEK_YEAR) {
            if (calendar.isWeekDateSupported()) {
                value = calendar.getWeekYear();
            } else {
                // use calendar year 'y' instead
                patternCharIndex = PATTERN_YEAR;
                field = PATTERN_INDEX_TO_CALENDAR_FIELD[patternCharIndex];
                value = calendar.get(field);
            }
        } else if (field == CalendarBuilder.ISO_DAY_OF_WEEK) {
            value = CalendarBuilder.toISODayOfWeek(calendar.get(Calendar.DAY_OF_WEEK));
        } else {
            value = calendar.get(field);
        }



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

Этот логгер в первую очередь ориентирован на многопоточные среды с сотнями одновременных потоков. Всё продуманно и проверенно много раз. За каждой кажущейся простотой здесь всегда стоит рефакторинг.

Ну баги видны невооруженным взглядом, то что у вы "не видите" не означает что их нет. Сначала неплохо было бы довести до безошибочной работы, а потом сравнивать производительность.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845059
Дмитрий Мух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasА ведь объективно существующие логгеры это каменный век. Это как использовать в Порше (Spring) сиденья от лады.
Так то можно утверждать, что объективно логгеры вообще не нужны. Достаточно stdout и stderr.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845176
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей,

Я вижу что люди с трудом верят Гитхабу (новым проектам), но охотно верят помойке Stackoverflow.

Всё это проверялось и оттачивалось несколько лет, а сам логгер концептуально ведёт историю около 10ти лет.
Это наукоёмкая разработка на самом деле, и инновационная.

Но к сути дела.. SimpleDateFormat.format потокобезопасный. Вот тест:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
import java.text.SimpleDateFormat

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS")
Thread.start {
for (i in 1..10000) {
System.out.println("Thread 1: " + simpleDateFormat.format(new Date()))
}
}
Thread.start {
for (i in 1..10000) {
System.out.println("Thread 2: " + simpleDateFormat.format(new Date()))
}
}



Далее - за каждый найденный баг я плачу 20$ (максимум 100$ общая сумма на всех - т.е. 5 багов, я всё таки не рокфеллер).
Я знаю только 1 маленький баг с выводом в stdout вместо stderr - но он не влияет ни на что на самом деле.

Пользуйтесь этим логгерром, надеюсь он понравится Вам больше чем старьё то что есть.

авторТак то можно утверждать, что объективно логгеры вообще не нужны. Достаточно stdout и stderr.
Не совсем согласен. Нужно слишком много доп. параметров вручную передавать в Stdout - например время и т.д.
Код захламляется.
Но Вы не далеки от истины :)
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845193
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Стандартный JUL был неудачен. Если-бы в тело JDK изначально была бы заложена библиотека
по уровню похожая на Log4j старых олдскульных версий 1.2.х то никакие другие логгеры
вообще нафик не впали.

По поводу мостов между slf4j и slf4j-your-fucken-impl, я бы хотел сказать что высокопроизводительный
логгер приложению вобщем-то не нужен. Потому-что главная задача приложения - делать
полезную работу. А если у вас весь смысл работы сконцетрирован в быстром логгировании и
то вы либо в TRACE mode, что само по себе - редко. Либо логгер выполняет несвойственные
ему задачи (например шлёт месседжи по JMS или Syslog). Всё это - какие-то архитектурные
просчёты и их надо обсуждать на высшем уровне а не оптимизировать кольцевые бобины и
прочие оверинжинеринги.

Если кто-то очень хочет логгированием вести учот статистики к примеру то тут есть JMX и Atomic счетчики и прочие
надстройки которые делают эти задачи эффективнее.

По поводу
Код: java
1.
- адской скоростью и маленьким потреблением памяти


Если быть дотошным - вы не управляете этой памятью. Т.к. тело месседжа всё равно формируется на прикладном
уровне. Поэтому о каком потреблении идёт речь - непонятно. Нужен какой-то тест или демо чтоб показать
что имеется в виду.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845198
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasНо к сути дела.. SimpleDateFormat.format потокобезопасный. Вот тест:

Дружище. Твой тест внутри содержит искусственную задержки. Это вывод на экран.
Я думаю что тебе стоит убрать этот вывод. Создать хотяб-ы 1000 потоков и проверить
гипотезу о том что содержимое ::parse() и ::format() дало взаимное тождество. И конечно
не на константе а на спектре разных дат.

Очень странно что ты не наступал на дефект SimpleDateFormat. Он действительно
был потоко-небезопасный в семерке. Его все нормальные люди оборачивали
ThreadLocal<SimpleDateFormat>.

Так что иди и проверяй очень тщательно.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845201
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторПо поводу мостов между slf4j и slf4j-your-fucken-impl, я бы хотел сказать что высокопроизводительный
логгер приложению вобщем-то не нужен. Потому-что главная задача приложения - делать
полезную работу. А если у вас весь смысл работы сконцетрирован в быстром логгировании и
то вы либо в TRACE mode, что само по себе - редко. Либо логгер выполняет несвойственные
ему задачи (например шлёт месседжи по JMS или Syslog). Всё это - какие-то архитектурные
просчёты и их надо обсуждать на высшем уровне а не оптимизировать кольцевые бобины и
прочие оверинжинеринги.

Про Syslog это Вы в моих тредах за 2013 год прочитали?
https://www.sql.ru/forum/1028371/syslog-rfc5424

Так я собственно и сказал там что Syslog к логгеру никак не относится.

Кстати к вопросу о несвойственности - в Slf4j есть «маркеры» - бизнес функционал чистый.
В «Бобине» это конечно выключено и не поддерживается.

Насчёт производительности - к примеру у вашего заказчика клиринговый файл на 250000 записей.
И его загрузчик на определённых данных даёт неправильный расчёт, скажем задвоение комиссии.
Вы просите заказчика включить трейсы и отправить Вам на анализ.
Вот тут возникает проблема с «производительность логгера не важна».
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845203
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytondakeirasНо к сути дела.. SimpleDateFormat.format потокобезопасный. Вот тест:

Дружище. Твой тест внутри содержит искусственную задержки. Это вывод на экран.
Я думаю что тебе стоит убрать этот вывод. Создать хотяб-ы 1000 потоков и проверить
гипотезу о том что содержимое ::parse() и ::format() дало взаимное тождество. И конечно
не на константе а на спектре разных дат.

Очень странно что ты не наступал на дефект SimpleDateFormat. Он действительно
был потоко-небезопасный в семерке. Его все нормальные люди оборачивали
ThreadLocal<SimpleDateFormat>.

Так что иди и проверяй очень тщательно.
Спасибо за совет, друг.

Есть хорошие новости:

Всё проверено.
С задержками, и без, на 10000000 записей (без шуток).

SimpleDateFormat.format потокобезопасен 100%,
Вызывает проблемы “parse”.

Насчёт задержек это всё очевидные вещи. Естественно я это учёл, и делал разные тесты.
Как учёл и оптимизацию Javac и JRE - принудительно обращался к инициализированным переменным чтобы избежать пропуска неиспользуемого кода для их инициализации.

И вообще - отбросьте сомнения :) Код полностью оттестирован и отточен. Смело качайте!
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845204
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторThreadLocal<SimpleDateFormat>

Это всё проходилось, и даже в Бобине, и было выпилено.

На благо пользователей.

ThreadLocal негативно отображается на эффективности работы GC в контексте веб контейнера, и его нужно избегать по возможности.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845205
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторСтандартный JUL был неудачен. Если-бы в тело JDK изначально была бы заложена библиотека
по уровню похожая на Log4j старых олдскульных версий 1.2.х то никакие другие логгеры
вообще нафик не впали.

По какому уровню Log4j? Совершенно не индустриальная библиотека, которая по стечению обстоятельств и отсутствия альтернатив стала популярной.
У неё совершенно упоротая концепция иерархических логгеров - абсолютно не удобная привязка к уровню логирования.
Непонятно почему нельзя было изначально сделать её нормально.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845206
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторЕсли быть дотошным - вы не управляете этой памятью. Т.к. тело месседжа всё равно формируется на прикладном
уровне. Поэтому о каком потреблении идёт речь - непонятно. Нужен какой-то тест или демо чтоб показать
что имеется в виду.
это если Root логгер выключен.

Как только проходит чуть дальше сообщение - всё, логгер начинает работать и потреблять Java Heap. И тут уже начинает играть роль оптимизация логгера по потреблению памяти.
А также по обеспечению эффективности GC, т.н. memory footprint.

Я запишу видео сравнение с Logback на примере Веб приложения и выложу на этой неделе.
Спасибо, хорошая идея.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845230
Андрей Панфилов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasЯ вижу что люди с трудом верят Гитхабу (новым проектам), но охотно верят помойке Stackoverflow.

Всё это проверялось и оттачивалось несколько лет, а сам логгер концептуально ведёт историю около 10ти лет.
Это наукоёмкая разработка на самом деле, и инновационная.А причем тут стэковерфлоу вообще? Есть код SimpleDateFormat, по коду оно в одном месте пишет в поле protected Calendar calendar , в другом месте оно ожидает прочесть записанные данные, соответственно если пишем из разных потоков, то выходит, что читаем уже мусор - это обычный code review, тут даже никакие тесты не нужны. Ну а если вы не можете правильный тест составить - это уже ваши проблемы, а не ревьювера, вот пример из https://bugs.java.com/bugdatabase/view_bug.do?bug_id=4228335

Код: 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.text.DateFormat;
import java.util.Date;

/**
 * Demonstrate that java.text.SimpleDateFormat is not thread-safe.
 *
 * @author <a href="mailto:###@###.###">Kevin J. Butler</a>
 * @version $Revision: 22$
 */
public class TestDateFormat {

	public static boolean stopping = false;

	static class Tester extends Thread {

		DateFormat dateFormat;

		Date date;

		String expected;

		int failures = 0;

		public Tester(String name, DateFormat df, Date d) {
			super(name);
			this.dateFormat = df;
			this.date = d;
			this.expected = df.format(d);
		}

		public void run() {
			while (!stopping) {
				String newText = dateFormat.format(date);
				if (!newText.equals(expected)) {
					failures++;
					System.err.println(
							Thread.currentThread() + " got " + newText +
									", expected " + expected
					);
				}
			}
		}

	}

	public static boolean testDateFormat(
			DateFormat dateFormat
	) {
		Date d1 = new Date(0);
		Date d2 = new Date();

		Tester t1 = new Tester("Tester1", dateFormat, d1);
		Tester t2 = new Tester("Tester2", dateFormat, d2);

		t1.start();
		t2.start();
		try {
			Thread.sleep(5000);
			stopping = true;
			t1.join();
			t2.join();
		} catch (InterruptedException ex) {
		}
		System.err.println("Thread1.failures = " + t1.failures +
				" Thread2.failures = " + t2.failures
		);
		return t1.failures == 0 && t2.failures == 0;
	}

	public static void main(String[] args) {
		DateFormat dateFormat = DateFormat.getDateInstance();
		System.out.println("Testing with DateFormat object");
		testDateFormat(dateFormat);
	}

}



Код: plaintext
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.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
377.
378.
379.
380.
381.
382.
383.
384.
385.
386.
387.
388.
389.
390.
391.
392.
393.
394.
395.
396.
397.
398.
399.
400.
401.
402.
403.
404.
405.
406.
407.
408.
409.
410.
411.
412.
413.
414.
415.
416.
417.
418.
419.
420.
421.
422.
423.
424.
425.
426.
427.
428.
429.
430.
431.
432.
433.
434.
435.
436.
437.
438.
439.
440.
441.
442.
443.
444.
445.
446.
447.
448.
449.
450.
451.
452.
453.
454.
455.
456.
457.
458.
459.
460.
461.
462.
463.
464.
465.
466.
467.
468.
469.
470.
471.
472.
473.
474.
475.
476.
477.
478.
479.
480.
481.
482.
483.
484.
485.
486.
487.
488.
489.
490.
491.
492.
493.
494.
495.
496.
497.
498.
499.
500.
501.
502.
503.
504.
505.
506.
507.
508.
509.
510.
511.
512.
513.
514.
515.
516.
517.
518.
519.
520.
521.
522.
523.
524.
525.
526.
527.
528.
529.
530.
531.
532.
533.
534.
535.
536.
537.
538.
539.
540.
541.
542.
543.
544.
545.
546.
547.
548.
549.
550.
551.
552.
553.
554.
555.
556.
557.
558.
559.
560.
561.
562.
563.
564.
565.
566.
567.
568.
569.
570.
571.
572.
573.
574.
575.
576.
577.
578.
579.
580.
581.
582.
583.
584.
585.
586.
587.
588.
589.
590.
591.
592.
593.
594.
595.
596.
597.
598.
599.
600.
601.
602.
603.
604.
605.
606.
607.
608.
609.
610.
611.
612.
613.
614.
615.
616.
617.
618.
619.
620.
621.
622.
623.
624.
625.
626.
627.
628.
629.
630.
631.
632.
633.
634.
635.
636.
637.
638.
639.
640.
641.
642.
643.
644.
645.
646.
647.
648.
649.
650.
651.
652.
653.
654.
655.
656.
657.
658.
659.
660.
661.
662.
663.
664.
665.
666.
667.
668.
669.
670.
671.
672.
673.
674.
675.
676.
677.
678.
679.
680.
681.
682.
683.
684.
685.
686.
687.
688.
689.
690.
691.
692.
693.
694.
695.
696.
697.
698.
699.
700.
701.
702.
703.
704.
705.
706.
707.
708.
709.
710.
711.
712.
713.
714.
715.
716.
717.
718.
719.
720.
721.
722.
723.
724.
725.
726.
727.
728.
729.
730.
731.
732.
733.
734.
735.
736.
737.
738.
739.
740.
741.
742.
743.
744.
745.
746.
747.
748.
749.
750.
751.
752.
753.
754.
755.
756.
757.
758.
759.
760.
761.
762.
763.
764.
765.
766.
767.
768.
769.
770.
771.
772.
773.
774.
775.
776.
777.
778.
779.
780.
781.
782.
783.
784.
785.
786.
787.
788.
789.
790.
791.
792.
793.
794.
795.
796.
797.
798.
799.
800.
801.
802.
803.
804.
805.
806.
807.
808.
809.
810.
811.
812.
813.
814.
815.
816.
817.
818.
819.
820.
821.
822.
823.
824.
825.
826.
827.
828.
829.
830.
831.
832.
833.
834.
835.
836.
837.
838.
839.
840.
841.
842.
843.
844.
845.
846.
847.
848.
849.
850.
851.
852.
853.
854.
855.
856.
857.
858.
859.
860.
861.
862.
863.
864.
865.
866.
867.
868.
869.
870.
871.
872.
873.
874.
875.
876.
877.
878.
879.
880.
881.
882.
883.
884.
885.
886.
887.
888.
889.
890.
891.
892.
893.
894.
895.
896.
897.
898.
899.
900.
901.
902.
903.
904.
905.
906.
907.
908.
909.
910.
911.
912.
913.
914.
915.
916.
917.
918.
919.
920.
921.
922.
923.
924.
925.
926.
927.
928.
929.
930.
931.
932.
933.
934.
935.
936.
937.
938.
939.
940.
941.
942.
943.
944.
945.
946.
947.
948.
949.
950.
951.
952.
953.
954.
955.
956.
957.
958.
959.
960.
961.
962.
963.
964.
965.
966.
967.
968.
969.
970.
971.
972.
973.
974.
975.
976.
977.
978.
979.
980.
981.
982.
983.
984.
985.
986.
987.
988.
989.
990.
991.
992.
993.
994.
995.
996.
997.
998.
999.
1000.
1001.
1002.
1003.
1004.
1005.
1006.
1007.
1008.
1009.
1010.
1011.
1012.
1013.
1014.
1015.
1016.
1017.
1018.
1019.
1020.
1021.
1022.
1023.
1024.
1025.
1026.
1027.
1028.
1029.
1030.
1031.
1032.
1033.
1034.
1035.
1036.
1037.
1038.
1039.
1040.
1041.
1042.
1043.
1044.
1045.
1046.
1047.
1048.
1049.
1050.
1051.
1052.
1053.
1054.
1055.
1056.
1057.
1058.
1059.
1060.
1061.
1062.
1063.
1064.
1065.
1066.
1067.
1068.
1069.
1070.
1071.
1072.
1073.
1074.
1075.
1076.
1077.
1078.
1079.
1080.
1081.
1082.
1083.
1084.
1085.
1086.
1087.
1088.
1089.
1090.
1091.
1092.
1093.
1094.
1095.
1096.
1097.
1098.
1099.
1100.
1101.
1102.
1103.
1104.
1105.
1106.
1107.
1108.
1109.
1110.
1111.
1112.
1113.
1114.
1115.
1116.
1117.
1118.
1119.
1120.
1121.
1122.
1123.
1124.
1125.
1126.
1127.
1128.
1129.
1130.
1131.
1132.
1133.
1134.
1135.
1136.
1137.
1138.
1139.
1140.
1141.
1142.
1143.
1144.
1145.
1146.
1147.
1148.
1149.
1150.
1151.
1152.
1153.
1154.
1155.
1156.
1157.
1158.
1159.
1160.
1161.
1162.
1163.
1164.
1165.
1166.
1167.
1168.
1169.
1170.
1171.
1172.
1173.
1174.
1175.
1176.
1177.
1178.
1179.
1180.
1181.
1182.
1183.
1184.
1185.
1186.
1187.
1188.
1189.
1190.
1191.
1192.
1193.
1194.
1195.
1196.
1197.
1198.
1199.
1200.
1201.
1202.
1203.
1204.
1205.
1206.
1207.
1208.
1209.
1210.
1211.
1212.
1213.
1214.
1215.
1216.
1217.
1218.
1219.
1220.
1221.
1222.
1223.
1224.
1225.
1226.
1227.
1228.
1229.
1230.
1231.
1232.
1233.
1234.
1235.
1236.
1237.
1238.
1239.
1240.
1241.
1242.
1243.
1244.
1245.
1246.
1247.
1248.
1249.
1250.
1251.
1252.
1253.
1254.
1255.
1256.
1257.
1258.
1259.
1260.
1261.
1262.
1263.
1264.
1265.
1266.
1267.
1268.
1269.
1270.
1271.
1272.
1273.
1274.
1275.
1276.
1277.
1278.
1279.
1280.
1281.
1282.
1283.
1284.
1285.
1286.
1287.
1288.
1289.
1290.
1291.
1292.
1293.
1294.
1295.
1296.
1297.
1298.
1299.
1300.
1301.
1302.
1303.
1304.
1305.
1306.
1307.
1308.
1309.
1310.
1311.
1312.
1313.
1314.
1315.
1316.
1317.
1318.
1319.
1320.
1321.
1322.
1323.
1324.
1325.
1326.
1327.
1328.
1329.
1330.
1331.
1332.
1333.
1334.
1335.
1336.
1337.
1338.
1339.
1340.
1341.
1342.
1343.
1344.
1345.
1346.
1347.
1348.
1349.
1350.
1351.
1352.
1353.
1354.
1355.
1356.
1357.
1358.
1359.
1360.
1361.
1362.
1363.
1364.
1365.
1366.
1367.
1368.
1369.
1370.
1371.
1372.
1373.
1374.
1375.
1376.
1377.
1378.
1379.
1380.
1381.
1382.
1383.
1384.
1385.
1386.
1387.
1388.
1389.
1390.
1391.
1392.
1393.
1394.
1395.
1396.
1397.
1398.
1399.
1400.
1401.
1402.
1403.
1404.
1405.
1406.
1407.
1408.
1409.
1410.
1411.
1412.
1413.
1414.
1415.
1416.
1417.
1418.
1419.
1420.
1421.
1422.
1423.
1424.
1425.
1426.
1427.
1428.
1429.
1430.
1431.
1432.
1433.
1434.
1435.
1436.
1437.
1438.
1439.
1440.
1441.
1442.
1443.
1444.
1445.
1446.
1447.
1448.
1449.
1450.
1451.
1452.
1453.
1454.
1455.
1456.
1457.
1458.
1459.
1460.
1461.
1462.
1463.
1464.
1465.
1466.
1467.
1468.
1469.
1470.
1471.
1472.
1473.
1474.
1475.
1476.
1477.
1478.
1479.
1480.
1481.
1482.
1483.
1484.
1485.
1486.
1487.
1488.
1489.
1490.
1491.
1492.
1493.
1494.
1495.
1496.
1497.
1498.
1499.
1500.
1501.
1502.
1503.
1504.
1505.
1506.
1507.
1508.
1509.
1510.
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Testing with DateFormat object
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/01/1970, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/01/1970, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/1970, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 01/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester2,5,main] got 01/01/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 05/08/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Thread[Tester1,5,main] got 01/01/2019, expected 01/01/1970
Thread[Tester2,5,main] got 05/08/1970, expected 05/08/2019
Exception in thread "Tester1" java.lang.ArrayIndexOutOfBoundsException: 593
	at sun.util.calendar.BaseCalendar.getCalendarDateFromFixedDate(BaseCalendar.java:453)
	at java.util.GregorianCalendar.computeFields(GregorianCalendar.java:2397)
	at java.util.GregorianCalendar.computeFields(GregorianCalendar.java:2312)
	at java.util.Calendar.complete(Calendar.java:2268)
	at java.util.Calendar.get(Calendar.java:1826)
	at java.text.SimpleDateFormat.subFormat(SimpleDateFormat.java:1119)
	at java.text.SimpleDateFormat.format(SimpleDateFormat.java:966)
	at java.text.SimpleDateFormat.format(SimpleDateFormat.java:936)
	at java.text.DateFormat.format(DateFormat.java:345)
	at TestDateFormat$Tester.run(TestDateFormat.java:37)
Thread1.failures = 622 Thread2.failures = 873

Process finished with exit code 0


dakeirasДалее - за каждый найденный баг я плачу 20$ (максимум 100$ общая сумма на всех - т.е. 5 багов, я всё таки не рокфеллер).
Я знаю только 1 маленький баг с выводом в stdout вместо stderr - но он не влияет ни на что на самом деле.

Перечисляйте на палку andrey.b.panfilov 60$ (там еще файловые дескрипторы текут и запись не в те файлы происходит)
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845300
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Классический сет реализаций таких как LogBack, Log4j2 e.t.c написан на Java.

Наш Робин-Бобин написан на Groovy. И есть у меня теперь сомнения в том
что "адская скорость" имеет место.

Автор, как ты делал бенчмарк?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845405
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Панфилов,

Ок, хороший баг нашёл, спасибо.

andrey.b.panfilov - gmail.com?

Напиши пожалуйста детали других багов.

PS: баг с SimpleDateFormat очень маленький - там различие в 5-10 миллисикунд возникает в логе. Поэтому незаметно.
Но это не хорошо. Я поправлю.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845406
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonКлассический сет реализаций таких как LogBack, Log4j2 e.t.c написан на Java.

Наш Робин-Бобин написан на Groovy. И есть у меня теперь сомнения в том
что "адская скорость" имеет место.

Автор, как ты делал бенчмарк?

Groovy там со статической компиляцией. Т.е. таже самая Java.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845410
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей, в Груви файлы не надо закрывать, он сам их закрывает. Ты про это говорил?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845412
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasmaytonКлассический сет реализаций таких как LogBack, Log4j2 e.t.c написан на Java.

Наш Робин-Бобин написан на Groovy. И есть у меня теперь сомнения в том
что "адская скорость" имеет место.

Автор, как ты делал бенчмарк?

Groovy там со статической компиляцией. Т.е. таже самая Java.
Тоесть это и есть ответ на вопрос о бенчмарке?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845419
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasАндрей, в Груви файлы не надо закрывать, он сам их закрывает. Ты про это говорил?
Лол, то есть все настолько плохо со знаниями? За попытку конечно 5, но тут же не лохи сидят
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845420
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytondakeirasпропущено...


Groovy там со статической компиляцией. Т.е. таже самая Java.
Тоесть это и есть ответ на вопрос о бенчмарке?

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

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

— Тестовый стенд представляет собой гибридное Spring Boot приложение, имеющее около 150 постоянных потоков, как синхронизированных, так и постоянно работающих в фоне.
Он использует JPA, Hibernate, Groovy, REST. Стенд нагружался, влючалось логирование SQL и binding в JPA/Hibernate. Ну и самое главное — стенд использовал библиотеку Blackbox, которая логирует буквально каждый expression в коде бизнес логики. Т.е. вывод примерно 25Мб/с логов. Около 400 одновременно записываемых файлов.

Дальше с Java Visual VM. Анализировалось потребление CPU и особенно памяти и эффективности GC.

Анализировались Heap Dumps, профайлер и разные статистики.

С Бобиной приложение работало ощутимо намного быстрее и меньше потребляло памяти. Конкретных замеров я не делал и не знаю, этично ли это делать лично мне как автору по отношению к другим Опен Сорс разработчикам (Logback).
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845422
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл ник,

вообще отлично. Давайте на личности переходить, оскорблять.

Это типичный современный Российский подход.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845433
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasзабыл ник,

вообще отлично. Давайте на личности переходить, оскорблять.

Это типичный современный Российский подход.
Во-первых я не из России, во-вторых мы на форуме а не на маркетинг-вечеринке, а в-третьих чрезмерная самонадеянность чревата. Одно дело вбросить свою либу и спросить - мол, как оно ребята? Другое дело оголтело втюхивать свою поделку выдавая ее за край передовой мысли.
Попытка сделать что-то новое это хорошо, тут никто и не пытается наехать. А вот то что вы понятия не имеете как писать потокобезопасный код, работать с файлами, писать тесты и мерить перфоманс то тут вы попались с головой, и что вы так удивляетесь негативному фидбэку?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845442
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей,

Я кажется понял твою идею насчёт закрытия файлов. Можно словить too many open files, да?

Надо подумать как закрывать их оптимально, возможно сделаю настраивамый expression "isNeedToCloseFile".
Если закрывать\открывать каждый раз - это будет тормозить.

Это было осмысленное решение не закрывать их.

забыл ник,

где конкретно я попался что не умею писать потокобезопасный код?
Есть minor баг с SimpleDateFormat, который выражается тем что миллисикунды не всегда правильно в файлах пишутся.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845446
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В версии 1.x файлы закрывались и архивировались:

https://github.com/INFINITE-TECHNOLOGY/BOBBIN/blob/ca0fb4d1a5966e7dbe0471be67234422f55c49bc/src/main/groovy/io/infinite/bobbin/destinations/FileDestination.groovy#L79

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
    static void zipAndDelete(File file) {
        final Integer BUFFER_LENGTH = 2048
        if (file.isFile()) {
            new File(file.zipFileName as String).getParentFile().mkdirs()
            FileOutputStream fileOutputStream = new FileOutputStream(file.zipFileName as String)
            ZipOutputStream zipOutputStream = new ZipOutputStream(new BufferedOutputStream(fileOutputStream))
            byte[] bytes = new byte[BUFFER_LENGTH]
            FileInputStream fileInputStream = new FileInputStream(file)
            BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream, BUFFER_LENGTH)
            ZipEntry entry = new ZipEntry(file.getName())
            zipOutputStream.putNextEntry(entry)
            Integer countBytes
            while ((countBytes = bufferedInputStream.read(bytes, 0, BUFFER_LENGTH)) != -1) {
                zipOutputStream.write(bytes, 0, countBytes)
            }
            bufferedInputStream.close()
            zipOutputStream.close()
            file.delete()
        }
    }



Я убрал архивирование, т.к. концептуально это не задача логгера.
Наверное надо вернуть закрытие файлов, когда они точно становятся неиспользуемыми (например при смене даты).
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845447
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras, дорогой друг. Я тебе настойчиво советую провести сравнительное тестирование
твоей бобины с любой другой имплементацией. Если та (другая имплементация) будет
медленной - приводи пример конфигов. Есть масса стероидов как ее разогнать.
Я убежден в этом.

P.S. Груви никогда не был быстрым с точки зрения runtime.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845451
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

ок сделаю, в течении 1 недели.

Насчёт Груви - это устаревшее на 10 лет инфа. С динамической компиляцией он медленней обычное Джавы, но достаточно быстр.
Со статической компиляцией - он одинаковый по скорости с Джавой (Груви код в равнозначный Джава код переводится).
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845484
Kachalov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasЯ убрал архивирование, т.к. концептуально это не задача логгера.
- не вдаваясь в детали, лично за себя скажу, что мне нравится та функциональность которая есть в Log4J - например, когда захотелось отправить логи через JMS в сборщик логов, не пришлось ничего менять в коде приложения
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845488
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasmayton,

ок сделаю, в течении 1 недели.

Насчёт Груви - это устаревшее на 10 лет инфа. С динамической компиляцией он медленней обычное Джавы, но достаточно быстр.
Со статической компиляцией - он одинаковый по скорости с Джавой (Груви код в равнозначный Джава код переводится).
Я попробую поднять свой бенчмарк Groovy в разрезе численных расчетов. Кажется у нас были
какие-то суровые проблемы с этим. В основном касалось не компилляции а динамической типизации.

Как они порешались сегодня - я не знаю. Но по состоянию на года 3 назад они все еще были.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845494
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytondakeirasmayton,

ок сделаю, в течении 1 недели.

Насчёт Груви - это устаревшее на 10 лет инфа. С динамической компиляцией он медленней обычное Джавы, но достаточно быстр.
Со статической компиляцией - он одинаковый по скорости с Джавой (Груви код в равнозначный Джава код переводится).
Я попробую поднять свой бенчмарк Groovy в разрезе численных расчетов. Кажется у нас были
какие-то суровые проблемы с этим. В основном касалось не компилляции а динамической типизации.

Как они порешались сегодня - я не знаю. Но по состоянию на года 3 назад они все еще были.

Так говорю же, у меня используется Статическая Компиляция (аннотаций нет т.к. используется глобальный плагин Gradle для статической компиляции - "Groovy Enterprise Plugin") - все типы статические.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845496
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KachalovdakeirasЯ убрал архивирование, т.к. концептуально это не задача логгера.
- не вдаваясь в детали, лично за себя скажу, что мне нравится та функциональность которая есть в Log4J - например, когда захотелось отправить логи через JMS в сборщик логов, не пришлось ничего менять в коде приложения
Я-же говорю. Встроить в JDK просто одну удачную библиотечку наподобие этой - и конец всем
терзаниям и велосипедам.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845498
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasmaytonпропущено...

Я попробую поднять свой бенчмарк Groovy в разрезе численных расчетов. Кажется у нас были
какие-то суровые проблемы с этим. В основном касалось не компилляции а динамической типизации.

Как они порешались сегодня - я не знаю. Но по состоянию на года 3 назад они все еще были.

Так говорю же, у меня используется Статическая Компиляция (аннотаций нет т.к. используется глобальный плагин Gradle для статической компиляции - "Groovy Enterprise Plugin") - все типы статические.
Я говорю не о компилляции. А о типизации. Я надеюсь ты понимаешь разницу?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845501
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Моё предложение в силе.

Андрей нашёл 1 явный баг (minor) и 1 потенциальный баг с max open files exceeded.
Жду его детали чтобы перевести $.

За каждый найденный баг перевожу 20$, макс 5 багов (100$) - в общей сложности на всех.

Насчёт потокобезопасности - после анализа Ник не найден, я вижу потокобезопасный баг с довольно редкой частотой.
Тоже minor. Готов перевести $.

Итого пока 2 minor бага (потокобезопасность), 1 потенциальный баг с закрытием файлов (мне надо это обдумать).

Теперь прошу всех отписавшихся скачать и поюзать этот логгер.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845502
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

В Груви Статическая компиляция значит Статическую Типизацию.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845504
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Частота записи в не те файлы 1 случай на 27500 строк.
Это в синтетическом тесте. На практике это будет - 1 на миллионы.

Пренебрежимо для логгера.

Won't fix - перформанс дороже.

Но это хороший фидбек и засчитывается как баг.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845505
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras, я проверю. Но мой вопрос к перформансу - по прежнему актуален.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845509
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasЧастота записи в не те файлы 1 случай на 27500 строк.
Это в синтетическом тесте. На практике это будет - 1 на миллионы.

Пренебрежимо для логгера.

Won't fix - перформанс дороже.

Но это хороший фидбек и засчитывается как баг.
Капец... ты классный менеджер

Won't fix...
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845512
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KachalovdakeirasЯ убрал архивирование, т.к. концептуально это не задача логгера.
- не вдаваясь в детали, лично за себя скажу, что мне нравится та функциональность которая есть в Log4J - например, когда захотелось отправить логи через JMS в сборщик логов, не пришлось ничего менять в коде приложения

с Logstash сейчас и так не приходится менять код. Зато работает быстрее чем JMS.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845516
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytondakeirasЧастота записи в не те файлы 1 случай на 27500 строк.
Это в синтетическом тесте. На практике это будет - 1 на миллионы.

Пренебрежимо для логгера.

Won't fix - перформанс дороже.

Но это хороший фидбек и засчитывается как баг.
Капец... ты классный менеджер

Won't fix...

Это обсуждаемо естественно.

Чтобы сделать полностью потокобезопасно - надо добавлять либо synchronized, либо ThreadLocal, либо изобретать что-то.
Первые 2 - замедляют (ThreadLocal так же плохо влияет на GC).

Вопрос - надо ли оно, если на практике почти не проявляется? Зато работает быстрее?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845522
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В космос с тобой лететь нельзя...
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845526
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

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

Сейчас индустриальная стратегия - делать поле логгера статичным в классах.
Это означает повышенную конкуренцию по сравнению с полем экземпляра класса.

А значит - частое переключение лог файла.

Я уже делал разные реализации включая LogFileManager и ThreadLocal - от всего этого GC плохеет.

Я подумаю ещё...
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845528
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не забудь в README.md описать чем ты там жертвуешь в пользу перформанса.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845530
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну быстрее всего логи просто не писать
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845576
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Внёс изменения в соотвествии с рекомендациями уважаемых комментаторов:
- SimpleDateFormat убрал (заменил на FastDateFormat из Apache commons)
- Добавил ThreadLocal для файлов. Теперь будет потокобезопасно, и даже ещё быстрее.
- Добавил закрытие файлов

Это пока не релиз. Я несколько дней это всё погоняю на тестовых проектах.

Посмотрите коммит, есть ли ещё пожелания.

https://github.com/INFINITE-TECHNOLOGY/BOBBIN/commit/1f30913ace83cc283318bd6f77631d8f117357cd

Прошу комментаторов оставить свои детали для paypal.

Прошу всех скачать логгер и начать им пользоваться :)

Он реально очень крут, посоны...
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845700
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
off
Мне вспоминается детская сказка про Толстяка который страдал каннибализмом.



Robbin, a bobbin, the big-bellied Ben,
He ate more meat than threescore men;
He ate a cow, he ate a calf,
He ate a butcher and a half;
He ate a church, he ate a steeple,
He ate the priest and all the people.

В переводе Маршака это звучало примерно так.

Робин Бобин Барабек
Скушал 40 человек...


В данном случае bobbin следовало переводить как "катушка".

Робин - толстая-катушка
Он сожрал - более 60 людей... и так далее.

Вобщем этот slf4j логгер должен ассоциироваться с ужасным канибалом который
поедает коров, священников а так-же здания и сооружения.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845773
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

Бобина это катушка, часть полётного регистратора (чёрного ящика - BlackBox - мой другой проект по автоматическому добавлению логирования в код - если интересно - расскажу о нём).

Также бобина используется для бекапов на ленту (кассета).

Ну и последнее - у меня есть проект Carburetor (AST API), Бобиной так же называют генератор в двигателях.

Так что это исключительно логичное наименование.

Вы скачали логгер?:)
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845803
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нет. Я сейчас хочу вернуться к своему проекту CardRaytracer и посмотреть почему Groovy-версию
трассировщика луча мы оставили в ветке экспериментальных. Возможно он не работал (это один поинт)
или работал медленно (это другой). Но после того как разберусь я смогу показать коеэффициент
перформанса между Java/Groovy на вычислительных операциях и каллбеках.

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

Если у вас есть какие-то дополнения и предложения - буду рад услышать.

P.S. Нет ваш логгер я пока не скачал. Мне непонятна его идея. По крайней мере вы ее
не раскрыли. И брать просто так логгер без идеи я не хочу. Мне это не интересно.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845825
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

Здесь не стоит вопрос быстродействия Груви.
Во первых используется Статическая компиляция, которая равнозначна Java коду (см. ниже), во вторых это не предмет этой темы.
Тех. стек исследован и проверен на быстродействие.

Если интересно ниже класс на Груви и его декомпилированная Java версия. Как видно это обычный Java код.
(Используется @CompileStatic глобально через плагин Gradle)

Groovy класс:
package io.infinite.bobbin.destinations

import io.infinite.bobbin.BobbinFile
import io.infinite.bobbin.Level
import io.infinite.bobbin.config.DestinationConfig
import org.slf4j.helpers.Util

class FileDestination extends Destination {

ThreadLocal<BobbinFile> bobbinFileMap = new ThreadLocal<BobbinFile>()

///////////////////CONSTRUCTOR \/\/\/\/\/\/
FileDestination(DestinationConfig destinationConfig) {
super(destinationConfig)
}
///////////////////CONSTRUCTOR /\/\/\/\/\/\

@Override
protected void store(String finalOutputMessageText, Level level, String className, String date) {
String newFileName = bobbinScriptEngine.evalFileName(level.value(), className, date)
refreshCurrentFile(newFileName)
bobbinFileMap.get().writer.write(finalOutputMessageText)
bobbinFileMap.get().writer.flush()
}

void refreshCurrentFile(String newFileName) {
if (bobbinFileMap.get() == null) {
bobbinFileMap.set(initFile(newFileName))
} else {
if (bobbinFileMap.get().fileName != newFileName) {
bobbinFileMap.get().writer.close()
bobbinFileMap.set(initFile(newFileName))
}
}
}

BobbinFile initFile(String fileName) {
BobbinFile file = new BobbinFile(fileName)
file.fileName = fileName
file.getParentFile().mkdirs()
file.writer = new FileWriter(file, true)
return file
}

static {
Util.report("Bobbin: " + Thread.currentThread().getName().padRight(16) + ": " + "application working dir: " + new BobbinFile("./").getCanonicalPath())
}

}


Он же декомпилирован (Java код):
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package io.infinite.bobbin.destinations;

import groovy.transform.Generated;
import io.infinite.bobbin.BobbinFile;
import io.infinite.bobbin.Level;
import io.infinite.bobbin.config.DestinationConfig;
import java.io.FileWriter;
import org.codehaus.groovy.runtime.ScriptBytecodeAdapter;
import org.codehaus.groovy.runtime.StringGroovyMethods;
import org.slf4j.helpers.Util;

public class FileDestination extends Destination {
private ThreadLocal<BobbinFile> bobbinFileMap;

public FileDestination(DestinationConfig destinationConfig) {
super(destinationConfig);
ThreadLocal var2 = new ThreadLocal();
this.bobbinFileMap = var2;
}

protected void store(String finalOutputMessageText, Level level, String className, String date) {
String newFileName = ((FileDestination)this).getBobbinScriptEngine().evalFileName(level.value(), className, date);
this.refreshCurrentFile(newFileName);
Object var10000 = null;
((FileWriter)((BobbinFile)this.bobbinFileMap.get()).getWriter()).write(finalOutputMessageText);
var10000 = null;
((FileWriter)((BobbinFile)this.bobbinFileMap.get()).getWriter()).flush();
var10000 = null;
}

public void refreshCurrentFile(String newFileName) {
Object var10000;
if (this.bobbinFileMap.get() == null) {
this.bobbinFileMap.set(this.initFile(newFileName));
var10000 = null;
} else if (ScriptBytecodeAdapter.compareNotEqual(((BobbinFile)this.bobbinFileMap.get()).getFileName(), newFileName)) {
((FileWriter)((BobbinFile)this.bobbinFileMap.get()).getWriter()).close();
var10000 = null;
this.bobbinFileMap.set(this.initFile(newFileName));
var10000 = null;
}

}

public BobbinFile initFile(String fileName) {
BobbinFile file = new BobbinFile(fileName);
file.setFileName(fileName);
Object var10001 = null;
((BobbinFile)file).getParentFile().mkdirs();
FileWriter var4 = new FileWriter(file, true);
file.setWriter(var4);
var10001 = null;
return file;
}

static {
Util.report(StringGroovyMethods.plus(StringGroovyMethods.plus(StringGroovyMethods.plus(StringGroovyMethods.plus("Bobbin: ", StringGroovyMethods.padRight(Thread.currentThread().getName(), 16)), ": "), "application working dir: "), ((BobbinFile)(new BobbinFile("./"))).getCanonicalPath()));
Object var10000 = null;
}

@Generated
public ThreadLocal<BobbinFile> getBobbinFileMap() {
return this.bobbinFileMap;
}

@Generated
public void setBobbinFileMap(ThreadLocal<BobbinFile> var1) {
this.bobbinFileMap = var1;
}
}


Касательно идеи - вот это отличный вопрос.

Идея очень простая - использовать нативные булевские выражения на Java/Groovy для настройки уровня логирования и классов.
Например:
Код: java
1.
"levels": "['debug', 'info', 'warn', 'error'].contains(level)"


Код: java
1.
"classes": "className.contains('conf.plugins.input')"



И тоже самое для форматирования:
Код: java
1.
"format": "level.toUpperCase() + ' [' + threadName + '] ' + dateTime + ': ' + message + '\\n'"



Круто, да? Не нужен никакой чудо-синтаксис форматирования Log4j.
Не нужна чудо-концепция иерархических логгеров.

И ещё: имя файла также настраивается:
Код: java
1.
"fileName": "\"./LOGS/THREADS/${threadGroupName}/${threadName}/${level}/${threadName}_${level}_${date}.log\"


Как видно, оно содержит ${threadName} - и другие переменные - вот так лёгким движением руки ОДНА настройка отвечает за создание МНОГИХ файлов.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845830
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasGroovy класс:


Я вот всё никак не мог дойти почитать код. Что-то меня останавливало.
То ли то, что автор оценивает умных людей как идиотов, даже не разоравшись.
То ли что не понимает, что документацию пишуют чтобы читать, а не чтобы высокомерно отвергать.
Но тут понял- человек, неспособный вставить исходник как код- точно не может написать ничего интересного.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845836
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasИдея очень простая - использовать нативные булевские выражения на Java/Groovy для настройки уровня логирования и классов.

А если мне на ходу надо включить TRACE? Без остановки приложения.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845837
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey Tomin,

Где я кого-то высокомерно оценивал? Можно пример или цитату мою?

Я вставил под кат чтобы конкретно Mayton прочитал, и не захламлять тему.

В том же сообщении исходники вставлены как код.

В данном случае (как и в нескольких других в этой теме от других комментаторов) вы переходите на личности, зачем-то подразумеваете мою тупость и пр.

Можно пожалуйста перестать это делать, и обсуждать вопросы по теме?

авторТо ли что не понимает, что документацию пишуют чтобы читать, а не чтобы высокомерно отвергать.
Не совсем понял, вы про какую документацию? Есть Вики, там довольно детально всё описано.
Никто ничего не отвергает.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845838
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytondakeirasИдея очень простая - использовать нативные булевские выражения на Java/Groovy для настройки уровня логирования и классов.

А если мне на ходу надо включить TRACE? Без остановки приложения.

Это опасненько. В Бобине не поддерживается такое сейчас.
Можно обсудить - надо ли такое поддерживать.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845843
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasmaytonпропущено...

А если мне на ходу надо включить TRACE? Без остановки приложения.

Это опасненько. В Бобине не поддерживается такое сейчас.
Можно обсудить - надо ли такое поддерживать.
Стоп-стоп. Родной. Ты о чем?

Это не надо обсуждать. Это надо просто вынести в самый главный поинт. Библиотека логгирования
такая как Log4j например поддерживает смену режима на ходу персонально для каждого логгера.
И еще дает много чего для аппендеров. В принципе имеет конроль над runtime.

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

Даже не скачивая.

Ферштейн?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845854
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytondakeirasпропущено...


Это опасненько. В Бобине не поддерживается такое сейчас.
Можно обсудить - надо ли такое поддерживать.
Стоп-стоп. Родной. Ты о чем?

Это не надо обсуждать. Это надо просто вынести в самый главный поинт. Библиотека логгирования
такая как Log4j например поддерживает смену режима на ходу персонально для каждого логгера.
И еще дает много чего для аппендеров. В принципе имеет конроль над runtime.

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

Даже не скачивая.

Ферштейн?

Log4j не поддерживает перенастройку в рантайме.
https://stackoverflow.com/questions/4598702/dynamically-changing-log4j-log-level

Либо нужно код подгонять, либо JMS, либо небезопасный в веб приложениях configureAndWatch опять же требующий модификацию в коде.

Это нельзя назвать поддержкой.

Так что повторю вопрос: вы правда пользуетесь этим функционалом? У вас он интегрирован? (а он требует интеграции в код)
Если да, то можно дальше подумать над его добавлением, спросить других участников.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845859
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasmaytonпропущено...

Стоп-стоп. Родной. Ты о чем?

Это не надо обсуждать. Это надо просто вынести в самый главный поинт. Библиотека логгирования
такая как Log4j например поддерживает смену режима на ходу персонально для каждого логгера.
И еще дает много чего для аппендеров. В принципе имеет конроль над runtime.

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

Даже не скачивая.

Ферштейн?

Log4j не поддерживает перенастройку в рантайме.
https://stackoverflow.com/questions/4598702/dynamically-changing-log4j-log-level

Либо нужно код подгонять, либо JMS, либо небезопасный в веб приложениях configureAndWatch опять же требующий модификацию в коде.

Это нельзя назвать поддержкой.

Так что повторю вопрос: вы правда пользуетесь этим функционалом? У вас он интегрирован? (а он требует интеграции в код)
Если да, то можно дальше подумать над его добавлением, спросить других участников.

Ну налету конечно не так часто пользуются. Но в нормальной организации тебе никто не даст залить новые артифакты для того чтобы поменять уровень трассировки логов. А вот поменять log4j-конфиг вполне себе можно. И это как сказал mayton - основополагающая штука для любого логера. Или ты думал что все такие тупые а ты один Д'Артаньян?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845860
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasmaytonпропущено...

Стоп-стоп. Родной. Ты о чем?

Это не надо обсуждать. Это надо просто вынести в самый главный поинт. Библиотека логгирования
такая как Log4j например поддерживает смену режима на ходу персонально для каждого логгера.
И еще дает много чего для аппендеров. В принципе имеет конроль над runtime.

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

Даже не скачивая.

Ферштейн?

Log4j не поддерживает перенастройку в рантайме.
https://stackoverflow.com/questions/4598702/dynamically-changing-log4j-log-level

Либо нужно код подгонять, либо JMS, либо небезопасный в веб приложениях configureAndWatch опять же требующий модификацию в коде.

Это нельзя назвать поддержкой.

Так что повторю вопрос: вы правда пользуетесь этим функционалом? У вас он интегрирован? (а он требует интеграции в код)
Если да, то можно дальше подумать над его добавлением, спросить других участников.
На прошлом проекте - пользовался и очень даже. Включал и выключал логгеры и аппендеры.

Что там потоконебезопасно? Приведи пример почему это нельзя.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845862
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл никdakeirasпропущено...


Log4j не поддерживает перенастройку в рантайме.
https://stackoverflow.com/questions/4598702/dynamically-changing-log4j-log-level

Либо нужно код подгонять, либо JMS, либо небезопасный в веб приложениях configureAndWatch опять же требующий модификацию в коде.

Это нельзя назвать поддержкой.

Так что повторю вопрос: вы правда пользуетесь этим функционалом? У вас он интегрирован? (а он требует интеграции в код)
Если да, то можно дальше подумать над его добавлением, спросить других участников.

Ну налету конечно не так часто пользуются. Но в нормальной организации тебе никто не даст залить новые артифакты для того чтобы поменять уровень трассировки логов. А вот поменять log4j-конфиг вполне себе можно. И это как сказал mayton - основополагающая штука для любого логера. Или ты думал что все такие тупые а ты один Д'Артаньян?

Я не понимаю, вы про какие артефакты? Точно также меняется Bobbin.json конфиг.
И ещё раз прошу - пожалуйста не переходите на личности.
Это последнее предупреждение, если ещё раз увижу оскорбительные комментарии - я уйду из этой темы\сайта.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845864
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторНа прошлом проекте - пользовался и очень даже. Включал и выключал логгеры и аппендеры.

Что там потоконебезопасно? Приведи пример почему это нельзя.

Оки, давай обсудим эту фичу. Если нужная фича - добавим, без проблем.

Не, не потоконебезопасно - просто опасно - криворукий админ врубит на продакшене трейсы - и продакшен рухнет.

В твоём случае - перезапустить приложение было затруднительно? Нужно было именно в рантайме?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845868
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasавторНа прошлом проекте - пользовался и очень даже. Включал и выключал логгеры и аппендеры.

Что там потоконебезопасно? Приведи пример почему это нельзя.

Оки, давай обсудим эту фичу. Если нужная фича - добавим, без проблем.

Не, не потоконебезопасно - просто опасно - криворукий админ врубит на продакшене трейсы - и продакшен рухнет.

В твоём случае - перезапустить приложение было затруднительно? Нужно было именно в рантайме?
Нет-нет. Нечего обсуждать. Добавляй сразу.

В моем случае перезапускать биржевое приложение было дорого. Стоит денег. Понимаешь?
Кроме того это не приложение а целый грид из полу-сотни узлов.

По поводу потоконебезопасно. Мне очень приятно конечно что ты так заботишся о потокобезопасности.
Тем более что страницу назад тебя группа людей убеждала в том что календарь небезопасен.
По этому поводу - не переживай. Log4j1.2.x - библиотечка промышленного уровня. Она давно
оттестирована и работает эталонно надёжно. Те странные юзкейсы которые ты нарисовал - я не понял.
Что там упадёт от включение TRACE - непонятно. Будь пожалуйта более конкретным.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845875
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

Оки, добавим эту фичу, спасибо.

Теперь встаёт вопрос - как это лучше всего сделать.

Через условный "FileWatchService" (т.е. через файл Bobbin.json с настройками логгера на дисковой системе) - или как-то иначе?
Я держу в голове сейчас use cases с микросервисами - в облаке невозможно будет полезть файл на диске поменять.

Как вариант - можно подготовить апишку в логгере, а конечное приложение при желании может её как Веб-сервис опубликовать.
(но даже тут - это сработает только на одном ноде).
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845887
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не с того края зашел. Ты сначала разработай runtime. Тоесть чтобы это концептуально было и работало.

А как конфигурить - это вопрос не этого форума. Как хочешь. Хоть json, хоть ямл. Хоть JMX.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845900
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonНе с того края зашел. Ты сначала разработай runtime. Тоесть чтобы это концептуально было и работало.

А как конфигурить - это вопрос не этого форума. Как хочешь. Хоть json, хоть ямл. Хоть JMX.

Ок, согласен. Посижу подумаю.
Скорее всего это будет API для опубликования его как Веб сервис через админский endpoint в конечном приложении.

Bobbin Configuration REST Web Service Format.

И он собственно будет принимать такой же формат как в Bobbin.json.

(Для других читателей - здесь речь именно о runtime конфигурации без перезапуска приложения. Изначальная инициализация осуществляется через Bobbin.json - файл с настройками логгера - он конечно изначально поддерживается и вокруг него собственно логгер и построен).



О прочем: я погонял изменения по комментам из этой темы на тестовых стендах (помимо testng тестов). Всё ок.
Обуликовал релиз:

Код: xml
1.
2.
3.
4.
5.
<dependency>
  <groupId>io.infinite</groupId>
  <artifactId>bobbin</artifactId>
  <version>2.0.5</version>
</dependency>



Код: java
1.
compile 'io.infinite:bobbin:2.0.4'
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845901
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Поправочка:

Код: sql
1.
compile 'io.infinite:bobbin:2.0.5'
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845956
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasLog4j не поддерживает перенастройку в рантайме.
https://stackoverflow.com/questions/4598702/dynamically-changing-log4j-log-level Делая далеко идущие утверждения, было бы не худо ссылаться на документацию . Ну или, хотя бы, внимательно читать ответы SO по вашей же ссылке.
Настройки Log4j 1.2 меняются схожим образом. Для xml-конфигурации - точно работает.
Да, у Log4j 1.2 может терять сообщения при такой переконфигурации, но это - другая проблема.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845970
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. Sidorov,

Обсуждался конкретно Log4j.

Log4j2 это совершенно другой проект.

По ссылке Stackoverflow выше касательно Log4j:

авторCaution: configureAndWatch method is unsafe for use in J2EE environments due to a Thread leak

Можно пример как это настраивается в Log4j без изменения пользовательского кода?

PS: необязательно в каждом сообщении делать присказки типа "далекоидущие выводы" и пр., это касается всех комментаторов.
Вы не профессора, а я не студент на дипломном проекте.
Однозначно одно - у меня достаточно опыта признавать свои ошибки и понимать что мои знания сильно ограничены.
Что не мешает мне создавать охуенные проекты, полезные для всех.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845981
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasЧто не мешает мне создавать охуенные проекты, полезные для всех.
Что за проекты? Сколько их? И из какой предметной области?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845991
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

В основном инфраструктура:
- автоматизация кода, логирование, профилирование, безопасность (аутентификация, авторизация) - для микросервисов\облака.

Есть прикладной проект Pigeon - он в первую очередь для банков.

https://i-t.io/
https://github.com/INFINITE-TECHNOLOGY/
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845997
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasPigeon

А можно уточнить для каких это целей применяется?
Мельком посмотрел - для отправки сообщения каждый раз пересоздается URLConnection. (А обертка для него aka SenderDefault каждый раз пересоздается через рефлексию).
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39845999
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
СЗОТ

Pigeon:

SenderDefaultHttpsUnsecure#sendHttpMessage при отправке каждого сообщения создает новый SSLContext и меняет HttpsURLConnection.setDefaultSSLSocketFactory

Это "охуенно" ?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846003
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LelouchdakeirasPigeon

А можно уточнить для каких это целей применяется?
Мельком посмотрел - для отправки сообщения каждый раз пересоздается URLConnection. (А обертка для него aka SenderDefault каждый раз пересоздается через рефлексию).

Посылать OTP через SMS гейтвей либо Transaction (покупки) Push Notifications (SOAP, JSON) на внешний хост.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846004
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LelouchСЗОТ

Pigeon:

SenderDefaultHttpsUnsecure#sendHttpMessage при отправке каждого сообщения создает новый SSLContext и меняет HttpsURLConnection.setDefaultSSLSocketFactory

Это "охуенно" ?

Можно чуть больше деталей, в чём Вы видите проблему. Я буду рад исправить. Это кстати скоро идёт на продакшен после 8 месячного тестирования.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846007
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasmayton,

В основном инфраструктура:
- автоматизация кода, логирование, профилирование, безопасность (аутентификация, авторизация) - для микросервисов\облака.

Есть прикладной проект Pigeon - он в первую очередь для банков.

https://i-t.io/
https://github.com/INFINITE-TECHNOLOGY/
Non-commercial open-source software organization?

А как вы зарабатываете? Вы альтруисты?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846009
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras,

1) Зачем каждый раз пересоздавать SslContext?
2) Зачем использовать глобальные настройки SslSocketFactory? (Любой другой код, соседствующий с этой библиотекой и использующий HttpsUrlConnection может вести себя неожидано)
3) Зачем каждый раз пересоздавать обертку для отправки запросов?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846010
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras,

if (httpRequest.method == "POST") { <-- я понимаю, что это работает, так как "POST" интернируется, но почему не equals?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846012
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytondakeirasmayton,

В основном инфраструктура:
- автоматизация кода, логирование, профилирование, безопасность (аутентификация, авторизация) - для микросервисов\облака.

Есть прикладной проект Pigeon - он в первую очередь для банков.

https://i-t.io/
https://github.com/INFINITE-TECHNOLOGY/
Non-commercial open-source software organization?

А как вы зарабатываете? Вы альтруисты?
На грантах правительственных сидим. :)

На самом деле там 1 человек я пока. Никак не зарабатываем, даже донатим бабло на другой опенсорс.
Бабло с зарплаты своей, работаю на другой фирме я.

Когда-нибудь если что-то станет популярным, появятся и другие контрибьюторы\мейнтейнеры.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846013
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Последний вопрос не в кассу, это же groovy.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846014
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lelouchdakeiras,

if (httpRequest.method == "POST") { <-- я понимаю, что это работает, так как "POST" интернируется, но почему не equals?

Груви код, там надо == писать. По умолчанию == в Груви это equals.

http://docs.groovy-lang.org/latest/html/documentation/core-operators.html#_identity_operator
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846015
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasLelouchdakeiras,

if (httpRequest.method == "POST") { <-- я понимаю, что это работает, так как "POST" интернируется, но почему не equals?

Груви код, там надо == писать. По умолчанию == в Груви это equals.

http://docs.groovy-lang.org/latest/html/documentation/core-operators.html#_identity_operator

да, я уже понял, постом выше.

application.config стоит поправить:
Код: java
1.
2.
3.
4.
pigeonConfFile=C:/Users/anton.pryamostanov/IdeaProjects/PIGEON_PLUGINS/src/conf/Pigeon.json
pigeonOutPluginsDir=C:/Users/anton.pryamostanov/IdeaProjects/PIGEON_PLUGINS/src/conf/plugins/output
pigeonInputPluginsRestDir=C:/Users/anton.pryamostanov/IdeaProjects/PIGEON_PLUGINS/src/conf/plugins/input/rest
pigeonInputPluginsHttpDir=C:/Users/anton.pryamostanov/IdeaProjects/PIGEON_PLUGINS/src/conf/plugins/input/http
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846017
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lelouchdakeiras,

1) Зачем каждый раз пересоздавать SslContext?
2) Зачем использовать глобальные настройки SslSocketFactory? (Любой другой код, соседствующий с этой библиотекой и использующий HttpsUrlConnection может вести себя неожидано)
3) Зачем каждый раз пересоздавать обертку для отправки запросов?

По вопросу №1 - SSLContext.getInstance("TLS") - это разве не Singletone?
Без шуток, если честно особо не глядел.

Если нет, поправлю. Не надо так делать.

По вопросу №2 - это standalone приложение, оно не подразумевает размещение на общем сервере приложений с другими.
Именно по причине глобалього defaultSSLSocketFactory.

Какие есть альтернативы setDefaultSSLSocketFactory?

По вопросу №3 - это отлично подмеченно. Поправлю.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846018
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Прошу учитывать, что Pigeon это пред-релизное состояние, RC.
99.99% готовность, в течении нескольких недель будет релиз.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846019
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А чё в вашем ПИНГВИНЕ нулевое тестовое покрытие? Нуу... это несеръёзно брадт...

Уж коли пилишь гранты - то пили хорошо.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846020
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonА чё в вашем ПИНГВИНЕ нулевое тестовое покрытие? Нуу... это несеръёзно брадт...

Уж коли пилишь гранты - то пили хорошо.

Ну какие гранты? Это шутка была.

Там отдельный проект есть PIGEON_PLUGINS в нём Self Testы разные, включая повторную отправку, таймауты и пр.

Руки не доходят вкорячить это в билд.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846024
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasLelouchdakeiras,

1) Зачем каждый раз пересоздавать SslContext?
2) Зачем использовать глобальные настройки SslSocketFactory? (Любой другой код, соседствующий с этой библиотекой и использующий HttpsUrlConnection может вести себя неожидано)
3) Зачем каждый раз пересоздавать обертку для отправки запросов?

По вопросу №1 - SSLContext.getInstance("TLS") - это разве не Singletone?
Без шуток, если честно особо не глядел.

Если нет, поправлю. Не надо так делать.

По вопросу №2 - это standalone приложение, оно не подразумевает размещение на общем сервере приложений с другими.
Именно по причине глобалього defaultSSLSocketFactory.

Какие есть альтернативы setDefaultSSLSocketFactory?

По вопросу №3 - это отлично подмеченно. Поправлю.
1) В java 8 и 11 нет.
2) У вас каждый outputQueue имеет собственную настройку senderClassName . Использование SenderDefaultHttps и SenderDefaultHttpsUnsecure для разных очередей приведет к гонке на defaultSSLSocketFactory. Можно использовать HttpsUrlConnection#setSocketFactory
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846025
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А чего форков нету? Никому не нужен видать пингвин.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846031
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonА чего форков нету? Никому не нужен видать пингвин.

Ну Голубь (Pigeon, почтовый голубь) ещё не в релизе - и объективно маловероятно что кто-то в банках будет ставить нераспространённый опен сорс.
Я поговорю со своими знакомыми, может кто-то захочит поменять самописные скрипты для рассылок на это приложение.

А вот то что нет скачиваний Bobbin - вот это неожиданно... Видно настолько людям приелись существующие логгеры, что они уже не воспринимают их критично и ленятся что-то новое пробовать...
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846033
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторHttpsUrlConnection#setSocketFactory

Спасибо, отличный совет. Так и сделаю, скоро поменяю.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846037
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я вижу тут оживлённое обсуждение и других проектов пошло.

Тогда сделаю анонс: скоро будет выпущен новый проект - portable аналог Spring Security для микросервисов + авторизационный сервер к нему.

Portable значит что может использоваться с любыми платформами для микросервисов, не ограничиваясь Spring или Java вообще.
Например можно его подключить к Python.

Это будет одно из очень немногих end-to-end бесплатных решений для безопасности микросервисов - начиная от Authorization Granting и заканчивая Authorization Validation.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846040
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasА вот то что нет скачиваний Bobbin - вот это неожиданно...

ну я бы тоже не стал его использовать.
Как минимум:
1) заявление о производительности, но 0 бенчмарков
2) только синхронные аппендеры
3) отсутсвие возможности перенастроить уровень логирования в runtime.
4) Необходимость тащить за логгером 5мб зависимости в виде groovy (logback например - 2 зависимости суммарно 800кб)
5) Малое количество доступных аппендеров
6) меня терзают смутные сомнения о FileDestination - КМК каждый поток может создать свой FileWriter для каждого файла и попробовать что-то туда записать. Что при этом будет с содержимым файла?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846042
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
7) любой exception в Destination#store просто свалит поток, вызвавший логирование...
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846043
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasА вот то что нет скачиваний Bobbin - вот это неожиданно... Видно настолько людям приелись существующие логгеры, что они уже не воспринимают их критично и ленятся что-то новое пробовать...
Да чет не хоца. Тут прям на глазах пофиксили джуниорский баг.
Вобщем-та есть некое.... ощущение что проект - школьный.

Не обижайся уж.

Мы не злые. Просто трезвый расчет...
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846047
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

автортолько синхронные аппендеры
Почему синхронные? Как раз таки полностью асинхронные. В этом выигрышь и достигается.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846048
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras,

что в них, простите, асинхронного? store явно вызывает FileWriter#write
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846049
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторТут прям на глазах пофиксили джуниорский баг.
Баг практически ни на что не влиял.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846050
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lelouch,

но на каждый поток - отдельный файл :)
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846051
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lelouchdakeiras,

что в них, простите, асинхронного? store явно вызывает FileWriter#write

на каждый поток отдельный файл и отдельный FileWriter - полностью асинхронная запись, без потерь на synchronized.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846053
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras,

Это асинхронным его не делает. Кроме этого ОЧЕНЬ усложняет анализ логов.
+ Не могли бы вы показать, где к имени файла примешивается идентификатор потока?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846054
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras,

вот только поток каждый раз ждет, пока файл будет записан. Асинхронные аппендеры это про другое - возможность накапливать много событий в очередь и выводить их в файл 1 куском.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846056
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras,

Если я правильно понял, то на уровне конфигурации:
"fileName": "\"./LOGS/${threadName}/${level}/${threadName}_${level}_${date}.log\"",

при этом если пользователь НЕ укажет threadName при настроке навзания или пути файла - то видимо он ССЗБ :) прэлэстно
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846057
vas0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasLelouchdakeiras,

что в них, простите, асинхронного? store явно вызывает FileWriter#write

на каждый поток отдельный файл и отдельный FileWriter - полностью асинхронная запись, без потерь на synchronized.Код не смотрел, поэтому мой вопрос может показаться ламерский. Потери на synchronized это же не просто потери, synchronized дает гарантию visibility. Что корректное значение записаное в одним потоке, будет прочитано в другом. Как это достигается здесь, через использование immutable+final объектов или как?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846059
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vas0,

ThreadLocal
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846061
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lelouchdakeiras,

вот только поток каждый раз ждет, пока файл будет записан. Асинхронные аппендеры это про другое - возможность накапливать много событий в очередь и выводить их в файл 1 куском.

Я понимаю про Буферизующие\асинхронные аппендеры (с отдельным тредом). Всё это было и было выпилено за вредностью\ненадобностью.

Но я не понимаю почему Вы говорите что в Бобине потоки будут ждать, пока будет записан другой файл.
Методы Бобины (store, etc) НЕ синхронные, соотвественно копируются на вызов из каждого потока АСИНХРОННО.

авторвот только поток каждый раз ждет, пока файл будет записан.


авторЭто асинхронным его не делает. Кроме этого ОЧЕНЬ усложняет анализ логов.
Наоборот, упрощает, потоки надо группировать (threadGroupName) и логи раскидывать по папкам красиво.
У меня 200 логов я кайфую как всё под контролем.

авторНе могли бы вы показать, где к имени файла примешивается идентификатор потока?
Это хороший вопрос.
Вот тут:
https://github.com/INFINITE-TECHNOLOGY/BOBBIN/blob/master/src/main/groovy/io/infinite/bobbin/BobbinScriptEngine.groovy

Код: java
1.
2.
3.
4.
5.
6.
7.
    String getThreadName() {
        return Thread.currentThread().getName()
    }

    String getThreadGroupName() {
        return Thread.currentThread().getThreadGroup().getName()
    }



Это даёт использовать неявные field reference (добавленные Groovy при компиляции на основании getter'ов выше) в имени файла:

Код: java
1.
"fileName": "\"./LOGS/THREADS/${threadGroupName}/${threadName}/${level}/${threadName}_${level}_${date}.log\""
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846062
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lelouchdakeiras,

Если я правильно понял, то на уровне конфигурации:
"fileName": "\"./LOGS/${threadName}/${level}/${threadName}_${level}_${date}.log\"",

при этом если пользователь НЕ укажет threadName при настроке навзания или пути файла - то видимо он ССЗБ :) прэлэстно

Да, возникнет обычный io congestion, как в других логгерах.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846063
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vas0dakeirasпропущено...


на каждый поток отдельный файл и отдельный FileWriter - полностью асинхронная запись, без потерь на synchronized.Код не смотрел, поэтому мой вопрос может показаться ламерский. Потери на synchronized это же не просто потери, synchronized дает гарантию visibility. Что корректное значение записаное в одним потоке, будет прочитано в другом. Как это достигается здесь, через использование immutable+final объектов или как?

Тут потоки никак не взаимодействуют.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846064
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хочу ещё раз подчеркнуть - в Бобине НЕТ io waits/congestion (если отдельные файлы на каждый поток настроены).

Там нет ни одного синхронного метода, за исключением нативных методов ОС при записи по конкретному дескриптору.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846066
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras,
dakeiras потоки будут ждать, пока будет записан другой файл.
Потоки будут ждать, пока будет записан ИХ файл. И да, это долго в ряде случаев.

dakeirasНаоборот, упрощает, потоки надо группировать (threadGroupName) и логи раскидывать по папкам красиво.
У меня 200 логов я кайфую как всё под контролем.

А теперь представим что одно событие обрабатывается в нескольких потоках:
1) контроллер добавляет сообщение в очередь
2) Поток слушающий очередь, достает его, нарезает на независимые операции и запускает через Executor#invokeAll. После этого отправляет сообщение через условную atmosphere.
3) atmosphere через свой пул рассылает web socket клиентам.
Как в ваших "удобных" логах собрать весь путь сообщения? видимо только через что-то внешнее
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846069
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторПотоки будут ждать, пока будет записан ИХ файл. И да, это долго в ряде случаев.
Идею понял.

Это тестировалось, асинхронные аппендеры - менее эффективны.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846070
vas0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну если данные генерируются в каких то потоках, а в каких то других потоках идет запись в файлы. Чем тут поможет ThreadLocal?
Только если работа уже идет на уровне immutable string объектах, для объектов другого типа без синхронизации можешь получить некорректные значение.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846071
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras,

dakeirasДа, возникнет обычный io congestion, как в других логгерах.
См logstash > fileAppender > prudent.
И да, в других логгерах это возникнет, если пользователь явно настроит 2 разных аппендера на 1 файл. В вашем - если не укажет настроку, которая ни разу не обязательна с его точки зрения.

dakeirasнет io waits
С чего это вдруг их нет?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846072
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторА теперь представим что одно событие обрабатывается в нескольких потоках:
1) контроллер добавляет сообщение в очередь
2) Поток слушающий очередь, достает его, нарезает на независимые операции и запускает через Executor#invokeAll. После этого отправляет сообщение через условную atmosphere.
3) atmosphere через свой пул рассылает web socket клиентам.
Как в ваших "удобных" логах собрать весь путь сообщения? видимо только через что-то внешнее

Через MDC. Имя файла поддерживает MDC, будет кросс-поточный лог файл для конкретного id.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846074
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Точно также это делается для "username", request id, и прочего.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846075
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vas0Ну если данные генерируются в каких то потоках, а в каких то других потоках идет запись в файлы. Чем тут поможет ThreadLocal?
Только если работа уже идет на уровне immutable string объектах, для объектов другого типа без синхронизации можешь получить некорректные значение.

Данные генерируются и записываются в рамках 1 потока.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846076
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras,


dakeirasЭто тестировалось, асинхронные аппендеры - менее эффективны.

Они более эффективны даже с точки зрения скорости записи этого самого файла, потому что могут писать его 1 куском. Посмотрите хотя тесты последовательного чтения/записи (например по 1мб) и рандомного (по 4к во всяких crystal disk)
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846077
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasЧерез MDC. Имя файла поддерживает MDC, будет кросс-поточный лог файл для конкретного id.

То есть чтобы не страдать от вашего логгера, пользователь обязан использовать MDC?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846078
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати Бобина даёт невиданный функционал по кросс-поточному и кросс-классовому отслеживанию действий юзера - очень легко настроить чтобы на каждого юзера (или отдельного юзера) были свои лог файлы, через MDC.

Теперь видите какой это царский функционал?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846079
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LelouchdakeirasЧерез MDC. Имя файла поддерживает MDC, будет кросс-поточный лог файл для конкретного id.

То есть чтобы не страдать от вашего логгера, пользователь обязан использовать MDC?

В других логгерах это без MDC не сделать. Только там будет общий файл-каша.
А тут отдельные файлы.

Единственная альтернатива - переименовывать потоки, что не рекомендуется.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846080
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторСм logstash > fileAppender > prudent.
И да, в других логгерах это возникнет, если пользователь явно настроит 2 разных аппендера на 1 файл. В вашем - если не укажет настроку, которая ни разу не обязательна с его точки зрения.


Посмотрю, спасибо.

авторОни более эффективны даже с точки зрения скорости записи этого самого файла, потому что могут писать его 1 куском. Посмотрите хотя тесты последовательного чтения/записи (например по 1мб) и рандомного (по 4к во всяких crystal disk)

Это тоже посмотрю. Благодарю.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846081
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasКстати Бобина даёт невиданный функционал по кросс-поточному и кросс-классовому отслеживанию действий юзера - очень легко настроить чтобы на каждого юзера (или отдельного юзера) были свои лог файлы, через MDC.

Теперь видите какой это царский функционал?

Нет не вижу.
Что по остальным пунктам? Например IOException при ошибке записи файла.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846083
vas0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasvas0Ну если данные генерируются в каких то потоках, а в каких то других потоках идет запись в файлы. Чем тут поможет ThreadLocal?
Только если работа уже идет на уровне immutable string объектах, для объектов другого типа без синхронизации можешь получить некорректные значение.

Данные генерируются и записываются в рамках 1 потока. А как же асинхронные апендеры?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846084
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vas0dakeirasпропущено...


Данные генерируются и записываются в рамках 1 потока. А как же асинхронные апендеры?
Их нет. Тут ничего нет кроме консоли и файла. Кстати, dakeiras, вы в курсе, что System.out.println синхронный?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846086
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lelouchvas0пропущено...
А как же асинхронные апендеры?
Их нет. Тут ничего нет кроме консоли и файла. Кстати, dakeiras, вы в курсе, что System.out.println синхронный?

Даже уточню - выполняет синхронизацию на this.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846087
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot dakeiras]В других логгерах это без MDC не сделать. Только там будет общий файл-каша.
Решается условным graylog. И это удобнее чем "куча файлов"
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846093
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras,

ну и на последок хочу заметить, что ваш логгер в том числе не защищен от случая, когда 2 потока имеют одинаковое название.
https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#setName(java.lang.String) Every thread has a name for identification purposes. More than one thread may have the same name. If a name is not specified when a thread is created, a new name is generated for it.

Нигде в документации не заостряется, что имя файла явно должно содержать threadName в настройках шаблона имени файла и не указано требование уникальности имени потока (или уникальности пары threadGroupName и threadName).

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

Как когда-то выразился мой преподавать на 1 курсе:
Ваша программа представляет из себя хрупкую игрушку, работающую только в руках создателя.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846107
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasКстати Бобина даёт невиданный функционал по кросс-поточному и кросс-классовому отслеживанию действий юзера - очень легко настроить чтобы на каждого юзера (или отдельного юзера) были свои лог файлы, через MDC.

Теперь видите какой это царский функционал?
Обычно (в 99%) случаев настройкой системы логгирования заняты дев-опсы. И они себе ставят
вполне себе конкретные задачи. Как-то
- безопасность и аудит
- перформанс
- анализ ошибок

Для всех этих задач этот царский функционал не нужен. Ну или я не знаю такого юзкейса.
Логгировать отдельно поток нет никакого смысла. Поток - это ресурс который берут из "обоймы"
доступных ресурсов и роль потока в крупном приложении может серъезно менятся в считанные
секунды.

Вести одновременно 200 логов с точки зрения файловой системы накладно т.к. нужно иметь
200 файловых дескрипторов и соотв 200 объектов представляющих файл (буферов). Накладные
расходы можно считать а можно и нет. Но поинт опять-же в том что это может быть накладно
(так-же как и держать 65000 открытых сокетов на веб-сервере) и иногда количество переходит
в качество. Для старых магнитных накопителей время seektime безсмысленно тратится
на беготню по поверхности диска и вы получаете жалкие 25 мегабайт в секунду потому-что
вместо throughput получили IOPS, и чтобы получить паспортные пропускные способности
диска - вам лучше вернуться к классической схеме где есть 1 или 2 лога на всё приложение.

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

Зачем нужны логи без хвостиков - я не знаю. Это epic fail и такие логи не будут отражать
важные действия которые возможно повлекли за собой падение.

Провертье мою гипотезу. Нажмите reset под нагрузкой и проследите что самые последние
бизнес аудиты были сохранены.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846109
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторОбычно (в 99%) случаев настройкой системы логгирования заняты дев-опсы. И они себе ставят
вполне себе конкретные задачи. Как-то
- безопасность и аудит
- перформанс
- анализ ошибок

Для всех этих задач этот царский функционал не нужен. Ну или я не знаю такого юзкейса.
Логгировать отдельно поток нет никакого смысла. Поток - это ресурс который берут из "обоймы"
доступных ресурсов и роль потока в крупном приложении может серъезно менятся в считанные
секунды.

Я завтра с работы подробно отвечу на комментарии.

Касательно ELK - там невозможно вручную логи смотреть, поэтому отдельные файлы на каждый лог - дают выигрыш в производительности - за счёт отсутствия io congestion.

Если нет ELK, в случаях с пакетными приложениями, ETL, индустриальными приложениями с фиксированными потоками - там возможность отдельных лог файлов это супер фича.
Когда требуется вручную разбирать лог файлы. И в процессе отладки приложения.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846113
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lelouchdakeiras,

ну и на последок хочу заметить, что ваш логгер в том числе не защищен от случая, когда 2 потока имеют одинаковое название.
https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#setName(java.lang.String) Every thread has a name for identification purposes. More than one thread may have the same name. If a name is not specified when a thread is created, a new name is generated for it.

Нигде в документации не заостряется, что имя файла явно должно содержать threadName в настройках шаблона имени файла и не указано требование уникальности имени потока (или уникальности пары threadGroupName и threadName).

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

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

Никто не говорит, что обязательно разделять.

Просто с точки зрения здравого смысла, если у вас есть 500 потоков - писать лог в единый файл - это бред, наркомания укоренившаяся с годами.
Т.к. очевидно что это вызывает очередь на запись в этот файл.

Хрупкая или нет - есть артифакты публично доступные через Magen/Gradle.

Качаем, ломаем - я плачу бабло.
У меня принцип - ОТВЕЧАТЬ за свой опен сорс софт.

PS: если не нравится threadName, ну напишите threadName+Thread.currentThread().getId()
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846115
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Т.е. хотите - делайте 1 файл на поток, хотите отдельные файлы по уровням, Бобина всё это отлично поддерживает.

Никаких умозрительных ограничений и незадокументированных архитектурных проблем нет.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846116
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пока я отвечу более детально, прошу всех скачать Бобину (через Maven, Gradle, jar - как удобно) и просто начать ей пользоваться.

Настроить по своим предпочтениям. И наслаждаться свободой от ига logback и прочих log4j.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846118
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Релиз 2.0.5 - он с учётом фидбека из этой темы.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846121
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasЯ завтра с работы подробно отвечу на комментарии.

Касательно ELK - там невозможно вручную логи смотреть, поэтому отдельные файлы на каждый лог - дают выигрыш в производительности - за счёт отсутствия io congestion.

Если нет ELK, в случаях с пакетными приложениями, ETL, индустриальными приложениями с фиксированными потоками - там возможность отдельных лог файлов это супер фича.
Когда требуется вручную разбирать лог файлы. И в процессе отладки приложения.
А что касательно Elastic-Kibana? Речь вообще про него не идёт.
Или вы делаете узкоспециализированное решение?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846122
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasПока я отвечу более детально, прошу всех скачать Бобину (через Maven, Gradle, jar - как удобно) и просто начать ей пользоваться.

Настроить по своим предпочтениям. И наслаждаться свободой от ига logback и прочих log4j.
А ты хитрец. Хочешь бесплатную бригаду тестировщиков?

Ты с Панфиловым расчитался?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846123
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytondakeirasПока я отвечу более детально, прошу всех скачать Бобину (через Maven, Gradle, jar - как удобно) и просто начать ей пользоваться.

Настроить по своим предпочтениям. И наслаждаться свободой от ига logback и прочих log4j.
А ты хитрец. Хочешь бесплатную бригаду тестировщиков?

Ты с Панфиловым расчитался?
конечно! Ща как затестирую за ваш счет да как раскручусь, донат польётся рекой.

Кстати, правительсто оплачивает мне 10 опер сорс проектов, но я выкладываю только 5, остальные сам использую.

Как с тем армянином (который к сожалению умер) и бесплатным хлебом.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846141
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasМожно пример как это настраивается в Log4j без изменения пользовательского кода?Сейчас уже сложно найти ссылку на общедоступное руководство по log4j 1.2, поэтому я дал ссылку на документацию, где есть говорящее "andWatch". XML-конфигурация регулярно проверяется на обновление (мониторится дата-время xml-файла и, возможно, его размер). Если изменение обнаружено - запускается процесс переконфигурации.

Практически, когда мне потребовалось написать XML-конфигурацию log4j, то, лично я, сделать этого не смог - не разобрался с DTD. Зато, после недолгих поисков, нашёл онлайновый конвертор, скормил ему простую конфигурацию из файла свойств и получил шаблон, который потом менял под собственные нужды. Всё это проделывалось лет шесть назад и прекрасно работало.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846144
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasПросто с точки зрения здравого смысла, если у вас есть 500 потоков - писать лог в единый файл - это бред, наркомания укоренившаяся с годами.Нет задачи "писать лог в единый файл" и наркомания тут совершенно не в тему.
Если анализ проблемы требует анализ данных от пятисот потоков - так тому и быть.
И вот в этом случае собирать и синхронизировать данные из пятисот логов - проще сразу убиться, предварительно застрелив автора этой гениальной задумки.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846150
Андрей Панфилов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasАндрей нашёл 1 явный баг (minor)
У вас какое-то определение minor/major несколько странное... Вы внимательно читали выхлоп от 21941782 ? Там mm, dd, yyyy и пр. не полностью замещаются, а перемешиваются, т.е. на "границах" разница получается на самом деле не микросекунды, а секунды, минуты, часы, месяцы, годы - если такой лог куда-то грузить для дальнейшего анализа, то в нем сообщения будут банально теряться.

dakeiras1 потенциальный баг с max open files exceededт.е. до конца раскрутить вы замечание не смогли, а вот Lelouch смог 21943227 :
Lelouch6) меня терзают смутные сомнения о FileDestination - КМК каждый поток может создать свой FileWriter для каждого файла и попробовать что-то туда записать. Что при этом будет с содержимым файла?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846158
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. Sidorov,
Вроде стандартная фича логеров, писать в один файл, но после времени идёт id потока.
Удобно.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846169
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras,

Хотели тесты - получайте

https://github.com/oleg-zinovev/bobbin-test-suite

1) TestIOExceptionOnLog - показывает, что в случае ошибки IO полезная работа (в данном случае установка флага work) не выполняется. Для демонстрации этого кейса на Windows можно указать несуществующий диск (вместо /some/missing/root/directory/on/my/mac). На *nix достаточно запустить от пользователя, который не имеет права на запись в /.

2) TestSameName - показывает ошибки при одинаковом имени файла. На Windows возможно тест завершиться с ошибкой на первых 3х ассретах. Так как *nix позволяет писать в один файл из нескольких процессов/потоков, для демонстрации проблемы пришлось сгенерировать строку лога, превышающий размеры буфера записи в FileWriter (возможно, есть меньший размер буфера, при котором начнется перемешивание, связанный с работой файловой системы, но тут я хз). При этом на *nix ошибок записи нет, но содержимое логов перемешивается. Последний assert проверяет именно это.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846307
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovdakeirasПросто с точки зрения здравого смысла, если у вас есть 500 потоков - писать лог в единый файл - это бред, наркомания укоренившаяся с годами.Нет задачи "писать лог в единый файл" и наркомания тут совершенно не в тему.
Если анализ проблемы требует анализ данных от пятисот потоков - так тому и быть.
И вот в этом случае собирать и синхронизировать данные из пятисот логов - проще сразу убиться, предварительно застрелив автора этой гениальной задумки.

Логгер «Бобина» позволяет удобно настраивать отображения вывода данных логирования в разных проекциях, в зависимости от необходимости:

- По потокам
- По уровню сообщения (error, debug, etc)
- По классам
- По MDC - например отслеживать работу по конкретному пользователю или по конкретному transaction id

Эти критерии можно группировать и комбинировать как угодно, например по группам потоков, пакетам классов - ограничений нет никаких.

1 сообщение может выводится во множество файлов одновременно.

Всё ещё хочется застрелить за такую идею? Плохая идея?

По остальным комментариям - отвечу с работы, заранее большое спасибо за тесты и фидбек.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846312
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasВсё ещё хочется застрелить за такую идею? Плохая идея?


За идею вас тут никто не расстреливают, просто никто кроме вас не видит преимуществ в этой идеи.
А вот реализация идеи хромает.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846345
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LelouchdakeirasВсё ещё хочется застрелить за такую идею? Плохая идея?


За идею вас тут никто не расстреливают, просто никто кроме вас не видит преимуществ в этой идеи.
А вот реализация идеи хромает.

Человек выше написал:

авторзастрелив автора этой гениальной задумки

Мне лично хочется самому застрелиться от конфигов logback и log4jX.

Сейчас начну смотреть тесты и комменты.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846348
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lelouch,

Огромное спасибо, что потратили время и сделали тесты.
Сейчас буду смотреть.

Респект.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846353
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasLelouchпропущено...


За идею вас тут никто не расстреливают, просто никто кроме вас не видит преимуществ в этой идеи.
А вот реализация идеи хромает.

Человек выше написал:

авторзастрелив автора этой гениальной задумки

Мне лично хочется самому застрелиться от конфигов logback и log4jX.

Сейчас начну смотреть тесты и комменты.
Ты ставишь нас в глупое положение. Ведь мы не видим те ужасные конфиги на которые
ты смотришь сейчас. Сделай милость. Приведи конфиг для одинаковой конфигурации для Робин-Катушка-Толтсяк
и Лог4Джей и Логбэк.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846373
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytondakeirasпропущено...


Человек выше написал:

пропущено...


Мне лично хочется самому застрелиться от конфигов logback и log4jX.

Сейчас начну смотреть тесты и комменты.
Ты ставишь нас в глупое положение. Ведь мы не видим те ужасные конфиги на которые
ты смотришь сейчас. Сделай милость. Приведи конфиг для одинаковой конфигурации для Робин-Катушка-Толтсяк
и Лог4Джей и Логбэк.

Вот несколько моментов описано:
https://github.com/INFINITE-TECHNOLOGY/BOBBIN/wiki/1---Introduction#problems

Это если чуть конкретнее.

Но в общем случае конфиги Бобины просто невоспроизводимы в других логгерах из-за функциональных ограничений SiftingAppender - либо огромные по размеру (отдельные блоки НА КАЖДЫЙ КЛАСС либо на весь пакет целиком)
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846379
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras, ты пишешь

Existing logging solutions provide only partial support for scripting in configuration.
Поясни эту фразу. Что значит scripting in configuration? Где partial? И где может быть full?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846388
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lelouch,

Посмотрел 1й тест: TestIOExceptionOnLog

Сделал PR: https://github.com/oleg-zinovev/bobbin-test-suite/pull/1

Бобина есть в JCenter, не обязательно ещё её собвстенный репозиторий подключать, это описано в инструкции:
https://github.com/INFINITE-TECHNOLOGY/BOBBIN/wiki/3---Usage#add-maven-dependency

Так же тест не воспроизводился под виндой из-за UAC Virtualization. Я чуть подправил.

Теперь касательно сути самого теста: это осмысленное поведение.
Я считаю, что выполнение не должно продолжаться при отказе системы логирования.

Принцип такой: чем раньше упадёт - тем лучше. А шанс того что упадёт само приложение чуть позже, если упал логгер - есть.

Это очередная "гениальная" фича в Logback - супрессить ошибки в логгере.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846391
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytondakeiras, ты пишешь

Existing logging solutions provide only partial support for scripting in configuration.
Поясни эту фразу. Что значит scripting in configuration? Где partial? И где может быть full?

В Бобине full support скриптинга в конфиге, все поля это скрипты:
- levels
- classes
- fileName
- format
и пр.

Partial из документации к Бобине:
Note: Logback supports Groovy Script filter - but it is applicable only on specific appender configuration, not on Logger configuration.
Т.е. только фильтр и только на уровне аппендеров...
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846392
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lelouch, сейчас посмотрю второй тест.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846394
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846395
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasmaytondakeiras, ты пишешь

пропущено...

Поясни эту фразу. Что значит scripting in configuration? Где partial? И где может быть full?

В Бобине full support скриптинга в конфиге, все поля это скрипты:
- levels
- classes
- fileName
- format
и пр.

Partial из документации к Бобине:
Note: Logback supports Groovy Script filter - but it is applicable only on specific appender configuration, not on Logger configuration.
Т.е. только фильтр и только на уровне аппендеров...
Но ты понимаешь что есть семантическое различие между конфигом и кодом?

В коде находят ошибки другого рода. Код сложнее тестировать. Код вообще
в общем случае корректен недоказуемо.

Конфиг - всегда корректен если просто прошел валидацию.

Ты, беря возможности Groovy перенёс часть логики в конфиги и выставил это как преимущество.
Но на самом деле это не разу не приемущество. Это - недостаток. Это - ненадёжность системы.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846412
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytondakeirasпропущено...


В Бобине full support скриптинга в конфиге, все поля это скрипты:
- levels
- classes
- fileName
- format
и пр.

Partial из документации к Бобине:
пропущено...

Т.е. только фильтр и только на уровне аппендеров...
Но ты понимаешь что есть семантическое различие между конфигом и кодом?

В коде находят ошибки другого рода. Код сложнее тестировать. Код вообще
в общем случае корректен недоказуемо.

Конфиг - всегда корректен если просто прошел валидацию.

Ты, беря возможности Groovy перенёс часть логики в конфиги и выставил это как преимущество.
Но на самом деле это не разу не приемущество. Это - недостаток. Это - ненадёжность системы.

Вот. Прямо в точку.

Нет разницы между конфигом и кодом.

Есть единая система - с изменениями на этапах:
1) Сборки\компиляции
2) Запуска (старта) работы\перезапуске
3) В Runtime

Всё.

То что в конфигах не должны быть скрипты - это миф, страшилка родом из 90х.
Типа тормозит, небезопасно и пр. Это всё несостоятельно, и в результате приводит к декларативному программированию в конфигах ( https://github.com/INFINITE-TECHNOLOGY/BOBBIN/wiki/1---Introduction#declarative-programming-in-logger-configuration)
а также к изобретению волшебных синтаксисов.

А также типа пользователь не разберётся как настроить. Если дев опс не в состоянии осилить скрипт - он по определению не дев опс.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846421
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasТо что в конфигах не должны быть скрипты - это миф, страшилка родом из 90х.
Типа тормозит, небезопасно и пр. Это всё несостоятельно, и в результате приводит к декларативному программированию в конфигах ( https://github.com/INFINITE-TECHNOLOGY/BOBBIN/wiki/1---Introduction#declarative-programming-in-logger-configuration)
а также к изобретению волшебных синтаксисов.

А также типа пользователь не разберётся как настроить. Если дев опс не в состоянии осилить скрипт - он по определению не дев опс.
Капец какой-то. Вот ты Windows используешь. И тестишь на нем своего Толстого-Робина
(отдельный вопрос почему ибо не энтерпрайзно. но потом спрошу) но хоть раз заглядывал
в самое крупное хранилище настрек Windows. А именно в Windows-registry?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846422
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lelouch,

Касательно второго теста - там ошибка не в truncation, строка содержит данные от нескольких потоков.
Т.к. 1 общий файл настроен.

Наверное всё таки придётся добавить synchronized(file) в store...

Сейчас подумаю.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846427
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytondakeirasТо что в конфигах не должны быть скрипты - это миф, страшилка родом из 90х.
Типа тормозит, небезопасно и пр. Это всё несостоятельно, и в результате приводит к декларативному программированию в конфигах ( https://github.com/INFINITE-TECHNOLOGY/BOBBIN/wiki/1---Introduction#declarative-programming-in-logger-configuration)
а также к изобретению волшебных синтаксисов.

А также типа пользователь не разберётся как настроить. Если дев опс не в состоянии осилить скрипт - он по определению не дев опс.
Капец какой-то. Вот ты Windows используешь. И тестишь на нем своего Толстого-Робина
(отдельный вопрос почему ибо не энтерпрайзно. но потом спрошу) но хоть раз заглядывал
в самое крупное хранилище настрек Windows. А именно в Windows-registry?

Что значит не ентерпрайзно? Зачем какие-то предосуждения?
Всё в CI, Travis CI, автоматизированные билды, snapshots.

https://travis-ci.com/INFINITE-TECHNOLOGY/BOBBIN

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

Насчёт Windows registry - стараюсь туда не заглядывать, в эту помойку.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846435
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasmaytonпропущено...

Капец какой-то. Вот ты Windows используешь. И тестишь на нем своего Толстого-Робина
(отдельный вопрос почему ибо не энтерпрайзно. но потом спрошу) но хоть раз заглядывал
в самое крупное хранилище настрек Windows. А именно в Windows-registry?

Что значит не ентерпрайзно? Зачем какие-то предосуждения?
Всё в CI, Travis CI, автоматизированные билды, snapshots.

https://travis-ci.com/INFINITE-TECHNOLOGY/BOBBIN

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

Насчёт Windows registry - стараюсь туда не заглядывать, в эту помойку.
Ну вот загляни. Там - нет кода. Ну 99.99% нет.
Просто концепция такая. И слава богу что нет.
Когда появится код - сопровождать систему станет на порядки сложно.
Потому что покорректировать параметр с 5 на 10 стоит одних человеческих усилий.
А просмотреть SPEL/MVEL или любой другой сниппет - уже можешь подряжать
в работу разаработчика.

А доказательтво правоты кода - вообще отдельная история. Об этом еще Гильберт
писал. О полноте...
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846436
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasНет разницы между конфигом и кодом.прикольно).
Вот оно - ФП.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846438
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras,

Посмотрев ваш PR, хотелось бы уточнить - как вы поняли проблему теста TestIOExceptionOnLog?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846440
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasLelouch,

Касательно второго теста - там ошибка не в truncation, строка содержит данные от нескольких потоков.
Т.к. 1 общий файл настроен.

Наверное всё таки придётся добавить synchronized(file) в store...

Сейчас подумаю.
А где я написал что ошибка в truncation ??? Цитату пожалуйста. Ошибка в смешивании содержимого
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846444
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PetroNotC SharpdakeirasНет разницы между конфигом и кодом.прикольно).
Вот оно - ФП.
(морщится)

Нет. Это не ФП. Это просто перенос complexity с одной части кода в другую.

У ФП есть конкретный перечень признаков. Кажется профессор Душкин
писал в своей книге задачи и проблемы которые конкретно решает ФП.

То что делает автор к ФП не отностится.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846449
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LelouchdakeirasLelouch,

Касательно второго теста - там ошибка не в truncation, строка содержит данные от нескольких потоков.
Т.к. 1 общий файл настроен.

Наверное всё таки придётся добавить synchronized(file) в store...

Сейчас подумаю.
А где я написал что ошибка в truncation ??? Цитату пожалуйста. Ошибка в смешивании содержимого

Сорян, не так понял.

Это очень крутой баг Вы нашли.

Большое спасибо.

Сейчас исправлю.

Думаю сделать синхронизацию по canonicalName файла (строке).
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846450
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lelouchdakeiras,

Посмотрев ваш PR, хотелось бы уточнить - как вы поняли проблему теста TestIOExceptionOnLog?

Если диск переполняется или неправильные настройки Бобины (она не инициализируется), Вы бы хотели чтобы всё работало дальше - если Логгер не пашет.

Правильно понял Вас?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846452
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

Ок. Раз названия нету, назовем это конфигуразмом. Когда вместо программирования выносим в конфиг.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846454
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytondakeirasпропущено...


Что значит не ентерпрайзно? Зачем какие-то предосуждения?
Всё в CI, Travis CI, автоматизированные билды, snapshots.

https://travis-ci.com/INFINITE-TECHNOLOGY/BOBBIN

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

Насчёт Windows registry - стараюсь туда не заглядывать, в эту помойку.
Ну вот загляни. Там - нет кода. Ну 99.99% нет.
Просто концепция такая. И слава богу что нет.
Когда появится код - сопровождать систему станет на порядки сложно.
Потому что покорректировать параметр с 5 на 10 стоит одних человеческих усилий.
А просмотреть SPEL/MVEL или любой другой сниппет - уже можешь подряжать
в работу разаработчика.

А доказательтво правоты кода - вообще отдельная история. Об этом еще Гильберт
писал. О полноте...

Сорри, но это бесполезно. Спорить с людьми которые уверены что "конфиги не должны содержать динамически интерпретируемые скрипты". Это банальные предрассудки.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846455
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PetroNotC Sharpmayton,

Ок. Раз названия нету, назовем это конфигуразмом. Когда вместо программирования выносим в конфиг.

Нет. Декларативное XML программирование (logback.xml) переносится в императивное программирование Groovy (Bobbin.json).

Пример:
автор<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>

Вы считаете что это удобно?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846456
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PetroNotC Sharpmayton,

Ок. Раз названия нету, назовем это конфигуразмом. Когда вместо программирования выносим в конфиг.
Я помню что ребят из поддержки 1С часто назыли "конфигурастами".

Им обидно наверное было...
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846457
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasПринцип такой: чем раньше упадёт - тем лучше. А шанс того что упадёт само приложение чуть позже, если упал логгер - есть.

Это очередная "гениальная" фича в Logback - супрессить ошибки в логгере.Как человек, который более шести лет отработал в техподдержке региональной информационной системы, могу ответственно заявить, что с таким подходом вас примут только такие маргиналы, как и вы сами.
Задача любой системы - обслуживать пользователей. Протоколирование ошибок - всего лишь приятный бонус для разработчика. Но, тем, кто эксплуатирует систему, в достаточной степени наплевать на ваше (разработчика) удобство.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846458
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Log4j2 (текущих версий) конфигурится "ямлом".

https://logging.apache.org/log4j/2.x/manual/configuration.html

Достаточно лаконично. Тоесть лаконично настолько чтобы вообще не думать даже о какой-либо минимизации конфигов.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846459
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytondakeirasНасчёт Windows registry - стараюсь туда не заглядывать, в эту помойку.Ну вот загляни. Там - нет кода. Ну 99.99% нет.Вот-вот
Один вариантов сохранения "бестелесых" вирусов - хранение кода в реестре.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846465
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. Sidorovmaytonпропущено...
Ну вот загляни. Там - нет кода. Ну 99.99% нет.Вот-вот
Один вариантов сохранения "бестелесых" вирусов - хранение кода в реестре.
Ну эт. в тему стеганографии. Насколько я помню в таких случаях тело вируса безвредно.
И может годами лежать у вас локально и не тревожить.

А антивирус ищет даже не это тело а сам бут-страппер который должен это тело найти
и раскрутить дальше.

Помните RARJpeg и картинки с котиками где страшным водяным знаком прошито туловище
какого-нить wanna-cry или васи-вымогателя.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846470
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot Basil A. Sidorov]dakeirasПротоколирование ошибок - всего лишь приятный бонус для разработчика.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846473
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonLog4j2 (текущих версий) конфигурится "ямлом".

https://logging.apache.org/log4j/2.x/manual/configuration.html

Достаточно лаконично. Тоесть лаконично настолько чтобы вообще не думать даже о какой-либо минимизации конфигов.

А ну раз ямлом - то заебись! Пойду напишу вручную ямл на пару страниц.
И потом умру тихо.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846475
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonPetroNotC Sharpmayton,

Ок. Раз названия нету, назовем это конфигуразмом. Когда вместо программирования выносим в конфиг.
Я помню что ребят из поддержки 1С часто назыли "конфигурастами".

Им обидно наверное было...да, называли)). Пусть относятся к этому с юмором.
У нас тоже, декларативное программирование это конфигуразм.
))
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846481
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lelouch,

Пофиксил перемешивание данных.

Сейчас выложу версию.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846484
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasmaytonLog4j2 (текущих версий) конфигурится "ямлом".

https://logging.apache.org/log4j/2.x/manual/configuration.html

Достаточно лаконично. Тоесть лаконично настолько чтобы вообще не думать даже о какой-либо минимизации конфигов.

А ну раз ямлом - то заебись! Пойду напишу вручную ямл на пару страниц.
И потом умру тихо.
Я так и не дождался образца твоего конфига.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846486
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PetroNotC Sharpmaytonпропущено...

Я помню что ребят из поддержки 1С часто назыли "конфигурастами".

Им обидно наверное было...да, называли)). Пусть относятся к этому с юмором.
У нас тоже, декларативное программирование это конфигуразм.
))
Язык Пролог - декларативен почти совсем. И ничо. Работает в своем сегменте.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846496
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytondakeirasпропущено...


А ну раз ямлом - то заебись! Пойду напишу вручную ямл на пару страниц.
И потом умру тихо.
Я так и не дождался образца твоего конфига.

Код: 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.
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.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="InfiniteDebug" class="ch.qos.logback.classic.sift.SiftingAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>DEBUG</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <discriminator>
            <key>automaticThreadName</key>
            <defaultValue>Unnamed Thread</defaultValue>
        </discriminator>
        <sift>
            <appender name="${automaticThreadName}" class="ch.qos.logback.core.rolling.RollingFileAppender">
                <file>./LOGS/${automaticThreadName}/DEBUG/${automaticThreadName}_DEBUG_TODAY.log</file>
                <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                    <Pattern>%d{yyyy-MM-dd HH:mm:ss}:%level:%thread:%logger:%msg%n</Pattern>
                </encoder>
                <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                    <FileNamePattern>./LOGS/${automaticThreadName}/DEBUG/ARCHIVE/%d{yyyyMMdd, aux}/${automaticThreadName}_%d{yyyyMMdd}_DEBUG.zip</FileNamePattern>
                </rollingPolicy>
            </appender>
        </sift>
    </appender>
    <appender name="InfiniteInfo" class="ch.qos.logback.classic.sift.SiftingAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <discriminator>
            <key>automaticThreadName</key>
            <defaultValue>Unnamed Thread</defaultValue>
        </discriminator>
        <sift>
            <appender name="${automaticThreadName}" class="ch.qos.logback.core.rolling.RollingFileAppender">
                <file>./LOGS/${automaticThreadName}/INFO/${automaticThreadName}_INFO_TODAY.log</file>
                <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                    <Pattern>%d{yyyy-MM-dd HH:mm:ss}:%level:%thread:%logger:%msg%n</Pattern>
                </encoder>
                <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                    <FileNamePattern>./LOGS/${automaticThreadName}/INFO/ARCHIVE/%d{yyyyMMdd, aux}/${automaticThreadName}_%d{yyyyMMdd}_INFO.zip</FileNamePattern>
                </rollingPolicy>
            </appender>
        </sift>
    </appender>
    <appender name="InfiniteWarn" class="ch.qos.logback.classic.sift.SiftingAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>WARN</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <discriminator>
            <key>automaticThreadName</key>
            <defaultValue>Unnamed Thread</defaultValue>
        </discriminator>
        <sift>
            <appender name="${automaticThreadName}" class="ch.qos.logback.core.rolling.RollingFileAppender">
                <file>./LOGS/${automaticThreadName}/WARN/${automaticThreadName}_WARN_TODAY.log</file>
                <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                    <Pattern>%d{yyyy-MM-dd HH:mm:ss}:%level:%thread:%logger:%msg%n</Pattern>
                </encoder>
                <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                    <FileNamePattern>./LOGS/${automaticThreadName}/WARN/ARCHIVE/%d{yyyyMMdd, aux}/${automaticThreadName}_%d{yyyyMMdd}_WARN.zip</FileNamePattern>
                </rollingPolicy>
            </appender>
        </sift>
    </appender>
    <appender name="InfiniteError" class="ch.qos.logback.classic.sift.SiftingAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <discriminator>
            <key>automaticThreadName</key>
            <defaultValue>Unnamed Thread</defaultValue>
        </discriminator>
        <sift>
            <appender name="DEBUG_${automaticThreadName}" class="ch.qos.logback.core.rolling.RollingFileAppender">
                <file>./LOGS/${automaticThreadName}/ERROR/${automaticThreadName}_ERROR_TODAY.log</file>
                <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                    <Pattern>%d{yyyy-MM-dd HH:mm:ss}:%level:%thread:%logger:%msg%n</Pattern>
                </encoder>
                <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                    <FileNamePattern>./LOGS/${automaticThreadName}/ERROR/ARCHIVE/%d{yyyyMMdd, aux}/${automaticThreadName}_%d{yyyyMMdd}_ERROR.zip</FileNamePattern>
                </rollingPolicy>
            </appender>
        </sift>
    </appender>
    <appender name="System.out" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <Pattern>%d{yyyy-MM-dd HH:mm:ss}:%level:%thread:%logger:%msg%n</Pattern>
        </encoder>
    </appender>
    <logger name="io.infinite" level="debug" additivity="false">
        <appender-ref ref="InfiniteDebug"/>
        <appender-ref ref="InfiniteInfo"/>
        <appender-ref ref="InfiniteWarn"/>
        <appender-ref ref="InfiniteError"/>
    </logger>
    <root level="info">
        <appender-ref ref="System.out"/>
    </root>
</configuration>
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846504
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras,
А теперь рядом минимальный с логами default.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846507
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PetroNotC Sharpdakeiras,
А теперь рядом минимальный с логами default.

Зачем?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846508
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasLelouch,

Пофиксил перемешивание данных.

Сейчас выложу версию.

bobbinFile.getCanonicalPath().intern() - использование пула строк виртуальной машины не является хорошим решением - там и так их много (как минимум со слов Шипилева). А вы еще и вызываете попытку интернирования на каждую операцию.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846510
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lelouch,

Согласен. Откачу.

Подумаю ещё как исправить.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846531
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasPetroNotC Sharpdakeiras,
А теперь рядом минимальный с логами default.

Зачем?
Для quck start должна быть некая дефолтная конфигурация чтоб любой разработчик мог
легко интегрировать твоего Бобина в свой проект. В противном случае нужен шаблон или визард
создания Бобино-подобного проекта а это сам понимаешь - чёртов гиморр.

Причем дефолтная конфигурация должна быть компактна. Например как в log4j.

Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="Console"/>
    </Root>
  </Loggers>
</Configuration>



Что касается меня - так я ленив. Я-бы и это не писал. Но не писать совсем нельзя. Иначе аппеднеры не разберуться
куда писать. В консоль или в файл.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846536
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonтак я ленив.прям как я)))
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846541
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PetroNotC Sharpmaytonтак я ленив.прям как я)))

Третьим буду:)
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846547
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytondakeirasпропущено...


Зачем?
Для quck start должна быть некая дефолтная конфигурация чтоб любой разработчик мог
легко интегрировать твоего Бобина в свой проект. В противном случае нужен шаблон или визард
создания Бобино-подобного проекта а это сам понимаешь - чёртов гиморр.

Причем дефолтная конфигурация должна быть компактна. Например как в log4j.

Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="Console"/>
    </Root>
  </Loggers>
</Configuration>



Что касается меня - так я ленив. Я-бы и это не писал. Но не писать совсем нельзя. Иначе аппеднеры не разберуться
куда писать. В консоль или в файл.

Аа, сорян. Ты имеешь в виду стартовый конфиг Бобины.

Рад что такой вопрос, значит немного заинтересовало.

1) Бобина работает в минимуме вообще без конфига - пишет в консоль всё подряд.
2) Вот пример минимального конфига с файлом:
Код: javascript
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
{
  "destinations": [
    {
      "name": "io.infinite.bobbin.destinations.FileDestination",
      "properties": {
        "fileName": "\"./LOGS/THREADS/application.log\""
      }
    },
    {
      "name": "io.infinite.bobbin.destinations.ConsoleDestination"
    }
  ]
}



3) Вот пример конфига с указанием уровней, классов и разбиением на несколько файлов и указанием формата:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
{
  "levels": "['debug', 'info', 'warn', 'error', 'trace'].contains(level)",
  "classes": "className.contains('your.package.name')",
  "destinations": [
    {
      "name": "io.infinite.bobbin.destinations.FileDestination",
      "levels": "['info', 'warn', 'error', 'trace'].contains(level)",
      "classes": "className.contains('your.package.name.subpackage')",
      "properties": {
        "fileName": "\"./LOGS/${className}.log\""
      },
      "format": "\"${level}|${threadName}|${className}|${message}\\n\""
    },
    {
      "name": "io.infinite.bobbin.destinations.ConsoleDestination",
      "levels": "level=='info'"
    }
  ]
}
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846552
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Данный rule избыточен по своей природе.
Код: javascript
1.
"levels": "['debug', 'info', 'warn', 'error', 'trace'].contains(level)"



На самом деле здесь достаточно одного параметра
Код: java
1.
level = ....



Все остальные - из него вытекают.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846554
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это что?
Код: java
1.
"fileName": "\"./LOGS/${className}.log\""


На каждый className будет создаваться отдельный файл?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846566
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonЭто что?
Код: java
1.
"fileName": "\"./LOGS/${className}.log\""


На каждый className будет создаваться отдельный файл?

Я бы даже уточнил, что скрывается за className? Имя логгера (LoggerFactory.getLogger(SomeClass.class)) ? Или имя вызывающего класса?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846569
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonДанный rule избыточен по своей природе.
Код: javascript
1.
"levels": "['debug', 'info', 'warn', 'error', 'trace'].contains(level)"



На самом деле здесь достаточно одного параметра
Код: java
1.
level = ....



Все остальные - из него вытекают.

Не понял мысль. Что избыточно?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846570
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonЭто что?
Код: java
1.
"fileName": "\"./LOGS/${className}.log\""


На каждый className будет создаваться отдельный файл?

Да. Но так использовать не обязательно, это пример.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846573
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LelouchmaytonЭто что?
Код: java
1.
"fileName": "\"./LOGS/${className}.log\""


На каждый className будет создаваться отдельный файл?

Я бы даже уточнил, что скрывается за className? Имя логгера (LoggerFactory.getLogger(SomeClass.class)) ? Или имя вызывающего класса?

В терминологии Slf4j - имя логгера.
В терминологии Бобины - имя класса:

Конструктор Бобины:
Код: java
1.
2.
3.
    Bobbin(String className) {
        this.className = className
    }
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846576
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasmaytonДанный rule избыточен по своей природе.
Код: javascript
1.
"levels": "['debug', 'info', 'warn', 'error', 'trace'].contains(level)"



На самом деле здесь достаточно одного параметра
Код: java
1.
level = ....



Все остальные - из него вытекают.

Не понял мысль. Что избыточно?
Левел - это уровень. Как уровень воды в ведре. Он - один.

У тебя не может быть одновременно пол-ведра и четверть ведра.

Если логгирование грамотно спроектировано то детализация регулируется порогом чувствительности логгера.
И не должно быть попытки логгировать WARN + TRACE при этом забить болт на промежуточные уровни.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846581
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasLelouchпропущено...


Я бы даже уточнил, что скрывается за className? Имя логгера (LoggerFactory.getLogger(SomeClass.class)) ? Или имя вызывающего класса?

В терминологии Slf4j - имя логгера.
В терминологии Бобины - имя класса:

Конструктор Бобины:
Код: java
1.
2.
3.
    Bobbin(String className) {
        this.className = className
    }


Ты-же понимаешь что в контексте одного jvm процесса могут существовать несколько одинаковых className
в разных класслоадерах. Ты-же понимаешь что для некоторых сущностей (анонимные классы) сложно
определить className.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846583
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasLelouchпропущено...


Я бы даже уточнил, что скрывается за className? Имя логгера (LoggerFactory.getLogger(SomeClass.class)) ? Или имя вызывающего класса?

В терминологии Slf4j - имя логгера.
В терминологии Бобины - имя класса:

Конструктор Бобины:
Код: java
1.
2.
3.
    Bobbin(String className) {
        this.className = className
    }



Почему не использовать общепринятую терминологию Slf4j?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846602
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lelouchdakeirasпропущено...


В терминологии Slf4j - имя логгера.
В терминологии Бобины - имя класса:

Конструктор Бобины:
Код: java
1.
2.
3.
    Bobbin(String className) {
        this.className = className
    }



Почему не использовать общепринятую терминологию Slf4j?

Я принимаю API (интерфейс) Slf4j (хотя и он под вопросом - см. Google Flogger).
На этом я ограничился в основном.

Это же касается и уровней логирования:
авторЛевел - это уровень. Как уровень воды в ведре. Он - один.

У тебя не может быть одновременно пол-ведра и четверть ведра.

Если логгирование грамотно спроектировано то детализация регулируется порогом чувствительности логгера.
И не должно быть попытки логгировать WARN + TRACE при этом забить болт на промежуточные уровни.

Это ущербная философия log4j.
Один человек сделал (автор), теперь все повторяют за ним.

В Бобине всё иначе.

Вот документация:
https://github.com/INFINITE-TECHNOLOGY/BOBBIN/wiki/2---Key-Features#events

Events
In Object-oriented terms, existing logging frameworks consider log messages as events belonging to the same hierarchy:

- Trace
- Debug extends Trace
- Info extends Debug
- Warning extends Info
- Error extends Warning
This happens due to comparable nature of conventional Log Levels: e.g. Trace < Debug < Info < Warning < Error.

This is a traditional paradigm which is so old that people just take it is as something granted and immutable.

We change this paradigm.

Bobbin considers log messages as separate independent events with different types (as per their level).

With Bobbin it is possible to configure enabled logger levels in a granular way without filter, using array:

Код: javascript
1.
2.
3.
{
  "levels": "['info'].contains(level)"
}
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846603
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytondakeirasпропущено...


В терминологии Slf4j - имя логгера.
В терминологии Бобины - имя класса:

Конструктор Бобины:
Код: java
1.
2.
3.
    Bobbin(String className) {
        this.className = className
    }


Ты-же понимаешь что в контексте одного jvm процесса могут существовать несколько одинаковых className
в разных класслоадерах. Ты-же понимаешь что для некоторых сущностей (анонимные классы) сложно
определить className.
В 99% случаев это class name. И нет смысла его по другому называть из-за 1% случаев.
Это контр-интуитивно.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846604
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нет ни одной, ни малейшей причины считать что например error это подмножество debug, как это делается во всех остальных логгеров.
Это ярчайшая наркомания, от которой волосы дыбом встают в 2019 году.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846607
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lelouch,

Пофиксил смешение данных, 2.0.7.

Ещё раз огромное спасибо. Сразу видно - человек мега мозг Java.
Сходу такое увидеть. Респект нереальный.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846617
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasLelouch,

Пофиксил смешение данных, 2.0.7.

Ещё раз огромное спасибо. Сразу видно - человек мега мозг Java.
Сходу такое увидеть. Респект нереальный.

Поправочка, 2.0.8...
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846621
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasmaytonпропущено...

Ты-же понимаешь что в контексте одного jvm процесса могут существовать несколько одинаковых className
в разных класслоадерах. Ты-же понимаешь что для некоторых сущностей (анонимные классы) сложно
определить className.
В 99% случаев это class name. И нет смысла его по другому называть из-за 1% случаев.
Это контр-интуитивно.
Упорство - это хорошая черта. Я уважаю упорных.

Но иногда упорство переходит в твердолобость.

Как мы объясним пользователю или кастомеру clash имен классов?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846622
vas0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras,

Мельком глянул код например здесь,
Код: java
1.
2.
3.
4.
5.
class Bobbin extends MarkerIgnoringBase {
    String className
    List<Destination> destinations = new ArrayList<>()
    BobbinScriptEngine bobbinScriptEngine
}

У тебя же код выполняется в многопоточной среде так? А классы потоко-небезопастны. За счет чего у тебя идет согласованное чтение/запись если ты не используешь никакие примитивы синхронизации (synchronized, volatile, ReentrantLock) ?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846623
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytondakeirasпропущено...

В 99% случаев это class name. И нет смысла его по другому называть из-за 1% случаев.
Это контр-интуитивно.
Упорство - это хорошая черта. Я уважаю упорных.

Но иногда упорство переходит в твердолобость.

Как мы объясним пользователю или кастомеру clash имен классов?
Ок, без проблем. Пусть будет Logger Name ( in most cases Class Name). Ок?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846624
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vas0,

Тут вообще весь проект и всё обсуждение строится на многопоточности и как оптимизировать быстродействие синхронизации.

На текущий момент:
- Файлы в ThreadLocal, чтобы не была запись в чужой файл
- ConcurrentHashMap + ReentrantLock - чтобы в одном файле строки выводились синхронно для разных потоков

Всё остальное потокобезопасно и не требует синхронизации.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846625
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasmaytonпропущено...

Упорство - это хорошая черта. Я уважаю упорных.

Но иногда упорство переходит в твердолобость.

Как мы объясним пользователю или кастомеру clash имен классов?
Ок, без проблем. Пусть будет Logger Name ( in most cases Class Name). Ок?
Да это ОК.

Был такой персонаж. Капитан Врунглель.
Он говорил - Как вы яхту назовёте - так она и поплывет.

Логгер - должен называться логгер. А никак не className. И вообще в современной JDK
не стоит завязываться на имя класса. И семантика должна быть как у логгера.
А не как у класса. Логгер - важен. Логгер может накрывать группу классов.
Имя логгера может браться откуда угодно. Он может быть динамичен. Но он не может
быть равен 1:1 с классом. Классы - сущность которой управляет класслоадер.
Логгеры - сущность которой управляем мы и бизнес.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846626
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytondakeirasпропущено...

Ок, без проблем. Пусть будет Logger Name ( in most cases Class Name). Ок?
Да это ОК.

Был такой персонаж. Капитан Врунглель.
Он говорил - Как вы яхту назовёте - так она и поплывет.

Логгер - должен называться логгер. А никак не className. И вообще в современной JDK
не стоит завязываться на имя класса. И семантика должна быть как у логгера.
А не как у класса. Логгер - важен. Логгер может накрывать группу классов.
Имя логгера может браться откуда угодно. Он может быть динамичен. Но он не может
быть равен 1:1 с классом. Классы - сущность которой управляет класслоадер.
Логгеры - сущность которой управляем мы и бизнес.
Ок, согласен. Спасибо.

Чуть позже переименую переменную.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846741
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasГде я кого-то высокомерно оценивал? Можно пример или цитату мою?


А пожалуйста:
dakeirasлегкой и простой настройкой (в отличии от невменяемых настроек других логгеров)


dakeirasПо какому уровню Log4j? Совершенно не индустриальная библиотека, которая по стечению обстоятельств и отсутствия альтернатив стала популярной.
У неё совершенно упоротая концепция иерархических логгеров - абсолютно не удобная привязка к уровню логирования.
Непонятно почему нельзя было изначально сделать её нормально.

Достаточно?

dakeirasВ данном случае (как и в нескольких других в этой теме от других комментаторов) вы переходите на личности, зачем-то подразумеваете мою тупость и пр.

Вы сами первый начали.
Вообще начать тему с заявления "20 лет все фигнёй занимались а я тут пришёл и сделал намного лучше" - это подставится под сильную критику.

dakeirasавторТо ли что не понимает, что документацию пишуют чтобы читать, а не чтобы высокомерно отвергать.
Не совсем понял, вы про какую документацию? Есть Вики, там довольно детально всё описано.
Никто ничего не отвергает.

Вам сразу указали на то, что нельзя использовать SimpleDateFormat в многопоточном коде. Что в его документации это явно написано.
Но зачем-то Вы упёрлись, что можно, что "я тестировал" (тут Шипёлёв привычно икнул).

Ну и вооще- предлагать всем библиотеку логирования, которая тащит с собой несколько мегабайт зависимостей (groovy-runtime) - это странной действо, заставляющее перейти на личность автора.
SDK это такая вещь, в которой размер имеет значение.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846765
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey Tomin,
+1
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846842
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey Tomin,

Вы скачали Бобину? Попробуйте.
Удивитесь, насколько всё сделано лучше чем logback.

А так Ваша предвзятость обоснована уверенностью, что «всё уже изобретено» и всё новое (особенно от неизвестных авторов) - не нужно.

Советую менять настрой. Вот только краткий список проектов в Pipeline:
- Портирование BlackBox на GCLIB - автоматическое добавление логирования на этапе компиляции. Реализовано сейчас на Groovy AST и работает только с Груви кодом
- Step Up авторизационный сервер и валидация JWT без обращения к БД - при помощи regex, и настройкой доступа на авторизационном сервере (а не на сервере ресурсов) - в универсальной форме
- Универсальный CRUD GUI к HATEOAS сервисам на ReactJs

Из того что уже сделано:
- Pigeon - рассылки и push notifications (SOAP, REST)
- BlackBox - уникальный проект по автоматическому добавлению логирования с помощью аннотации (на уровнях от Ошибки с аргументами вызова, Вызова метода, Стейтментов - и до самого НИЖНЕГО уровня - expression). Работает на Груви AST API.
- Supplies - разные утилиты мелкие
Ну и сама Бобина.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846851
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну и вооще- предлагать всем библиотеку логирования, которая тащит с собой несколько мегабайт зависимостей (groovy-runtime) - это странной действо, заставляющее перейти на личность автора.
SDK это такая вещь, в которой размер имеет значение.

Место на диске чтоли кончится?))
Вы похоже из любителей битовых масок в прикладных приложениях)
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846873
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras, по поводу скачать и попробовать. Я обещаю что когда-нибудь попробую.
Но до того как попробовать я обычно пытаюсь понять каково "прендазначение" вещи.
Например. Предназначение жопы - чтобы испражняться. Хотя есть некоторые
любители странного секса которые хотят погрузить в чью-то жопу свой крайний
отросток. И когда например мен на code-review приносят константы завёрнутые
в java interface - я просто спрашиваю. Ты что - любишь совокупляться в жопу?

Понятно да?

Предназначение. Ты должен сообществу объяснить предназначение твоей библиотеки.
Про BlackBox можешь даже не рассказывать. Форум не знает что это такое и никому
не интересны твои тестерские практики. Плевать на блек бокс. У нас - другие задачи.

Далее. По поводу Толстого Бобина.

И какую идею закладывал туда автор. Или какую философию. Обычно зрелость
продукта определяется этим. Например Log4j2 в режиме Async использует (косвенно)
зависимость от библиотеки неблокирующих очередей disruptor. Эта библиотечка
буферизирует не дисковый трафик а именно события. Events. Вот такая вот идея.
Хотя возможность асинхронной записи в файл тоже поддерживается но это другая
настройка.

За кадром остался вопрос перформанса. Ты так и не предоставил сообществу никаких
бенчмарков. Я по прежнему убёжден что Groovy генерирует самый медленный код
(для интенсивных вычислений) и никто меня не убедил в обратном. Грубо говоря
в линейке Java/Kotlin/Scala/Groovy, последний занимает последнее место. Груви - медленный
покемон в этом списке. И ты выкатил на общий суд тайм-критичную библиотеку взяв
за основу самый медленный компиллятор.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846892
Фотография Valentin Kolesnikov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Может вам будет полезен метод U.format(string, .. args) в библиотеке из соседней ветки.

20531307

Хорошего Вам дня!
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846908
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasВы скачали Бобину? Попробуйте.

Я вроде уже объяснил причину, почему не буду это делать.

dakeirasУдивитесь, насколько всё сделано лучше чем logback.

У меня код очень многопоточный, с высоким требованием к производительности. После SimpleDateFormat дальше читать не интересно- если есть столь очевидная бага- зачем искать другие? Конкаренси баги могут стрелять очень редко и ОЧЕНЬ больно. Мне наших баг хватает. logback работает быстро и надёжно.

dakeirasА так Ваша предвзятость обоснована уверенностью, что «всё уже изобретено» и всё новое (особенно от неизвестных авторов) - не нужно.

Нет.
Чтобы изобрести что-то хорошее, надо сначала понять то, что сделали предшественники.
Для тестов использовать JMH например. И показывать преимущество в виде конкретных тестов, которые каждый может запустить и получить результат.

Показать преимущество настройки в виде примеров, а не просто слов.

Ну и груви я только удаляю из кода- мне не нравится базовая идея (заметьте- я не говорю, что она плохая).

dakeiras- BlackBox - уникальный проект по автоматическому добавлению логирования с помощью аннотации (на уровнях от Ошибки с аргументами вызова, Вызова метода, Стейтментов - и до самого НИЖНЕГО уровня - expression).

Я тут думаю, как очень нужную либу перевести с кодогенерации при компиляции на лямбды- потому что "добавление кода в компиляции"- это добавление проблем в отладке.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846929
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Давайте здесь не обсуждать производительность Груви.
Это оффтопик.
Можно отдельную тему сделать. Если в кратце - Вы заблуждаетесь, это опять же МИФ, основанный на ОООЧЕНЬ ранних версиях (более 8 лет назад). Ещё раз повторю что используется @CompileStatic во всех классах Бобины, так что он даёт просто обычный Java код.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846930
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я уже даже приводил пример декомпилированного класса в этой теме, если охота - можно посмотреть и убедиться.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846937
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторПосле SimpleDateFormat дальше читать не интересно- если есть столь очевидная бага- зачем искать другие
Мой богатый опыт подсказывает что что-то очевидно только при поверхностном ознакомлении.

Изначально ВСЕ экземпляры класса Bobbin были в ThreadLocal.
Так что не было это микроскопической баги с SimpleDateFormat.

Потом дизайн поменяли, и это стало актуально. Уже исправлено.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846948
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторТы должен сообществу объяснить предназначение твоей библиотеки.
Про BlackBox можешь даже не рассказывать. Форум не знает что это такое и никому
не интересны твои тестерские практики. Плевать на блек бокс. У нас - другие задачи.

Далее. По поводу Толстого Бобина.

И какую идею закладывал туда автор. Или какую философию. Обычно зрелость
продукта определяется этим. Например Log4j2 в режиме Async использует (косвенно)
зависимость от библиотеки неблокирующих очередей disruptor. Эта библиотечка
буферизирует не дисковый трафик а именно события. Events. Вот такая вот идея.
Хотя возможность асинхронной записи в файл тоже поддерживается но это другая
настройка.

За кадром остался вопрос перформанса. Ты так и не предоставил сообществу никаких
бенчмарков. Я по прежнему убёжден что Groovy генерирует самый медленный код
(для интенсивных вычислений) и никто меня не убедил в обратном. Грубо говоря
в линейке Java/Kotlin/Scala/Groovy, последний занимает последнее место. Груви - медленный
покемон в этом списке. И ты выкатил на общий суд тайм-критичную библиотеку взяв
за основу самый медленный компиллятор.

Из readme.md:

авторBobbin is a high-performance Groovy Slf4j-compatible logger designed for multi-threaded applications (especially those with persistent threads like batch and messaging applications).

Bobbin leverages the concept of Logback/Log4j2 sifting appenders while providing much more easier configuration using native Groovy/Java scripting expressions.

https://github.com/INFINITE-TECHNOLOGY/BOBBIN

Из Вики:

авторBobbin creates multiple isolated log files using a simple JSON configuration supporting Groovy Scripts to compute file names and other dynamic parameters during run-time.

Some of the File name segregation criteria include:

- Thread Name
- - Thread Group Name
- Class Name
- Log level
- MDC values
- Date
- Any other run-time parameters and their combinations
Bobbin leverages the concept of Logback/Log4j2 sifting appenders while providing much more easier configuration using native Groovy/Java scripting expressions.

Bobbin is high-performance logger optimized to be used in heavy load multi-threaded environments (with hundreds of persistent threads - especially those with persistent threads like batch and messaging applications).

It's CPU, GC and RAM footprint has been tuned to work as a primary logger within Spring stack, including Web context and JPA.

https://github.com/INFINITE-TECHNOLOGY/BOBBIN/wiki

Не хотел этого говорить, но "не читал, но осуждаю"...

Насчёт Бенчмарка: будет в течении 3-4 дней:
- Однопоточная работа в 1 файл
- Однопоточная работа в много файлов
- Многопоточная в 1 файл
- Многопоточная в много файлов со смешиванием потоков
- Многопоточная в много файлов без смешивания потоков (1 поток на файл)

авторНу и груви я только удаляю из кода- мне не нравится базовая идея (заметьте- я не говорю, что она плохая).
Вот и причина Вашей предвзятости.
В своё время лень было изучить - значит "не понравилась идея".

Как тут написали, люди 10 лет делали Груви, а тут такой кадр нарисовался - и ему идея не нравится.
Зато появился котлин - сразу всем понравилось :) Потому что он продвинут при нечестной конкуренции.
И не поддерживает и половины функционала Груви.

авторДля тестов использовать JMH например. И показывать преимущество в виде конкретных тестов, которые каждый может запустить и получить результат.
Спасибо за инфо, изучу и возможно использую.

авторЯ тут думаю, как очень нужную либу перевести с кодогенерации при компиляции на лямбды- потому что "добавление кода в компиляции"- это добавление проблем в отладке.
Зато лямбды это легко отлаживать.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846950
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мы все ждем тестов с @Jmh.

Нужно убедительное доказательство перформанса. Иначе - это не интересно.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846954
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Валентин Колесников,

авторМожет вам будет полезен метод U.format(string, .. args) в библиотеке из соседней ветки.

20531307

Хорошего Вам дня!

Мощь. Обязательно изучу.
Уже сейчас её можно использовать с Бобиной, добавив в билд - и настроив format в Bobbin.json:

Код: javascript
1.
"format": "U.format(\"DateTime = {} Message = {}\", dateTime, message)",
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846955
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonМы все ждем тестов с @Jmh.

Нужно убедительное доказательство перформанса. Иначе - это не интересно.

Оки. Скоро будет бенчмарк.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846968
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras- Многопоточная в 1 файл
- Многопоточная в много файлов со смешиванием потоков


Этого достатоно. Если интересует скорость, то потоков будет много, а читать десятки файлов логов- так себе занятие.

dakeirasавторНу и груви я только удаляю из кода- мне не нравится базовая идея (заметьте- я не говорю, что она плохая).
Вот и причина Вашей предвзятости.
В своё время лень было изучить - значит "не понравилась идея".


Да я писал даже на нём. Работало. Для примитивных проектов типа UI пойдёт. Писать многопоточную математику- ад.

dakeirasКак тут написали, люди 10 лет делали Груви, а тут такой кадр нарисовался - и ему идея не нравится.


Вы не понимаете разницы между "мне не нравится" и "Совершенно не индустриальная библиотека, которая по стечению обстоятельств и отсутствия альтернатив стала популярной.", "в отличии от невменяемых настроек других логгеров" и свежего перла "продвинут при нечестной конкуренции"?

dakeirasЗато появился котлин - сразу всем понравилось :) Потому что он продвинут при нечестной конкуренции.
И не поддерживает и половины функционала Груви.


Понравился он далеко не всем и не сразу. Кто-то дальше любит scala, кто-то ceylon, кто-то groovy. Каждому своё.
А про "нечестную конкуренцию"- вот это интересно- расскажите, пожалуйста.

dakeirasавторЯ тут думаю, как очень нужную либу перевести с кодогенерации при компиляции на лямбды- потому что "добавление кода в компиляции"- это добавление проблем в отладке.
Зато лямбды это легко отлаживать.

Я дебажил и грувивскую "магию", и самописную кодогенерацию и лямбды.
Можете верить, можете нет- но лямбды дебажить проще всего.
Особенно "прелестно" втыкать в ошибки самописного мавен-плагина. Вот у нас в 5% билдов почему-то падает с безумным стектрейсом- я даже браться за это не хочу...
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846972
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторА про "нечестную конкуренцию"- вот это интересно- расскажите, пожалуйста.


Элементарно. Забашляли Гуглу чтобы Идею протолкнуть в Android Studio и далее - забашляли чтобы сделать Котлин офиц. языком для Android.

Котлин вообще появился без надобности, нет у него use case.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846974
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я уже молчу, что сама Intellij Idea застряла по функционалу в 2000х.

Не могут до сих пор нормальную поддержку Gradle сделать.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846976
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasавторА про "нечестную конкуренцию"- вот это интересно- расскажите, пожалуйста.


Элементарно. Забашляли Гуглу чтобы Идею протолкнуть в Android Studio и далее - забашляли чтобы сделать Котлин офиц. языком для Android.

Бред какой.
IDEA сдала Android Studio потому что работники гугла пользовуются перешли на IDEA. Вот и всё.
У них вообще в разработки порядка особо нет и деньги не сделали бы ничего.
Поддержали котлин в андроид потому что решили, что это хорошо для андроид и всё.

dakeirasКотлин вообще появился без надобности, нет у него use case.

Бреслав прямым текстом говорил, что цели создания котлина (в порядке его приоритетов):
- потому что это интересно
- у фирмы достаточно денег, чтобы выделить работников для разработки неведомой фигни с нулевой одходностью
- они хотели поднять свой статус как фирмы
- на java писать надоело и непродуктивно, а scala/groovy не вызывали энтузиазма.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846978
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сборщиков много. И среда вовсе не обязана поддержать их всех на 100%.

Понимаете да? Это не ее ответственность поддерживать всех и вся. Иначе стоимость
техподдержки превысит вообще прибыль от существования проекта.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846981
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonСборщиков много. И среда вовсе не обязана поддержать их всех на 100%.

Понимаете да? Это не ее ответственность поддерживать всех и вся. Иначе стоимость
техподдержки превысит вообще прибыль от существования проекта.

Это смешно.

Есть 2 сборщика: Maven и Gradle.

И среда:
1) Обязана их поддерживать
2) В 2019 НЕ должна изобретать свою сборку ("проект\модули")

Иначе такая среда не нужна. Есть индустриальный стандарт в Java.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846986
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey Tomindakeirasпропущено...


Элементарно. Забашляли Гуглу чтобы Идею протолкнуть в Android Studio и далее - забашляли чтобы сделать Котлин офиц. языком для Android.

Бред какой.
IDEA сдала Android Studio потому что работники гугла пользовуются перешли на IDEA. Вот и всё.
У них вообще в разработки порядка особо нет и деньги не сделали бы ничего.
Поддержали котлин в андроид потому что решили, что это хорошо для андроид и всё.

dakeirasКотлин вообще появился без надобности, нет у него use case.

Бреслав прямым текстом говорил, что цели создания котлина (в порядке его приоритетов):
- потому что это интересно
- у фирмы достаточно денег, чтобы выделить работников для разработки неведомой фигни с нулевой одходностью
- они хотели поднять свой статус как фирмы
- на java писать надоело и непродуктивно, а scala/groovy не вызывали энтузиазма.

Вы просто подтвердили мои слова.

Тут есть ещё момент - суды между Oracle и Google касательно Java в Android.
Но Гугл должен был выбрать Груви, а не котлин.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846988
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasmaytonСборщиков много. И среда вовсе не обязана поддержать их всех на 100%.

Понимаете да? Это не ее ответственность поддерживать всех и вся. Иначе стоимость
техподдержки превысит вообще прибыль от существования проекта.

Это смешно.

Есть 2 сборщика: Maven и Gradle.

И среда:
1) Обязана их поддерживать
2) В 2019 НЕ должна изобретать свою сборку ("проект\модули")

Иначе такая среда не нужна. Есть индустриальный стандарт в Java.
Я sbt пользуюсь. И он хреново поддерживается. Что мне делать?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846989
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasТут есть ещё момент - суды между Oracle и Google касательно Java в Android.
Но Гугл должен был выбрать Груви, а не котлин.
Зачем ты в технический топик затаскиваешь суды крупных контор?
Это вообще никаким боком не имеет отношения к теме топика.

Обсуждаем Толстого Робина-Бобина.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846990
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytondakeirasпропущено...


Это смешно.

Есть 2 сборщика: Maven и Gradle.

И среда:
1) Обязана их поддерживать
2) В 2019 НЕ должна изобретать свою сборку ("проект\модули")

Иначе такая среда не нужна. Есть индустриальный стандарт в Java.
Я sbt пользуюсь. И он хреново поддерживается. Что мне делать?

Ничего не сделать. А стоит Идея конски в месяц.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39846991
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytondakeirasТут есть ещё момент - суды между Oracle и Google касательно Java в Android.
Но Гугл должен был выбрать Груви, а не котлин.
Зачем ты в технический топик затаскиваешь суды крупных контор?
Это вообще никаким боком не имеет отношения к теме топика.

Обсуждаем Толстого Робина-Бобина.

Оки.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847000
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey Tomin,

Кстати, посмотрел код и возникли вопросы:
1. В FileDestination в 100-поточном коде будет создано 100 объектов типа "файл" для одного (реального) файла. Зачем это надо? Не говоря уже про расход памяти- зачем?
2. За счёт чего Ваш код должен быть быстрее logback? Какие проблемы Вы в нём нашли?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847003
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasЕсть 2 сборщика: Maven и Gradle.

И среда:
1) Обязана их поддерживать
2) В 2019 НЕ должна изобретать свою сборку ("проект\модули")

Иначе такая среда не нужна. Есть индустриальный стандарт в Java.

1. А как же Bazel?
2. Каким образом среда оказалась Вам должна?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847004
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasНо Гугл должен был выбрать Груви, а не котлин.

Опять "должен". Когда это Гугл задолжал Вам?
Они выбрали то, что считали лучшим. Не согласны- Ваше право.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847012
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasя уже молчу, что сама Intellij Idea застряла по функционалу в 2000х.

Не могут до сих пор нормальную поддержку Gradle сделать.

1. А кто обогнал IDEA? Что сильно лучше?
2. По поводу поддержки gradle. Вы просто, видимо, не делали подобные вещи.

Несложно "разобрать" maven-проект (хотя наши бойцы сумели тут удивить IDEA - не каждая версия может собрать наши проекты- но это просто от зуда от шила в ж..е). В вот gradle - это не метаинформация, это набор команд. И чтобы нормально его поддержать- надо понять, что автор сего думал. Это очень сложная задача.
Хотите сделать лучше? Ну так сделайте.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847020
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey TomindakeirasЕсть 2 сборщика: Maven и Gradle.

И среда:
1) Обязана их поддерживать
2) В 2019 НЕ должна изобретать свою сборку ("проект\модули")

Иначе такая среда не нужна. Есть индустриальный стандарт в Java.

1. А как же Bazel?
2. Каким образом среда оказалась Вам должна?

Я бабло за неё башляю, каждые 3 месяца. Притом дорого стоит.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847022
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey TominAlexey Tomin,

Кстати, посмотрел код и возникли вопросы:
1. В FileDestination в 100-поточном коде будет создано 100 объектов типа "файл" для одного (реального) файла. Зачем это надо? Не говоря уже про расход памяти- зачем?
2. За счёт чего Ваш код должен быть быстрее logback? Какие проблемы Вы в нём нашли?

Как минимум за счёт отсутствия волшебного синтаксиса "форматирования" сообщения.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847026
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey Tomindakeirasя уже молчу, что сама Intellij Idea застряла по функционалу в 2000х.

Не могут до сих пор нормальную поддержку Gradle сделать.

1. А кто обогнал IDEA? Что сильно лучше?
2. По поводу поддержки gradle. Вы просто, видимо, не делали подобные вещи.

Несложно "разобрать" maven-проект (хотя наши бойцы сумели тут удивить IDEA - не каждая версия может собрать наши проекты- но это просто от зуда от шила в ж..е). В вот gradle - это не метаинформация, это набор команд. И чтобы нормально его поддержать- надо понять, что автор сего думал. Это очень сложная задача.
Хотите сделать лучше? Ну так сделайте.

Они и тут нечестную конкуренцию используют - kotlin dsl нормально поддерживается в Идее, а вот Груви - нет.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847027
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasAlexey Tominпропущено...


1. А кто обогнал IDEA? Что сильно лучше?
2. По поводу поддержки gradle. Вы просто, видимо, не делали подобные вещи.

Несложно "разобрать" maven-проект (хотя наши бойцы сумели тут удивить IDEA - не каждая версия может собрать наши проекты- но это просто от зуда от шила в ж..е). В вот gradle - это не метаинформация, это набор команд. И чтобы нормально его поддержать- надо понять, что автор сего думал. Это очень сложная задача.
Хотите сделать лучше? Ну так сделайте.

Они и тут нечестную конкуренцию используют - kotlin dsl нормально поддерживается в Идее, а вот Груви - нет.

я имею в виду gradle dsl
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847044
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasAlexey Tominпропущено...


1. А кто обогнал IDEA? Что сильно лучше?
2. По поводу поддержки gradle. Вы просто, видимо, не делали подобные вещи.

Несложно "разобрать" maven-проект (хотя наши бойцы сумели тут удивить IDEA - не каждая версия может собрать наши проекты- но это просто от зуда от шила в ж..е). В вот gradle - это не метаинформация, это набор команд. И чтобы нормально его поддержать- надо понять, что автор сего думал. Это очень сложная задача.
Хотите сделать лучше? Ну так сделайте.

Они и тут нечестную конкуренцию используют - kotlin dsl нормально поддерживается в Идее, а вот Груви - нет.
Ну Kotlin это их собственная разработка.

Представь что я пожаловался что iPhone не поддерживает зарядки от Xiaomi. А должен?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847059
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytondakeirasпропущено...


Они и тут нечестную конкуренцию используют - kotlin dsl нормально поддерживается в Идее, а вот Груви - нет.
Ну Kotlin это их собственная разработка.

Представь что я пожаловался что iPhone не поддерживает зарядки от Xiaomi. А должен?

эээээ, да.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847062
betelgeizex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
dakeiras,

Groovy - по определению медленный язык, даже с CompileStatic.
Вот идиоматичный код на груви (компилируется и выполняется успешно):

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
@CompileStatic
class Test1 {

    static void main(String[] args) {
        if (!args) {
            println("error")
        }
        // TODO
    }
}



После декомпиляции получаю вот это:

Код: java
1.
2.
3.
4.
5.
6.
7.
  public static void main(String... args) {
        if (!DefaultTypeTransformation.booleanUnbox(args)) {
            DefaultGroovyMethods.println(Test1.class, "error");
            Object var10000 = null;
        }

  }



Спускаюсь по коду DefaultTypeTransformation.booleanUnbox , и в итоге вижу вот это:

Код: java
1.
2.
        // if the object is not null and no Boolean, try to call an asBoolean() method on the object
        return (Boolean) InvokerHelper.invokeMethod(object, "asBoolean", InvokerHelper.EMPTY_ARGS);



Можете сами проверить. В стандартной библиотеке рефлексия везде! Какая тут производительность?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847064
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasAlexey Tomin2. За счёт чего Ваш код должен быть быстрее logback? Какие проблемы Вы в нём нашли?
Как минимум за счёт отсутствия волшебного синтаксиса "форматирования" сообщения.

Это про что конкретно? Если есть поддержка SLF4J то это тоже есть. А у Вас вроде есть.

dakeirasОни и тут нечестную конкуренцию используют - kotlin dsl нормально поддерживается в Идее, а вот Груви - нет.

Я писал компилятор, несколько раз.
И понимаю, что поддержку kotlin DSL сделать в разы проще, чем грэдла/груви.

Вообще Kotlin мне нравится тем, что я понимаю, как это в кишочках всё работает. Это вообще кайф- понимать внутренности. Больше был только когда Module2 изучал- но он намного проще.
Особенно когда представляешь, какого разбирать тот же groovy или (чур меня, чур) С (С++ даже пытаюсь- мозг взорвётся).
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847076
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey Tomin,

авторМожете сами проверить. В стандартной библиотеке рефлексия везде! Какая тут производительность?

Так в 2006м году считалось, что рефлексия медленная.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847086
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasAlexey Tomin,

авторМожете сами проверить. В стандартной библиотеке рефлексия везде! Какая тут производительность?

Так в 2006м году считалось, что рефлексия медленная.
А что случилось с 2006 года?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847127
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytondakeirasAlexey Tomin,

пропущено...


Так в 2006м году считалось, что рефлексия медленная.
А что случилось с 2006 года?

https://docs.oracle.com/javase/8/docs/technotes/guides/reflection/enhancements.html#a1.4
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847131
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasmaytonпропущено...

А что случилось с 2006 года?

https://docs.oracle.com/javase/8/docs/technotes/guides/reflection/enhancements.html#a1.4
Дорогой друг. Можно попросить тебя не разговаривать ссылками.
В противном случае у нас разговор получается ниочем. Ты мне дал ссылку где нет цифр.
И нет оценки пользы или вреда от рефлексии или ее использования или не использования.
Мы не знаем сколько тактов CPU стоит рефлексия. И похоже ты, не знаешь как Groovy
работает с типизаций.

Поэтому. Будь добр. Разворачивай свою мысль. И у нас получится диалог.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847141
betelgeizex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
dakeirasmaytonпропущено...

А что случилось с 2006 года?

https://docs.oracle.com/javase/8/docs/technotes/guides/reflection/enhancements.html#a1.4

https://docs.oracle.com/javase/tutorial/reflect/index.html

авторThe Java Tutorials have been written for JDK 8.
...
reflective operations have slower performance than their non-reflective counterparts, and should be avoided in sections of code which are called frequently in performance-sensitive applications.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847142
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytondakeirasпропущено...


https://docs.oracle.com/javase/8/docs/technotes/guides/reflection/enhancements.html#a1.4
Дорогой друг. Можно попросить тебя не разговаривать ссылками.
В противном случае у нас разговор получается ниочем. Ты мне дал ссылку где нет цифр.
И нет оценки пользы или вреда от рефлексии или ее использования или не использования.
Мы не знаем сколько тактов CPU стоит рефлексия. И похоже ты, не знаешь как Groovy
работает с типизаций.

Поэтому. Будь добр. Разворачивай свою мысль. И у нас получится диалог.
Вы спросили, что изменилось - я ответил. Оптимизировали рефлексию, она перестала "тормозить".
В Java рефлексия одна из основных фич. Без неё Java вообще не нужна.

Если не нравится рефлексия - пишите на C.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847145
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторreflective operations have slower performance than their non-reflective counterparts, and should be avoided in sections of code which are called frequently in performance-sensitive applications.

YouTube Video
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847146
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл добавить, управляющую программу на Groovy написал и придумал я.
Это была первая в МИРЕ управляющая программа для ровера на Груви.

Она опрашивала джойстик и управляла PWM драйверами через i2c.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847147
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
и там использовалась система логирования - предвестник Bobbin.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847153
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonА что случилось с 2006 года?тут уже показывали кино с что такое современная рефлексия, и не однократно. там чел на примерах показывал время срабатывания.
современная рефлексия очень даже быстрая.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847194
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вадяmaytonА что случилось с 2006 года?тут уже показывали кино с что такое современная рефлексия, и не однократно. там чел на примерах показывал время срабатывания.
современная рефлексия очень даже быстрая.
И на рендеринге 3D-графики тоже быстрая?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847206
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonвадяпропущено...
тут уже показывали кино с что такое современная рефлексия, и не однократно. там чел на примерах показывал время срабатывания.
современная рефлексия очень даже быстрая.
И на рендеринге 3D-графики тоже быстрая?
А зачем Вы делаете на Java программный 3d рендеринг? Это токсикомания.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847207
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вадяmaytonА что случилось с 2006 года?тут уже показывали кино с что такое современная рефлексия, и не однократно. там чел на примерах показывал время срабатывания.
современная рефлексия очень даже быстрая.

Вы случайно с MethodHandles не путаете?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847213
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
betelgeizexdakeiras,

Groovy - по определению медленный язык, даже с CompileStatic.
Вот идиоматичный код на груви (компилируется и выполняется успешно):

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
@CompileStatic
class Test1 {

    static void main(String[] args) {
        if (!args) {
            println("error")
        }
        // TODO
    }
}




А какой смысл этого кода?
args.length == 0?
args == null?
Зачем так писать?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847216
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonИ на рендеринге 3D-графики тоже быстрая?это к чему?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847217
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LelouchВы случайно с MethodHandles не путаете?нет, там выступление именно про ревлексию
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847219
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LelouchВы случайно с MethodHandles не путаете?
YouTube Video
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847243
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasmaytonпропущено...

И на рендеринге 3D-графики тоже быстрая?
А зачем Вы делаете на Java программный 3d рендеринг? Это токсикомания.
Я надеюсь что в части творческих экспериментов мы с вами лежим на одной полочке.
Ведь % использований вашего фреймворка равен нулю. Разумеется я не считаю вас самого.

По поводу оценки эффективности того или иного компиллятора. Обычно берут какой-то
численный метод и замеряют эффективность либо в количестве операций которые выполнились
за единицу времени либо оценивают период (милисекундах или мкс) одной операции.

Операции I/O обычно не рассматривают в качестве оси измерений т.к. тут в основном
работает контекст операционной системы и ваше приложение просто стоит на паузе
либо ожидает асинк-колл от финала этой операции.

У вас есть на примете какой-то численный метод или любая бизнес-логика которая достаточно
длительное время нагружает процессор и память без взаимодействия с I/O ?

И эта логика должна быть написана на Groovy.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847546
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вадя,

Спасибо.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847557
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras,

А почему вы используете именно Groovy?
Какие преимущества перед Java кроме динамической типизации (которую вы не используете). До сих пор даже поддержки lambda из java 8 нет (в стабильной ветке).
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847578
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть когнитивный парадокс. Когда человек теряет ключи на тёмной улице. Он подходит
к ближайшему фонарю и начинает искать там.

Я рискну предположить что просто господин топик-стартер хоршо знает Groovy и целенаправленно
выбрал его для разработки библиотеки. Просто такова человеческая природа.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847625
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonЕсть когнитивный парадокс. Когда человек теряет ключи на тёмной улице. Он подходит
к ближайшему фонарю и начинает искать там.

Я рискну предположить что просто господин топик-стартер хоршо знает Groovy и целенаправленно
выбрал его для разработки библиотеки. Просто такова человеческая природа.
ну «хорошо» это громко конечно сказано:) Но чуть глубже обычного знаю, т.к. сделал проект на AST API в нём (BlackBox) - метапрограммирование, заставляет поизучать саму платформу...

Касательно самого языка - у него есть 4 могучие фичи:
1) Runtime компиляция
2) Closures
3) Динамическое добавление полей и методов в существующие классы (например Exception.isAlreadyLogged)
4) AST API

Ещё сам SDK даёт кучу полезного например @ToString,Sql builder, Json Slurper и проч.
Также неплохая вещь с синтетическими полями и getters/setters.
Traits - для множественного наследования.
Ну и синтаксис: :? in и прочее.

Ещё он может использоваться как процедурная Java, например PL/SQL программистами.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847633
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasКасательно самого языка - у него есть 4 могучие фичи:
1) Runtime компиляция

Рантайм компилляция была во времена самых ранних JSP/Servlets. Этим никого не удивишь.
Но кроме рантаймовости этот процесс вносит множество почти нерешаемых задач безопасности.
А именно - как защитить сервер приложений от потенциального злоумышленника если он
каким-то образом завладел контекстом рандайм компилляции.

Поэтому сама по себе постановка рантайма не полная без обсуждения того как вокруг
этого выстроить кучу баръеров безопасности. В каких песочницах запускать и какие права
выдавать.

Какое-то время мы работали с одним европейским банком и кастомер выставил нам самые жесткие
требования касающиеся пользовательского ввода. Это касалось не только SQL-инжекции.
Это самое первое что мы фиксили. Любой. Вообще самый любой пользовательский ввод
в формочку должен был рассматриваться пристально как угроза.

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

Вобщем опасная эта штука динамика в компилляции. Сложно доказать ее безопаснсоть.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847635
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras3) Динамическое добавление полей и методов в существующие классы (например Exception.isAlreadyLogged)

Тут ничего не могу сказать. Кроме того что это нарушает классическое SOLID.
Особенно в части Open/Closed, Liskov subst. e.t.c.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847637
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras4) AST API

Здесь я даю +1. Это хорошо. Но это хорошо изначально для других языков где AST был просто
частью исполнительной системы как было задумано. В лиспах он смотрится органично. Возможно в Erlang.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847879
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторРантайм компилляция была во времена самых ранних JSP/Servlets. Этим никого не удивишь.
Но кроме рантаймовости этот процесс вносит множество почти нерешаемых задач безопасности.
А именно - как защитить сервер приложений от потенциального злоумышленника если он
каким-то образом завладел контекстом рандайм компилляции.

Поэтому сама по себе постановка рантайма не полная без обсуждения того как вокруг
этого выстроить кучу баръеров безопасности. В каких песочницах запускать и какие права
выдавать.

Какое-то время мы работали с одним европейским банком и кастомер выставил нам самые жесткие
требования касающиеся пользовательского ввода. Это касалось не только SQL-инжекции.
Это самое первое что мы фиксили. Любой. Вообще самый любой пользовательский ввод
в формочку должен был рассматриваться пристально как угроза.

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

Вобщем опасная эта штука динамика в компилляции. Сложно доказать ее безопаснсоть.
У вас фундаментально неверные представления касательно безопасности приложений.
То что вы написали - это вольные фантазии школьника в перемешку с гордостью работы на ыуропэйскый банк.
Особенно порадовало про "контекст рантайм компиляции".
Хорошо что не аутофиляции. @Autowired RuntimeCompilationContext блеядь.
Press H to hack database.

Ваш эуропэйскый (косовский чтоле?) банк не требовал случайно, чтобы HTTPS использовалось?

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

Кстати от "динамики в компиляции" отлично помогают перфокарты - хер поменяешь!

Песочницы. Прямо как в Android. Наверно сложная архитектура подразумевается, с docker и прочая.
Весь пост это просто пёрл сплошной.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39847882
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JSR223 просто плачет в печали. Хуже динамической компиляции и reflection оказалась только runtime компиляция.

Надеюсь вы его выключили сразу (кстати интересно, можно ли его выключить).

Это отличная стратегия для троллинга - на Java форуме доказывать что ВСЕ отличия Java от C++ тормозят и небезопасны и пользователи нипаймут (ну если пишем для тупых юзеров - то да, но они и всё остальное не поймут)

Самое печальное что в реальной жизни (на работе) такие люди делают тоже самое.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39848580
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если тут это кому-либо интересно, Бобина теперь и в Maven Central.

Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
    <dependencies>
        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <version>2.5.4</version>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>io.i-t</groupId>
            <artifactId>bobbin</artifactId>
            <version>2.0.10</version>
        </dependency>
    </dependencies>



Это было сделано по просьбам нескольких больших корпораций начинающих использовать Бобину, т.к. они используют зеркало Maven Central и у них нет JCenter. Потом детально изучу их юз кейс и сделаю обзор.

А некоторые комментаторы пусть продолжают думать что они самые умные на свете и всё знают.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39848592
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Корпораций?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39848620
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonКорпораций?

Google, Apple и Oracle.
И даже Тим Кук сказал «It’s a revolution, Mayton»
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39848622
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeirasЕсли тут это кому-либо интересно, Бобина теперь и в Maven Central.

Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
    <dependencies>
        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <version>2.5.4</version>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>io.i-t</groupId>
            <artifactId>bobbin</artifactId>
            <version>2.0.10</version>
        </dependency>
    </dependencies>



Это было сделано по просьбам нескольких больших корпораций начинающих использовать Бобину, т.к. они используют зеркало Maven Central и у них нет JCenter. Потом детально изучу их юз кейс и сделаю обзор.

А некоторые комментаторы пусть продолжают думать что они самые умные на свете и всё знают.

Кстати, что помешало сделать groovy зависимостью bobbin? Чтобы не приходилось добавлять в зависимости и то и то.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39848624
betelgeizex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
LelouchdakeirasЕсли тут это кому-либо интересно, Бобина теперь и в Maven Central.

...

Это было сделано по просьбам нескольких больших корпораций начинающих использовать Бобину, т.к. они используют зеркало Maven Central и у них нет JCenter. Потом детально изучу их юз кейс и сделаю обзор.

А некоторые комментаторы пусть продолжают думать что они самые умные на свете и всё знают.

Кстати, что помешало сделать groovy зависимостью bobbin? Чтобы не приходилось добавлять в зависимости и то и то.

Глупости! Надо cделать bobbin зависимостью groovy.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39848630
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LelouchmaytonКорпораций?

Google, Apple и Oracle.
И даже Тим Кук сказал «It’s a revolution, Mayton»
Ну дай бох.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39927668
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lelouch,

авторКстати, что помешало сделать groovy зависимостью bobbin? Чтобы не приходилось добавлять в зависимости и то и то.

Понимание того как работает Maven, Gradle.
Да и вообще знание рекомендуемых практик.

Не рекомендуется использовать нетранзитивные зависимости в библиотеках из-за возможных конфликтов модулей.

Но ваше незнание простительно - тут даже самих разработчиков Gradle мне пришлось наискивать:

https://github.com/gradle/guides/issues/204
https://discuss.gradle.org/t/gradle-groovy-library-scope-documentation-best-practices-grapes/31054

Поэтому просто доверяйте грамотным товарищам - отбросьте сомнения!

Представляем Бобину 3.0.0:

https://m.habr.com/ru/post/488614/
https://github.com/INFINITE-TECHNOLOGY/BOBBIN

Ещё проще, ещё быстрее и ещё удобнее.
Теперь с YAML конфигурацией.

Код: yaml
1.
2.
3.
4.
5.
6.
7.
8.
destinations:
  - name: io.infinite.bobbin.config.ConsoleDestinationConfig
    levels: [warn, error, info]
  - name: io.infinite.bobbin.config.FileDestinationConfig
    packages: [io.infinite]
    fileName: ("./LOGS/INFINITE/${className}/${level}/${className}_${level}_${date}.log")
  - name: io.infinite.bobbin.config.FileDestinationConfig
    fileName: ("./LOGS/PACKAGES/${className}/${level}/${className}_${level}_${date}.log")
    format: dateTime + '|' + level + '|' + threadName + '|' + className + '|' + message + '\n' 
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39927731
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras
Если тут это кому-либо интересно, Бобина теперь и в Maven Central.
...
Это было сделано по просьбам нескольких больших корпораций начинающих использовать Бобину, т.к. они используют зеркало Maven Central и у них нет JCenter. Потом детально изучу их юз кейс и сделаю обзор.

А некоторые комментаторы пусть продолжают думать что они самые умные на свете и всё знают.


Ну и? Пушил я в этот мавен централ- ничего в этом сложного или почётного нет- они всё берут, лишь бы open source было.

Лично мне бобина не подходит просто потому, что груви- а я его только удаляю из проектов.
Буду дальше, как лох, logback использовать.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39927738
Андрей Панфилов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey Tomin
Ну и? Пушил я в этот мавен централ- ничего в этом сложного или почётного нет- они всё берут, лишь бы open source было.

Лично мне бобина не подходит просто потому, что груви- а я его только удаляю из проектов.
Буду дальше, как лох, logback использовать.
Да ТС вообще какой-то странныйнеадекватный:

помойкаСразу скажу, что Хабр оказался наиболее эффективной площадкой для обсуждения — самые ценные отклики были именно отсюда.
у него на хабрепомойке вопросы типа "а как эту фигню подключить к проекту?", а здесь же ему несколько реальных багов выставили (т.е. по факту на помойке никто даже толком не смотрел что там внутри), но ценность помоечных комментариев выше
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39927935
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras
Lelouch,

авторКстати, что помешало сделать groovy зависимостью bobbin? Чтобы не приходилось добавлять в зависимости и то и то.


Понимание того как работает Maven, Gradle.
Да и вообще знание рекомендуемых практик.



mavenAlthough transitive dependencies can implicitly include desired dependencies, it is a good practice to explicitly specify the dependencies you are directly using in your own source code. This best practice proves its value especially when the dependencies of your project changes their dependencies.

Я один тут вижу рекомендацию для библиотеки явно декларировать зависимости? а не "не включать их вообще".
То есть по хорошему, нужно явно перечислить в зависимостях вашей библиотеки необходимы модули groovy. А не умничать про знание практик и предлагать пользователю добавлять groovy-all в качестве зависимости.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39928122
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lelouch

Я один тут вижу рекомендацию для библиотеки явно декларировать зависимости? а не "не включать их вообще".
То есть по хорошему, нужно явно перечислить в зависимостях вашей библиотеки необходимы модули groovy. А не умничать про знание практик и предлагать пользователю добавлять groovy-all в качестве зависимости.


тут написано тоже самое что я сказал. В библиотеках нужно использовать нетранзитивные зависимости (как и сделано в Бобине).

у меня опечатка выше была:
Не рекомендуется использовать нетранзитивные зависимости в библиотеках из-за возможных конфликтов модулей.

Т.е. не нужно в библиотеках тащить лишние jar'ы. Это азы, основы!
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39928133
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я слышу грохот клавиатур...

Это летят фидбэки...
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39928148
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Я слышу грохот клавиатур...

Это летят фидбэки...


тут пару последних страниц комментариев удалили. Замечу без моего участия в дискуссии.

Спасибо моим сторонникам кстати.

Mayton, вы попробовали Бобину? Она реально может помочь улучшить логирование в Ваших проектах.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39928155
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я не использую Groovy.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39928156
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Я не использую Groovy.


Использовать Groovy совершенно не обязательно, чтобы пользоваться Бобиной.
Это SLF4J логгер, он работает в любых Java проектах, в Java коде.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39928159
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Стараюсь не использовать slf4j. Нет смысла в новых проектах. Добавляем Log4j2.
Вообще я помню нашу дискуссию по этим Бобинам. Я еще тогда не увидел никаких
нужных мне "киллер фич".
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39928187
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Стараюсь не использовать slf4j. Нет смысла в новых проектах. Добавляем Log4j2.
Вообще я помню нашу дискуссию по этим Бобинам. Я еще тогда не увидел никаких
нужных мне "киллер фич".


проблем нет!

Бобина работает и без SLF4J:
https://github.com/INFINITE-TECHNOLOGY/BOBBIN/wiki/3---Usage#standalone-usage

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

А ты - сделай внятную презентацию. Список фич. И эти фичи должны на 100% перекрывать
то что есть уже в LogBack/Log4j2.

Иначе нет вообще смысла переползать с логгера на логгер.

Понимаешь?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39928203
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

Ок. Сделаю презентацию и поработаю над onboarding. Я согласен этот момент не очень сейчас проработан.

Насчёт фич - тут вопрос не такой простой. Многие фичи в этих логгерах это crosscutting concerns и нарушение loose coupling. Например та же архивация - она была изначально в Бобине, но я её убрал.
Это не задача логгера архивировать логи.

Или например отправка по сети в logstash через сокет. Это вообще ОЧЕНЬ спорная вещь, учитывая относительно недавнее появление ELK - и существование уже на тот момент девопс методологии.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39928280
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras
mayton
Я не использую Groovy.


Использовать Groovy совершенно не обязательно, чтобы пользоваться Бобиной.


Это как? Он же вроде на Груви написан, или что-то пишется на нём.
Т.е. groovy.jar вывалится в проект
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39928285
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras
Lelouch

Я один тут вижу рекомендацию для библиотеки явно декларировать зависимости? а не "не включать их вообще".
То есть по хорошему, нужно явно перечислить в зависимостях вашей библиотеки необходимы модули groovy. А не умничать про знание практик и предлагать пользователю добавлять groovy-all в качестве зависимости.


тут написано тоже самое что я сказал. В библиотеках нужно использовать нетранзитивные зависимости (как и сделано в Бобине).

у меня опечатка выше была:
Не рекомендуется использовать нетранзитивные зависимости в библиотеках из-за возможных конфликтов модулей.

Т.е. не нужно в библиотеках тащить лишние jar'ы. Это азы, основы!


Вы специально игнорируете часть фразы
maven it is a good practice to explicitly specify the dependencies you are directly using in your own source code ?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39928291
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras,

Кстати, что по вашему является транзитивной зависимостью? Для bobbin груви - это прямая зависимость
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39928355
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А на сколько увеличится артифакт после сборки groovy-среды? Не хотелось-бы ради логгера втаскивать гигабайт всякого шлака.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39928382
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
А на сколько увеличится артифакт после сборки groovy-среды? Не хотелось-бы ради логгера втаскивать гигабайт всякого шлака.


на 8mb.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39928384
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lelouch
dakeiras,

Кстати, что по вашему является транзитивной зависимостью? Для bobbin груви - это прямая зависимость

Транзитивная compile
Нетранзитивная compileOnly
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39934104
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
записал видос по многочисленным просьбам трудящихся.

Приятного просмотра!

YouTube Video
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39934392
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras
Lelouch
dakeiras,

Кстати, что по вашему является транзитивной зависимостью? Для bobbin груви - это прямая зависимость

Транзитивная compile
Нетранзитивная compileOnly


Вопрос был в том, как вы лично определили, что груви для вашего логера- транзитивная зависимость...
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39934685
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lelouch
dakeiras
пропущено...

Транзитивная compile
Нетранзитивная compileOnly


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

Ещё раз, запомните раз и на всегда: лучшая практика делать Груви нетранзитивной зависимостью в библиотеках.

Т.к. клиентский код может иметь другую версию Груви.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39935177
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras
Lelouch
пропущено...


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

Ещё раз, запомните раз и на всегда: лучшая практика делать Груви нетранзитивной зависимостью в библиотеках.

Т.к. клиентский код может иметь другую версию Груви.


Еще раз прощу обоснование этого мнения. Приведенные Вами ссылки в контексте отдельно стоящей библиотеки говорят о другом.

А еще он может не иметь версии груви вообще (эдак в 99% случаев, язык не самый популярный). И с этим должен разбираться автор клиентского кода, благо для этого есть механизмы что в maven, что в gradle
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39935185
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras
Lelouch
пропущено...


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

Ещё раз, запомните раз и на всегда: лучшая практика делать Груви нетранзитивной зависимостью в библиотеках.

Т.к. клиентский код может иметь другую версию Груви.


Ну и если на то пошло - с гораздо большей вероятностью клиентский код может использовать другую версию slf4j-api. Однако эта зависимость у вас явная ( compile "org.slf4j:slf4j-api:1.7.25").
Чувствую что объяснения лучше "почему" - "потому-что" от Вас не получить.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39935190
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В 2000-е когда был пик веб-дизайна и сайто-строения очень ценилась метрика быстрой загрузки
landing-page. Дизайнеры разгоняли стартовую страничко до закрузки не более чем 3х секунд.
Картинки упрощали. Делали короткие флеш-ролики. Маркетинговая идея была в том
что ленивый потенциальный клиент в процессе ожидания вашей страницы мог клацнуть
новую вкладку и уйти искать товар в другой магазин. И это работает и сегодня.

Сегондня КМК в категории java-Библиотек и фреймворков я-бы выставил такую
меткрику как без-проблемность включения библиотеки в ваш проект.

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

И если в процессе развертывания или компилляции или рантайма вдруг (!) возникают
проблемы - 99% бородач спрыгнет с этой библиотеки и уйдет в LogBack/Log4j.

Тоесть развёртывание бобин должне предполагать такую гладкость как будто
вы ставите новое приложение в iPhone. Ну в нашем случае это скорее всего
включить в gradle 1 строчку кода где есть bobbin-all-inclusive сборка всей бобины со всеми
потрохами и зависимостями.

А те кто любят сами поковырять пускай ищуют bobbin-core сборку где идет
чистое ядро.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39935379
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras
Ещё раз, запомните раз и на всегда: лучшая практика делать Груви нетранзитивной зависимостью в библиотеках.

Т.к. клиентский код может иметь другую версию Груви.


Лучшая практика- не тревожить труп - не использовать груви.
Т.к. клиентский код вряд использует ЭТО.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39935385
Фотография Valentin Kolesnikov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey Tomin
dakeiras
Ещё раз, запомните раз и на всегда: лучшая практика делать Груви нетранзитивной зависимостью в библиотеках.

Т.к. клиентский код может иметь другую версию Груви.


Лучшая практика- не тревожить труп - не использовать груви.
Т.к. клиентский код вряд использует ЭТО.


Недавно вышел groovy 3.0.

https://groovy-lang.org/releasenotes/groovy-3.0.html

Хорошего вам дня!
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39935388
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Valentin Kolesnikov
Alexey Tomin
пропущено...


Лучшая практика- не тревожить труп - не использовать груви.
Т.к. клиентский код вряд использует ЭТО.


Недавно вышел groovy 3.0.

https://groovy-lang.org/releasenotes/groovy-3.0.html

Хорошего вам дня!


Спасибо!

Да, они всё никак не хотят закопать стюардессу.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39935390
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Письма Колесникова иногда похожи на отписки больших корпораций.
Вроде как вежливо. Но в то-же время ... пользы для скруля мало

Кидал-бы тихонько в твиттер А тут аудитория - нулевая.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39935582
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey Tomin
Valentin Kolesnikov
пропущено...


Недавно вышел groovy 3.0.

https://groovy-lang.org/releasenotes/groovy-3.0.html

Хорошего вам дня!


Спасибо!

Да, они всё никак не хотят закопать стюардессу.

этот труп позволяет на порядки сокращать время разработки корпоративных систем.
Экономя миллионы $.

У умелых руках конечно. :)
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39935584
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Несколько лет назад в скруле были создатели key-value-in-memory-dbms которые тоже говорили
подобные вещи. Славное время было. А щас - скушно как-то. Логгер - не dbms. Особо
нечего обсуждать. Так... цвет фломастеров просто.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39935702
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras
Alexey Tomin
пропущено...


Спасибо!

Да, они всё никак не хотят закопать стюардессу.

этот труп позволяет на порядки сокращать время разработки корпоративных систем.
Экономя миллионы $.

У умелых руках конечно. :)


В зависимости от задачи это про любой язык написать можно:)
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39935705
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras,

Можете рассказать, чем использование груви в проекте логера Вам помогло?
Имхо, сэкономило минут 30 разработки максимум в обмен на включение весьма неоднозначной зависимости. Кстати, когда ваш логер наконец перестанет ронять вызывающий код при ошибке io?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39935711
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras,

Ну и ещё в копилку о том, какие проблемы может принести код, написанный вашими умелыми руками - например, при использовании в пути файла логов имени пользователя/идентификатора запроса, при большом количестве пользователей/запросов в течении суток на Linux может произойти «ой» (именно такой use case вы приводили как «достоинство» бобины в прошлый раз). При чем этот «ой» вследствие того, что логер выбрасывает исключение при работе с io приведёт к отказу в обслуживании для новых запросов

Погуглите «too many open files» и ещё раз подумайте о логике кеширования bobbinFile :)
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39936637
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lelouch
dakeiras,

Можете рассказать, чем использование груви в проекте логера Вам помогло?
Имхо, сэкономило минут 30 разработки максимум в обмен на включение весьма неоднозначной зависимости. Кстати, когда ваш логер наконец перестанет ронять вызывающий код при ошибке io?

YAML конфигурация компилируется в класс, кто позволяет достичь максимальной производительности - по сравнению с единственной альтернативой (JSR 223), сохраняя полную гибкость настройки с помощью скриптовых выражений.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39936645
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lelouch
dakeiras,

Ну и ещё в копилку о том, какие проблемы может принести код, написанный вашими умелыми руками - например, при использовании в пути файла логов имени пользователя/идентификатора запроса, при большом количестве пользователей/запросов в течении суток на Linux может произойти «ой» (именно такой use case вы приводили как «достоинство» бобины в прошлый раз). При чем этот «ой» вследствие того, что логер выбрасывает исключение при работе с io приведёт к отказу в обслуживании для новых запросов

Погуглите «too many open files» и ещё раз подумайте о логике кеширования bobbinFile :)


Экосистема i-t.io полномастштабно работает в финансовой сфере около 8 месяцев: ETL, OLAP, API/Gateway, безопасность, SRE и пр.
Ежемесячно обрабатываются миллиарды $.

Не было зафиксировано ни одного инцидента, дефекта или ошибки связанной с нашей экосистемой.
Сейчас скоро например на проде запустится Голубь ( https://i-t.io/Pigeon ) - спустя почти 2 года тестирования несколькими командами (практически без моего участия), внешнего аудита безопасности.

Пользуйтесь, бесплатно. Это мой благодарный вклад в опен сорс. И моей организации, которая поддержала такой подход.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39936651
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot dakeiras#22097581]
Lelouch
dakeiras,

Не было зафиксировано ни одного инцидента, дефекта или ошибки связанной с нашей экосистемой.



Экосистеме spring 17 лет, за это время в ней найдено 19к ошибок. ИМХО, ваша экосистема - просто неуловимый Джо.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39936655
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras,

Кстати насчет голубя

Прямо совсем мельком взглянул на код

https://github.com/INFINITE-TECHNOLOGY/PIGEON/blob/master/pigeon-lib/src/main/groovy/io/infinite/pigeon/threads/SenderThread.groovy
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
@Override
    void run() {
        while (true) {
            while (!sendingQueue.isEmpty()) {
                try {
                    sendMessage(sendingQueue.poll())
                } catch (Exception e) {
                    println("Sender thread exception.")
                    println(new ExceptionUtils().stacktrace(e))
                    log.error("Sender thread exception.", e)
                }
            }
            synchronized (this) {
                this.wait()
            }
        }
    }


Метод BlockingQueue::take придумали трусы?:) Или вам за строки кода платят?
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39936658
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras,

Хотя о чем это я, там вообще много приседаний с потоками, которые заменяются ExecutorService.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39936665
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras,

И кажется об этой ошибке в вашем http клиенте вам уже писали
Если одновременно использовать
https://github.com/INFINITE-TECHNOLOGY/HTTP/blob/master/http/src/main/groovy/io/infinite/http/SenderDefaultHttpsUnsecure.groovy
и
https://github.com/INFINITE-TECHNOLOGY/HTTP/blob/master/http/src/main/groovy/io/infinite/http/SenderDefaultHttps.groovy
то результат будет непредсказуем (вы в этих реализациях меняете статическое поле HttpsURLConnection.defaultSSLSocketFactory)
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39936666
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторМетод BlockingQueue::take придумали трусы?:) Или вам за строки кода платят?

Протестирую и заменю если всё будет ок. Большое спасибо за указание!

Насчёт потоков и executor service - мне как-то потоки милее. Я не со всеми вещами концептуально единомышлен в Spring.

Кстати, вот ещё новая тема: HTTP клиент
https://i-t.io/HTTP
https://github.com/INFINITE-TECHNOLOGY/HTTP

- HTTP (plaintext)
- HTTPS
- HTTPS without server certificate validations (i.e. self-signed certificates)
- Basic Authentication
- AWS Signature v4
- Proxy
- Connection timeout
- Read timeout

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
import io.infinite.http.HttpRequest
import io.infinite.http.HttpResponse
import io.infinite.http.SenderDefaultHttps

        HttpRequest httpRequest = new HttpRequest(
                url: "https://google.com",
                method: "GET"
        )
        HttpResponse httpResponse = new HttpResponse()
        new SenderDefaultHttps().sendHttpMessage(httpRequest, httpResponse)
        if (httpResponse.status != 200) {
            throw new Exception("Error HTTP Code")
        }
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39936667
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras,

Выше ответил как)
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39936668
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lelouch
dakeiras,

И кажется об этой ошибке в вашем http клиенте вам уже писали
Если одновременно использовать
https://github.com/INFINITE-TECHNOLOGY/HTTP/blob/master/http/src/main/groovy/io/infinite/http/SenderDefaultHttpsUnsecure.groovy
и
https://github.com/INFINITE-TECHNOLOGY/HTTP/blob/master/http/src/main/groovy/io/infinite/http/SenderDefaultHttps.groovy
то результат будет непредсказуем (вы в этих реализациях меняете статическое поле HttpsURLConnection.defaultSSLSocketFactory)


Поправлю. Извиняюсь, ускользнуло в последний раз.

Завёл баг: https://github.com/INFINITE-TECHNOLOGY/HTTP/issues/1
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39936674
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras,

Кстати defaultSSLSocketFactory еще и не volatile, запись и чтение его в нескольких потоках приводит к гонке и оттуда можно прочитать что угодно (даже null)
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39936713
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras
Насчёт потоков и executor service - мне как-то потоки милее. Я не со всеми вещами концептуально единомышлен в Spring.


ExecutorService это не Spring, это core.

Вообще с таким уровнем знаний многопоточности Вами, Вашу библиотеку использовать нельзя. Вообще.
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39936771
lleming
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lelouch
dakeiras
пропущено...

этот труп позволяет на порядки сокращать время разработки корпоративных систем.
Экономя миллионы $.

У умелых руках конечно. :)


В Вне зависимости от задачи это про любой язык написать можно:)


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

Масло маслянное.

Brainfuck не всчет, поскольку его придумали не для сокращения и не для увеличения времени разработки (что лишь побочный эффект основной цели).
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39937273
dakeiras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey Tomin
dakeiras
Насчёт потоков и executor service - мне как-то потоки милее. Я не со всеми вещами концептуально единомышлен в Spring.


ExecutorService это не Spring, это core.

Вообще с таким уровнем знаний многопоточности Вами, Вашу библиотеку использовать нельзя. Вообще.

Вот с этого момента поподробнее. Про "знание многопоточности". (что является бессмыслицей уже семантически).

Какое такое "знание" у меня плохое\отсутствует? Желательно конкретно. А то некрасиво получается :)
...
Рейтинг: 0 / 0
Новый альтернативный Slf4j логгер Бобина
    #39937507
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dakeiras
Alexey Tomin
пропущено...


ExecutorService это не Spring, это core.

Вообще с таким уровнем знаний многопоточности Вами, Вашу библиотеку использовать нельзя. Вообще.

Вот с этого момента поподробнее. Про "знание многопоточности". (что является бессмыслицей уже семантически).

Какое такое "знание" у меня плохое\отсутствует? Желательно конкретно. А то некрасиво получается :)


Вам в этом треде уже несколько раз указывали на Ваши тривиальные ошибки.
Искать и повторять не буду.
...
Рейтинг: 0 / 0
320 сообщений из 320, показаны все 13 страниц
Форумы / Java [игнор отключен] [закрыт для гостей] / Новый альтернативный Slf4j логгер Бобина
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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