FELIX-1988 Apply 9.logs_plugin.patch by Valentin Valchev (thanks)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@911377 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/LogServlet.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/LogServlet.java
index f53dfe6..eb13d7c 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/LogServlet.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/LogServlet.java
@@ -25,10 +25,9 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.apache.felix.webconsole.WebConsoleConstants;
+import org.apache.felix.webconsole.SimpleWebConsolePlugin;
import org.apache.felix.webconsole.WebConsoleUtil;
-import org.apache.felix.webconsole.internal.BaseWebConsolePlugin;
-import org.apache.felix.webconsole.internal.Util;
+import org.apache.felix.webconsole.internal.OsgiManagerPlugin;
import org.json.JSONException;
import org.json.JSONWriter;
import org.osgi.framework.ServiceReference;
@@ -37,31 +36,33 @@
import org.osgi.service.log.LogService;
-public class LogServlet extends BaseWebConsolePlugin
+/**
+ * LogServlet provides support for reading the log messages.
+ */
+public class LogServlet extends SimpleWebConsolePlugin implements OsgiManagerPlugin
{
- public static final String LABEL = "logs";
- public static final String TITLE = "Log Service";
+ private static final String LABEL = "logs";
+ private static final String TITLE = "Log Service";
+ private static final String CSS[] = { "/res/ui/logs.css" };
private final static int MAX_LOGS = 200; //maximum number of log entries
+ // templates
+ private final String TEMPLATE;
+ /** Default constructor */
public LogServlet()
{
+ super(LABEL, TITLE, CSS);
+
+ // load templates
+ TEMPLATE = readTemplateFile( "/templates/logs.html" );
}
- public String getLabel()
- {
- return LABEL;
- }
-
-
- public String getTitle()
- {
- return TITLE;
- }
-
-
+ /**
+ * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
protected void doPost( HttpServletRequest req, HttpServletResponse resp ) throws ServletException, IOException
{
final int minLevel = WebConsoleUtil.getParameterInt( req, "minLevel", LogService.LOG_DEBUG );
@@ -73,29 +74,19 @@
}
- private void renderJSON( final PrintWriter pw, int minLogLevel ) throws IOException
+ private final void renderJSON( final PrintWriter pw, int minLogLevel ) throws IOException
{
// create status line
final LogReaderService logReaderService = ( LogReaderService ) this.getService( LogReaderService.class
.getName() );
- StringBuffer statusLine = new StringBuffer();
- if ( logReaderService == null )
- {
- statusLine.append( "Log Service is not installed/running." );
- }
- else
- {
- statusLine.append( "Log Service is running." );
- }
-
JSONWriter jw = new JSONWriter( pw );
try
{
jw.object();
jw.key( "status" );
- jw.value( statusLine );
+ jw.value( logReaderService == null ? Boolean.FALSE : Boolean.TRUE );
jw.key( "data" );
jw.array();
@@ -127,6 +118,9 @@
}
+ /**
+ * @see org.apache.felix.webconsole.AbstractWebConsolePlugin#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException,
IOException
{
@@ -145,23 +139,17 @@
}
+ /**
+ * @see org.apache.felix.webconsole.AbstractWebConsolePlugin#renderContent(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
protected void renderContent( HttpServletRequest request, HttpServletResponse response ) throws ServletException,
IOException
{
- final PrintWriter pw = response.getWriter();
-
- final String appRoot = ( String ) request.getAttribute( WebConsoleConstants.ATTR_APP_ROOT );
- Util.script( pw, appRoot, "logs.js" );
-
- pw.println( "<div id='plugin_content'/>" );
-
- Util.startScript( pw );
- pw.println( "renderLogs( );" );
- Util.endScript( pw );
+ response.getWriter().print(TEMPLATE);
}
- private void logJson( JSONWriter jw, LogEntry info, int index ) throws JSONException
+ private static final void logJson( JSONWriter jw, LogEntry info, int index ) throws JSONException
{
jw.object();
jw.key( "id" );
@@ -170,6 +158,8 @@
jw.value( info.getTime() );
jw.key( "level" );
jw.value( logLevel( info.getLevel() ) );
+ jw.key( "raw_level" );
+ jw.value( info.getLevel() );
jw.key( "message" );
jw.value( info.getMessage() );
jw.key( "service" );
@@ -180,7 +170,7 @@
}
- private String serviceDescription( ServiceReference serviceReference )
+ private static final String serviceDescription( ServiceReference serviceReference )
{
if ( serviceReference == null )
return "";
@@ -189,7 +179,7 @@
}
- private String logLevel( int level )
+ private static final String logLevel( int level )
{
switch ( level )
{
@@ -206,7 +196,7 @@
}
- private String exceptionMessage( Throwable e )
+ private static final String exceptionMessage( Throwable e )
{
if ( e == null )
return "";
diff --git a/webconsole/src/main/resources/res/ui/logs.css b/webconsole/src/main/resources/res/ui/logs.css
new file mode 100644
index 0000000..a87ad6e
--- /dev/null
+++ b/webconsole/src/main/resources/res/ui/logs.css
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#logs, #logs2 {
+ margin: 0;
+ padding: 0
+}
\ No newline at end of file
diff --git a/webconsole/src/main/resources/res/ui/logs.js b/webconsole/src/main/resources/res/ui/logs.js
index 0a3656f..2d6f00f 100644
--- a/webconsole/src/main/resources/res/ui/logs.js
+++ b/webconsole/src/main/resources/res/ui/logs.js
@@ -14,35 +14,26 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-function renderStatusLine() {
- $("#plugin_content").append( "<div class='fullwidth'><div class='statusline'/></div>" );
-}
-
-function renderView( /* Array of String */ columns, /* String */ buttons ) {
- renderStatusLine();
- renderButtons(buttons);
- var txt = "<div class='table'><table id='plugin_table' class='tablelayout'><thead><tr>";
- for ( var name in columns ) {
- txt = txt + "<th class='col_" + columns[name] + "'>" + columns[name] + "</th>";
- }
- txt = txt + "</tr></thead><tbody></tbody></table></div>";
- $("#plugin_content").append( txt );
- renderButtons(buttons);
- renderStatusLine();
-}
-
-function renderButtons( buttons ) {
- $("#plugin_content").append( "<form method='post' enctype='multipart/form-data'><div class='fullwidth'><div class='buttons'>" +
- buttons + "</div></div></form>" );
-}
-
+
+var logsElem = false;
+var logs2Elem = false;
+var tableElem = false;
+var statElem = false;
+
function renderData( eventData ) {
- $(".statusline").empty().append(eventData.status);
- $("#plugin_table > tbody > tr").remove();
- for ( var idx in eventData.data ) {
- entry( eventData.data[idx] );
- }
- $("#plugin_table").trigger("update");
+ statElem.empty().append(eventData.status ? i18n.status_ok : i18n.status_missing);
+ logsElem.css("display", eventData.status ? "block" : "none" );
+ if (eventData.status) {
+ $("#plugin_table > tbody > tr").remove();
+ var hasEntries = false;
+ for ( var idx in eventData.data ) {
+ entry( eventData.data[idx] );
+ hasEntries = true;
+ }
+ logs2Elem.css("display", hasEntries ? "block" : "none" );
+
+ if (hasEntries) tableElem.trigger("update").trigger("applyWidgets");
+ }
}
function entry( /* Object */ dataEntry ) {
@@ -57,11 +48,16 @@
var level = dataEntry.level;
var exception = dataEntry.exception;
var service = dataEntry.service;
-
+ switch (dataEntry.raw_level) { // i18n
+ case 1: level = i18n.error; break;
+ case 2: level = i18n.warn; break;
+ case 3: level = i18n.info; break;
+ case 4: level = i18n.debug; break;
+ }
parent.appendChild( td( null, null, [ text( printDate(dataEntry.received) ) ] ) );
parent.appendChild( td( null, null, [ text( level ) ] ) );
- parent.appendChild( td( null, null, [ text( message ) ] ) );
- parent.appendChild( td( null, null, [ text( service ) ] ) );
+ parent.appendChild( td( null, null, [ text( wordWrap(message) ) ] ) );
+ parent.appendChild( td( null, null, [ text( wordWrap(service) ) ] ) );
parent.appendChild( td( null, null, [ text( exception ) ] ) );
}
@@ -72,25 +68,24 @@
}
function loadData() {
- $.get(pluginRoot + "/data.json", { "minLevel":$("#minLevel").val()}, function(data) {
- renderData(data);
- }, "json");
+ $.get(pluginRoot + "/data.json", { "minLevel":$(".minLevel").val()}, renderData, "json");
+ return false; // for button
}
-function renderLogs() {
- $(document).ready(function(){
- renderView( ["Received", "Level", "Message", "Service", "Exception"],
- "<span>Severity at least: <select id='minLevel'><option value='1'>ERROR</option>" +
- "<option value='2'>WARN</option><option value='3'>INFO</option><option value='4' selected='selected'>DEBUG</option></select></span> "+
- "<button class='reloadButton' type='button' name='reload'>Reload</button>");
- loadData();
-
- $("#plugin_table").tablesorter();
- $(".reloadButton").click(loadData);
- $("#minLevel").change(function() {
- $.post(pluginRoot, { "minLevel":$("#minLevel").val()}, function(data) {
- renderData(data);
- }, "json");
- });
- });
-}
\ No newline at end of file
+$(document).ready(function() {
+ // install user interaction handlers
+ $(".reloadButton").click(loadData);
+ $(".minLevel").change(function() {
+ var value = $(this).val();
+ $(".minLevel").val(value); // same values for both select boxes
+ $.post(pluginRoot, {"minLevel":value}, function(data) {
+ renderData(data);
+ }, "json");
+ });
+ logsElem = $("#logs");
+ logs2Elem = $("#logs2");
+ tableElem = $("#plugin_table");
+ statElem = $(".statline");
+ // load logs
+ loadData();
+});
\ No newline at end of file
diff --git a/webconsole/src/main/resources/templates/logs.html b/webconsole/src/main/resources/templates/logs.html
new file mode 100644
index 0000000..17aba1a
--- /dev/null
+++ b/webconsole/src/main/resources/templates/logs.html
@@ -0,0 +1,68 @@
+<script type="text/javascript" src="res/ui/logs.js"></script>
+<script type="text/javascript">
+// <![CDATA[
+// i18n
+var i18n = {
+ status_ok : "${log.status.ok}",
+ status_missing : "${log.status.missing}",
+ error : "${log.level.error}",
+ warn : "${log.level.warn}",
+ info : "${log.level.info}",
+ debug : "${log.level.debug}"
+}
+// ]]>
+</script>
+
+<!-- status line -->
+<p class="statline"> </p>
+
+<div id="logs">
+<!-- buttons top -->
+<form method="post" enctype="multipart/form-data" action="">
+ <div class="ui-widget-header ui-corner-top buttonGroup">
+ <label>${log.severity.label}</label>
+ <select class="minLevel">
+ <option value="1">${log.level.error}</option>
+ <option value="2">${log.level.warn}</option>
+ <option value="3">${log.level.info}</option>
+ <option value="4" selected="selected">${log.level.debug}</option>
+ </select>
+ <button class="reloadButton">${reload}</button>
+ </div>
+</form>
+
+<div id="logs2">
+<table id="plugin_table" class="tablesorter nicetable">
+ <thead>
+ <tr>
+ <th class="col_Received">${log.received}</th>
+ <th class="col_Level">${log.level}</th>
+ <th class="col_Message">${log.message}</th>
+ <th class="col_Service">${log.service}</th>
+ <th class="col_Exception">${log.exception}</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr><td colspan="5"> </td></tr>
+ </tbody>
+</table>
+
+<!-- buttons bottom -->
+<form method="post" enctype="multipart/form-data" action="">
+ <div class="ui-widget-header ui-corner-bottom buttonGroup">
+ <label>${log.severity.label}</label>
+ <select class="minLevel">
+ <option value="1">${log.level.error}</option>
+ <option value="2">${log.level.warn}</option>
+ <option value="3">${log.level.info}</option>
+ <option value="4" selected="selected">${log.level.debug}</option>
+ </select>
+ <button class="reloadButton">${reload}</button>
+ </div>
+</form>
+</div> <!-- logs2 -->
+
+</div> <!-- logs -->
+
+<!-- status line -->
+<p class="statline"> </p>