Чому б не використовувати java.util.logging?


351

Вперше в своєму житті я опиняюся в положенні, коли я пишу API Java, який буде відкритий. Сподіваємось, що буде включено до багатьох інших проектів.

Для ведення журналу я (і справді люди, з якими я працюю) завжди використовував JUL (java.util.logging) і ніколи не мав з цим жодних проблем. Однак зараз мені потрібно більш детально зрозуміти, що мені робити для розробки API. Я провів кілька досліджень з цього приводу, і отриману інформацію я просто заплутався. Звідси ця посада.

Оскільки я родом з JUL, я упереджений цим. Мої знання про решту не такі великі.

З результатів проведених досліджень я прийшов до таких причин, чому люди не люблять JUL:

  1. "Я почав розвиватися на Java задовго до того, як Sun випустила JUL, і мені було просто легше продовжувати лог-фреймворк-X, а не вивчати щось нове" . Хм. Я не жартую, це насправді те, що кажуть люди. З цим аргументом ми все могли б робити COBOL. (однак я, безумовно, можу ставитись до того, що я сам лінивий чувак)

  2. "Мені не подобаються назви рівнів журналу в JUL" . Гаразд, серйозно, це просто недостатньо підстав для введення нової залежності.

  3. "Мені не подобається стандартний формат виводу з JUL" . Хм. Це лише конфігурація. Вам навіть не потрібно робити щось кодове. (правда, за старих часів вам, можливо, довелося створити свій власний клас Форматтер, щоб правильно його встановити).

  4. "Я використовую інші бібліотеки, які також використовують logging-Framework-X, тому я вважав, що простіше просто використовувати цю" . Це круговий аргумент, чи не так? Чому "всі" використовують logging-Framework-X, а не JUL?

  5. "Усі інші використовують logging-Framework-X" . Це для мене лише окремий випадок із вищезазначеного. Більшість не завжди права.

Тож справді велике питання - чому б не JUL? . Що це я пропустив? Основна причина для фасадів журналів (SLF4J, JCL) полягає в тому, що кілька реалізацій журналів існували історично, і причина цього насправді повертається до епохи до ЮЛ, як я бачу. Якби JUL був ідеальним, тоді фасадів реєстрації не існувало б, чи що? Щоб зробити справи більш заплутаними, JUL певною мірою є самим фасадом, що дозволяє обміняти обробники, формати та навіть LogManager.

Замість того, щоб використовувати декілька способів робити те саме (ведення журналів), чи не слід сумніватися, чому вони були потрібні в першу чергу? (і подивіться, чи існують ці причини)

Гаразд, моє дослідження поки що призвело до того, що я можу побачити, що це справді проблеми з JUL:

  1. Продуктивність . Деякі кажуть, що продуктивність у SLF4J краща за решту. Мені це здається випадком передчасної оптимізації. Якщо вам потрібно зареєструвати сотні мегабайт в секунду, то я не впевнений, що ви все одно на правильному шляху. JUL також розвинувся, і тести, які ви зробили на Java 1.4, більше не можуть бути правдивими. Ви можете прочитати про це тут, і це виправлення перетворило його на Java 7. Багато людей також говорять про накладні зв'язки рядків у методах реєстрації. Однак реєстрація на основі шаблонів дозволяє уникнути цієї вартості, і вона існує і в JUL. Особисто я ніколи не пишу журнал на основі шаблонів. Занадто ліниво для цього. Наприклад, якщо я це роблю з JUL:

    log.finest("Lookup request from username=" + username 
       + ", valueX=" + valueX
       + ", valueY=" + valueY));

    мій IDE попередить мене і попросить дозволу, що він повинен змінити його на:

    log.log(Level.FINEST, "Lookup request from username={0}, valueX={1}, valueY={2}", 
       new Object[]{username, valueX, valueY});

    .. що я, звичайно, прийму. Дозвіл наданий! Дякую за твою допомогу.

    Тому я фактично не пишу таких заяв, що робиться IDE.

    На закінчення щодо виступу я не знайшов нічого, що б підказало, що результативність JUL не в порядку в порівнянні з конкуренцією.

  2. Конфігурація від classpath . Нестабільний JUL не може завантажити конфігураційний файл з classpath. Це зробити кілька рядків коду . Я бачу, чому це може дратувати, але рішення коротке та просте.

  3. Наявність вихідних обробників . JUL поставляється з 5 вихідними обробниками поза коробкою: консоль, потік файлів, сокет і пам'ять. Вони можуть бути розширені або записані нові. Наприклад, це написання в UNIX / Linux Syslog та Журнал подій Windows. У мене особисто ніколи не було цієї вимоги, ні я не бачив, щоб вона використовувалася, але я, безумовно, можу сказати, чому це може бути корисною функцією. Зворотний зв'язок постачається разом із додатком для Syslog. Все-таки я б це заперечував

    1. 99,5% потреб у вихідних напрямках покриваються тим, що знаходиться в JUL поза коробкою.
    2. Спеціальні потреби можуть задовольняти спеціальні обробники на JUL, а не щось інше. Мені нічого не говорить про те, що для написання вихідного обробника Syslog для JUL потрібно більше часу, ніж це стосується іншої структури журналу.

