1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.classic.html;
15
16 import java.util.Map;
17
18 import ch.qos.logback.classic.PatternLayout;
19 import ch.qos.logback.classic.pattern.MDCConverter;
20 import ch.qos.logback.classic.spi.ILoggingEvent;
21 import ch.qos.logback.classic.html.DefaultCssBuilder;
22 import ch.qos.logback.core.html.HTMLLayoutBase;
23 import ch.qos.logback.core.html.IThrowableRenderer;
24 import ch.qos.logback.core.pattern.Converter;
25 import static ch.qos.logback.core.CoreConstants.LINE_SEPARATOR;
26
27
28
29
30
31
32
33
34
35
36
37
38
39 public class HTMLLayout extends HTMLLayoutBase<ILoggingEvent> {
40
41
42
43
44 static final String DEFAULT_CONVERSION_PATTERN = "%date%thread%level%logger%mdc%msg";
45
46 IThrowableRenderer<ILoggingEvent> throwableRenderer;
47
48
49
50
51
52
53 public HTMLLayout() {
54 pattern = DEFAULT_CONVERSION_PATTERN;
55 throwableRenderer = new DefaultThrowableRenderer();
56 cssBuilder = new DefaultCssBuilder();
57 }
58
59 @Override
60 public void start() {
61 int errorCount = 0;
62 if (throwableRenderer == null) {
63 addError("ThrowableRender cannot be null.");
64 errorCount++;
65 }
66 if (errorCount == 0) {
67 super.start();
68 }
69 }
70
71 protected Map<String, String> getDefaultConverterMap() {
72 return PatternLayout.defaultConverterMap;
73 }
74
75 public String doLayout(ILoggingEvent event) {
76 StringBuilder buf = new StringBuilder();
77 startNewTableIfLimitReached(buf);
78
79 boolean odd = true;
80 if (((counter++) & 1) == 0) {
81 odd = false;
82 }
83
84 String level = event.getLevel().toString().toLowerCase();
85
86 buf.append(LINE_SEPARATOR);
87 buf.append("<tr class=\"");
88 buf.append(level);
89 if (odd) {
90 buf.append(" odd\">");
91 } else {
92 buf.append(" even\">");
93 }
94 buf.append(LINE_SEPARATOR);
95
96 Converter<ILoggingEvent> c = head;
97 while (c != null) {
98 appendEventToBuffer(buf, c, event);
99 c = c.getNext();
100 }
101 buf.append("</tr>");
102 buf.append(LINE_SEPARATOR);
103
104 if (event.getThrowableProxy() != null) {
105 throwableRenderer.render(buf, event);
106 }
107 return buf.toString();
108 }
109
110 private void appendEventToBuffer(StringBuilder buf,
111 Converter<ILoggingEvent> c, ILoggingEvent event) {
112 buf.append("<td class=\"");
113 buf.append(computeConverterName(c));
114 buf.append("\">");
115 c.write(buf, event);
116 buf.append("</td>");
117 buf.append(LINE_SEPARATOR);
118 }
119
120 public IThrowableRenderer getThrowableRenderer() {
121 return throwableRenderer;
122 }
123
124 public void setThrowableRenderer(IThrowableRenderer<ILoggingEvent> throwableRenderer) {
125 this.throwableRenderer = throwableRenderer;
126 }
127
128 @Override
129 protected String computeConverterName(Converter c) {
130 if(c instanceof MDCConverter) {
131 MDCConverter mc = (MDCConverter) c;
132 String key = mc.getFirstOption();
133 if(key != null) {
134 return key;
135 } else {
136 return "MDC";
137 }
138 } else {
139 return super.computeConverterName(c);
140 }
141 }
142 }