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
63 public void setLocationInfo(boolean flag) {
64 locationInfo = flag;
65 }
66
67
68
69
70 public boolean getLocationInfo() {
71 return locationInfo;
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(Transform.escapeTags(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(Transform.escapeTags(event.getThreadName()));
118 buf.append("\">\r\n");
119
120 buf.append(" <log4j:message>");
121 buf.append(Transform.escapeTags(event.getFormattedMessage()));
122 buf.append("</log4j:message>\r\n");
123
124
125
126
127 IThrowableProxy tp = event.getThrowableProxy();
128 if (tp != null) {
129 StackTraceElementProxy[] stepArray = tp.getStackTraceElementProxyArray();
130 buf.append(" <log4j:throwable><![CDATA[");
131 for (StackTraceElementProxy step : stepArray) {
132 buf.append(CoreConstants.TAB);
133 buf.append(step.toString());
134 buf.append("\r\n");
135 }
136 buf.append("]]></log4j:throwable>\r\n");
137 }
138
139 if (locationInfo) {
140 StackTraceElement[] callerDataArray = event.getCallerData();
141 if (callerDataArray != null && callerDataArray.length > 0) {
142 StackTraceElement immediateCallerData = callerDataArray[0];
143 buf.append(" <log4j:locationInfo class=\"");
144 buf.append(immediateCallerData.getClassName());
145 buf.append("\"\r\n");
146 buf.append(" method=\"");
147 buf.append(Transform.escapeTags(immediateCallerData.getMethodName()));
148 buf.append("\" file=\"");
149 buf.append(Transform.escapeTags(immediateCallerData.getFileName()));
150 buf.append("\" line=\"");
151 buf.append(immediateCallerData.getLineNumber());
152 buf.append("\"/>\r\n");
153 }
154 }
155
156
157
158
159
160 if (this.getProperties()) {
161 Map<String, String> propertyMap = event.getMDCPropertyMap();
162
163 if ((propertyMap != null) && (propertyMap.size() != 0)) {
164 Set<Entry<String, String>> entrySet = propertyMap.entrySet();
165 buf.append(" <log4j:properties>");
166 for (Entry<String, String> entry : entrySet) {
167 buf.append("\r\n <log4j:data");
168 buf.append(" name='" + Transform.escapeTags(entry.getKey()) + "'");
169 buf.append(" value='" + Transform.escapeTags(entry.getValue()) + "'");
170 buf.append(" />");
171 }
172 buf.append("\r\n </log4j:properties>");
173 }
174 }
175
176 buf.append("\r\n</log4j:event>\r\n\r\n");
177
178 return buf.toString();
179 }
180
181 @Override
182 public String getContentType() {
183 return "text/xml";
184 }
185
186 }