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