2020
2121import java .time .LocalDateTime ;
2222import java .time .format .DateTimeFormatter ;
23- import java .util .logging .Formatter ;
24- import java .util .logging .Handler ;
25- import java .util .logging .SimpleFormatter ;
2623
2724/**
2825 * Logger wrapper providing simple logging with TRACE, INFO, WARN, and ERROR levels.
2926 *
30- * <p>This class wraps {@link java.util. logging.Logger} and provides:
27+ * <p>This class delegates to the configured logging backend and provides:
3128 *
3229 * <ul>
3330 * <li>Simple logging interface with format strings
31+ * <li>Native logging that does not initialize Java Util Logging (JUL)
32+ * <li>Optional JUL integration
3433 * <li>Developer debug mode for additional console output
35- * <li>Custom formatter for consistent log message format
3634 * </ul>
3735 *
3836 * <p>Developer debug mode can be enabled via:
4240 * <li>System property: {@code -Djmx.prometheus.exporter.developer.debug=true}
4341 * </ul>
4442 *
45- * <p>Thread-safety: This class is thread-safe. The underlying logger is thread-safe, and
46- * date formatting uses a thread-safe {@link DateTimeFormatter}.
43+ * <p>Thread-safety: This class is thread-safe. Logging backends are responsible for serializing
44+ * writes where required, and date formatting uses a thread-safe {@link DateTimeFormatter}.
4745 */
4846public class Logger {
4947
5048 /**
51- * The underlying Java util logger .
49+ * The configured logging backend .
5250 */
53- private final java . util . logging . Logger LOGGER ;
51+ private final LoggerBackend backend ;
5452
5553 /**
5654 * Cached logger name for developer debug output.
@@ -60,15 +58,15 @@ public class Logger {
6058 /**
6159 * Flag indicating if developer debug mode is enabled.
6260 *
63- * <p>When enabled, logs are also written to stdout in addition to the normal logging
64- * destination . Evaluated once at class load time.
61+ * <p>When enabled, logs are also written to stdout in addition to the configured logging
62+ * backend . Evaluated once at class load time.
6563 */
6664 private static volatile boolean DEVELOPER_DEBUG =
6765 "true" .equals (System .getenv ("JMX_PROMETHEUS_EXPORTER_DEVELOPER_DEBUG" ))
6866 || "true" .equals (System .getProperty ("jmx.prometheus.exporter.developer.debug" ));
6967
7068 /**
71- * Thread-safe date formatter for log timestamps.
69+ * Thread-safe date formatter for developer debug timestamps.
7270 */
7371 private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter .ofPattern ("yyyy-MM-dd HH:mm:ss.SSS" );
7472
@@ -78,16 +76,8 @@ public class Logger {
7876 * @param clazz the class for which to create a logger, must not be {@code null}
7977 */
8078 Logger (Class <?> clazz ) {
81- LOGGER = java .util .logging .Logger .getLogger (clazz .getName ());
82- loggerName = LOGGER .getName ();
83-
84- // Override the default formatter for the logger if it is SimpleFormatter
85- for (Handler handler : LOGGER .getHandlers ()) {
86- Formatter formatter = handler .getFormatter ();
87- if (null != formatter && formatter .getClass ().getName ().endsWith (SimpleFormatter .class .getName ())) {
88- handler .setFormatter (new LoggerFormatter ());
89- }
90- }
79+ loggerName = clazz .getName ();
80+ backend = LoggerFactory .createBackend (loggerName );
9181 }
9282
9383 /**
@@ -96,7 +86,7 @@ public class Logger {
9686 * @return {@code true} if TRACE logging is enabled, {@code false} otherwise
9787 */
9888 public boolean isTraceEnabled () {
99- return LOGGER . isLoggable (Level .TRACE . julLevel () );
89+ return backend . isEnabled (Level .TRACE );
10090 }
10191
10292 /**
@@ -105,7 +95,7 @@ public boolean isTraceEnabled() {
10595 * @return {@code true} if INFO logging is enabled, {@code false} otherwise
10696 */
10797 public boolean isInfoEnabled () {
108- return LOGGER . isLoggable (Level .INFO . julLevel () );
98+ return backend . isEnabled (Level .INFO );
10999 }
110100
111101 /**
@@ -114,7 +104,7 @@ public boolean isInfoEnabled() {
114104 * @return {@code true} if WARN logging is enabled, {@code false} otherwise
115105 */
116106 public boolean isWarnEnabled () {
117- return LOGGER . isLoggable (Level .WARN . julLevel () );
107+ return backend . isEnabled (Level .WARN );
118108 }
119109
120110 /**
@@ -123,7 +113,7 @@ public boolean isWarnEnabled() {
123113 * @return {@code true} if ERROR logging is enabled, {@code false} otherwise
124114 */
125115 public boolean isErrorEnabled () {
126- return LOGGER . isLoggable (Level .ERROR . julLevel () );
116+ return backend . isEnabled (Level .ERROR );
127117 }
128118
129119 /**
@@ -237,15 +227,14 @@ public void error(String format, Object... objects) {
237227 *
238228 * <p>Skips {@link String#format} since the message is already a plain string.
239229 *
240- * @param level the level
230+ * @param level the level
241231 * @param message the pre-formatted message
242232 */
243233 private void log (Level level , String message ) {
244- java .util .logging .Level julLevel = level .julLevel ();
245- boolean loggable = LOGGER .isLoggable (julLevel );
234+ boolean loggable = backend .isEnabled (level );
246235 boolean debug = DEVELOPER_DEBUG ;
247236 if (loggable ) {
248- LOGGER .log (julLevel , message );
237+ backend .log (level , message );
249238 }
250239 if (debug ) {
251240 developerDebug (level , message );
@@ -255,18 +244,17 @@ private void log(Level level, String message) {
255244 /**
256245 * Logs a formatted message at the given level.
257246 *
258- * @param level the level
259- * @param format the format string
247+ * @param level the level
248+ * @param format the format string
260249 * @param objects the objects to format
261250 */
262251 private void log (Level level , String format , Object ... objects ) {
263- java .util .logging .Level julLevel = level .julLevel ();
264- boolean loggable = LOGGER .isLoggable (julLevel );
252+ boolean loggable = backend .isEnabled (level );
265253 boolean debug = DEVELOPER_DEBUG ;
266254 if (loggable || debug ) {
267255 String message = format (format , objects );
268256 if (loggable ) {
269- LOGGER .log (julLevel , message );
257+ backend .log (level , message );
270258 }
271259 if (debug ) {
272260 developerDebug (level , message );
@@ -275,7 +263,7 @@ private void log(Level level, String format, Object... objects) {
275263 }
276264
277265 /**
278- * Writes a log message to stdout with timestamp, thread, level, and logger name.
266+ * Writes a developer debug message to stdout with timestamp, thread, level, and logger name.
279267 */
280268 private void developerDebug (Level level , String message ) {
281269 String timestamp = DATE_TIME_FORMATTER .format (LocalDateTime .now ());
0 commit comments