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