001/**
002 * Logback: the reliable, generic, fast and flexible logging framework.
003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
004 *
005 * This program and the accompanying materials are dual-licensed under
006 * either the terms of the Eclipse Public License v1.0 as published by
007 * the Eclipse Foundation
008 *
009 *   or (per the licensee's choosing)
010 *
011 * under the terms of the GNU Lesser General Public License version 2.1
012 * as published by the Free Software Foundation.
013 */
014package ch.qos.logback.classic;
015
016import java.util.HashMap;
017import java.util.Map;
018
019import ch.qos.logback.classic.pattern.*;
020import ch.qos.logback.classic.pattern.color.HighlightingCompositeConverter;
021import ch.qos.logback.classic.spi.ILoggingEvent;
022import ch.qos.logback.core.CoreConstants;
023import ch.qos.logback.core.pattern.PatternLayoutBase;
024import ch.qos.logback.core.pattern.color.*;
025import ch.qos.logback.core.pattern.parser.Parser;
026
027/**
028 * <p>
029 * A flexible layout configurable with pattern string. The goal of this class is
030 * to {@link #format format} a {@link ILoggingEvent} and return the results in a
031 * {#link String}. The format of the result depends on the <em>conversion
032 * pattern</em>.
033 * <p>
034 * For more information about this layout, please refer to the online manual at
035 * http://logback.qos.ch/manual/layouts.html#PatternLayout
036 * 
037 */
038
039public class PatternLayout extends PatternLayoutBase<ILoggingEvent> {
040
041    public static final Map<String, String> DEFAULT_CONVERTER_MAP = new HashMap<String, String>();
042    public static final Map<String, String> CONVERTER_CLASS_TO_KEY_MAP = new HashMap<String, String>();
043
044    /**
045     * @deprecated replaced by DEFAULT_CONVERTER_MAP
046     */
047    public static final Map<String, String> defaultConverterMap = DEFAULT_CONVERTER_MAP;
048
049    public static final String HEADER_PREFIX = "#logback.classic pattern: ";
050
051    static {
052        DEFAULT_CONVERTER_MAP.putAll(Parser.DEFAULT_COMPOSITE_CONVERTER_MAP);
053
054        DEFAULT_CONVERTER_MAP.put("d", DateConverter.class.getName());
055        DEFAULT_CONVERTER_MAP.put("date", DateConverter.class.getName());
056        // used by PrefixComposite converter
057        CONVERTER_CLASS_TO_KEY_MAP.put(DateConverter.class.getName(), "date");
058
059        DEFAULT_CONVERTER_MAP.put("ms", MicrosecondConverter.class.getName());
060        DEFAULT_CONVERTER_MAP.put("micros", MicrosecondConverter.class.getName());
061        CONVERTER_CLASS_TO_KEY_MAP.put(MicrosecondConverter.class.getName(), "micros");
062
063        DEFAULT_CONVERTER_MAP.put("r", RelativeTimeConverter.class.getName());
064        DEFAULT_CONVERTER_MAP.put("relative", RelativeTimeConverter.class.getName());
065        CONVERTER_CLASS_TO_KEY_MAP.put(RelativeTimeConverter.class.getName(), "relative");
066
067        DEFAULT_CONVERTER_MAP.put("level", LevelConverter.class.getName());
068        DEFAULT_CONVERTER_MAP.put("le", LevelConverter.class.getName());
069        DEFAULT_CONVERTER_MAP.put("p", LevelConverter.class.getName());
070        CONVERTER_CLASS_TO_KEY_MAP.put(LevelConverter.class.getName(), "level");
071
072        DEFAULT_CONVERTER_MAP.put("t", ThreadConverter.class.getName());
073        DEFAULT_CONVERTER_MAP.put("thread", ThreadConverter.class.getName());
074        CONVERTER_CLASS_TO_KEY_MAP.put(ThreadConverter.class.getName(), "thread");
075
076        DEFAULT_CONVERTER_MAP.put("lo", LoggerConverter.class.getName());
077        DEFAULT_CONVERTER_MAP.put("logger", LoggerConverter.class.getName());
078        DEFAULT_CONVERTER_MAP.put("c", LoggerConverter.class.getName());
079        CONVERTER_CLASS_TO_KEY_MAP.put(LoggerConverter.class.getName(), "logger");
080
081        DEFAULT_CONVERTER_MAP.put("m", MessageConverter.class.getName());
082        DEFAULT_CONVERTER_MAP.put("msg", MessageConverter.class.getName());
083        DEFAULT_CONVERTER_MAP.put("message", MessageConverter.class.getName());
084        CONVERTER_CLASS_TO_KEY_MAP.put(MessageConverter.class.getName(), "message");
085
086        DEFAULT_CONVERTER_MAP.put("C", ClassOfCallerConverter.class.getName());
087        DEFAULT_CONVERTER_MAP.put("class", ClassOfCallerConverter.class.getName());
088        CONVERTER_CLASS_TO_KEY_MAP.put(ClassOfCallerConverter.class.getName(), "class");
089
090        DEFAULT_CONVERTER_MAP.put("M", MethodOfCallerConverter.class.getName());
091        DEFAULT_CONVERTER_MAP.put("method", MethodOfCallerConverter.class.getName());
092        CONVERTER_CLASS_TO_KEY_MAP.put(MethodOfCallerConverter.class.getName(), "method");
093
094        DEFAULT_CONVERTER_MAP.put("L", LineOfCallerConverter.class.getName());
095        DEFAULT_CONVERTER_MAP.put("line", LineOfCallerConverter.class.getName());
096        CONVERTER_CLASS_TO_KEY_MAP.put(LineOfCallerConverter.class.getName(), "line");
097
098        DEFAULT_CONVERTER_MAP.put("F", FileOfCallerConverter.class.getName());
099        DEFAULT_CONVERTER_MAP.put("file", FileOfCallerConverter.class.getName());
100        CONVERTER_CLASS_TO_KEY_MAP.put(FileOfCallerConverter.class.getName(), "file");
101
102        DEFAULT_CONVERTER_MAP.put("X", MDCConverter.class.getName());
103        DEFAULT_CONVERTER_MAP.put("mdc", MDCConverter.class.getName());
104
105        DEFAULT_CONVERTER_MAP.put("ex", ThrowableProxyConverter.class.getName());
106        DEFAULT_CONVERTER_MAP.put("exception", ThrowableProxyConverter.class.getName());
107        DEFAULT_CONVERTER_MAP.put("rEx", RootCauseFirstThrowableProxyConverter.class.getName());
108        DEFAULT_CONVERTER_MAP.put("rootException", RootCauseFirstThrowableProxyConverter.class.getName());
109        DEFAULT_CONVERTER_MAP.put("throwable", ThrowableProxyConverter.class.getName());
110
111        DEFAULT_CONVERTER_MAP.put("xEx", ExtendedThrowableProxyConverter.class.getName());
112        DEFAULT_CONVERTER_MAP.put("xException", ExtendedThrowableProxyConverter.class.getName());
113        DEFAULT_CONVERTER_MAP.put("xThrowable", ExtendedThrowableProxyConverter.class.getName());
114
115        DEFAULT_CONVERTER_MAP.put("nopex", NopThrowableInformationConverter.class.getName());
116        DEFAULT_CONVERTER_MAP.put("nopexception", NopThrowableInformationConverter.class.getName());
117
118        DEFAULT_CONVERTER_MAP.put("cn", ContextNameConverter.class.getName());
119        DEFAULT_CONVERTER_MAP.put("contextName", ContextNameConverter.class.getName());
120        CONVERTER_CLASS_TO_KEY_MAP.put(ContextNameConverter.class.getName(), "contextName");
121
122        DEFAULT_CONVERTER_MAP.put("caller", CallerDataConverter.class.getName());
123        CONVERTER_CLASS_TO_KEY_MAP.put(CallerDataConverter.class.getName(), "caller");
124
125        DEFAULT_CONVERTER_MAP.put("marker", MarkerConverter.class.getName());
126        CONVERTER_CLASS_TO_KEY_MAP.put(MarkerConverter.class.getName(), "marker");
127
128        DEFAULT_CONVERTER_MAP.put("kvp", KeyValuePairConverter.class.getName());
129        CONVERTER_CLASS_TO_KEY_MAP.put(KeyValuePairConverter.class.getName(), "kvp");
130
131        DEFAULT_CONVERTER_MAP.put("property", PropertyConverter.class.getName());
132
133        DEFAULT_CONVERTER_MAP.put("n", LineSeparatorConverter.class.getName());
134
135        DEFAULT_CONVERTER_MAP.put("black", BlackCompositeConverter.class.getName());
136        DEFAULT_CONVERTER_MAP.put("red", RedCompositeConverter.class.getName());
137        DEFAULT_CONVERTER_MAP.put("green", GreenCompositeConverter.class.getName());
138        DEFAULT_CONVERTER_MAP.put("yellow", YellowCompositeConverter.class.getName());
139        DEFAULT_CONVERTER_MAP.put("blue", BlueCompositeConverter.class.getName());
140        DEFAULT_CONVERTER_MAP.put("magenta", MagentaCompositeConverter.class.getName());
141        DEFAULT_CONVERTER_MAP.put("cyan", CyanCompositeConverter.class.getName());
142        DEFAULT_CONVERTER_MAP.put("white", WhiteCompositeConverter.class.getName());
143        DEFAULT_CONVERTER_MAP.put("gray", GrayCompositeConverter.class.getName());
144        DEFAULT_CONVERTER_MAP.put("boldRed", BoldRedCompositeConverter.class.getName());
145        DEFAULT_CONVERTER_MAP.put("boldGreen", BoldGreenCompositeConverter.class.getName());
146        DEFAULT_CONVERTER_MAP.put("boldYellow", BoldYellowCompositeConverter.class.getName());
147        DEFAULT_CONVERTER_MAP.put("boldBlue", BoldBlueCompositeConverter.class.getName());
148        DEFAULT_CONVERTER_MAP.put("boldMagenta", BoldMagentaCompositeConverter.class.getName());
149        DEFAULT_CONVERTER_MAP.put("boldCyan", BoldCyanCompositeConverter.class.getName());
150        DEFAULT_CONVERTER_MAP.put("boldWhite", BoldWhiteCompositeConverter.class.getName());
151        DEFAULT_CONVERTER_MAP.put("highlight", HighlightingCompositeConverter.class.getName());
152
153        DEFAULT_CONVERTER_MAP.put("lsn", LocalSequenceNumberConverter.class.getName());
154        CONVERTER_CLASS_TO_KEY_MAP.put(LocalSequenceNumberConverter.class.getName(), "lsn");
155
156        DEFAULT_CONVERTER_MAP.put("sn", SequenceNumberConverter.class.getName());
157        DEFAULT_CONVERTER_MAP.put("sequenceNumber", SequenceNumberConverter.class.getName());
158        CONVERTER_CLASS_TO_KEY_MAP.put(SequenceNumberConverter.class.getName(), "sequenceNumber");
159
160        DEFAULT_CONVERTER_MAP.put("prefix", PrefixCompositeConverter.class.getName());
161
162    }
163
164    public PatternLayout() {
165        this.postCompileProcessor = new EnsureExceptionHandling();
166    }
167
168    public Map<String, String> getDefaultConverterMap() {
169        return DEFAULT_CONVERTER_MAP;
170    }
171
172    public String doLayout(ILoggingEvent event) {
173        if (!isStarted()) {
174            return CoreConstants.EMPTY_STRING;
175        }
176        return writeLoopOnConverters(event);
177    }
178
179    @Override
180    protected String getPresentationHeaderPrefix() {
181        return HEADER_PREFIX;
182    }
183}