001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache license, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the license for the specific language governing permissions and 015 * limitations under the license. 016 */ 017 package org.apache.logging.log4j.core.layout; 018 019 import org.apache.logging.log4j.core.LogEvent; 020 import org.apache.logging.log4j.core.config.Configuration; 021 import org.apache.logging.log4j.core.config.plugins.Plugin; 022 import org.apache.logging.log4j.core.config.plugins.PluginAttr; 023 import org.apache.logging.log4j.core.config.plugins.PluginConfiguration; 024 import org.apache.logging.log4j.core.config.plugins.PluginElement; 025 import org.apache.logging.log4j.core.config.plugins.PluginFactory; 026 import org.apache.logging.log4j.core.helpers.OptionConverter; 027 import org.apache.logging.log4j.core.pattern.LogEventPatternConverter; 028 import org.apache.logging.log4j.core.pattern.PatternFormatter; 029 import org.apache.logging.log4j.core.pattern.PatternParser; 030 import org.apache.logging.log4j.core.pattern.RegexReplacement; 031 032 import java.nio.charset.Charset; 033 import java.util.List; 034 035 /** 036 * <p>A flexible layout configurable with pattern string. The goal of this class 037 * is to {@link org.apache.logging.log4j.core.Layout#toByteArray format} a {@link LogEvent} and return the results. 038 * The format of the result depends on the <em>conversion pattern</em>. 039 * <p> 040 * <p/> 041 * <p>The conversion pattern is closely related to the conversion 042 * pattern of the printf function in C. A conversion pattern is 043 * composed of literal text and format control expressions called 044 * <em>conversion specifiers</em>. 045 * 046 * See the Log4j Manual for details on the supported pattern converters. 047 */ 048 @Plugin(name = "PatternLayout", type = "Core", elementType = "layout", printObject = true) 049 public final class PatternLayout extends AbstractStringLayout { 050 /** 051 * Default pattern string for log output. Currently set to the 052 * string <b>"%m%n"</b> which just prints the application supplied 053 * message. 054 */ 055 public static final String DEFAULT_CONVERSION_PATTERN = "%m%n"; 056 057 /** 058 * A conversion pattern equivalent to the TTCCCLayout. 059 * Current value is <b>%r [%t] %p %c %x - %m%n</b>. 060 */ 061 public static final String TTCC_CONVERSION_PATTERN = 062 "%r [%t] %p %c %x - %m%n"; 063 064 /** 065 * A simple pattern. 066 * Current value is <b>%d [%t] %p %c - %m%n</b>. 067 */ 068 public static final String SIMPLE_CONVERSION_PATTERN = 069 "%d [%t] %p %c - %m%n"; 070 071 private static final String KEY = "Converter"; 072 073 /** 074 * Initial converter for pattern. 075 */ 076 private List<PatternFormatter> formatters; 077 078 /** 079 * Conversion pattern. 080 */ 081 private final String conversionPattern; 082 083 /** 084 * True if any element in pattern formats information from exceptions. 085 */ 086 private boolean handlesExceptions; 087 088 /** 089 * The current Configuration. 090 */ 091 private final Configuration config; 092 093 private final RegexReplacement replace; 094 095 /** 096 * Constructs a EnhancedPatternLayout using the supplied conversion pattern. 097 * 098 * @param config The Configuration. 099 * @param replace The regular expression to match. 100 * @param pattern conversion pattern. 101 * @param charset The character set. 102 */ 103 private PatternLayout(Configuration config, final RegexReplacement replace, final String pattern, 104 final Charset charset) { 105 super(charset); 106 this.replace = replace; 107 this.conversionPattern = pattern; 108 this.config = config; 109 PatternParser parser = createPatternParser(config); 110 formatters = parser.parse((pattern == null) ? DEFAULT_CONVERSION_PATTERN : pattern); 111 handlesExceptions = parser.handlesExceptions(); 112 } 113 114 /** 115 * Set the <b>ConversionPattern</b> option. This is the string which 116 * controls formatting and consists of a mix of literal content and 117 * conversion specifiers. 118 * 119 * @param conversionPattern conversion pattern. 120 */ 121 public void setConversionPattern(final String conversionPattern) { 122 String pattern = OptionConverter.convertSpecialChars(conversionPattern); 123 if (pattern == null) { 124 return; 125 } 126 PatternParser parser = createPatternParser(this.config); 127 formatters = parser.parse(pattern); 128 handlesExceptions = parser.handlesExceptions(); 129 } 130 131 /** 132 * Formats a logging event to a writer. 133 * 134 * 135 * @param event logging event to be formatted. 136 * @return The event formatted as a String. 137 */ 138 public String toSerializable(final LogEvent event) { 139 StringBuilder buf = new StringBuilder(); 140 for (PatternFormatter formatter : formatters) { 141 formatter.format(event, buf); 142 } 143 String str = buf.toString(); 144 if (replace != null) { 145 str = replace.format(str); 146 } 147 return str; 148 } 149 150 /** 151 * Create a PatternParser. 152 * @param config The Configuration. 153 * @return The PatternParser. 154 */ 155 public static PatternParser createPatternParser(Configuration config) { 156 if (config == null) { 157 return new PatternParser(config, KEY, LogEventPatternConverter.class); 158 } 159 PatternParser parser = (PatternParser) config.getComponent(KEY); 160 if (parser == null) { 161 parser = new PatternParser(config, KEY, LogEventPatternConverter.class); 162 config.addComponent(KEY, parser); 163 parser = (PatternParser) config.getComponent(KEY); 164 } 165 return parser; 166 } 167 168 @Override 169 public String toString() { 170 return conversionPattern; 171 } 172 173 /** 174 * Create a pattern layout. 175 * @param pattern The pattern. If not specified, defaults to DEFAULT_CONVERSION_PATTERN. 176 * @param config The Configuration. Some Converters require access to the Interpolator. 177 * @param replace A Regex replacement String. 178 * @param charset The character set. 179 * @return The PatternLayout. 180 */ 181 @PluginFactory 182 public static PatternLayout createLayout(@PluginAttr("pattern") String pattern, 183 @PluginConfiguration Configuration config, 184 @PluginElement("replace") RegexReplacement replace, 185 @PluginAttr("charset") String charset) { 186 Charset c = Charset.isSupported("UTF-8") ? Charset.forName("UTF-8") : Charset.defaultCharset(); 187 if (charset != null) { 188 if (Charset.isSupported(charset)) { 189 c = Charset.forName(charset); 190 } else { 191 LOGGER.error("Charset " + charset + " is not supported for layout, using " + c.displayName()); 192 } 193 } 194 return new PatternLayout(config, replace, pattern == null ? DEFAULT_CONVERSION_PATTERN : pattern, c); 195 } 196 }