Я дуже стурбований тим, що є щось, що я не помітив. Використання фасадів ведення журналів та інших журналів, крім JUL, настільки поширене, що я мушу прийти до висновку, що це я просто не розумію. Боюся, це було б не перший раз. :-)

То що мені робити зі своїм API? Я хочу, щоб це стало успішним. Звичайно, я можу просто "піти з потоку" та впровадити SLF4J (який здається найпопулярнішим в наші дні), але заради мене все одно потрібно зрозуміти, що не так з JUL сьогодні, що вимагає всіх нечітких дій? Чи буду я саботажу, вибравши JUL для своєї бібліотеки?

Тестування продуктивності

(розділ додано nolan600 07 липня 2012 р.)

Нижче наведено посилання від Ceki про параметризацію SLF4J, яка в 10 разів і швидше, ніж у JUL. Тому я почав робити кілька простих тестів. На перший погляд твердження, безумовно, правильне. Ось попередні результати (але читайте далі!):

  • Час виконання SLF4J, резервний зворотний зв'язок: 1515
  • Час виконання SLF4J, бекенд JUL: 12938
  • Час виконання JUL: 16911

Цифри вище є msecs, тим менше, тим краще. Тож 10-кратна різниця в продуктивності спочатку насправді дуже близька. Моя початкова реакція: Це багато!

Ось ядро ​​тесту. Як видно ціле число, а рядок будується в циклі, який потім використовується в операторі журналу:

    for (int i = 0; i < noOfExecutions; i++) {
        for (char x=32; x<88; x++) {
            String someString = Character.toString(x);
            // here we log 
        }
    }

(Я хотів, щоб оператор журналу мав як примітивний тип даних (в даному випадку - int), так і складніший тип даних (в даному випадку - String). Не впевнений, що це має значення, але там він у вас є.)

Виписка журналу для SLF4J:

logger.info("Logging {} and {} ", i, someString);

Виписка журналу для JUL:

logger.log(Level.INFO, "Logging {0} and {1}", new Object[]{i, someString});

JVM був «розігрітий» тим же тестом, що виконувався один раз до того, як було проведено фактичне вимірювання. Java 1.7.03 використовувалася в Windows 7. Були використані останні версії SLF4J (v1.6.6) та Logback (v1.0.6). Stdout та stderr були перенаправлені на нульовий пристрій.

Однак, обережно зараз, виявляється, JUL витрачає більшу частину свого часу, getSourceClassName()оскільки JUL за замовчуванням друкує ім'я класу джерела у виході, а Logback - ні. Тож ми порівнюємо яблука та апельсини. Мені потрібно зробити тест ще раз і налаштувати реалізацію журналів аналогічним чином, щоб вони насправді виводили один і той же матеріал. Однак я підозрюю, що SLF4J + Зворотний зв'язок все одно вийде на вершину, але далеко від початкових цифр, як зазначено вище. Слідкуйте за налаштуваннями.

Btw: Тест був вперше, коли я фактично працював зі SLF4J або Logback. Приємне враження. JUL, безумовно, набагато менше вітає, коли ви починаєте.

Ефективність тестування (частина 2)

(розділ додано nolan600 08 липня 2012 р.)

Як виявляється, насправді не має значення для продуктивності того, як ви налаштовуєте свій шаблон у JUL, тобто включає він ім'я джерела чи ні. Я спробував дуже простий шаблон:

java.util.logging.SimpleFormatter.format="%4$s: %5$s [%1$tc]%n"

і це зовсім не змінило вищезазначені терміни. Мій профілер виявив, що лісоруб все ще проводив багато часу на дзвінках, getSourceClassName()навіть якщо це не було частиною моєї схеми. Шаблон не має значення.

