23
23
*/
24
24
package org .opengrok .indexer .util ;
25
25
26
+ import org .jetbrains .annotations .VisibleForTesting ;
26
27
import org .opengrok .indexer .configuration .RuntimeEnvironment ;
27
28
29
+ import java .util .Arrays ;
30
+ import java .util .Comparator ;
28
31
import java .util .HashMap ;
32
+ import java .util .List ;
29
33
import java .util .Map ;
34
+ import java .util .TreeMap ;
30
35
import java .util .concurrent .atomic .AtomicLong ;
31
36
import java .util .logging .Level ;
32
37
import java .util .logging .Logger ;
35
40
* Progress reporting via logging. The idea is that for anything that has a set of items
36
41
* to go through, it will ping an instance of this class for each item completed.
37
42
* This class will then log based on the number of pings. The bigger the progress,
38
- * the higher log level ({@link Level} value) will be used.
43
+ * the higher log level ({@link Level} value) will be used. The default base level is {@code Level.INFO}.
39
44
*/
40
45
public class Progress implements AutoCloseable {
41
46
private final Logger logger ;
42
47
private final Long totalCount ;
43
48
private final String suffix ;
44
49
45
50
private final AtomicLong currentCount = new AtomicLong ();
46
- private final Map <Level , Integer > levelCount ;
51
+ private final Map <Level , Integer > levelCountMap = new TreeMap <>( Comparator . comparingInt ( Level :: intValue ). reversed ()) ;
47
52
private Thread loggerThread = null ;
48
53
private volatile boolean run ;
49
54
55
+ private final Level baseLogLevel ;
56
+
50
57
private final Object sync = new Object ();
51
58
52
59
/**
53
60
* @param logger logger instance
54
61
* @param suffix string suffix to identify the operation
55
62
*/
56
63
public Progress (Logger logger , String suffix ) {
57
- this (logger , suffix , -1 );
64
+ this (logger , suffix , -1 , Level .INFO );
65
+ }
66
+
67
+ /**
68
+ * @param logger logger instance
69
+ * @param suffix string suffix to identify the operation
70
+ * @param logLevel base log level
71
+ */
72
+ public Progress (Logger logger , String suffix , Level logLevel ) {
73
+ this (logger , suffix , -1 , logLevel );
58
74
}
59
75
60
76
/**
@@ -63,22 +79,44 @@ public Progress(Logger logger, String suffix) {
63
79
* @param totalCount total count
64
80
*/
65
81
public Progress (Logger logger , String suffix , long totalCount ) {
82
+ this (logger , suffix , totalCount , Level .INFO );
83
+ }
84
+
85
+ /**
86
+ * @param logger logger instance
87
+ * @param suffix string suffix to identify the operation
88
+ * @param totalCount total count
89
+ * @param logLevel base log level
90
+ */
91
+ public Progress (Logger logger , String suffix , long totalCount , Level logLevel ) {
66
92
this .logger = logger ;
67
93
this .suffix = suffix ;
94
+ this .baseLogLevel = logLevel ;
68
95
69
96
if (totalCount < 0 ) {
70
97
this .totalCount = null ;
71
98
} else {
72
99
this .totalCount = totalCount ;
73
100
}
74
101
75
- levelCount = Map .of (Level .INFO , 100 ,
76
- Level .FINE , 50 ,
77
- Level .FINER , 10 ,
78
- Level .FINEST , 1 );
79
-
80
- // Assuming printProgress configuration setting cannot be changed on the fly.
81
- if (RuntimeEnvironment .getInstance ().isPrintProgress ()) {
102
+ // Note: Level.CONFIG is missing
103
+ final List <Level > standardLevels = Arrays .asList (Level .OFF , Level .SEVERE , Level .WARNING , Level .INFO ,
104
+ Level .FINE , Level .FINER , Level .FINEST , Level .ALL );
105
+ int i = standardLevels .indexOf (baseLogLevel );
106
+ for (int num : new int []{100 , 50 , 10 , 1 }) {
107
+ Level level = standardLevels .get (i );
108
+ if (level == null ) {
109
+ break ;
110
+ }
111
+ levelCountMap .put (level , num );
112
+ if (num == 1 ) {
113
+ break ;
114
+ }
115
+ i ++;
116
+ }
117
+
118
+ // Assuming the printProgress configuration setting cannot be changed on the fly.
119
+ if (!baseLogLevel .equals (Level .OFF ) && RuntimeEnvironment .getInstance ().isPrintProgress ()) {
82
120
spawnLogThread ();
83
121
}
84
122
}
@@ -120,21 +158,7 @@ private void logLoop() {
120
158
121
159
// Do not log if there was no progress.
122
160
if (cachedCount < currentCount ) {
123
- if (currentCount <= 1 || (totalCount != null && currentCount == totalCount )) {
124
- currentLevel = Level .INFO ;
125
- } else {
126
- if (lastLoggedChunk .getOrDefault (Level .INFO , -1L ) <
127
- currentCount / levelCount .get (Level .INFO )) {
128
- currentLevel = Level .INFO ;
129
- } else if (lastLoggedChunk .getOrDefault (Level .FINE , -1L ) <
130
- currentCount / levelCount .get (Level .FINE )) {
131
- currentLevel = Level .FINE ;
132
- } else if (lastLoggedChunk .getOrDefault (Level .FINER , -1L ) <
133
- currentCount / levelCount .get (Level .FINER )) {
134
- currentLevel = Level .FINER ;
135
- }
136
- }
137
-
161
+ currentLevel = getLevel (lastLoggedChunk , currentCount , currentLevel );
138
162
logIt (lastLoggedChunk , currentCount , currentLevel );
139
163
}
140
164
@@ -159,9 +183,27 @@ private void logLoop() {
159
183
}
160
184
}
161
185
186
+ @ VisibleForTesting
187
+ Level getLevel (Map <Level , Long > lastLoggedChunk , long currentCount , Level currentLevel ) {
188
+ // The intention is to log the initial and final count at the base log level.
189
+ if (currentCount <= 1 || (totalCount != null && currentCount == totalCount )) {
190
+ currentLevel = baseLogLevel ;
191
+ } else {
192
+ // Set the log level based on the "buckets".
193
+ for (Level level : levelCountMap .keySet ()) {
194
+ if (lastLoggedChunk .getOrDefault (level , -1L ) <
195
+ currentCount / levelCountMap .get (level )) {
196
+ currentLevel = level ;
197
+ break ;
198
+ }
199
+ }
200
+ }
201
+ return currentLevel ;
202
+ }
203
+
162
204
private void logIt (Map <Level , Long > lastLoggedChunk , long currentCount , Level currentLevel ) {
163
205
if (logger .isLoggable (currentLevel )) {
164
- lastLoggedChunk .put (currentLevel , currentCount / levelCount .get (currentLevel ));
206
+ lastLoggedChunk .put (currentLevel , currentCount / levelCountMap .get (currentLevel ));
165
207
StringBuilder stringBuilder = new StringBuilder ();
166
208
stringBuilder .append ("Progress: " );
167
209
stringBuilder .append (currentCount );
0 commit comments