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("r", RelativeTimeConverter::new); 074 DEFAULT_CONVERTER_SUPPLIER_MAP.put("relative", RelativeTimeConverter::new); 075 CONVERTER_CLASS_TO_KEY_MAP.put(RelativeTimeConverter.class.getName(), "relative"); 076 077 DEFAULT_CONVERTER_SUPPLIER_MAP.put("level", LevelConverter::new); 078 DEFAULT_CONVERTER_SUPPLIER_MAP.put("le", LevelConverter::new); 079 DEFAULT_CONVERTER_SUPPLIER_MAP.put("p", LevelConverter::new); 080 CONVERTER_CLASS_TO_KEY_MAP.put(LevelConverter.class.getName(), "level"); 081 082 DEFAULT_CONVERTER_SUPPLIER_MAP.put("t", ThreadConverter::new); 083 DEFAULT_CONVERTER_SUPPLIER_MAP.put("thread", ThreadConverter::new); 084 CONVERTER_CLASS_TO_KEY_MAP.put(ThreadConverter.class.getName(), "thread"); 085 086 DEFAULT_CONVERTER_SUPPLIER_MAP.put("lo", LoggerConverter::new); 087 DEFAULT_CONVERTER_SUPPLIER_MAP.put("logger", LoggerConverter::new); 088 DEFAULT_CONVERTER_SUPPLIER_MAP.put("c", LoggerConverter::new); 089 CONVERTER_CLASS_TO_KEY_MAP.put(LoggerConverter.class.getName(), "logger"); 090 091 DEFAULT_CONVERTER_SUPPLIER_MAP.put("m", MessageConverter::new); 092 DEFAULT_CONVERTER_SUPPLIER_MAP.put("msg", MessageConverter::new); 093 DEFAULT_CONVERTER_SUPPLIER_MAP.put("message", MessageConverter::new); 094 CONVERTER_CLASS_TO_KEY_MAP.put(MessageConverter.class.getName(), "message"); 095 096 DEFAULT_CONVERTER_SUPPLIER_MAP.put("C", ClassOfCallerConverter::new); 097 DEFAULT_CONVERTER_SUPPLIER_MAP.put("class", ClassOfCallerConverter::new); 098 CONVERTER_CLASS_TO_KEY_MAP.put(ClassOfCallerConverter.class.getName(), "class"); 099 100 DEFAULT_CONVERTER_SUPPLIER_MAP.put("M", MethodOfCallerConverter::new); 101 DEFAULT_CONVERTER_SUPPLIER_MAP.put("method", MethodOfCallerConverter::new); 102 CONVERTER_CLASS_TO_KEY_MAP.put(MethodOfCallerConverter.class.getName(), "method"); 103 104 DEFAULT_CONVERTER_SUPPLIER_MAP.put("L", LineOfCallerConverter::new); 105 DEFAULT_CONVERTER_SUPPLIER_MAP.put("line", LineOfCallerConverter::new); 106 CONVERTER_CLASS_TO_KEY_MAP.put(LineOfCallerConverter.class.getName(), "line"); 107 108 DEFAULT_CONVERTER_SUPPLIER_MAP.put("F", FileOfCallerConverter::new); 109 DEFAULT_CONVERTER_SUPPLIER_MAP.put("file", FileOfCallerConverter::new); 110 CONVERTER_CLASS_TO_KEY_MAP.put(FileOfCallerConverter.class.getName(), "file"); 111 112 DEFAULT_CONVERTER_SUPPLIER_MAP.put("X", MDCConverter::new); 113 DEFAULT_CONVERTER_SUPPLIER_MAP.put("mdc", MDCConverter::new); 114 115 DEFAULT_CONVERTER_SUPPLIER_MAP.put("ex", ThrowableProxyConverter::new); 116 DEFAULT_CONVERTER_SUPPLIER_MAP.put("exception", ThrowableProxyConverter::new); 117 DEFAULT_CONVERTER_SUPPLIER_MAP.put("rEx", RootCauseFirstThrowableProxyConverter::new); 118 DEFAULT_CONVERTER_SUPPLIER_MAP.put("rootException", RootCauseFirstThrowableProxyConverter::new); 119 DEFAULT_CONVERTER_SUPPLIER_MAP.put("throwable", ThrowableProxyConverter::new); 120 121 DEFAULT_CONVERTER_SUPPLIER_MAP.put("xEx", ExtendedThrowableProxyConverter::new); 122 DEFAULT_CONVERTER_SUPPLIER_MAP.put("xException", ExtendedThrowableProxyConverter::new); 123 DEFAULT_CONVERTER_SUPPLIER_MAP.put("xThrowable", ExtendedThrowableProxyConverter::new); 124 125 DEFAULT_CONVERTER_SUPPLIER_MAP.put("nopex", NopThrowableInformationConverter::new); 126 DEFAULT_CONVERTER_SUPPLIER_MAP.put("nopexception", NopThrowableInformationConverter::new); 127 128 DEFAULT_CONVERTER_SUPPLIER_MAP.put("cn", ContextNameConverter::new); 129 DEFAULT_CONVERTER_SUPPLIER_MAP.put("contextName", ContextNameConverter::new); 130 CONVERTER_CLASS_TO_KEY_MAP.put(ContextNameConverter.class.getName(), "contextName"); 131 132 DEFAULT_CONVERTER_SUPPLIER_MAP.put("caller", CallerDataConverter::new); 133 CONVERTER_CLASS_TO_KEY_MAP.put(CallerDataConverter.class.getName(), "caller"); 134 135 DEFAULT_CONVERTER_SUPPLIER_MAP.put("marker", MarkerConverter::new); 136 CONVERTER_CLASS_TO_KEY_MAP.put(MarkerConverter.class.getName(), "marker"); 137 138 DEFAULT_CONVERTER_SUPPLIER_MAP.put("kvp", KeyValuePairConverter::new); 139 CONVERTER_CLASS_TO_KEY_MAP.put(KeyValuePairConverter.class.getName(), "kvp"); 140 141 DEFAULT_CONVERTER_SUPPLIER_MAP.put("maskedKvp", MaskedKeyValuePairConverter::new); 142 CONVERTER_CLASS_TO_KEY_MAP.put(MaskedKeyValuePairConverter.class.getName(), "maskedKvp"); 143 144 DEFAULT_CONVERTER_SUPPLIER_MAP.put("property", PropertyConverter::new); 145 146 DEFAULT_CONVERTER_SUPPLIER_MAP.put("n", LineSeparatorConverter::new); 147 148 DEFAULT_CONVERTER_SUPPLIER_MAP.put("black", BlackCompositeConverter::new); 149 DEFAULT_CONVERTER_SUPPLIER_MAP.put("red", RedCompositeConverter::new); 150 DEFAULT_CONVERTER_SUPPLIER_MAP.put("green", GreenCompositeConverter::new); 151 DEFAULT_CONVERTER_SUPPLIER_MAP.put("yellow", YellowCompositeConverter::new); 152 DEFAULT_CONVERTER_SUPPLIER_MAP.put("blue", BlueCompositeConverter::new); 153 DEFAULT_CONVERTER_SUPPLIER_MAP.put("magenta", MagentaCompositeConverter::new); 154 DEFAULT_CONVERTER_SUPPLIER_MAP.put("cyan", CyanCompositeConverter::new); 155 DEFAULT_CONVERTER_SUPPLIER_MAP.put("white", WhiteCompositeConverter::new); 156 DEFAULT_CONVERTER_SUPPLIER_MAP.put("gray", GrayCompositeConverter::new); 157 DEFAULT_CONVERTER_SUPPLIER_MAP.put("boldRed", BoldRedCompositeConverter::new); 158 DEFAULT_CONVERTER_SUPPLIER_MAP.put("boldGreen", BoldGreenCompositeConverter::new); 159 DEFAULT_CONVERTER_SUPPLIER_MAP.put("boldYellow", BoldYellowCompositeConverter::new); 160 DEFAULT_CONVERTER_SUPPLIER_MAP.put("boldBlue", BoldBlueCompositeConverter::new); 161 DEFAULT_CONVERTER_SUPPLIER_MAP.put("boldMagenta", BoldMagentaCompositeConverter::new); 162 DEFAULT_CONVERTER_SUPPLIER_MAP.put("boldCyan", BoldCyanCompositeConverter::new); 163 DEFAULT_CONVERTER_SUPPLIER_MAP.put("boldWhite", BoldWhiteCompositeConverter::new); 164 DEFAULT_CONVERTER_SUPPLIER_MAP.put("highlight", HighlightingCompositeConverter::new); 165 166 DEFAULT_CONVERTER_SUPPLIER_MAP.put("lsn", LocalSequenceNumberConverter::new); 167 CONVERTER_CLASS_TO_KEY_MAP.put(LocalSequenceNumberConverter.class.getName(), "lsn"); 168 169 DEFAULT_CONVERTER_SUPPLIER_MAP.put("sn", SequenceNumberConverter::new); 170 DEFAULT_CONVERTER_SUPPLIER_MAP.put("sequenceNumber", SequenceNumberConverter::new); 171 CONVERTER_CLASS_TO_KEY_MAP.put(SequenceNumberConverter.class.getName(), "sequenceNumber"); 172 173 DEFAULT_CONVERTER_SUPPLIER_MAP.put("prefix", PrefixCompositeConverter::new); 174 175 } 176 177 public PatternLayout() { 178 this.postCompileProcessor = new EnsureExceptionHandling(); 179 } 180 181 public Map<String, Supplier<DynamicConverter>> getDefaultConverterSupplierMap() { 182 return DEFAULT_CONVERTER_SUPPLIER_MAP; 183 } 184 185 /** 186 * <p>BEWARE: The map of type String,String for mapping conversion words is deprecated. 187 * Use {@link #getDefaultConverterSupplierMap()} instead.</p> 188 * 189 * <p>Existing code such as getDefaultMap().put("k", X.class.getName()) should be replaced by 190 * getDefaultConverterSupplierMap().put("k", X::new) </p> 191 * 192 * <p>Note that values in the map will still be taken into account and processed correctly.</p> 193 * 194 * @return a map of keys and class names 195 */ 196 @Deprecated 197 public Map<String, String> getDefaultConverterMap() { 198 return DEFAULT_CONVERTER_MAP; 199 } 200 201 public String doLayout(ILoggingEvent event) { 202 if (!isStarted()) { 203 return CoreConstants.EMPTY_STRING; 204 } 205 return writeLoopOnConverters(event); 206 } 207 208 @Override 209 protected String getPresentationHeaderPrefix() { 210 return HEADER_PREFIX; 211 } 212}