Тому я приходжу до висновку щодо продуктивності, що, принаймні, для випробуваного протоколу, заснованого на шаблоні, здається, що в реальній різниці між показниками JUL (повільний) та SLF4J + Logback (швидкий) приблизно 10. Так, як сказав Секі.

Я також бачу іншу річ, а саме те, що getLogger()дзвінок SLF4J набагато дорожчий, ніж дитто JUL. (95 мс проти 0,3 мс, якщо мій профілер точний). Це має сенс. SLF4J повинен зробити деякий час для прив'язки основної реалізації журналу. Це мене не лякає. Ці дзвінки мають бути дещо рідкісними протягом життя програми. Швидкість повинна бути в реальних дзвінках журналу.

Остаточний висновок

(розділ додано nolan600 08 липня 2012 р.)

Дякую за всі ваші відповіді. Всупереч тому, що я спочатку думав, що вирішив використовувати SLF4J для свого API. Це ґрунтується на ряді речей та ваших даних:

  1. Це дає гнучкість у виборі реалізації журналу під час розгортання.

  2. Проблеми з відсутністю гнучкості конфігурації JUL при запуску всередині сервера додатків.

  3. SLF4J, звичайно, набагато швидший, як детально описано вище, зокрема, якщо ви з'єднаєте його з Logback. Навіть якщо це був просто брутальний тест, я маю підстави вважати, що на оптимізацію SLF4J + Logback значно більше зусиль пішло, ніж на JUL.

  4. Документація. Документація для SLF4J просто набагато більш вичерпна і точна.

  5. Гнучкість візерунка. Коли я робив тести, я встановив, що JUL імітує схему за замовчуванням від Logback. Цей візерунок включає назву нитки. Виявляється, JUL не може цього зробити поза коробкою. Гаразд, я цього не пропустив дотепер, але я не думаю, що це річ, якої не повинно бути відсутнім у системі журналів. Період!

  6. Більшість (або багато) проектів Java сьогодні використовують Maven, тому додавання залежності - це не така вже й велика річ, особливо якщо ця залежність досить стабільна, тобто не постійно змінює свій API. Це, мабуть, справедливо для SLF4J. Також банку SLF4J та друзі невеликі за розміром.

Тож дивна річ, що сталася, полягала в тому, що я насправді дуже засмутився JUL після того, як трохи попрацював зі SLF4J. Я все ще шкодую, що так має бути з JUL. JUL далеко не ідеальний, але такий спосіб виконує свою роботу. Просто не досить добре. Те саме можна сказати Propertiesяк приклад, але ми не задумуємось про те, щоб абстрагувати те, щоб люди могли підключити власну бібліотеку конфігурацій і що у вас є. Я думаю, що причина полягає в тому, що Propertiesзнаходиться трохи вище планки, в той час як навпаки справедливо для сьогоднішнього липня ..., а в минулому він входив до нуля, оскільки його не існувало.


8
Я не буду ставити запитання про закриття, оскільки це добре представлене питання цікаве, але це межа, якщо ви читаєте FAQ: важко буде знайти остаточну унікальну відповідь, не грунтуючись на думках.
Denys Séguret

Що, можливо, ви пропустили, це те, що багато авторів фреймворку відмовилися від спроби використовувати JUL, і тому його часто важче використовувати, якщо ви просто не зробите ванільну яву.
Denys Séguret

3
Вводити в оману використання загального терміна "logging-Framework-X", коли йдеться про популярні рамки (і) ведення журналу, що передбачають jul У цьому випадку слід використовувати "log4j". Інші популярні фреймворки, такі як SLF4J та logback, з'явилися добре після виходу jul.
Чекі

1
@Acuariano. Проект Netty просто використовує Reflection для перевірки того, який фреймворк журналів доступний на classpath. Дивіться тут джерело. Див InternalLoggerFactory.java.
peterh

1
@xenoterracide ще важливішим було б оновлення Java 9, оскільки вона була представлена java.lang.System.Logger, що є інтерфейсом , який можна перенаправляти на будь-яку фактичну рамку реєстрації, яку ви хочете, доки ця рамка наздогнала і забезпечила реалізацію цього інтерфейсу. У поєднанні з модулярізацією ви навіть можете розгорнути додаток із пакетним JRE, що не містить java.util.logging, якщо ви віддаєте перевагу інший фреймворк.
Холгер

