001/** 002 * Logback: the reliable, generic, fast and flexible logging framework. 003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved. 004 * 005 * This program and the accompanying materials are dual-licensed under 006 * either the terms of the Eclipse Public License v1.0 as published by 007 * the Eclipse Foundation 008 * 009 * or (per the licensee's choosing) 010 * 011 * under the terms of the GNU Lesser General Public License version 2.1 012 * as published by the Free Software Foundation. 013 */ 014package ch.qos.logback.core.status; 015 016import static ch.qos.logback.core.CoreConstants.LINE_SEPARATOR; 017 018import java.io.IOException; 019import java.io.PrintWriter; 020import java.io.StringWriter; 021import java.util.List; 022 023import jakarta.servlet.ServletException; 024import jakarta.servlet.http.HttpServlet; 025import jakarta.servlet.http.HttpServletRequest; 026import jakarta.servlet.http.HttpServletResponse; 027 028import ch.qos.logback.core.CoreConstants; 029import ch.qos.logback.core.helpers.Transform; 030import ch.qos.logback.core.util.CachingDateFormatter; 031 032abstract public class ViewStatusMessagesServletBase extends HttpServlet { 033 034 private static final long serialVersionUID = -3551928133801157219L; 035 private static CachingDateFormatter SDF = new CachingDateFormatter("yyyy-MM-dd HH:mm:ss"); 036 037 static String SUBMIT = "submit"; 038 static String CLEAR = "Clear"; 039 040 protected abstract StatusManager getStatusManager(HttpServletRequest req, HttpServletResponse resp); 041 042 protected abstract String getPageTitle(HttpServletRequest req, HttpServletResponse resp); 043 044 int count; 045 046 protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 047 048 count = 0; 049 StatusManager sm = getStatusManager(req, resp); 050 051 resp.setContentType("text/html"); 052 PrintWriter output = resp.getWriter(); 053 054 output.append("<html>\r\n"); 055 output.append("<head>\r\n"); 056 printCSS(req.getContextPath(), output); 057 output.append("</head>\r\n"); 058 output.append("<body>\r\n"); 059 output.append(getPageTitle(req, resp)); 060 061 output.append("<form method=\"POST\">\r\n"); 062 output.append("<input type=\"submit\" name=\"" + SUBMIT + "\" value=\"" + CLEAR + "\">"); 063 output.append("</form>\r\n"); 064 065 if (CLEAR.equalsIgnoreCase(req.getParameter(SUBMIT))) { 066 sm.clear(); 067 sm.add(new InfoStatus("Cleared all status messages", this)); 068 } 069 070 output.append("<table>"); 071 StringBuilder buf = new StringBuilder(); 072 if (sm != null) { 073 printList(buf, sm); 074 } else { 075 output.append("Could not find status manager"); 076 } 077 output.append(buf); 078 output.append("</table>"); 079 output.append("</body>\r\n"); 080 output.append("</html>\r\n"); 081 output.flush(); 082 output.close(); 083 } 084 085 public void printCSS(String localRef, PrintWriter output) { 086 output.append(" <STYLE TYPE=\"text/css\">\r\n"); 087 output.append(" .warn { font-weight: bold; color: #FF6600;} \r\n"); // orange 088 output.append(" .error { font-weight: bold; color: #CC0000;} \r\n"); 089 output.append(" table { margin-left: 2em; margin-right: 2em; border-left: 2px solid #AAA; }\r\n"); 090 output.append(" tr.even { background: #FFFFFF; }\r\n"); 091 output.append(" tr.odd { background: #EAEAEA; }\r\n"); 092 output.append(" td { padding-right: 1ex; padding-left: 1ex; border-right: 2px solid #AAA; }\r\n"); 093 output.append(" td.date { text-align: right; font-family: courier, monospace; font-size: smaller; }"); 094 output.append(LINE_SEPARATOR); 095 096 output.append(" td.level { text-align: right; }"); 097 output.append(LINE_SEPARATOR); 098 output.append(" tr.header { background: #596ED5; color: #FFF; font-weight: bold; font-size: larger; }"); 099 output.append(CoreConstants.LINE_SEPARATOR); 100 101 output.append(" td.exception { background: #A2AEE8; white-space: pre; font-family: courier, monospace;}"); 102 output.append(LINE_SEPARATOR); 103 104 output.append(" </STYLE>\r\n"); 105 106 } 107 108 public void printList(StringBuilder buf, StatusManager sm) { 109 buf.append("<table>\r\n"); 110 printHeader(buf); 111 List<Status> statusList = sm.getCopyOfStatusList(); 112 for (Status s : statusList) { 113 count++; 114 printStatus(buf, s); 115 } 116 buf.append("</table>\r\n"); 117 } 118 119 public void printHeader(StringBuilder buf) { 120 buf.append(" <tr class=\"header\">\r\n"); 121 buf.append(" <th>Date </th>\r\n"); 122 buf.append(" <th>Level</th>\r\n"); 123 buf.append(" <th>Origin</th>\r\n"); 124 buf.append(" <th>Message</th>\r\n"); 125 buf.append(" </tr>\r\n"); 126 127 } 128 129 String statusLevelAsString(Status s) { 130 switch (s.getEffectiveLevel()) { 131 case Status.INFO: 132 return "INFO"; 133 case Status.WARN: 134 return "<span class=\"warn\">WARN</span>"; 135 case Status.ERROR: 136 return "<span class=\"error\">ERROR</span>"; 137 } 138 return null; 139 } 140 141 String abbreviatedOrigin(Status s) { 142 Object o = s.getOrigin(); 143 if (o == null) { 144 return null; 145 } 146 String fqClassName = o.getClass().getName(); 147 int lastIndex = fqClassName.lastIndexOf(CoreConstants.DOT); 148 if (lastIndex != -1) { 149 return fqClassName.substring(lastIndex + 1, fqClassName.length()); 150 } else { 151 return fqClassName; 152 } 153 } 154 155 private void printStatus(StringBuilder buf, Status s) { 156 String trClass; 157 if (count % 2 == 0) { 158 trClass = "even"; 159 } else { 160 trClass = "odd"; 161 } 162 buf.append(" <tr class=\"").append(trClass).append("\">\r\n"); 163 String dateStr = SDF.format(s.getTimestamp()); 164 buf.append(" <td class=\"date\">").append(dateStr).append("</td>\r\n"); 165 buf.append(" <td class=\"level\">").append(statusLevelAsString(s)).append("</td>\r\n"); 166 buf.append(" <td>").append(abbreviatedOrigin(s)).append("</td>\r\n"); 167 buf.append(" <td>").append(s.getMessage()).append("</td>\r\n"); 168 buf.append(" </tr>\r\n"); 169 if (s.getThrowable() != null) { 170 printThrowable(buf, s.getThrowable()); 171 } 172 } 173 174 private void printThrowable(StringBuilder buf, Throwable t) { 175 buf.append(" <tr>\r\n"); 176 buf.append(" <td colspan=\"4\" class=\"exception\"><pre>"); 177 StringWriter sw = new StringWriter(); 178 PrintWriter pw = new PrintWriter(sw); 179 t.printStackTrace(pw); 180 buf.append(Transform.escapeTags(sw.getBuffer())); 181 buf.append(" </pre></td>\r\n"); 182 buf.append(" </tr>\r\n"); 183 184 } 185}