Статьи

Какой из них быстрее? Log4j или Logback?


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

В первой статье я представил журналирование как высокоэффективную, недорогую альтернативу вездесущей System.out.println (), которую все Java-люди так любят. Я использовал  log4j  в этой статье. Log4j — это прочная основа, которая выполняет свои обещания. За все годы, что я использовал его, он никогда не подводил меня. Я могу искренне рекомендовать это. Тем не менее, сказав, что есть также несколько альтернатив, которые были на рынке некоторое время, и я рад сообщить, что, по крайней мере, одна из них, кажется, бросает вызов log4j в своем собственном газоне. Я говорю о  Logback .

Это, конечно, не новичок в этом блоке — и это одна из причин, по которой я предлагаю вам рассмотреть это для приложений корпоративного уровня. Быстрый взгляд на  Maven Central предполагает, что первая версия была опубликована еще в 2006 году. В период с 2006 по 8 июня 2012 года, когда последняя версия была отправлена ​​в Maven Central, было 46 версий. Сравните это с log4j. Первая версия была отправлена ​​в Maven Central в 2005 году, а последняя — 26 мая 2012 года, и между ними было всего 14 различных версий. Я не хочу использовать эти данные для сравнения этих двух структур. Единственная цель состоит в том, чтобы заверить читателя, что Logback существует достаточно долго и достаточно актуален, чтобы к нему относились серьезно.

Быть рядом — это одно, а оставить свой след — иначе. Что касается амбиций и намерений, Logback ясно дает понять, что намерен стать преемником log4j, и говорит об этом на  домашней странице., Конечно, есть исчерпывающий список функций / преимуществ, которые Logback утверждает по сравнению с Log4j. Вы можете прочитать о них по  этой ссылке . Это действительно так. Суть этой статьи заключается в том, что я предлагаю, чтобы при проектировании и разработке Java-приложений корпоративного уровня, было бы внимательнее относиться к ведению журналов, а также рассмотреть возможность использования  Logback .

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

Самое первое, что обещает Logback — это более быстрая реализация (по этой  ссылке ). В самом деле? Я хотел бы проверить это требование.

Я начинаю с создания ванильного Java-приложения с использованием Maven. 

Файл: MavenCommands.bat

call mvn archetype:create ^
 -DarchetypeGroupId=org.apache.maven.archetypes ^
 -DgroupId=org.academy ^
 -DartifactId=logger

К сожалению, это предустановлено с помощью JUnit 3. Я настроил JUnit 4, а также добавил Contiperf, чтобы я мог запускать тесты несколько раз — что пригодится, если я буду проверять производительность.

Файл: /logger/pom.xml

[...]

<junit.version>4.10</junit.version>         
<contiperf.version>2.2.0</contiperf.version>

[...]
                         
<dependency>                                
 <groupid>junit</groupid>                
 <artifactid>junit</artifactid>          
 <version>${junit.version}</version>     
 <scope>test</scope>                     
</dependency>                               
     
<dependency>                                
 <groupid>org.databene</groupid>         
 <artifactid>contiperf</artifactid>      
 <version>${contiperf.version}</version> 
 <scope>test</scope>                     
</dependency>

Кроме того, мне нравится явно контролировать версию Java, которая используется для компиляции и выполнения моего кода.

Файл: /logger/pom.xml

[...]

<maven-compiler-plugin.version>2.0.2</maven-compiler-plugin.version>
<java.version>1.7</java.version>                                    

[...]
 
<plugin>                                                        
 <groupid>org.apache.maven.plugins</groupid>                 
 <artifactid>maven-compiler-plugin</artifactid>              
 <version>${maven-compiler-plugin.version}</version>         
 <configuration>                                             
  <source>${java.version}                        
  <target>${java.version}</target>                        
 </configuration>                                            
</plugin> 

Последняя из конфигураций — на данный момент. Шлепни по верному запуску юнит-тестов.

Файл: /logger/pom.xml

[...]

<maven-surefire-plugin.version>2.12</maven-surefire-plugin.version>                                

