17ba0605dc97fb81bde8311510d27b3ccba170008Ceki Gulcu/**
27ba0605dc97fb81bde8311510d27b3ccba170008Ceki Gulcu * Copyright (c) 2004-2011 QOS.ch
37ba0605dc97fb81bde8311510d27b3ccba170008Ceki Gulcu * All rights reserved.
47ba0605dc97fb81bde8311510d27b3ccba170008Ceki 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
77ba0605dc97fb81bde8311510d27b3ccba170008Ceki Gulcu * "Software"), to  deal in  the Software without  restriction, including
87ba0605dc97fb81bde8311510d27b3ccba170008Ceki 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.
157ba0605dc97fb81bde8311510d27b3ccba170008Ceki Gulcu *
167ba0605dc97fb81bde8311510d27b3ccba170008Ceki Gulcu * THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
177ba0605dc97fb81bde8311510d27b3ccba170008Ceki 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.
237ba0605dc97fb81bde8311510d27b3ccba170008Ceki Gulcu *
247ba0605dc97fb81bde8311510d27b3ccba170008Ceki Gulcu */
2588c4c456766193e012eb890e2208473d99b91f83Ceki Gulcupackage org.slf4j.ext;
2688c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu
2788c4c456766193e012eb890e2208473d99b91f83Ceki Gulcuimport org.slf4j.Logger;
2888c4c456766193e012eb890e2208473d99b91f83Ceki Gulcuimport org.slf4j.Marker;
2988c4c456766193e012eb890e2208473d99b91f83Ceki Gulcuimport org.slf4j.MarkerFactory;
303c0ab3466b6fa6e915974c72558d64c570734700Ceki Gulcuimport org.slf4j.helpers.FormattingTuple;
3188c4c456766193e012eb890e2208473d99b91f83Ceki Gulcuimport org.slf4j.helpers.MessageFormatter;
3288c4c456766193e012eb890e2208473d99b91f83Ceki Gulcuimport org.slf4j.spi.LocationAwareLogger;
3388c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu
3488c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu/**
359f10490a05f7344f4b3ef657e8991f5d51934e2fCeki Gulcu * A utility that provides standard mechanisms for logging certain kinds of
3688c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu * activities.
3788c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu *
3888c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu * @author Ralph Goers
3988c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu * @author Ceki Gülcü
4088c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu */
4188c4c456766193e012eb890e2208473d99b91f83Ceki Gulcupublic class XLogger extends LoggerWrapper implements Logger {
4288c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu
4331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    private static final String FQCN = XLogger.class.getName();
4431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    static Marker FLOW_MARKER = MarkerFactory.getMarker("FLOW");
4531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    static Marker ENTRY_MARKER = MarkerFactory.getMarker("ENTRY");
4631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    static Marker EXIT_MARKER = MarkerFactory.getMarker("EXIT");
4731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu
4831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    static Marker EXCEPTION_MARKER = MarkerFactory.getMarker("EXCEPTION");
4931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    static Marker THROWING_MARKER = MarkerFactory.getMarker("THROWING");
5031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    static Marker CATCHING_MARKER = MarkerFactory.getMarker("CATCHING");
5131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu
5231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    static String EXIT_MESSAGE_0 = "exit";
5331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    static String EXIT_MESSAGE_1 = "exit with ({})";
5431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu
5531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    static String ENTRY_MESSAGE_0 = "entry";
5631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    static String ENTRY_MESSAGE_1 = "entry with ({})";
5731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    static String ENTRY_MESSAGE_2 = "entry with ({}, {})";
5831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    static String ENTRY_MESSAGE_3 = "entry with ({}, {}, {})";
5931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    static String ENTRY_MESSAGE_4 = "entry with ({}, {}, {}, {})";
6031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    static int ENTRY_MESSAGE_ARRAY_LEN = 5;
6131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    static String[] ENTRY_MESSAGE_ARRAY = new String[ENTRY_MESSAGE_ARRAY_LEN];
6231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    static {
6331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        ENTRY_MARKER.add(FLOW_MARKER);
6431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        EXIT_MARKER.add(FLOW_MARKER);
6531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        THROWING_MARKER.add(EXCEPTION_MARKER);
6631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        CATCHING_MARKER.add(EXCEPTION_MARKER);
6731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu
6831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        ENTRY_MESSAGE_ARRAY[0] = ENTRY_MESSAGE_0;
6931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        ENTRY_MESSAGE_ARRAY[1] = ENTRY_MESSAGE_1;
7031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        ENTRY_MESSAGE_ARRAY[2] = ENTRY_MESSAGE_2;
7131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        ENTRY_MESSAGE_ARRAY[3] = ENTRY_MESSAGE_3;
7231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        ENTRY_MESSAGE_ARRAY[4] = ENTRY_MESSAGE_4;
7388c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu    }
7488c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu
7531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    public enum Level {
7631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        TRACE("TRACE", LocationAwareLogger.TRACE_INT), DEBUG("DEBUG", LocationAwareLogger.DEBUG_INT), INFO("INFO", LocationAwareLogger.INFO_INT), WARN("WARN",
7731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu                        LocationAwareLogger.WARN_INT), ERROR("ERROR", LocationAwareLogger.ERROR_INT);
7831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu
7931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        private final String name;
8031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        private final int level;
8131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu
8231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        public String toString() {
8331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            return this.name;
8431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        }
8531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu
8631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        public int intValue() {
8731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            return this.level;
8831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        }
8931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu
9031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        private Level(String name, int level) {
9131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            this.name = name;
9231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            this.level = level;
9331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        }
9488c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu    }
9588c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu
9631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    /**
9731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * Given an underlying logger, construct an XLogger
9831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     *
9931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * @param logger
10031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     *          underlying logger
10131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     */
10231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    public XLogger(Logger logger) {
10331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        // If class B extends A, assuming B does not override method x(), the caller
10431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        // of new B().x() is A and not B, see also
10531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        // http://bugzilla.slf4j.org/show_bug.cgi?id=114
10631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        super(logger, LoggerWrapper.class.getName());
10788c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu    }
10831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu
10931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    /**
11031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * Log method entry.
11131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     *
11231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * @param argArray
11331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     *          supplied parameters
11431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     */
11531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    public void entry(Object... argArray) {
11631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        if (instanceofLAL && logger.isTraceEnabled(ENTRY_MARKER)) {
11731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            String messagePattern = null;
11831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            if (argArray.length < ENTRY_MESSAGE_ARRAY_LEN) {
11931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu                messagePattern = ENTRY_MESSAGE_ARRAY[argArray.length];
12031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            } else {
12131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu                messagePattern = buildMessagePattern(argArray.length);
12231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            }
12331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            FormattingTuple tp = MessageFormatter.arrayFormat(messagePattern, argArray);
12431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            ((LocationAwareLogger) logger).log(ENTRY_MARKER, FQCN, LocationAwareLogger.TRACE_INT, tp.getMessage(), argArray, tp.getThrowable());
12531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        }
12688c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu    }
12731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu
12831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    /**
12931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * Log method exit
13031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     */
13131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    public void exit() {
13231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        if (instanceofLAL && logger.isTraceEnabled(ENTRY_MARKER)) {
13331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            ((LocationAwareLogger) logger).log(EXIT_MARKER, FQCN, LocationAwareLogger.TRACE_INT, EXIT_MESSAGE_0, null, null);
13431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        }
13588c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu    }
13631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu
13731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    /**
13831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * Log method exit
13931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     *
14031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * @param result
14131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     *          The result of the method being exited
14231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     */
14331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    public <T> T exit(T result) {
14431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        if (instanceofLAL && logger.isTraceEnabled(ENTRY_MARKER)) {
14531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            FormattingTuple tp = MessageFormatter.format(EXIT_MESSAGE_1, result);
14631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            ((LocationAwareLogger) logger).log(EXIT_MARKER, FQCN, LocationAwareLogger.TRACE_INT, tp.getMessage(), new Object[] { result }, tp.getThrowable());
14731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        }
14831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        return result;
14988c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu    }
15031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu
15131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    /**
15231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * Log an exception being thrown. The generated log event uses Level ERROR.
15331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     *
15431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * @param throwable
15531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     *          the exception being caught.
15631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     */
15731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    public <T extends Throwable> T throwing(T throwable) {
15831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        if (instanceofLAL) {
15931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            ((LocationAwareLogger) logger).log(THROWING_MARKER, FQCN, LocationAwareLogger.ERROR_INT, "throwing", null, throwable);
16031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        }
16131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        return throwable;
16288c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu    }
16331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu
16431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    /**
16531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * Log an exception being thrown allowing the log level to be specified.
16631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     *
16731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * @param level
16831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     *          the logging level to use.
16931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * @param throwable
17031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     *          the exception being caught.
17131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     */
17231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    public <T extends Throwable> T throwing(Level level, T throwable) {
17331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        if (instanceofLAL) {
17431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            ((LocationAwareLogger) logger).log(THROWING_MARKER, FQCN, level.level, "throwing", null, throwable);
17531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        }
17631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        return throwable;
17788c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu    }
17831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu
17931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    /**
18031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * Log an exception being caught. The generated log event uses Level ERROR.
18131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     *
18231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * @param throwable
18331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     *          the exception being caught.
18431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     */
18531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    public void catching(Throwable throwable) {
18631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        if (instanceofLAL) {
18731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            ((LocationAwareLogger) logger).log(CATCHING_MARKER, FQCN, LocationAwareLogger.ERROR_INT, "catching", null, throwable);
18831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        }
18988c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu    }
19031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu
19131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    /**
19231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * Log an exception being caught allowing the log level to be specified.
19331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     *
19431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * @param level
19531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     *          the logging level to use.
19631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     * @param throwable
19731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     *          the exception being caught.
19831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu     */
19931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    public void catching(Level level, Throwable throwable) {
20031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        if (instanceofLAL) {
20131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            ((LocationAwareLogger) logger).log(CATCHING_MARKER, FQCN, level.level, "catching", null, throwable);
20231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        }
20388c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu    }
20431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu
20531212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu    private static String buildMessagePattern(int len) {
20631212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        StringBuilder sb = new StringBuilder();
20731212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        sb.append(" entry with (");
20831212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        for (int i = 0; i < len; i++) {
20931212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            sb.append("{}");
21031212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu            if (i != len - 1)
21131212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu                sb.append(", ");
21231212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        }
21331212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        sb.append(')');
21431212435723e2dfd5d6716d1f6a7b0e66a1e6b38Ceki Gulcu        return sb.toString();
21588c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu    }
21688c4c456766193e012eb890e2208473d99b91f83Ceki Gulcu}
217