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.Charsets; 027 import org.apache.logging.log4j.core.helpers.OptionConverter; 028 import org.apache.logging.log4j.core.pattern.LogEventPatternConverter; 029 import org.apache.logging.log4j.core.pattern.PatternFormatter; 030 import org.apache.logging.log4j.core.pattern.PatternParser; 031 import org.apache.logging.log4j.core.pattern.RegexReplacement; 032 033 import java.nio.charset.Charset; 034 import java.util.List; 035 036 /** 037 * <p>A flexible layout configurable with pattern string. The goal of this class 038 * is to {@link org.apache.logging.log4j.core.Layout#toByteArray format} a {@link LogEvent} and return the results. 039 * The format of the result depends on the <em>conversion pattern</em>. 040 * <p> 041 * <p/> 042 * <p>The conversion pattern is closely related to the conversion 043 * pattern of the printf function in C. A conversion pattern is 044 * composed of literal text and format control expressions called 045 * <em>conversion specifiers</em>. 046 * 047 * See the Log4j Manual for details on the supported pattern converters. 048 */ 049 @Plugin(name = "PatternLayout", type = "Core", elementType = "layout", printObject = true) 050 public final class PatternLayout extends AbstractStringLayout { 051 /** 052 * Default pattern string for log output. Currently set to the 053 * string <b>"%m%n"</b> which just prints the application supplied 054 * message. 055 */ 056 public static final String DEFAULT_CONVERSION_PATTERN = "%m%n"; 057 058 /** 059 * A conversion pattern equivalent to the TTCCCLayout. 060 * Current value is <b>%r [%t] %p %c %x - %m%n</b>. 061 */ 062 public static final String TTCC_CONVERSION_PATTERN = 063 "%r [%t] %p %c %x - %m%n"; 064 065 /** 066 * A simple pattern. 067 * Current value is <b>%d [%t] %p %c - %m%n</b>. 068 */ 069 public static final String SIMPLE_CONVERSION_PATTERN = 070 "%d [%t] %p %c - %m%n"; 071 072 /** Key to identify pattern converters. */ 073 public static final String KEY = "Converter"; 074 075 /** 076 * Initial converter for pattern. 077 */ 078 private List<PatternFormatter> formatters; 079 080 /** 081 * Conversion pattern. 082 */ 083 private final String conversionPattern; 084 085 086 /** 087 * The current Configuration. 088 */ 089 private final Configuration config; 090 091 private final RegexReplacement replace; 092 093 /** 094 * Constructs a EnhancedPatternLayout using the supplied conversion pattern. 095 * 096 * @param config The Configuration. 097 * @param replace The regular expression to match. 098 * @param pattern conversion pattern. 099 * @param charset The character set. 100 */ 101 private PatternLayout(final Configuration config, final RegexReplacement replace, final String pattern, 102 final Charset charset) { 103 super(charset); 104 this.replace = replace; 105 this.conversionPattern = pattern; 106 this.config = config; 107 final PatternParser parser = createPatternParser(config); 108 formatters = parser.parse(pattern == null ? DEFAULT_CONVERSION_PATTERN : pattern, true); 109 } 110 111 /** 112 * Set the <b>ConversionPattern</b> option. This is the string which 113 * controls formatting and consists of a mix of literal content and 114 * conversion specifiers. 115 * 116 * @param conversionPattern conversion pattern. 117 */ 118 public void setConversionPattern(final String conversionPattern) { 119 final String pattern = OptionConverter.convertSpecialChars(conversionPattern); 120 if (pattern == null) { 121 return; 122 } 123 final PatternParser parser = createPatternParser(this.config); 124 formatters = parser.parse(pattern); 125 } 126 127 /** 128 * Formats a logging event to a writer. 129 * 130 * 131 * @param event logging event to be formatted. 132 * @return The event formatted as a String. 133 */ 134 public String toSerializable(final LogEvent event) { 135 final StringBuilder buf = new StringBuilder(); 136 for (final PatternFormatter formatter : formatters) { 137 formatter.format(event, buf); 138 } 139 String str = buf.toString(); 140 if (replace != null) { 141 str = replace.format(str); 142 } 143 return str; 144 } 145 146 /** 147 * Create a PatternParser. 148 * @param config The Configuration. 149 * @return The PatternParser. 150 */ 151 public static PatternParser createPatternParser(final Configuration config) { 152 if (config == null) { 153 return new PatternParser(config, KEY, LogEventPatternConverter.class); 154 } 155 PatternParser parser = (PatternParser) config.getComponent(KEY); 156 if (parser == null) { 157 parser = new PatternParser(config, KEY, LogEventPatternConverter.class); 158 config.addComponent(KEY, parser); 159 parser = (PatternParser) config.getComponent(KEY); 160 } 161 return parser; 162 } 163 164 @Override 165 public String toString() { 166 return conversionPattern; 167 } 168 169 /** 170 * Create a pattern layout. 171 * @param pattern The pattern. If not specified, defaults to DEFAULT_CONVERSION_PATTERN. 172 * @param config The Configuration. Some Converters require access to the Interpolator. 173 * @param replace A Regex replacement String. 174 * @param charsetName The character set. 175 * @return The PatternLayout. 176 */ 177 @PluginFactory 178 public static PatternLayout createLayout(@PluginAttr("pattern") final String pattern, 179 @PluginConfiguration final Configuration config, 180 @PluginElement("replace") final RegexReplacement replace, 181 @PluginAttr("charset") final String charsetName) { 182 final Charset charset = Charsets.getSupportedCharset(charsetName); 183 return new PatternLayout(config, replace, pattern == null ? DEFAULT_CONVERSION_PATTERN : pattern, charset); 184 } 185 }