2017-01-09 3 views
1

В приложении, над которым мы работаем, существует так много протоколов отладки и трассировки, что даже когда уровень журналирования отключает их, единственные накладные расходы на создание массивов аргументов сообщений становятся проблемой в наше время -чувствительные алгоритмы. Теперь мы не хотим полностью удалять журналы (поскольку они, очевидно, полезны во время разработки и тестирования), но мы хотим как-то уменьшить их накладные расходы. Мы рассмотрели несколько вариантов:Удаление журналов отладки с помощью ProGuard

  • Ditching Slf4j API и использование Log4j2 с ленивым протоколированием требует слишком много рефакторинга и ручного труда. То же самое относится к пользовательской логгерной оболочке и обертыванию всех вызовов регистратора с помощью операторов if.
  • Код постпроцессора может автоматически обернуть все журналы с условными операторами (поэтому массивы аргументов никогда не создаются) или вообще не удалять их.
  • ProGuard может удалить все вызовы регистратора.

Поскольку мы не нашли никаких пост-процессоров кода, которые могли бы вывести из строя из коробки, мы решили пойти с решением ProGuard. Это наша основная настройка ProGuard:

-optimizations code/removal/simple,code/removal/advanced 
-dontobfuscate 
-dontshrink 
-keep class * 
-keepclassmembers class * { 
    *; 
} 
-assumenosideeffects class org.slf4j.Logger { 
    void trace(...); 
    void debug(...); 
} 

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

log.debug("Evidence {} is unverifiable for product {}", evidence, product.getData().getName()); 

... превратилась бы в это:

product.getData().getName() 

Как ни странно, но и оставляет все посвящения массива объектов:

log.debug("{} {} {}", first, second, third); 
// ...becomes: 
Object[] var10000 = new Object[]{first, second, third}; 

Теперь я знать, что это должно быть оптимизировано JIT (удаление неиспользуемых переменных). Меня больше беспокоит первый случай, когда все вызываемые методы не удаляются вместе с протоколированием. Они могут варьироваться от безвредного (простого обращения с геттером) до несколько худшего (size() вызов параллельной коллекции).

Текущее решение ProGuard является «достаточно хорошим», но мне интересно, можно ли полностью удалить записи регистрации (и их побочные эффекты). Можем ли мы достичь этого через конфигурацию ProGuard или есть ли для этого существующий инструмент?

ответ

0

Просто сумасшедшая идея: как насчет создания собственного интерфейса & реализация с идентичными интерфейсами с slf4j, но с развернутыми varargs? По сути, вы fork slf4j соответствуют вашим требованиям.

Еще одна идея - создать инструмент миграции SLF4J-to-Log4j2. Если ваша компания согласна, вы можете предложить это в качестве вклада в проект Log4j2, поэтому вам не нужно его поддерживать. :-)

+0

Пользовательский интерфейс регистрации - это именно то, чего мы пытаемся избежать - для этого, вероятно, потребуется слишком много ручного рефакторинга. Переключение на Log4j2 API позволило бы решить некоторые из наших проблем, хотя я рассмотрю его. – JustACluelessNewbie

+0

К счастью, slf4j API небольшой; Я предполагаю, что это главным образом импорт, а в коде, заменяющий LoggerFactory с помощью LogManager и MDC ThreadContext. –

+0

Да, это должен быть вопрос использования find-replace и, возможно, реорганизация некоторых потенциально дорогостоящих журналов для использования 'Suppliers'. Поскольку решение ProGuard уже работает (kinda, sorta), сопряжение этих двух должно быть достаточным. Я надеюсь. – JustACluelessNewbie