Статьи

Какие средства ведения журналов для приложений Swing?


Скрестив пальцы, после долгого пика других дел, я смогу возобновить написание статей с техническим содержанием.
В то же время я хотел бы обсудить
одну из первых проблем, которую люди начали подавать против
BetterBeansBinding : использовать средство ведения журнала для библиотеки, в которой пока нет ведения журнала, за исключением небольшого числа System. err.println () заявления. Один комментатор предложил использовать
SLF4J вместо java.util.logging, и я пока не могу сказать, какое решение лучше.

Просто чтобы дать некоторый контекст, я повторяю, как я до сих пор использовал каркасы ведения журналов в своих проектах:

  • В начале я использовал log4j .
  • Приблизительно в 2001 году, если я хорошо помню, я начал использовать обычное ведение журнала , все еще настроенный с помощью log4j. В то время я в основном занимался серверными приложениями; ограниченное количество проектов, которые я делал в Swing, вероятно, вообще не имели регистрации.
  • В 2004 году я все еще использовал протоколирование общин, но более активное участие в Jini помогло мне освоиться с java.util.logging.
  • С 2005/2006 года я использую только java.util.logging, отчасти потому, что я значительно увеличил процент своих проектов Swing, отчасти потому, что большая часть серверной работы, которой я занимался в последнее время, делится большим количеством компонентов с моими настольные проекты.

Уже несколько месяцев blueMarine использует очень простую настроенную версию java.util.logging: единственная новая возможность — каждый метод принимает стиль varargs, такой как в PrintWriter.printf ():

import it.tidalwave.logger.Logger;

...

Logger logger = Logger.getLogger("name");
int x = ...;
String s = ...;
logger.fine(">>>> x=%d, s=%s", x, s);

Это не только намного удобнее для чтения, чем конкатенация строковых литералов и переменных с оператором +, но и быстрее, когда журнал отключен. Фактически реализация методов ведения журнала заключена в if (…), который проверяет текущий уровень ведения журнала; это означает, что объединение строк выполняется только тогда, когда необходимо ведение журнала:

package it.tidalwave.logger;

public class Logger
{
private java.util.logging.Logger delegate = ...;

public void fine (String pattern, Object ... args)
{
if (delegate.isLoggable(Level.FINE))
{
delegate.fine(String.format(pattern, args));
}
}
}

Напротив, прямое использование java.util.logging заставляет передавать одно сообщение, объединенное с +, которое всегда использует конкатенацию строк, даже если результат будет отброшен, потому что связанный уровень ведения журнала отключен. Вот почему в критических разделах производительности люди используют для инкапсуляции java.util.logging в код приложения, включая тест на уровень, как в:

if (logger.isLoggable(Level.FINE))
{
logger.fine(...);
}

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

Мне не нравится заново изобретать колесо, поэтому мой пользовательский регистратор будет в конечном итоге заменен SLF4J, который, среди прочего, предлагает аналогичный стиль ведения журнала, ориентированный на шаблоны; Кроме того, его подключаемая конструкция позволяет отправлять данные журнала для ряда различных целей. Я делаю это не сразу, потому что у меня есть другие приоритеты в BlueMarine.

Так что, с точки зрения, я не был бы против использования SLF4J в BetterBeansBinding. Единственное, что меня беспокоит, это то, что это решение вводит зависимость, в то время как у BeansBinding на данный момент нет * никаких * зависимостей. Учтите, что одно из ограничений BBB — возможность работать в качестве замены «вставки» для BeansBinding, а в SLF4J вам потребуется заменить существующий файл JAR на ДВА файла JAR.

Итак, я вижу следующие варианты:

  1. Используйте java.util.logging (один jar, но подробный код)
  2. Скопируйте настроенный регистратор, похожий на тот, что в blueMarine, в BBB (один jar, читаемый код, но несколько классов для вырезания и вставки и ощущение NIH).
  3. Используйте SLF4J и живите с зависимостью (несколько jar, читаемый код, без вырезок и вставок).
  4. Используйте SLF4J и предоставьте «OneJAR» версию BBB с встраиванием классов SLF4J (звучит как «все плюсы и минусы»).

Решение № 4 должно соответствовать лицензиям BBB и SLF4J (LGPL 2.1 и MIT-подобным), и это то, что мне больше нравится в данный момент, но я должен проверить. На данный момент (1.2.3-SNAPSHOT) BBB разделен на три подкомпонента, поэтому идея создания «OneJAR» уже присутствует в BBB — в дополнение к возможности выпуска jar для каждого модуля, конфигурации, которая могла бы использовать, например, с OSGi, платформой NetBeans и во всех случаях, когда строгая замена оригинальной привязки BeansBinding не требуется.

Мысли?