1   /*
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2026, QOS.ch. All rights reserved.
4    *
5    * This program and the accompanying materials are dual-licensed under
6    * either the terms of the Eclipse Public License v2.0 as published by
7    * the Eclipse Foundation
8    *
9    *   or (per the licensee's choosing)
10   *
11   * under the terms of the GNU Lesser General Public License version 2.1
12   * as published by the Free Software Foundation.
13   */
14  
15  package ch.qos.logback.classic.pattern;
16  
17  import java.io.IOException;
18  import java.nio.file.Files;
19  import java.nio.file.Paths;
20  import java.util.Arrays;
21  import java.util.List;
22  import java.util.stream.Collectors;
23  
24  import org.junit.jupiter.api.AfterEach;
25  import org.junit.jupiter.api.BeforeAll;
26  import org.junit.jupiter.api.BeforeEach;
27  import org.junit.jupiter.api.Disabled;
28  import org.junit.jupiter.api.Test;
29  import org.slf4j.Logger;
30  import org.slf4j.LoggerFactory;
31  
32  import ch.qos.logback.classic.ClassicTestConstants;
33  import ch.qos.logback.classic.LoggerContext;
34  import ch.qos.logback.classic.testUtil.Gaussian;
35  import ch.qos.logback.core.status.OnConsoleStatusListener;
36  
37  @Disabled
38  public class LoggerNameConverterPerfTest {
39  
40      static final String NAMES_FILE = ClassicTestConstants.INPUT_PREFIX + "fqcn.txt";
41  
42      static List<String> NAMES_LIST;
43  
44      static int SIZE;
45      static double MEAN;
46      static double DEVIATION;
47      static Gaussian G;
48  
49      LoggerContext loggerContext = new LoggerContext();
50      LoggerConverter loggerConverter = new LoggerConverter();
51  
52      LoggerNameOnlyLoggingEvent event = new LoggerNameOnlyLoggingEvent();
53  
54      Logger logger = LoggerFactory.getLogger(this.getClass());
55  
56      @BeforeAll
57      static public void loadClassNames() throws IOException {
58  
59          NAMES_LIST = Files.lines(Paths.get(NAMES_FILE)).collect(Collectors.toList());
60  
61          SIZE = NAMES_LIST.size();
62          MEAN = SIZE / 2;
63          DEVIATION = MEAN / 8;
64          G = new Gaussian(MEAN, DEVIATION);
65          System.out.println("names list size=" + SIZE);
66      }
67  
68      @BeforeEach
69      public void setUp() {
70          OnConsoleStatusListener ocsl = new OnConsoleStatusListener();
71          ocsl.setContext(loggerContext);
72          ocsl.start();
73          loggerContext.getStatusManager().add(ocsl);
74          loggerConverter.setOptionList(Arrays.asList("30"));
75          loggerConverter.setContext(loggerContext);
76          loggerConverter.start();
77      }
78  
79      @AfterEach
80      public void tearDown() {
81  
82      }
83  
84      @Test
85      public void measureAbbreviationPerf() {
86          for (int i = 0; i < 10 * 1000; i++) {
87              performAbbreviation();
88          }
89          for (int i = 0; i < 10 * 1000; i++) {
90              performAbbreviation();
91          }
92          final int runLength = 1000 * 1000;
93          System.out.println("Start measurements");
94          long start = System.nanoTime();
95          for (int i = 0; i < runLength; i++) {
96              performAbbreviation();
97          }
98          long end = System.nanoTime();
99          long diff = end - start;
100         double average = diff * 1.0D / runLength;
101         logger.atInfo().addArgument(average).log("Average = {} nanos");
102         int cacheMisses = loggerConverter.getCacheMisses();
103 
104         logger.atInfo().addArgument(cacheMisses).log("cacheMisses = {} ");
105         logger.atInfo().addArgument(runLength).log("total calls= = {} ");
106 
107         double cacheMissRate = loggerConverter.getCacheMissRate() * 100;
108         logger.atInfo().addArgument(cacheMissRate).log("cacheMiss rate %= {} ");
109 
110     }
111 
112     public void performAbbreviation() {
113         String fqn = getFQN();
114         event.setLoggerName(fqn);
115         loggerConverter.convert(event);
116     }
117 
118     private String getFQN() {
119         while (true) {
120             int index = (int) G.getGaussian();
121             if (index >= 0 && index < SIZE) {
122                 return NAMES_LIST.get(index);
123             } else {
124                 continue;
125             }
126         }
127     }
128 
129 }