Відповіді:


207

Відмова : Я є засновником проектів log4j, SLF4J та logback.

Є об'єктивні причини віддати перевагу SLF4J. Для одного, SLF4J дозволяє кінцевому користувачеві свободу вибирати основу основи ведення журналу . Окрім того, більш довільні користувачі, як правило, віддають перевагу тому, що він пропонує можливості виходу за межі log4j , а відстань у липні відстає. Для деяких користувачів jul може бути достатньо, але для багатьох інших це просто не так. У двох словах, якщо для вас важливий журнал, ви хочете використовувати SLF4J з logback як основну реалізацію. Якщо ведення журналу неважливо, jul нормально.

Однак, як розробник oss, потрібно враховувати уподобання своїх користувачів, а не лише своїх власних. Звідси випливає, що ви повинні прийняти SLF4J не тому, що ви переконані, що SLF4J кращий, ніж jul, а тому, що більшість розробників Java на даний момент (липень 2012 року) віддають перевагу SLF4J як API реєстрації. Якщо в кінцевому підсумку ви вирішили не піклуватися про популярну думку, врахуйте наступні факти:

  1. ті, хто вважає за краще jul, роблять це з зручності, тому що jul в комплекті з JDK. Наскільки мені відомо, інших об'єктивних аргументів на користь липня немає
  2. ваше власне вподобання jul - це саме те, перевага .

Таким чином, проведення «важких фактів» над громадською думкою, хоча і, здавалося б, сміливе, є логічною помилкою в даному випадку.

Якщо все ще не впевнений, JB Nizet робить додатковий і потужний аргумент:

За винятком того, що кінцевий користувач міг би вже здійснити це налаштування для свого коду чи іншої бібліотеки, яка використовує log4j або logback. jul є розширюваним, але, маючи розширити logback, jul, log4j, і Бог знає лише, які інші рамки ведення журналу, оскільки він використовує чотири бібліотеки, які використовують чотири різні рамки реєстрації, є громіздкими. Використовуючи SLF4J, ви дозволяєте йому налаштувати потрібні рамки ведення журналу, а не ту, яку ви обрали. Пам’ятайте, що типовий проект використовує безліч бібліотек, а не лише вашу .

Якщо з будь-якої причини ви ненавидите API SLF4J і його використання буде витісняти задоволення від вашої роботи, то, безумовно, йдіть на jul Зрештою, є способи перенаправити jul на SLF4J .

До речі, параметризація jul принаймні у 10 разів повільніше, ніж SLF4J, що в кінцевому підсумку робить помітну різницю.


2
@Ceki, можливо, ви хочете трохи розробити інформацію про відмову, щоб вона згадувала вашу поточну роль у проектах log4j, slf4j та logback. Причина, природно, пояснити свої упередження.
Thorbjørn Ravn Andersen

2
Чи є якась підтримка твердження, що більшість розробників Java віддають перевагу SLF4J як API реєстрації?
Олів'є Кайло

3
Суть мого допису полягає в тому, що різні розробники мають різні уподобання, що, здається, суперечливо. Так?
Чекі

1
якщо чесно, я хотів би побачити орієнтири 2018 року на Java 11 (або що б там не було), а також проти log4j2 в режимі асинхронізації.
ксенотеррацид

5
Ось я, використовуючи SLF4J, і мені ще доводиться мати справу з усіма іншими рамками ведення журналу, якими користуються інші бібліотеки. Використання SLF4J не вирішує проблему гетерогенних реєстраторів, а лише робить її гіршою. xkcd.com/927
Чарлі,

34
  1. java.util.loggingбула представлена ​​в Java 1.4. Перед цим використовувались для ведення журналів, тому існує багато інших API-журналів. Ті інтерфейси API, які активно використовувались до Java 1.4, і, таким чином, мали великий ринок спільного використання, який не опустився до 0, коли вийшов 1.4.

  2. JUL не почав все так чудово, багато речей, про які ви згадали, де набагато гірше в 1.4, а покращилися лише в 1.5 (і, мабуть, і в 6, але я не надто впевнений).

  3. JUL не дуже підходить для декількох додатків з різною конфігурацією в одному JVM (думаю, кілька веб-додатків, які не повинні взаємодіяти). Tomcat потрібно перестрибнути через кілька обручів, щоб приступити до роботи (ефективно повторно впроваджуючи JUL, якщо я правильно це зрозумів).

  4. Ви не завжди можете впливати на те, які рамки ведення журналу використовують ваші бібліотеки. Тому використання SLF4J (який насправді є лише дуже тонким шаром API над іншими бібліотеками) допомагає зберігати дещо послідовну картину всього світу журналів (так що ви можете вирішити базовий фреймворк журналу, зберігаючи при цьому бібліотеку в одній системі).

  5. Бібліотеки не можуть легко змінюватися. Якщо попередня версія бібліотеки використовувала журнал-бібліотека-X, вона не може легко перейти на журнал-журнал-Y (наприклад, JUL), навіть якщо остання явно суперечлива: будь-якому користувачеві цієї бібліотеки потрібно було б навчитися новий фреймворк ведення журналу та (принаймні) перенастроювання їх журналу. Це велике "ні-ні", особливо коли воно не приносить явного вигоди більшості людей.

