View Javadoc
1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
4    *
5    * This program and the accompanying materials are dual-licensed under
6    * either the terms of the Eclipse Public License v1.0 as published by
7    * the Eclipse Foundation
8    *
9    *   or (per the licensee's choosing)
10   *
11   * under the terms of the GNU Lesser General Public License version 2.1
12   * as published by the Free Software Foundation.
13   */
14  package ch.qos.logback.access;
15  
16  import ch.qos.logback.access.pattern.ContentLengthConverter;
17  import ch.qos.logback.access.pattern.DateConverter;
18  import ch.qos.logback.access.pattern.ElapsedSecondsConverter;
19  import ch.qos.logback.access.pattern.ElapsedTimeConverter;
20  import ch.qos.logback.access.pattern.EnsureLineSeparation;
21  import ch.qos.logback.access.pattern.FullRequestConverter;
22  import ch.qos.logback.access.pattern.FullResponseConverter;
23  import ch.qos.logback.access.pattern.LineSeparatorConverter;
24  import ch.qos.logback.access.pattern.LocalIPAddressConverter;
25  import ch.qos.logback.access.pattern.LocalPortConverter;
26  import ch.qos.logback.access.pattern.NAConverter;
27  import ch.qos.logback.access.pattern.QueryStringConverter;
28  import ch.qos.logback.access.pattern.RemoteHostConverter;
29  import ch.qos.logback.access.pattern.RemoteIPAddressConverter;
30  import ch.qos.logback.access.pattern.RemoteUserConverter;
31  import ch.qos.logback.access.pattern.RequestAttributeConverter;
32  import ch.qos.logback.access.pattern.RequestContentConverter;
33  import ch.qos.logback.access.pattern.RequestCookieConverter;
34  import ch.qos.logback.access.pattern.RequestHeaderConverter;
35  import ch.qos.logback.access.pattern.RequestMethodConverter;
36  import ch.qos.logback.access.pattern.RequestParameterConverter;
37  import ch.qos.logback.access.pattern.RequestProtocolConverter;
38  import ch.qos.logback.access.pattern.RequestURIConverter;
39  import ch.qos.logback.access.pattern.RequestURLConverter;
40  import ch.qos.logback.access.pattern.ResponseContentConverter;
41  import ch.qos.logback.access.pattern.ResponseHeaderConverter;
42  import ch.qos.logback.access.pattern.ServerNameConverter;
43  import ch.qos.logback.access.pattern.SessionIDConverter;
44  import ch.qos.logback.access.pattern.StatusCodeConverter;
45  import ch.qos.logback.access.pattern.ThreadNameConverter;
46  import ch.qos.logback.access.spi.IAccessEvent;
47  import ch.qos.logback.core.pattern.PatternLayoutBase;
48  import ch.qos.logback.core.pattern.color.*;
49  import ch.qos.logback.core.pattern.parser.Parser;
50  
51  import java.util.HashMap;
52  import java.util.Map;
53  
54  /**
55   * <p>
56   * This class is a module-specific implementation of
57   * {@link ch.qos.logback.access.PatternLayout} to allow http-specific patterns
58   * to be used. The <code>ch.qos.logback.access.PatternLayout</code> provides a
59   * way to format the logging output that is just as easy and flexible as the
60   * usual <code>PatternLayout</code>.
61   * </p>
62   * <p/>
63   * For more information about this layout, please refer to the online manual at
64   * http://logback.qos.ch/manual/layouts.html#AccessPatternLayout
65   *
66   * @author Ceki G&uuml;lc&uuml;
67   * @author S&eacute;bastien Pennec
68   */
69  public class PatternLayout extends PatternLayoutBase<IAccessEvent> {
70  
71      public static final Map<String, String> defaultConverterMap = new HashMap<String, String>();
72      public static final String HEADER_PREFIX = "#logback.access pattern: ";
73  
74      public static final String CLF_PATTERN = "%h %l %u [%t] \"%r\" %s %b";
75      public static final String CLF_PATTERN_NAME = "common";
76      public static final String CLF_PATTERN_NAME_2 = "clf";
77      public static final String COMBINED_PATTERN = "%h %l %u [%t] \"%r\" %s %b \"%i{Referer}\" \"%i{User-Agent}\"";
78      public static final String COMBINED_PATTERN_NAME = "combined";
79  
80      static {
81          defaultConverterMap.putAll(Parser.DEFAULT_COMPOSITE_CONVERTER_MAP);
82  
83          defaultConverterMap.put("a", RemoteIPAddressConverter.class.getName());
84          defaultConverterMap.put("remoteIP", RemoteIPAddressConverter.class.getName());
85  
86          defaultConverterMap.put("A", LocalIPAddressConverter.class.getName());
87          defaultConverterMap.put("localIP", LocalIPAddressConverter.class.getName());
88  
89          defaultConverterMap.put("b", ContentLengthConverter.class.getName());
90          defaultConverterMap.put("B", ContentLengthConverter.class.getName());
91          defaultConverterMap.put("bytesSent", ContentLengthConverter.class.getName());
92  
93          defaultConverterMap.put("h", RemoteHostConverter.class.getName());
94          defaultConverterMap.put("clientHost", RemoteHostConverter.class.getName());
95  
96          defaultConverterMap.put("H", RequestProtocolConverter.class.getName());
97          defaultConverterMap.put("protocol", RequestProtocolConverter.class.getName());
98  
99          defaultConverterMap.put("i", RequestHeaderConverter.class.getName());
100         defaultConverterMap.put("header", RequestHeaderConverter.class.getName());
101 
102         defaultConverterMap.put("I", ThreadNameConverter.class.getName());
103         defaultConverterMap.put("threadName", ThreadNameConverter.class.getName());
104 
105         defaultConverterMap.put("l", NAConverter.class.getName());
106 
107         defaultConverterMap.put("m", RequestMethodConverter.class.getName());
108         defaultConverterMap.put("requestMethod", RequestMethodConverter.class.getName());
109 
110         defaultConverterMap.put("q", QueryStringConverter.class.getName());
111         defaultConverterMap.put("queryString", QueryStringConverter.class.getName());
112 
113         defaultConverterMap.put("r", RequestURLConverter.class.getName());
114         defaultConverterMap.put("requestURL", RequestURLConverter.class.getName());
115 
116         defaultConverterMap.put("s", StatusCodeConverter.class.getName());
117         defaultConverterMap.put("statusCode", StatusCodeConverter.class.getName());
118 
119         defaultConverterMap.put("S", SessionIDConverter.class.getName());
120         defaultConverterMap.put("sessionID", SessionIDConverter.class.getName());
121 
122         defaultConverterMap.put("t", DateConverter.class.getName());
123         defaultConverterMap.put("date", DateConverter.class.getName());
124 
125         defaultConverterMap.put("u", RemoteUserConverter.class.getName());
126         defaultConverterMap.put("user", RemoteUserConverter.class.getName());
127 
128         defaultConverterMap.put("U", RequestURIConverter.class.getName());
129         defaultConverterMap.put("requestURI", RequestURIConverter.class.getName());
130 
131         defaultConverterMap.put("v", ServerNameConverter.class.getName());
132         defaultConverterMap.put("server", ServerNameConverter.class.getName());
133 
134         defaultConverterMap.put("localPort", LocalPortConverter.class.getName());
135 
136         defaultConverterMap.put("requestAttribute", RequestAttributeConverter.class.getName());
137         defaultConverterMap.put("reqAttribute", RequestAttributeConverter.class.getName());
138 
139         defaultConverterMap.put("reqCookie", RequestCookieConverter.class.getName());
140         defaultConverterMap.put("requestCookie", RequestCookieConverter.class.getName());
141 
142         defaultConverterMap.put("responseHeader", ResponseHeaderConverter.class.getName());
143 
144         defaultConverterMap.put("requestParameter", RequestParameterConverter.class.getName());
145         defaultConverterMap.put("reqParameter", RequestParameterConverter.class.getName());
146 
147         defaultConverterMap.put("requestContent", RequestContentConverter.class.getName());
148 
149         defaultConverterMap.put("responseContent", ResponseContentConverter.class.getName());
150 
151         defaultConverterMap.put("fullRequest", FullRequestConverter.class.getName());
152         defaultConverterMap.put("fullResponse", FullResponseConverter.class.getName());
153 
154         defaultConverterMap.put("elapsedTime", ElapsedTimeConverter.class.getName());
155         defaultConverterMap.put("D", ElapsedTimeConverter.class.getName());
156 
157         defaultConverterMap.put("elapsedSeconds", ElapsedSecondsConverter.class.getName());
158         defaultConverterMap.put("T", ElapsedSecondsConverter.class.getName());
159 
160         defaultConverterMap.put("n", LineSeparatorConverter.class.getName());
161 
162         defaultConverterMap.put("black", BlackCompositeConverter.class.getName());
163         defaultConverterMap.put("red", RedCompositeConverter.class.getName());
164         defaultConverterMap.put("green", GreenCompositeConverter.class.getName());
165         defaultConverterMap.put("yellow", YellowCompositeConverter.class.getName());
166         defaultConverterMap.put("blue", BlueCompositeConverter.class.getName());
167         defaultConverterMap.put("magenta", MagentaCompositeConverter.class.getName());
168         defaultConverterMap.put("cyan", CyanCompositeConverter.class.getName());
169         defaultConverterMap.put("white", WhiteCompositeConverter.class.getName());
170         defaultConverterMap.put("gray", GrayCompositeConverter.class.getName());
171         defaultConverterMap.put("boldRed", BoldRedCompositeConverter.class.getName());
172         defaultConverterMap.put("boldGreen", BoldGreenCompositeConverter.class.getName());
173         defaultConverterMap.put("boldYellow", BoldYellowCompositeConverter.class.getName());
174         defaultConverterMap.put("boldBlue", BoldBlueCompositeConverter.class.getName());
175         defaultConverterMap.put("boldMagenta", BoldMagentaCompositeConverter.class.getName());
176         defaultConverterMap.put("boldCyan", BoldCyanCompositeConverter.class.getName());
177         defaultConverterMap.put("boldWhite", BoldWhiteCompositeConverter.class.getName());
178     }
179 
180     public PatternLayout() {
181         // set a default value for pattern
182         setPattern(CLF_PATTERN);
183         // by default postCompileProcessor is an EnsureLineSeparation instance
184         this.postCompileProcessor = new EnsureLineSeparation();
185     }
186 
187     /**
188      * Returns the default converter map for this instance.
189      */
190     @Override
191     public Map<String, String> getDefaultConverterMap() {
192         return defaultConverterMap;
193     }
194 
195     @Override
196     public String doLayout(IAccessEvent event) {
197         if (!isStarted()) {
198             return null;
199         }
200         return writeLoopOnConverters(event);
201     }
202 
203     @Override
204     public void start() {
205         if (getPattern().equalsIgnoreCase(CLF_PATTERN_NAME) || getPattern().equalsIgnoreCase(CLF_PATTERN_NAME_2)) {
206             setPattern(CLF_PATTERN);
207         } else if (getPattern().equalsIgnoreCase(COMBINED_PATTERN_NAME)) {
208             setPattern(COMBINED_PATTERN);
209         }
210         super.start();
211     }
212 
213     @Override
214     protected String getPresentationHeaderPrefix() {
215         return HEADER_PREFIX;
216     }
217 }