17ba0605dc97fb81bde8311510d27b3ccba170008Ceki Gulcu/**
27ba0605dc97fb81bde8311510d27b3ccba170008Ceki Gulcu * Copyright (c) 2004-2011 QOS.ch
388c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu * All rights reserved.
488c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu *
57ba0605dc97fb81bde8311510d27b3ccba170008Ceki Gulcu * Permission is hereby granted, free  of charge, to any person obtaining
67ba0605dc97fb81bde8311510d27b3ccba170008Ceki Gulcu * a  copy  of this  software  and  associated  documentation files  (the
788c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu * "Software"), to  deal in  the Software without  restriction, including
888c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu * without limitation  the rights to  use, copy, modify,  merge, publish,
97ba0605dc97fb81bde8311510d27b3ccba170008Ceki Gulcu * distribute,  sublicense, and/or sell  copies of  the Software,  and to
107ba0605dc97fb81bde8311510d27b3ccba170008Ceki Gulcu * permit persons to whom the Software  is furnished to do so, subject to
117ba0605dc97fb81bde8311510d27b3ccba170008Ceki Gulcu * the following conditions:
127ba0605dc97fb81bde8311510d27b3ccba170008Ceki Gulcu *
137ba0605dc97fb81bde8311510d27b3ccba170008Ceki Gulcu * The  above  copyright  notice  and  this permission  notice  shall  be
147ba0605dc97fb81bde8311510d27b3ccba170008Ceki Gulcu * included in all copies or substantial portions of the Software.
1588c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu *
1688c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu * THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
1788c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu * EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
187ba0605dc97fb81bde8311510d27b3ccba170008Ceki Gulcu * MERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND
197ba0605dc97fb81bde8311510d27b3ccba170008Ceki Gulcu * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
207ba0605dc97fb81bde8311510d27b3ccba170008Ceki Gulcu * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
217ba0605dc97fb81bde8311510d27b3ccba170008Ceki Gulcu * OF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION
227ba0605dc97fb81bde8311510d27b3ccba170008Ceki Gulcu * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2388c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu *
2488c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu */
2588c4c456766193e012eb890e2208473d99b91f83Ceki Gulcupackage org.slf4j.bridge;
2688c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu
2788c4c456766193e012eb890e2208473d99b91f83Ceki Gulcuimport java.text.MessageFormat;
2888c4c456766193e012eb890e2208473d99b91f83Ceki Gulcuimport java.util.MissingResourceException;
2988c4c456766193e012eb890e2208473d99b91f83Ceki Gulcuimport java.util.ResourceBundle;
3088c4c456766193e012eb890e2208473d99b91f83Ceki Gulcuimport java.util.logging.Handler;
3188c4c456766193e012eb890e2208473d99b91f83Ceki Gulcuimport java.util.logging.Level;
3288c4c456766193e012eb890e2208473d99b91f83Ceki Gulcuimport java.util.logging.LogManager;
3388c4c456766193e012eb890e2208473d99b91f83Ceki Gulcuimport java.util.logging.LogRecord;
3488c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu
3588c4c456766193e012eb890e2208473d99b91f83Ceki Gulcuimport org.slf4j.Logger;
3688c4c456766193e012eb890e2208473d99b91f83Ceki Gulcuimport org.slf4j.LoggerFactory;
3788c4c456766193e012eb890e2208473d99b91f83Ceki Gulcuimport org.slf4j.spi.LocationAwareLogger;
3888c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu
3988c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu// Based on http://bugzilla.slf4j.org/show_bug.cgi?id=38
4088c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu
4188c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu/**
4213f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * <p>Bridge/route all JUL log records to the SLF4J API.</p>
4313f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * <p>Essentially, the idea is to install on the root logger an instance of
4413f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * <code>SLF4JBridgeHandler</code> as the sole JUL handler in the system. Subsequently, the
4588c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu * SLF4JBridgeHandler instance will redirect all JUL log records are redirected
4688c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu * to the SLF4J API based on the following mapping of levels:
4713f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * </p>
4888c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu * <pre>
4988c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu * FINEST  -&gt; TRACE
5088c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu * FINER   -&gt; DEBUG
5188c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu * FINE    -&gt; DEBUG
5288c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu * INFO    -&gt; INFO
5388c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu * WARNING -&gt; WARN
5413f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * SEVERE  -&gt; ERROR</pre>
5513f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * <p><b>Programmatic installation:</b></p>
5613f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * <pre>
5713f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * // Optionally remove existing handlers attached to j.u.l root logger
5813f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * SLF4JBridgeHandler.removeHandlersForRootLogger();  // (since SLF4J 1.6.5)
5913f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu
6013f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * // add SLF4JBridgeHandler to j.u.l's root logger, should be done once during
6113f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * // the initialization phase of your application
6213f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * SLF4JBridgeHandler.install();</pre>
6313f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * <p><b>Installation via <em>logging.properties</em> configuration file:</b></p>
6413f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * <pre>
6513f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * // register SLF4JBridgeHandler as handler for the j.u.l. root logger
6613f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * handlers = org.slf4j.bridge.SLF4JBridgeHandler</pre>
6713f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * <p>Once SLF4JBridgeHandler is installed, logging by j.u.l. loggers will be directed to
6813f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * SLF4J. Example: </p>
6988c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu * <pre>
7013f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * import  java.util.logging.Logger;
7113f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * ...
7288c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu * // usual pattern: get a Logger and then log a message
7313f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * Logger julLogger = Logger.getLogger(&quot;org.wombat&quot;);
7413f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * julLogger.fine(&quot;hello world&quot;); // this will get redirected to SLF4J</pre>
7513f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu *
7613f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * <p>Please note that translating a java.util.logging event into SLF4J incurs the
7788c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu * cost of constructing {@link LogRecord} instance regardless of whether the
7888c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu * SLF4J logger is disabled for the given level. <b>Consequently, j.u.l. to
7913f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * SLF4J translation can seriously increase the cost of disabled logging
8013f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * statements (60 fold or 6000% increase) and measurably impact the performance of enabled log
8113f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * statements (20% overall increase).</b> Please note that as of logback-version 0.9.25,
8213f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * it is possible to completely eliminate the 60 fold translation overhead for disabled
8313f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * log statements with the help of <a href="http://logback.qos.ch/manual/configuration.html#LevelChangePropagator">LevelChangePropagator</a>.
8488c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu * </p>
8513f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu *
8613f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * <p>If you are concerned about application performance, then use of <code>SLF4JBridgeHandler</code>
8713f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * is appropriate only if any one the following two conditions is true:</p>
8813f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * <ol>
8913f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * <li>few j.u.l. logging statements are in play</li>
9013f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * <li>LevelChangePropagator has been installed</li>
9113f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu * </ol>
9213f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu *
9388c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu * @author Christian Stein
9488c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu * @author Joern Huxhorn
9588c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu * @author Ceki G&uuml;lc&uuml;
9688c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu * @author Darryl Smith
9788c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu * @since 1.5.1
9888c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu */
9988c4c456766193e012eb890e2208473d99b91f83Ceki Gulcupublic class SLF4JBridgeHandler extends Handler {
10088c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu
10131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    // The caller is java.util.logging.Logger
10231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    private static final String FQCN = java.util.logging.Logger.class.getName();
10331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    private static final String UNKNOWN_LOGGER_NAME = "unknown.jul.logger";
10488c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu
10531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    private static final int TRACE_LEVEL_THRESHOLD = Level.FINEST.intValue();
10631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    private static final int DEBUG_LEVEL_THRESHOLD = Level.FINE.intValue();
10731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    private static final int INFO_LEVEL_THRESHOLD = Level.INFO.intValue();
10831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    private static final int WARN_LEVEL_THRESHOLD = Level.WARNING.intValue();
10988c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu
11031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    /**
11131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * Adds a SLF4JBridgeHandler instance to jul's root logger.
11231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * <p/>
11331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * <p/>
11431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * This handler will redirect j.u.l. logging to SLF4J. However, only logs enabled
11531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * in j.u.l. will be redirected. For example, if a log statement invoking a
11631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * j.u.l. logger is disabled, then the corresponding non-event will <em>not</em>
11731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * reach SLF4JBridgeHandler and cannot be redirected.
11831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     */
11931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    public static void install() {
12031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        LogManager.getLogManager().getLogger("").addHandler(new SLF4JBridgeHandler());
12131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    }
12288c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu
12331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    private static java.util.logging.Logger getRootLogger() {
12431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        return LogManager.getLogManager().getLogger("");
12588c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu    }
12688c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu
12731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    /**
12831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * Removes previously installed SLF4JBridgeHandler instances. See also
12931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * {@link #install()}.
13031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     *
13131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * @throws SecurityException A <code>SecurityException</code> is thrown, if a security manager
13231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     *                           exists and if the caller does not have
13331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     *                           LoggingPermission("control").
13431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     */
13531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    public static void uninstall() throws SecurityException {
13631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        java.util.logging.Logger rootLogger = getRootLogger();
13731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        Handler[] handlers = rootLogger.getHandlers();
13831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        for (int i = 0; i < handlers.length; i++) {
13931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            if (handlers[i] instanceof SLF4JBridgeHandler) {
14031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu                rootLogger.removeHandler(handlers[i]);
14131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            }
14231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        }
14313f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu    }
14413f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu
14531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    /**
14631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * Returns true if SLF4JBridgeHandler has been previously installed, returns false otherwise.
14731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     *
14831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * @return true if SLF4JBridgeHandler is already installed, false other wise
14931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * @throws SecurityException
15031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     */
15131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    public static boolean isInstalled() throws SecurityException {
15231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        java.util.logging.Logger rootLogger = getRootLogger();
15331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        Handler[] handlers = rootLogger.getHandlers();
15431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        for (int i = 0; i < handlers.length; i++) {
15531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            if (handlers[i] instanceof SLF4JBridgeHandler) {
15631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu                return true;
15731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            }
15831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        }
15931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        return false;
16013f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu    }
1619d2796d04333e3790cc6f8d30d0b003a34ff942aCeki Gulcu
16231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    /**
16331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * Invoking this method removes/unregisters/detaches all handlers currently attached to the root logger
16431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * @since 1.6.5
16531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     */
16631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    public static void removeHandlersForRootLogger() {
16731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        java.util.logging.Logger rootLogger = getRootLogger();
16831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        java.util.logging.Handler[] handlers = rootLogger.getHandlers();
16931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        for (int i = 0; i < handlers.length; i++) {
17031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            rootLogger.removeHandler(handlers[i]);
17131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        }
17231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    }
1739d2796d04333e3790cc6f8d30d0b003a34ff942aCeki Gulcu
17431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    /**
17531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * Initialize this handler.
17631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     */
17731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    public SLF4JBridgeHandler() {
17831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    }
17988c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu
18031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    /**
18131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * No-op implementation.
18231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     */
18331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    public void close() {
18431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        // empty
18531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    }
18688c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu
18731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    /**
18831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * No-op implementation.
18931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     */
19031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    public void flush() {
19131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        // empty
19231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    }
19388c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu
19431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    /**
19531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * Return the Logger instance that will be used for logging.
19631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     */
19731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    protected Logger getSLF4JLogger(LogRecord record) {
19831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        String name = record.getLoggerName();
19931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        if (name == null) {
20031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            name = UNKNOWN_LOGGER_NAME;
20131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        }
20231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        return LoggerFactory.getLogger(name);
20388c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu    }
20488c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu
20531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    protected void callLocationAwareLogger(LocationAwareLogger lal, LogRecord record) {
20631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        int julLevelValue = record.getLevel().intValue();
20731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        int slf4jLevel;
20888c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu
20931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        if (julLevelValue <= TRACE_LEVEL_THRESHOLD) {
21031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            slf4jLevel = LocationAwareLogger.TRACE_INT;
21131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        } else if (julLevelValue <= DEBUG_LEVEL_THRESHOLD) {
21231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            slf4jLevel = LocationAwareLogger.DEBUG_INT;
21331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        } else if (julLevelValue <= INFO_LEVEL_THRESHOLD) {
21431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            slf4jLevel = LocationAwareLogger.INFO_INT;
21531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        } else if (julLevelValue <= WARN_LEVEL_THRESHOLD) {
21631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            slf4jLevel = LocationAwareLogger.WARN_INT;
21731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        } else {
21831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            slf4jLevel = LocationAwareLogger.ERROR_INT;
21931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        }
22031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        String i18nMessage = getMessageI18N(record);
22131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        lal.log(null, FQCN, slf4jLevel, i18nMessage, null, record.getThrown());
22288c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu    }
22388c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu
22431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    protected void callPlainSLF4JLogger(Logger slf4jLogger, LogRecord record) {
22531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        String i18nMessage = getMessageI18N(record);
22631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        int julLevelValue = record.getLevel().intValue();
22731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        if (julLevelValue <= TRACE_LEVEL_THRESHOLD) {
22831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            slf4jLogger.trace(i18nMessage, record.getThrown());
22931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        } else if (julLevelValue <= DEBUG_LEVEL_THRESHOLD) {
23031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            slf4jLogger.debug(i18nMessage, record.getThrown());
23131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        } else if (julLevelValue <= INFO_LEVEL_THRESHOLD) {
23231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            slf4jLogger.info(i18nMessage, record.getThrown());
23331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        } else if (julLevelValue <= WARN_LEVEL_THRESHOLD) {
23431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            slf4jLogger.warn(i18nMessage, record.getThrown());
23531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        } else {
23631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            slf4jLogger.error(i18nMessage, record.getThrown());
23731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        }
23888c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu    }
23988c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu
24031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    /**
24131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * Get the record's message, possibly via a resource bundle.
24231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     *
24331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * @param record
24431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * @return
24531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     */
24631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    private String getMessageI18N(LogRecord record) {
24731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        String message = record.getMessage();
24813f05d200a898247b2a8d00b0ee82461ade2004eCeki Gulcu
24931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        if (message == null) {
25031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            return null;
25131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        }
25288c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu
25331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        ResourceBundle bundle = record.getResourceBundle();
25431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        if (bundle != null) {
25531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            try {
25631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu                message = bundle.getString(message);
25731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            } catch (MissingResourceException e) {
25831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            }
25931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        }
26031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        Object[] params = record.getParameters();
26131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        // avoid formatting when there are no or 0 parameters. see also
26231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        // http://bugzilla.slf4j.org/show_bug.cgi?id=212
26331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        if (params != null && params.length > 0) {
26431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            message = MessageFormat.format(message, params);
26531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        }
26631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        return message;
26788c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu    }
26888c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu
26931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    /**
27031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * Publish a LogRecord.
27131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * <p/>
27231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * The logging request was made initially to a Logger object, which
27331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * initialized the LogRecord and forwarded it here.
27431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * <p/>
27531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * This handler ignores the Level attached to the LogRecord, as SLF4J cares
27631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * about discarding log statements.
27731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     *
27831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * @param record Description of the log event. A null record is silently ignored
27931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     *               and is not published.
28031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     */
28131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    public void publish(LogRecord record) {
28231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        // Silently ignore null records.
28331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        if (record == null) {
28431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            return;
28531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        }
28688c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu
28731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        Logger slf4jLogger = getSLF4JLogger(record);
28831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        String message = record.getMessage(); // can be null!
28931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        // this is a check to avoid calling the underlying logging system
29031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        // with a null message. While it is legitimate to invoke j.u.l. with
29131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        // a null message, other logging frameworks do not support this.
29231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        // see also http://bugzilla.slf4j.org/show_bug.cgi?id=108
29331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        if (message == null) {
29431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            message = "";
29531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        }
29631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        if (slf4jLogger instanceof LocationAwareLogger) {
29731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            callLocationAwareLogger((LocationAwareLogger) slf4jLogger, record);
29831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        } else {
29931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            callPlainSLF4JLogger(slf4jLogger, record);
30031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        }
30188c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu    }
30288c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu
30388c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu}
304