Сказавши все, що я думаю, JUL є принаймні вагомою альтернативою іншим системам ведення журналу.


1
Дякую Йоахіму, я вдячний за ваш пост. Ваші (1) та (2) для мене просто історія. Колись давно. Ваш (4) є наслідком цього, а потім стає тим, що я називаю циклічним аргументом. Ваш (3), проте, дійсно цікавий. Може бути, ви на чомусь? Але це вплине лише на тих, хто будує контейнери для додатків, яких наприкінці дня дуже мало людей. Або що?
peterh

3
Що ж, хто ігнорує історію, приречений повторювати її ;-) Історія є дуже актуальна в розробці програмного забезпечення. Люди не рухаються занадто швидко, а заміна існуючих сторонніх бібліотек стандартними API працює добре, лише якщо стандартні API працюють принаймні так само добре, як і сторонні бібліотеки. І вони не були спочатку (а, мабуть, і досі не роблять).
Йоахім Зауер

Йоахіме, мені цікаво те, що ви, мабуть, ще не в деяких випадках, про які ви згадуєте. Це було м'ясо. Заміна бібліотеки реєстраторів у наявному коді є досить тривіальною і може бути автоматизована в наші дні. У SLF4J є інструмент для того, що підтверджує мою думку. Тож я думаю, що масивна бібліотека, написана у 2002 році з log4j, може бути перетворена в JUL за лічені хвилини за допомогою автоматизованого інструменту. (Я не знаю, чи існує такий). То чому ж цього не відбувається?
peterh

3
@ nolan6000: Я не знаю достатньо конкретики, щоб детально розповідати про цю фразу, і я це не дуже важливий. Навіть якщо JUL зараз стоїть нарівні зі сторонніми рамками, інертність та наявна інфраструктура все ще є вагомою причиною не перемикатися. Наприклад, якщо бібліотека X використовувала slf4j у версії 1.1, перехід на JUL в 1.2 (або навіть 2.0) був би основною проблемою для багатьох користувачів (які вже правильно налаштували стару систему і повинні були б зробити це повторно, щоб не було очевидного посилення) .
Йоахім Зауер

@ nolan6000 навіть якщо ви не переймаєтесь історією, бібліотеки, які ви використовуєте у своїх програмах, безсумнівно. Немає задоволення відкидати бібліотеку просто тому, що вона використовувала інший фреймворк, ніж ви.
Thorbjørn Ravn Andersen

29

IMHO, головна перевага використання фасаду журналу, наприклад slf4j, полягає в тому, що ви дозволяєте кінцевому користувачу бібліотеки вибирати, яку конкретну реалізацію журналу він бажає, а не нав'язувати свій вибір кінцевому користувачеві.

Можливо, він вклав час і гроші в Log4j або LogBack (спеціальні формати, додатки тощо) і вважає за краще продовжувати використовувати Log4j або LogBack, а не конфігурувати jul. Немає проблем: slf4j дозволяє це. Чи розумний вибір використовувати Log4j протягом липня? Можливо, може й ні. Але тобі все одно. Нехай кінцевий користувач вибирає те, що він віддає перевагу.


Дякую JB. Моє запитання, чи дійсно я так багато накладаю на користувача / реалізатора моєї бібліотеки, примушуючи JUL до нього? Якщо він незадоволений, наприклад, стандартними обробниками вихідних даних JUL, він може просто поміняти їх на свій час, коли я це бачу. Я дуже не бачу ЮЛ як стригучу куртку. Мені здається, настільки ж гнучким та розтяжним, як і решта.
peterh

