Статьи

Logback: повторное ведение журнала

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

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

В первой статье я представил журналирование как высокоэффективную, недорогую альтернативу вездесущей 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

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

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

Файл: /logger/pom.xml

01
02
03
04
05
06
07
08
09
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
[...]
 
 
                                                                               
  
                      
                      UTF-8
                      
         
                      
                      4.10
                               
         
                      
                      2.2.0
                      
 [...]                          
 
                                                                        
 
[...]
                          
                     
 
                                                
  
                      
                      junit
                                 
  
                      
                      junit
                           
  
                      
                      ${junit.version}
                      
  
                      
                      test
                                      
 
                                                                              
      
 
                                                     
  
                      
                      org.databene
                               
  
                      
                      contiperf
                            
  
                      
                      ${contiperf.version}
                       
  
                      
                      test
                                           
 
                    

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

Файл: /logger/pom.xml

01
02
03
04
05
06
07
08
09
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
[...]
 
 
                     
                     2.0.2
                     
 
                     
                     1.7
                                                         
 
[...]
 
  
 
                                                                             
  
                      
                      org.apache.maven.plugins
                                       
  
                      
                      maven-compiler-plugin
                                    
  
                      
                      ${maven-compiler-plugin.version}
                               
  
                                                                   
   
                      ${java.version}                       
   
                       
                       ${java.version}
                                               
  
                                                                  
 
                     

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

Файл: /logger/pom.xml

01
02
03
04
05
06
07
08
09
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
[...]
 
 
                     
                     2.12
                                                     
 
[...]
 
                          
 
                                                                             
  
                      
                      org.apache.maven.plugins
                                       
  
                      
                      maven-surefire-plugin
                                    
  
                      
                      ${maven-surefire-plugin.version}
                               
  
                                                                    
   
                                                                   
    
                        
                        org.apache.maven.surefire
                                
    
                        
                        surefire-junit47
                                   
    
                        
                        ${maven-surefire-plugin.version}
                         
   
                                                                  
  
                                                                   
  
                                                                   
   
                       
                       -XX:-UseSplitVerifier
                       
  
                                                                  
 
                            

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

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

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
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

01
02
03
04
05
06
07
08
09
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
org.slf4j
            
 
 
slf4j-api
      
 
 
${slf4j.version}
     
 
                              
 
                               
 
 
org.slf4j
            
 
 
jcl-over-slf4j
 
 
 
${slf4j.version}
     
 
 
runtime
                  
 
                              
 
                               
 
 
org.slf4j
            
 
 
slf4j-log4j12
  
 
 
${slf4j.version}
     
 
 
runtime
                 

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

Файл: /logger/pom.xml

01
02
03
04
05
06
07
08
09
10
11
12
13
14
ch.qos.logback
       
 
 
logback-classic
 
 
 
${logback.version}
  

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

Файл: /logger/pom.xml

1
2
3
4
5
6
1.6.1
    
 
 
1.0.6

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

Файл: src / main / resources / log4j.properties

1
2
3
4
5
6
7
# Set root logger level to DEBUG and its only appender to A1.
log4j.rootLogger=DEBUG, A1
 
# configure A1 to spit out data in console
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
Наконец, на момент истины. Я запускал тесты трижды с каждой структурой, то есть 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-приложение корпоративного уровня.
Это все для этой статьи. Удачного кодирования.