001/*
002 * Copyright 2015-2024 the original author or authors
003 *
004 * This software is licensed under the Apache License, Version 2.0,
005 * the GNU Lesser General Public License version 2 or later ("LGPL")
006 * and the WTFPL.
007 * You may choose either license to govern your use of this software only
008 * upon the condition that you accept all of the terms of either
009 * the Apache License 2.0, the LGPL 2.1+ or the WTFPL.
010 */
011package org.minidns.jul;
012
013import java.io.ByteArrayInputStream;
014import java.io.IOException;
015import java.io.InputStream;
016import java.io.PrintWriter;
017import java.io.StringWriter;
018import java.nio.charset.StandardCharsets;
019import java.text.SimpleDateFormat;
020import java.util.Date;
021import java.util.logging.ConsoleHandler;
022import java.util.logging.Formatter;
023import java.util.logging.Handler;
024import java.util.logging.Level;
025import java.util.logging.LogManager;
026import java.util.logging.LogRecord;
027import java.util.logging.Logger;
028
029@SuppressWarnings("DateFormatConstant")
030public class MiniDnsJul {
031
032    private static final Logger LOGGER = Logger.getLogger(MiniDnsJul.class.getName());
033
034    private static final InputStream LOG_MANAGER_CONFIG = new ByteArrayInputStream((
035// @formatter:off
036"org.minidns.level=FINEST" + '\n'
037).getBytes(StandardCharsets.UTF_8)
038);
039// @formatter:on
040
041    private static final SimpleDateFormat LONG_LOG_TIME_FORMAT = new SimpleDateFormat("hh:mm:ss.SSS");
042
043    private static final SimpleDateFormat SHORT_LOG_TIME_FORMAT = new SimpleDateFormat("mm:ss.SSS");
044
045    private static final Handler CONSOLE_HANDLER = new ConsoleHandler();
046
047    private static boolean shortLog = true;
048
049    static {
050        try {
051            LogManager.getLogManager().readConfiguration(LOG_MANAGER_CONFIG);
052        } catch (SecurityException | IOException e) {
053            LOGGER.log(Level.SEVERE, "Could not apply MiniDNS JUL configuration", e);
054        }
055
056        CONSOLE_HANDLER.setLevel(Level.OFF);
057        CONSOLE_HANDLER.setFormatter(new Formatter() {
058            @Override
059            public String format(LogRecord logRecord) {
060                StringBuilder sb = new StringBuilder(256);
061
062                Date date = new Date(logRecord.getMillis());
063                String dateString;
064                if (shortLog) {
065                    synchronized (SHORT_LOG_TIME_FORMAT) {
066                        dateString = SHORT_LOG_TIME_FORMAT.format(date);
067                    }
068                } else {
069                    synchronized (LONG_LOG_TIME_FORMAT) {
070                        dateString = LONG_LOG_TIME_FORMAT.format(date);
071                    }
072                }
073                sb.append(dateString).append(' ');
074
075                String level = logRecord.getLevel().toString();
076                if (shortLog) {
077                    level = level.substring(0, 1);
078                }
079                sb.append(level).append(' ');
080
081                String loggerName = logRecord.getLoggerName();
082                if (shortLog) {
083                    String[] parts = loggerName.split("\\.");
084                    loggerName = parts[parts.length > 1 ? parts.length - 1 : 0];
085                }
086                sb.append(loggerName);
087                sb.append(' ').append(logRecord.getSourceMethodName());
088
089                if (shortLog) {
090                    sb.append(' ');
091                } else {
092                    sb.append('\n');
093                }
094
095                sb.append(formatMessage(logRecord));
096                if (logRecord.getThrown() != null) {
097                    StringWriter sw = new StringWriter();
098                    PrintWriter pw = new PrintWriter(sw);
099                    // CHECKSTYLE:OFF
100                    pw.println();
101                    logRecord.getThrown().printStackTrace(pw);
102                    // CHECKSTYLE:ON
103                    pw.close();
104                    sb.append(sw);
105                }
106                sb.append('\n');
107                return sb.toString();
108            }
109        });
110        Logger.getLogger("org.minidns").addHandler(CONSOLE_HANDLER);
111    }
112
113    public static void enableMiniDnsTrace() {
114        enableMiniDnsTrace(true);
115    }
116
117    public static void enableMiniDnsTrace(boolean shortLog) {
118        MiniDnsJul.shortLog = shortLog;
119        CONSOLE_HANDLER.setLevel(Level.FINEST);
120    }
121
122    public static void disableMiniDnsTrace() {
123        CONSOLE_HANDLER.setLevel(Level.OFF);
124    }
125}