12
За винятком того, що кінцевий користувач міг би вже здійснити це налаштування для свого коду чи іншої бібліотеки, яка використовує log4j або LogBack. jul є розширюваним, але, маючи розширювати LogBack, jul, log4j, Бог знає лише, які інші рамки ведення журналів, оскільки він використовує 4 бібліотеки, які використовують 4 різні рамки реєстрації, громіздкі. Використовуючи slf4j, ви дозволяєте йому налаштувати рамки журналу, які він хоче. не той, кого ви вибрали. Пам’ятайте, що типові проекти використовують безліч бібліотек, а не лише вашу.
JB Nizet

6

Я почав, як і я підозрюю, використовувати JUL, тому що це було найпростіше негайно розпочати. З часом, однак, я побажав, що витратив трохи більше часу на вибір.

Моє головне питання полягає в тому, що у нас є значна кількість «бібліотечного» коду, який використовується у багатьох програмах, і всі вони використовують JUL. Щоразу, коли я використовую ці інструменти в додатку типу веб-сервісу, журнал просто зникає або стає кудись непередбачуваним або дивним.

Нашим рішенням було додати фасад до коду бібліотеки, що означало, що виклики журналу бібліотеки не змінюються, а динамічно переспрямовуються на будь-який механізм реєстрації. Якщо вони включені в інструмент POJO, вони спрямовуються на JUL, але коли вони розгорнуті як веб-додаток, вони переспрямовуються на LogBack.

Нам шкода, звичайно, - це те, що код бібліотеки не використовує параметризований журнал, але це тепер може бути дооснащено як і коли потрібно.

Ми використовували slf4j для побудови фасаду.


1
З якоїсь причини ви не просто використовували пакет "переадресація java.util.logging на slf4j" в дистрибутиві slf4j?
Thorbjørn Ravn Andersen

2
Ми це зробили, але мало значення, оскільки головна перевага переходу до slf4j - це ефективна параметризована реєстрація журналів. Якби ми використовували це з самого початку, ми б зараз не мали жодної роботи.
OldCurmudgeon

1
Я згоден, що це низько висячий плід slf4j.
Thorbjørn Ravn Andersen

3

Я запускав jul проти slf4j-1.7.21 через logback-1.1.7, вихід на SSD, Java 1.8, Win64

jul запустив 48449 мс, зворотній зв'язок 27185 мс для циклу 1М.

І все-таки трохи більше швидкості та трохи приємнішого API не варто для мене 3 бібліотеки та 800 Кб.

package log;

import java.util.logging.Level;
import java.util.logging.Logger;

public class LogJUL
{
    final static Logger logger = Logger.getLogger(LogJUL.class.getSimpleName());

    public static void main(String[] args) 
    {
        int N = 1024*1024;

        long l = System.currentTimeMillis();

        for (int i = 0; i < N; i++)
        {
            Long lc = System.currentTimeMillis();

            Object[] o = { lc };

            logger.log(Level.INFO,"Epoch time {0}", o);
        }

        l = System.currentTimeMillis() - l;

        System.out.printf("time (ms) %d%n", l);
    }
}

і

package log;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LogSLF
{
    static Logger logger = LoggerFactory.getLogger(LogSLF.class);


    public static void main(String[] args) 
    {
        int N = 1024*1024;

        long l = System.currentTimeMillis();

        for (int i = 0; i < N; i++)
        {
            Long lc = System.currentTimeMillis();

            logger.info("Epoch time {}", lc);
        }

        l = System.currentTimeMillis() - l;

        System.out.printf("time (ms) %d%n", l);
    }

}

2
Ви не порівнюєте, як за подібне. Чому ви явно створюєте масив для jul? Я думаю, що це тому, що slf4j не вистачає одноаргументного перевантаження logger.info(). Таким чином, ви навмисно калічать продуктивність jul, щоб компенсувати недолік в інтерфейсі slf4j. Натомість слід кодувати обидва методи так, як вони ідіоматично кодуються.
Клітос Кіріако

2
Ви неправильно зрозуміли це. Вам не доведеться використовувати додаткові 800K. Єдина думка полягає в тому, що дуже тонку api SLF4J варто використовувати, тому що тоді ви (або інші, хто, можливо, повторно використовувати один день вашого коду!) Можете вільно переходити між JUL, Logback, Log4j тощо. SLF4J - це лише ~ 28K. SLF4J до мосту JUL (slf4j-jdk ... jar) становить лише ~ 9K.
riskop
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.