]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.api.cms/src/org/argeo/api/cms/CmsLog.java
Follow start levels more closely
[lgpl/argeo-commons.git] / org.argeo.api.cms / src / org / argeo / api / cms / CmsLog.java
1 package org.argeo.api.cms;
2
3 import java.lang.System.Logger;
4 import java.text.MessageFormat;
5 import java.util.Objects;
6 import java.util.function.Supplier;
7
8 /**
9 * A Commons Logging / SLF4J style logging utilities usually wrapping a standard
10 * Java platform {@link Logger}, but which can fallback to other mechanism, if a
11 * system logger is not available.
12 */
13 public interface CmsLog {
14 /*
15 * SYSTEM LOGGER STYLE METHODS
16 */
17 boolean isLoggable(Level level);
18
19 void log(Level level, Supplier<String> msgSupplier, Throwable thrown);
20
21 void log(Level level, String msg, Throwable thrown);
22
23 void log(Level level, String format, Object... params);
24
25 default void log(Level level, String msg) {
26 log(level, msg, (Throwable) null);
27 }
28
29 default void log(Level level, Supplier<String> msgSupplier) {
30 log(level, msgSupplier, (Throwable) null);
31 }
32
33 default void log(Level level, Object obj) {
34 Objects.requireNonNull(obj);
35 log(level, obj.toString());
36 }
37
38 /*
39 * SLF4j / COMMONS LOGGING STYLE METHODS
40 */
41 @Deprecated
42 CmsLog getLogger();
43
44 default boolean isDebugEnabled() {
45 return getLogger().isLoggable(Level.DEBUG);
46 }
47
48 default boolean isErrorEnabled() {
49 return getLogger().isLoggable(Level.ERROR);
50 }
51
52 default boolean isInfoEnabled() {
53 return getLogger().isLoggable(Level.INFO);
54 }
55
56 default boolean isTraceEnabled() {
57 return getLogger().isLoggable(Level.TRACE);
58 }
59
60 default boolean isWarnEnabled() {
61 return getLogger().isLoggable(Level.WARNING);
62 }
63
64 /*
65 * TRACE
66 */
67
68 default void trace(String message) {
69 getLogger().log(Level.TRACE, message);
70 }
71
72 default void trace(Supplier<String> message) {
73 getLogger().log(Level.TRACE, message);
74 }
75
76 default void trace(Object message) {
77 getLogger().log(Level.TRACE, Objects.requireNonNull(message));
78 }
79
80 default void trace(String message, Throwable t) {
81 getLogger().log(Level.TRACE, message, t);
82 }
83
84 default void trace(Object message, Throwable t) {
85 trace(Objects.requireNonNull(message).toString(), t);
86 }
87
88 default void trace(String format, Object... arguments) {
89 getLogger().log(Level.TRACE, format, arguments);
90 }
91
92 /*
93 * DEBUG
94 */
95
96 default void debug(String message) {
97 getLogger().log(Level.DEBUG, message);
98 }
99
100 default void debug(Supplier<String> message) {
101 getLogger().log(Level.DEBUG, message);
102 }
103
104 default void debug(Object message) {
105 getLogger().log(Level.DEBUG, message);
106 }
107
108 default void debug(String message, Throwable t) {
109 getLogger().log(Level.DEBUG, message, t);
110 }
111
112 default void debug(Object message, Throwable t) {
113 debug(Objects.requireNonNull(message).toString(), t);
114 }
115
116 default void debug(String format, Object... arguments) {
117 getLogger().log(Level.DEBUG, format, arguments);
118 }
119
120 /*
121 * INFO
122 */
123
124 default void info(String message) {
125 getLogger().log(Level.INFO, message);
126 }
127
128 default void info(Supplier<String> message) {
129 getLogger().log(Level.INFO, message);
130 }
131
132 default void info(Object message) {
133 getLogger().log(Level.INFO, message);
134 }
135
136 default void info(String message, Throwable t) {
137 getLogger().log(Level.INFO, message, t);
138 }
139
140 default void info(Object message, Throwable t) {
141 info(Objects.requireNonNull(message).toString(), t);
142 }
143
144 default void info(String format, Object... arguments) {
145 getLogger().log(Level.INFO, format, arguments);
146 }
147
148 /*
149 * WARN
150 */
151
152 default void warn(String message) {
153 getLogger().log(Level.WARNING, message);
154 }
155
156 default void warn(Supplier<String> message) {
157 getLogger().log(Level.WARNING, message);
158 }
159
160 default void warn(Object message) {
161 getLogger().log(Level.WARNING, message);
162 }
163
164 default void warn(String message, Throwable t) {
165 getLogger().log(Level.WARNING, message, t);
166 }
167
168 default void warn(Object message, Throwable t) {
169 warn(Objects.requireNonNull(message).toString(), t);
170 }
171
172 default void warn(String format, Object... arguments) {
173 getLogger().log(Level.WARNING, format, arguments);
174 }
175
176 /*
177 * ERROR
178 */
179
180 default void error(String message) {
181 getLogger().log(Level.ERROR, message);
182 }
183
184 default void error(Supplier<String> message) {
185 getLogger().log(Level.ERROR, message);
186 }
187
188 default void error(Object message) {
189 getLogger().log(Level.ERROR, message);
190 }
191
192 default void error(String message, Throwable t) {
193 getLogger().log(Level.ERROR, message, t);
194 }
195
196 default void error(Object message, Throwable t) {
197 error(Objects.requireNonNull(message).toString(), t);
198 }
199
200 default void error(String format, Object... arguments) {
201 getLogger().log(Level.ERROR, format, arguments);
202 }
203
204 /**
205 * Exact mapping of ${java.lang.System.Logger.Level}, in case it is not
206 * available.
207 */
208 public static enum Level {
209 ALL(Integer.MIN_VALUE), //
210 TRACE(400), //
211 DEBUG(500), //
212 INFO(800), //
213 WARNING(900), //
214 ERROR(1000), //
215 OFF(Integer.MAX_VALUE); //
216
217 final int severity;
218
219 private Level(int severity) {
220 this.severity = severity;
221 }
222
223 public final int getSeverity() {
224 return severity;
225 }
226 }
227
228 /*
229 * STATIC UTILITIES
230 */
231
232 static CmsLog getLog(Class<?> clss) {
233 return getLog(Objects.requireNonNull(clss).getName());
234 }
235
236 static CmsLog getLog(String name) {
237 if (isSystemLoggerAvailable) {
238 return new SystemCmsLog(name);
239 } else { // typically Android
240 return new FallBackCmsLog();
241 }
242 }
243
244 static final boolean isSystemLoggerAvailable = isSystemLoggerAvailable();
245
246 static boolean isSystemLoggerAvailable() {
247 try {
248 Logger logger = System.getLogger(CmsLog.class.getName());
249 logger.log(java.lang.System.Logger.Level.TRACE, () -> "System logger is available.");
250 return true;
251 } catch (NoSuchMethodError | NoClassDefFoundError e) {// Android
252 return false;
253 }
254 }
255 }
256
257 /**
258 * Uses {@link System.Logger}, should be used on proper implementations of the
259 * Java platform.
260 */
261 class SystemCmsLog implements CmsLog {
262 private final Logger logger;
263
264 SystemCmsLog(String name) {
265 logger = System.getLogger(name);
266 }
267
268 @Override
269 public boolean isLoggable(Level level) {
270 return logger.isLoggable(convertSystemLevel(level));
271 }
272
273 @Override
274 public void log(Level level, Supplier<String> msgSupplier, Throwable thrown) {
275 logger.log(convertSystemLevel(level), msgSupplier, thrown);
276 }
277
278 @Override
279 public void log(Level level, String msg, Throwable thrown) {
280 logger.log(convertSystemLevel(level), msg, thrown);
281 }
282
283 java.lang.System.Logger.Level convertSystemLevel(Level level) {
284 switch (level.severity) {
285 case Integer.MIN_VALUE:
286 return java.lang.System.Logger.Level.ALL;
287 case 400:
288 return java.lang.System.Logger.Level.TRACE;
289 case 500:
290 return java.lang.System.Logger.Level.DEBUG;
291 case 800:
292 return java.lang.System.Logger.Level.INFO;
293 case 900:
294 return java.lang.System.Logger.Level.WARNING;
295 case 1000:
296 return java.lang.System.Logger.Level.ERROR;
297 case Integer.MAX_VALUE:
298 return java.lang.System.Logger.Level.OFF;
299 default:
300 throw new IllegalArgumentException("Unexpected value: " + level.severity);
301 }
302 }
303
304 @Override
305 public void log(Level level, String format, Object... params) {
306 logger.log(convertSystemLevel(level), format, params);
307 }
308
309 @Override
310 public CmsLog getLogger() {
311 return this;
312 }
313 };
314
315 /** Dummy fallback for non-standard platforms such as Android. */
316 class FallBackCmsLog implements CmsLog {
317 @Override
318 public boolean isLoggable(Level level) {
319 return level.getSeverity() >= 800;// INFO and higher
320 }
321
322 @Override
323 public void log(Level level, Supplier<String> msgSupplier, Throwable thrown) {
324 if (isLoggable(level))
325 if (thrown != null || level.getSeverity() >= 900) {
326 System.err.println(msgSupplier.get());
327 thrown.printStackTrace();
328 } else {
329 System.out.println(msgSupplier.get());
330 }
331 }
332
333 @Override
334 public void log(Level level, String msg, Throwable thrown) {
335 if (isLoggable(level))
336 if (thrown != null || level.getSeverity() >= 900) {
337 System.err.println(msg);
338 thrown.printStackTrace();
339 } else {
340 System.out.println(msg);
341 }
342 }
343
344 @Override
345 public void log(Level level, String format, Object... params) {
346 if (format == null)
347 return;
348 String msg = MessageFormat.format(format, params);
349 log(level, msg);
350 }
351
352 @Override
353 public CmsLog getLogger() {
354 return this;
355 }
356 }