View Javadoc

1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2011, 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.core.status;
15  
16  import static ch.qos.logback.core.CoreConstants.LINE_SEPARATOR;
17  
18  import java.io.IOException;
19  import java.io.PrintWriter;
20  import java.io.StringWriter;
21  import java.util.List;
22  
23  import javax.servlet.ServletException;
24  import javax.servlet.http.HttpServlet;
25  import javax.servlet.http.HttpServletRequest;
26  import javax.servlet.http.HttpServletResponse;
27  
28  import ch.qos.logback.core.CoreConstants;
29  import ch.qos.logback.core.helpers.Transform;
30  import ch.qos.logback.core.util.CachingDateFormatter;
31  
32  abstract public class ViewStatusMessagesServletBase extends HttpServlet {
33  
34    private static final long serialVersionUID = -3551928133801157219L;
35    private static CachingDateFormatter SDF = new CachingDateFormatter(
36        "yyyy-MM-dd HH:mm:ss");
37  
38    static String SUBMIT = "submit";
39    static String CLEAR = "Clear";
40  
41    protected abstract StatusManager getStatusManager(HttpServletRequest req, HttpServletResponse resp);
42  
43    protected abstract String getPageTitle(HttpServletRequest req, HttpServletResponse resp);
44  
45    int count;
46  
47    protected void service(HttpServletRequest req, HttpServletResponse resp)
48        throws ServletException, IOException {
49  
50      count = 0;
51      StatusManager sm = getStatusManager(req, resp);
52  
53      resp.setContentType("text/html");
54      PrintWriter output = resp.getWriter();
55  
56      output.append("<html>\r\n");
57      output.append("<head>\r\n");
58      printCSS(req.getContextPath(), output);
59      output.append("</head>\r\n");
60      output.append("<body>\r\n");
61      output.append(getPageTitle(req, resp));
62  
63  
64      output.append("<form method=\"POST\">\r\n");
65      output.append("<input type=\"submit\" name=\""+SUBMIT+"\" value=\""+CLEAR+"\">");
66      output.append("</form>\r\n");
67  
68  
69      if(CLEAR.equalsIgnoreCase(req.getParameter(SUBMIT))) {
70        sm.clear();
71        sm.add(new InfoStatus("Cleared all status messages", this));
72      }
73      
74      output.append("<table>");
75      StringBuilder buf = new StringBuilder();
76      if(sm != null) {
77        printList(buf, sm);
78      } else {
79        output.append("Could not find status manager");
80      }
81      output.append(buf);
82      output.append("</table>");
83      output.append("</body>\r\n");
84      output.append("</html>\r\n");
85      output.flush();
86      output.close();
87    }
88  
89    public void printCSS(String localRef, PrintWriter output) {
90      output.append("  <STYLE TYPE=\"text/css\">\r\n");
91      output.append("    .warn  { font-weight: bold; color: #FF6600;} \r\n"); // orange
92      output.append("    .error { font-weight: bold; color: #CC0000;} \r\n");
93      output
94          .append("    table { margin-left: 2em; margin-right: 2em; border-left: 2px solid #AAA; }\r\n");
95      output.append("    tr.even { background: #FFFFFF; }\r\n");
96      output.append("    tr.odd  { background: #EAEAEA; }\r\n");
97      output
98          .append("    td { padding-right: 1ex; padding-left: 1ex; border-right: 2px solid #AAA; }\r\n");
99      output
100         .append("    td.date { text-align: right; font-family: courier, monospace; font-size: smaller; }");
101     output.append(LINE_SEPARATOR);
102 
103     output.append("  td.level { text-align: right; }");
104     output.append(LINE_SEPARATOR);
105     output
106         .append("    tr.header { background: #596ED5; color: #FFF; font-weight: bold; font-size: larger; }");
107     output.append(CoreConstants.LINE_SEPARATOR);
108 
109     output
110         .append("  td.exception { background: #A2AEE8; white-space: pre; font-family: courier, monospace;}");
111     output.append(LINE_SEPARATOR);
112 
113     output.append("  </STYLE>\r\n");
114 
115   }
116 
117   public void printList(StringBuilder buf, StatusManager sm) {
118     buf.append("<table>\r\n");
119     printHeader(buf);
120     List<Status> statusList = sm.getCopyOfStatusList();
121     for (Status s : statusList) {
122       count++;
123       printStatus(buf, s);
124     }
125     buf.append("</table>\r\n");
126   }
127 
128   public void printHeader(StringBuilder buf) {
129     buf.append("  <tr class=\"header\">\r\n");
130     buf.append("    <th>Date </th>\r\n");
131     buf.append("    <th>Level</th>\r\n");
132     buf.append("    <th>Origin</th>\r\n");
133     buf.append("    <th>Message</th>\r\n");
134     buf.append("  </tr>\r\n");
135 
136   }
137 
138   String statusLevelAsString(Status s) {
139     switch (s.getEffectiveLevel()) {
140     case Status.INFO:
141       return "INFO";
142     case Status.WARN:
143       return "<span class=\"warn\">WARN</span>";
144     case Status.ERROR:
145       return "<span class=\"error\">ERROR</span>";
146     }
147     return null;
148   }
149 
150   String abbreviatedOrigin(Status s) {
151     Object o = s.getOrigin();
152     if (o == null) {
153       return null;
154     }
155     String fqClassName = o.getClass().getName();
156     int lastIndex = fqClassName.lastIndexOf(CoreConstants.DOT);
157     if (lastIndex != -1) {
158       return fqClassName.substring(lastIndex + 1, fqClassName.length());
159     } else {
160       return fqClassName;
161     }
162   }
163 
164   private void printStatus(StringBuilder buf, Status s) {
165     String trClass;
166     if (count % 2 == 0) {
167       trClass = "even";
168     } else {
169       trClass = "odd";
170     }
171     buf.append("  <tr class=\"").append(trClass).append("\">\r\n");
172     String dateStr = SDF.format(s.getDate());
173     buf.append("    <td class=\"date\">").append(dateStr).append("</td>\r\n");
174     buf.append("    <td class=\"level\">").append(statusLevelAsString(s))
175         .append("</td>\r\n");
176     buf.append("    <td>").append(abbreviatedOrigin(s)).append("</td>\r\n");
177     buf.append("    <td>").append(s.getMessage()).append("</td>\r\n");
178     buf.append("  </tr>\r\n");
179     if (s.getThrowable() != null) {
180       printThrowable(buf, s.getThrowable());
181     }
182   }
183 
184   private void printThrowable(StringBuilder buf, Throwable t) {
185     buf.append("  <tr>\r\n");
186     buf.append("    <td colspan=\"4\" class=\"exception\"><pre>");
187     StringWriter sw = new StringWriter();
188     PrintWriter pw = new PrintWriter(sw);
189     t.printStackTrace(pw);
190     buf.append(Transform.escapeTags(sw.getBuffer()));
191     buf.append("    </pre></td>\r\n");
192     buf.append("  </tr>\r\n");
193 
194   }
195 }