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; 018import java.util.function.Supplier; 019 020import ch.qos.logback.classic.pattern.*; 021import ch.qos.logback.classic.pattern.color.HighlightingCompositeConverter; 022import ch.qos.logback.classic.spi.ILoggingEvent; 023import ch.qos.logback.core.CoreConstants; 024import ch.qos.logback.core.pattern.DynamicConverter; 025import ch.qos.logback.core.pattern.PatternLayoutBase; 026import ch.qos.logback.core.pattern.color.*; 027import ch.qos.logback.core.pattern.parser.Parser; 028 029/** 030 * <p> 031 * A flexible layout configurable with pattern string. The main method in this class is 032 * to {@link #doLayout(ILoggingEvent)}. It returns the results as a 033 * {#link String}. The format and contents of the result depends on the <em>conversion 034 * pattern</em>. 035 * <p> 036 * For more information about this layout, please refer to the online manual at 037 * http://logback.qos.ch/manual/layouts.html#PatternLayout 038 * 039 */ 040 041public class PatternLayout extends PatternLayoutBase<ILoggingEvent> { 042 043 public static final Map<String, Supplier<DynamicConverter>> DEFAULT_CONVERTER_SUPPLIER_MAP = new HashMap<>(); 044 045 /** 046 * @deprecated replaced by {@link #DEFAULT_CONVERTER_SUPPLIER_MAP} 047 */ 048 @Deprecated 049 public static final Map<String, String> DEFAULT_CONVERTER_MAP = new HashMap<>(); 050 public static final Map<String, String> CONVERTER_CLASS_TO_KEY_MAP = new HashMap<String, String>(); 051 052 /** 053 * @deprecated replaced by {@link #DEFAULT_CONVERTER_MAP} in turn itself replaced by 054 * {@link #DEFAULT_CONVERTER_SUPPLIER_MAP} 055 */ 056 @Deprecated 057 public static final Map<String, String> defaultConverterMap = DEFAULT_CONVERTER_MAP; 058 059 public static final String HEADER_PREFIX = "#logback.classic pattern: "; 060 061 static { 062 DEFAULT_CONVERTER_SUPPLIER_MAP.putAll(Parser.DEFAULT_COMPOSITE_CONVERTER_MAP); 063 064 DEFAULT_CONVERTER_SUPPLIER_MAP.put("d", DateConverter::new); 065 DEFAULT_CONVERTER_SUPPLIER_MAP.put("date", DateConverter::new); 066 // used by PrefixComposite converter 067 CONVERTER_CLASS_TO_KEY_MAP.put(DateConverter.class.getName(), "date"); 068 069 DEFAULT_CONVERTER_SUPPLIER_MAP.put("ms", MicrosecondConverter::new); 070 DEFAULT_CONVERTER_SUPPLIER_MAP.put("micros", MicrosecondConverter::new); 071 CONVERTER_CLASS_TO_KEY_MAP.put(MicrosecondConverter.class.getName(), "micros"); 072 073 DEFAULT_CONVERTER_SUPPLIER_MAP.put("ep", EpochConverter::new); 074 DEFAULT_CONVERTER_SUPPLIER_MAP.put("epoch", EpochConverter::new); 075 CONVERTER_CLASS_TO_KEY_MAP.put(EpochConverter.class.getName(), "epoch"); 076 077 DEFAULT_CONVERTER_SUPPLIER_MAP.put("r", RelativeTimeConverter::new); 078 DEFAULT_CONVERTER_SUPPLIER_MAP.put("relative", RelativeTimeConverter::new); 079 CONVERTER_CLASS_TO_KEY_MAP.put(RelativeTimeConverter.class.getName(), "relative"); 080 081 DEFAULT_CONVERTER_SUPPLIER_MAP.put("level", LevelConverter::new); 082 DEFAULT_CONVERTER_SUPPLIER_MAP.put("le", LevelConverter::new); 083 DEFAULT_CONVERTER_SUPPLIER_MAP.put("p", LevelConverter::new); 084 CONVERTER_CLASS_TO_KEY_MAP.put(LevelConverter.class.getName(), "level"); 085 086 DEFAULT_CONVERTER_SUPPLIER_MAP.put("t", ThreadConverter::new); 087 DEFAULT_CONVERTER_SUPPLIER_MAP.put("thread", ThreadConverter::new); 088 CONVERTER_CLASS_TO_KEY_MAP.put(ThreadConverter.class.getName(), "thread"); 089 090 DEFAULT_CONVERTER_SUPPLIER_MAP.put("lo", LoggerConverter::new); 091 DEFAULT_CONVERTER_SUPPLIER_MAP.put("logger", LoggerConverter::new); 092 DEFAULT_CONVERTER_SUPPLIER_MAP.put("c", LoggerConverter::new); 093 CONVERTER_CLASS_TO_KEY_MAP.put(LoggerConverter.class.getName(), "logger"); 094 095 DEFAULT_CONVERTER_SUPPLIER_MAP.put("m", MessageConverter::new); 096 DEFAULT_CONVERTER_SUPPLIER_MAP.put("msg", MessageConverter::new); 097 DEFAULT_CONVERTER_SUPPLIER_MAP.put("message", MessageConverter::new); 098 CONVERTER_CLASS_TO_KEY_MAP.put(MessageConverter.class.getName(), "message"); 099 100 DEFAULT_CONVERTER_SUPPLIER_MAP.put("C", ClassOfCallerConverter::new); 101 DEFAULT_CONVERTER_SUPPLIER_MAP.put("class", ClassOfCallerConverter::new); 102 CONVERTER_CLASS_TO_KEY_MAP.put(ClassOfCallerConverter.class.getName(), "class"); 103 104 DEFAULT_CONVERTER_SUPPLIER_MAP.put("M", MethodOfCallerConverter::new); 105 DEFAULT_CONVERTER_SUPPLIER_MAP.put("method", MethodOfCallerConverter::new); 106 CONVERTER_CLASS_TO_KEY_MAP.put(MethodOfCallerConverter.class.getName(), "method"); 107 108 DEFAULT_CONVERTER_SUPPLIER_MAP.put("L", LineOfCallerConverter::new); 109 DEFAULT_CONVERTER_SUPPLIER_MAP.put("line", LineOfCallerConverter::new); 110 CONVERTER_CLASS_TO_KEY_MAP.put(LineOfCallerConverter.class.getName(), "line"); 111 112 DEFAULT_CONVERTER_SUPPLIER_MAP.put("F", FileOfCallerConverter::new); 113 DEFAULT_CONVERTER_SUPPLIER_MAP.put("file", FileOfCallerConverter::new); 114 CONVERTER_CLASS_TO_KEY_MAP.put(FileOfCallerConverter.class.getName(), "file"); 115 116 DEFAULT_CONVERTER_SUPPLIER_MAP.put("X", MDCConverter::new); 117 DEFAULT_CONVERTER_SUPPLIER_MAP.put("mdc", MDCConverter::new); 118 119 DEFAULT_CONVERTER_SUPPLIER_MAP.put("ex", ThrowableProxyConverter::new); 120 DEFAULT_CONVERTER_SUPPLIER_MAP.put("exception", ThrowableProxyConverter::new); 121 DEFAULT_CONVERTER_SUPPLIER_MAP.put("rEx", RootCauseFirstThrowableProxyConverter::new); 122 DEFAULT_CONVERTER_SUPPLIER_MAP.put("rootException", RootCauseFirstThrowableProxyConverter::new); 123 DEFAULT_CONVERTER_SUPPLIER_MAP.put("throwable", ThrowableProxyConverter::new); 124 125 DEFAULT_CONVERTER_SUPPLIER_MAP.put("xEx", ExtendedThrowableProxyConverter::new); 126 DEFAULT_CONVERTER_SUPPLIER_MAP.put("xException", ExtendedThrowableProxyConverter::new); 127 DEFAULT_CONVERTER_SUPPLIER_MAP.put("xThrowable", ExtendedThrowableProxyConverter::new); 128 129 DEFAULT_CONVERTER_SUPPLIER_MAP.put("nopex", NopThrowableInformationConverter::new); 130 DEFAULT_CONVERTER_SUPPLIER_MAP.put("nopexception", NopThrowableInformationConverter::new); 131 132 DEFAULT_CONVERTER_SUPPLIER_MAP.put("cn", ContextNameConverter::new); 133 DEFAULT_CONVERTER_SUPPLIER_MAP.put("contextName", ContextNameConverter::new); 134 CONVERTER_CLASS_TO_KEY_MAP.put(ContextNameConverter.class.getName(), "contextName"); 135 136 DEFAULT_CONVERTER_SUPPLIER_MAP.put("caller", CallerDataConverter::new); 137 CONVERTER_CLASS_TO_KEY_MAP.put(CallerDataConverter.class.getName(), "caller"); 138 139 DEFAULT_CONVERTER_SUPPLIER_MAP.put("marker", MarkerConverter::new); 140 CONVERTER_CLASS_TO_KEY_MAP.put(MarkerConverter.class.getName(), "marker"); 141 142 DEFAULT_CONVERTER_SUPPLIER_MAP.put("kvp", KeyValuePairConverter::new); 143 CONVERTER_CLASS_TO_KEY_MAP.put(KeyValuePairConverter.class.getName(), "kvp"); 144 145 DEFAULT_CONVERTER_SUPPLIER_MAP.put("maskedKvp", MaskedKeyValuePairConverter::new); 146 CONVERTER_CLASS_TO_KEY_MAP.put(MaskedKeyValuePairConverter.class.getName(), "maskedKvp"); 147 148 DEFAULT_CONVERTER_SUPPLIER_MAP.put("property", PropertyConverter::new); 149 150 DEFAULT_CONVERTER_SUPPLIER_MAP.put("n", LineSeparatorConverter::new); 151 152 DEFAULT_CONVERTER_SUPPLIER_MAP.put("black", BlackCompositeConverter::new); 153 DEFAULT_CONVERTER_SUPPLIER_MAP.put("red", RedCompositeConverter::new); 154 DEFAULT_CONVERTER_SUPPLIER_MAP.put("green", GreenCompositeConverter::new); 155 DEFAULT_CONVERTER_SUPPLIER_MAP.put("yellow", YellowCompositeConverter::new); 156 DEFAULT_CONVERTER_SUPPLIER_MAP.put("blue", BlueCompositeConverter::new); 157 DEFAULT_CONVERTER_SUPPLIER_MAP.put("magenta", MagentaCompositeConverter::new); 158 DEFAULT_CONVERTER_SUPPLIER_MAP.put("cyan", CyanCompositeConverter::new); 159 DEFAULT_CONVERTER_SUPPLIER_MAP.put("white", WhiteCompositeConverter::new); 160 DEFAULT_CONVERTER_SUPPLIER_MAP.put("gray", GrayCompositeConverter::new); 161 DEFAULT_CONVERTER_SUPPLIER_MAP.put("boldRed", BoldRedCompositeConverter::new); 162 DEFAULT_CONVERTER_SUPPLIER_MAP.put("boldGreen", BoldGreenCompositeConverter::new); 163 DEFAULT_CONVERTER_SUPPLIER_MAP.put("boldYellow", BoldYellowCompositeConverter::new); 164 DEFAULT_CONVERTER_SUPPLIER_MAP.put("boldBlue", BoldBlueCompositeConverter::new); 165 DEFAULT_CONVERTER_SUPPLIER_MAP.put("boldMagenta", BoldMagentaCompositeConverter::new); 166 DEFAULT_CONVERTER_SUPPLIER_MAP.put("boldCyan", BoldCyanCompositeConverter::new); 167 DEFAULT_CONVERTER_SUPPLIER_MAP.put("boldWhite", BoldWhiteCompositeConverter::new); 168 DEFAULT_CONVERTER_SUPPLIER_MAP.put("highlight", HighlightingCompositeConverter::new); 169 170 DEFAULT_CONVERTER_SUPPLIER_MAP.put("lsn", LocalSequenceNumberConverter::new); 171 CONVERTER_CLASS_TO_KEY_MAP.put(LocalSequenceNumberConverter.class.getName(), "lsn"); 172 173 DEFAULT_CONVERTER_SUPPLIER_MAP.put("sn", SequenceNumberConverter::new); 174 DEFAULT_CONVERTER_SUPPLIER_MAP.put("sequenceNumber", SequenceNumberConverter::new); 175 CONVERTER_CLASS_TO_KEY_MAP.put(SequenceNumberConverter.class.getName(), "sequenceNumber"); 176 177 DEFAULT_CONVERTER_SUPPLIER_MAP.put("prefix", PrefixCompositeConverter::new); 178 179 } 180 181 public PatternLayout() { 182 this.postCompileProcessor = new EnsureExceptionHandling(); 183 } 184 185 public Map<String, Supplier<DynamicConverter>> getDefaultConverterSupplierMap() { 186 return DEFAULT_CONVERTER_SUPPLIER_MAP; 187 } 188 189 /** 190 * <p>BEWARE: The map of type String,String for mapping conversion words is deprecated. 191 * Use {@link #getDefaultConverterSupplierMap()} instead.</p> 192 * 193 * <p>Existing code such as getDefaultMap().put("k", X.class.getName()) should be replaced by 194 * getDefaultConverterSupplierMap().put("k", X::new) </p> 195 * 196 * <p>Note that values in the map will still be taken into account and processed correctly.</p> 197 * 198 * @return a map of keys and class names 199 */ 200 @Deprecated 201 public Map<String, String> getDefaultConverterMap() { 202 return DEFAULT_CONVERTER_MAP; 203 } 204 205 public String doLayout(ILoggingEvent event) { 206 if (!isStarted()) { 207 return CoreConstants.EMPTY_STRING; 208 } 209 return writeLoopOnConverters(event); 210 } 211 212 @Override 213 protected String getPresentationHeaderPrefix() { 214 return HEADER_PREFIX; 215 } 216}