[...]
                         
<plugin>                                                        
 <groupid>org.apache.maven.plugins</groupid>                 
 <artifactid>maven-surefire-plugin</artifactid>              
 <version>${maven-surefire-plugin.version}</version>         
 <dependencies>                                              
  <dependency>                                            
   <groupid>org.apache.maven.surefire</groupid>        
   <artifactid>surefire-junit47</artifactid>           
   <version>${maven-surefire-plugin.version}</version> 
  </dependency>                                           
 </dependencies>                                             
 <configuration>                                             
  <argline>-XX:-UseSplitVerifier</argline>
 </configuration>                                            
</plugin>        

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

Теперь давайте наконец добавим модульные тесты.

Файл: /logger/src/test/java/org/academy/AppTest.java

public class AppTest {                                 
 private final static Logger logger = LoggerFactory 
   .getLogger(AppTest.class);                 
                                                       
 @Rule                                              
 public ContiPerfRule i = new ContiPerfRule();      
                                                       
 @Test                                              
 @PerfTest(invocations = 10, threads = 1)           
 @Required(max = 1200, average = 1000)              
 public void test() {                         
  for(int i = 0; i<10000 ; i++){          
   logger.debug("Hello {}", "world.");        
  }                                              
 }                                                  
}  

Итак, мы использовали регистратор в моем модульном тесте, но не добавили реализацию регистратора. Что я собираюсь сделать, это добавить log4j (с slf4j) и logback (с присущей ему поддержкой slf4j) один за другим и выполнить этот простой тест несколько раз, чтобы сравнить производительность.

Чтобы добавить log4j, я использовал эту настройку.

Файл: /logger/pom.xml

<dependency>                                
 <groupid>org.slf4j</groupid>            
 <artifactid>slf4j-api</artifactid>      
 <version>${slf4j.version}</version>     
</dependency>                               
<dependency>                                
 <groupid>org.slf4j</groupid>            
 <artifactid>jcl-over-slf4j</artifactid> 
 <version>${slf4j.version}</version>     
 <scope>runtime</scope>                  
</dependency>                               
<dependency>                                
 <groupid>org.slf4j</groupid>            
 <artifactid>slf4j-log4j12</artifactid>  
 <version>${slf4j.version}</version>     
 <scope>runtime</scope>                  
</dependency> 

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

Файл: /logger/pom.xml

<dependency>                                
 <groupid>ch.qos.logback</groupid>       
 <artifactid>logback-classic</artifactid>
 <version>${logback.version}</version>   
</dependency>   

со следующими версиями.

Файл: /logger/pom.xml

<slf4j.version>1.6.1</slf4j.version>    
<logback.version>1.0.6</logback.version>

Наконец, на момент истины. Я запускал тесты трижды с каждой структурой, то есть logback и log4j. По сути, я log.debug () строка 1000 000 раз в каждом тесте и синхронизировал их. И так вышли окончательные цифры.

Фреймворк 1-й пробег 2-й пробег 3-й пробег
Logback 0,375 секунды 0,375 секунды 0,406 секунды
Log4j 0,454 секунды 0,453 секунды 0,454 секунды

Что касается этого небольшого эксперимента, Logback явно работает быстрее, чем Log4j. Конечно, это слишком упрощенный эксперимент, и многие действительные сценарии не были рассмотрены. Например, мы не использовали vanilla log4j. Мы использовали log4j в сочетании с API slf4j, что не совсем то же самое. Кроме того, скорость не единственное соображение. Log4j работает асинхронно (читай здесь и здесь ), тогда как, насколько я знаю, Logback — нет. Logback имеет довольно много отличных функций, которых нет у Log4j.

Таким образом, в отдельности этот маленький код ничего не доказывает. Если вообще, это возвращает меня к первому пункту, который я сделал — Logback — серьезный потенциал, и его стоит посмотреть, если вы разрабатываете / кодируете Java-приложение корпоративного уровня.

Это все для этой статьи. Удачного кодирования.

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