1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.classic.log4j;
15
16 import java.util.Map;
17 import java.util.Set;
18 import java.util.Map.Entry;
19
20 import ch.qos.logback.classic.spi.ILoggingEvent;
21 import ch.qos.logback.classic.spi.IThrowableProxy;
22 import ch.qos.logback.classic.spi.StackTraceElementProxy;
23 import ch.qos.logback.core.CoreConstants;
24 import ch.qos.logback.core.LayoutBase;
25 import ch.qos.logback.core.helpers.Transform;
26
27
28
29
30
31
32
33
34
35
36
37
38 public class XMLLayout extends LayoutBase<ILoggingEvent> {
39
40 private final int DEFAULT_SIZE = 256;
41 private final int UPPER_LIMIT = 2048;
42
43 private StringBuilder buf = new StringBuilder(DEFAULT_SIZE);
44 private boolean locationInfo = false;
45 private boolean properties = false;
46
47 @Override
48 public void start() {
49 super.start();
50 }
51
52
53
54
55
56
57
58
59
60
61
62 public void setLocationInfo(boolean flag) {
63 locationInfo = flag;
64 }
65
66
67
68
69 public boolean getLocationInfo() {
70 return locationInfo;
71 }
72
73
74
75
76
77
78
79
80 public void setProperties(final boolean flag) {
81 properties = flag;
82 }
83
84
85
86
87
88
89
90 public boolean getProperties() {
91 return properties;
92 }
93
94
95
96
97 public String doLayout(ILoggingEvent event) {
98
99
100
101 if (buf.capacity() > UPPER_LIMIT) {
102 buf = new StringBuilder(DEFAULT_SIZE);
103 } else {
104 buf.setLength(0);
105 }
106
107
108
109 buf.append("<log4j:event logger=\"");
110 buf.append(event.getLoggerName());
111 buf.append("\"\r\n");
112 buf.append(" timestamp=\"");
113 buf.append(event.getTimeStamp());
114 buf.append("\" level=\"");
115 buf.append(event.getLevel());
116 buf.append("\" thread=\"");
117 buf.append(event.getThreadName());
118 buf.append("\">\r\n");
119
120 buf.append(" <log4j:message><![CDATA[");
121
122
123 Transform.appendEscapingCDATA(buf, event.getFormattedMessage());
124 buf.append("]]></log4j:message>\r\n");
125
126
127
128
129
130 IThrowableProxy tp = event.getThrowableProxy();
131 if (tp != null) {
132 StackTraceElementProxy[] stepArray = tp.getStackTraceElementProxyArray();
133 buf.append(" <log4j:throwable><![CDATA[");
134 for (StackTraceElementProxy step : stepArray) {
135 buf.append(CoreConstants.TAB);
136 buf.append(step.toString());
137 buf.append("\r\n");
138 }
139 buf.append("]]></log4j:throwable>\r\n");
140 }
141
142 if (locationInfo) {
143 StackTraceElement[] callerDataArray = event.getCallerData();
144 if (callerDataArray != null && callerDataArray.length > 0) {
145 StackTraceElement immediateCallerData = callerDataArray[0];
146 buf.append(" <log4j:locationInfo class=\"");
147 buf.append(immediateCallerData.getClassName());
148 buf.append("\"\r\n");
149 buf.append(" method=\"");
150 buf.append(Transform.escapeTags(immediateCallerData.getMethodName()));
151 buf.append("\" file=\"");
152 buf.append(immediateCallerData.getFileName());
153 buf.append("\" line=\"");
154 buf.append(immediateCallerData.getLineNumber());
155 buf.append("\"/>\r\n");
156 }
157 }
158
159
160
161
162
163 if (this.getProperties()) {
164 Map<String, String> propertyMap = event.getMDCPropertyMap();
165
166 if ((propertyMap != null) && (propertyMap.size() != 0)) {
167 Set<Entry<String, String>> entrySet = propertyMap.entrySet();
168 buf.append(" <log4j:properties>");
169 for (Entry<String, String> entry : entrySet) {
170 buf.append("\r\n <log4j:data");
171 buf.append(" name='" + Transform.escapeTags(entry.getKey()) + "'");
172 buf.append(" value='" + Transform.escapeTags(entry.getValue()) + "'");
173 buf.append(" />");
174 }
175 buf.append("\r\n </log4j:properties>");
176 }
177 }
178
179 buf.append("\r\n</log4j:event>\r\n\r\n");
180
181 return buf.toString();
182 }
183
184 @Override
185 public String getContentType() {
186 return "text/xml";
187 }
188
189 }