You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by fm...@apache.org on 2009/04/18 14:07:11 UTC

svn commit: r766306 - in /felix/trunk/webconsole/src/main: java/org/apache/felix/webconsole/internal/compendium/LogServlet.java java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java resources/res/ui/admin.css resources/res/ui/logs.js

Author: fmeschbe
Date: Sat Apr 18 12:07:10 2009
New Revision: 766306

URL: http://svn.apache.org/viewvc?rev=766306&view=rev
Log:
FELIX-1042 Apply patch adding LogService panel (Thanks Filippo Diotalevi)

Added:
    felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/LogServlet.java   (with props)
    felix/trunk/webconsole/src/main/resources/res/ui/logs.js   (with props)
Modified:
    felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
    felix/trunk/webconsole/src/main/resources/res/ui/admin.css

Added: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/LogServlet.java
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/LogServlet.java?rev=766306&view=auto
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/LogServlet.java (added)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/LogServlet.java Sat Apr 18 12:07:10 2009
@@ -0,0 +1,229 @@
+/*
+ * 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.
+ */
+package org.apache.felix.webconsole.internal.compendium;
+
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Enumeration;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.felix.webconsole.internal.BaseWebConsolePlugin;
+import org.apache.felix.webconsole.internal.Util;
+import org.apache.felix.webconsole.internal.servlet.OsgiManager;
+import org.json.JSONException;
+import org.json.JSONWriter;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogEntry;
+import org.osgi.service.log.LogReaderService;
+import org.osgi.service.log.LogService;
+
+
+public class LogServlet extends BaseWebConsolePlugin
+{
+    public static final String LABEL = "logs";
+    public static final String TITLE = "Log Service";
+
+    private final static int MAX_LOGS = 200; //maximum number of log entries
+
+
+    public LogServlet()
+    {
+    }
+
+
+    public String getLabel()
+    {
+        return LABEL;
+    }
+
+
+    public String getTitle()
+    {
+        return TITLE;
+    }
+
+
+    protected void doPost( HttpServletRequest req, HttpServletResponse resp ) throws ServletException, IOException
+    {
+        final String minLevel = getParameter( req, "minLevel" );
+        resp.setContentType( "application/json" );
+        resp.setCharacterEncoding( "utf-8" );
+
+        renderJSON( resp.getWriter(), extractLogLevel( minLevel ) );
+    }
+
+
+    private 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.key( "data" );
+            jw.array();
+
+            int index = 0;
+            for ( Enumeration logEntries = logReaderService.getLog(); logEntries.hasMoreElements() && index < MAX_LOGS; )
+            {
+                LogEntry nextLog = ( LogEntry ) logEntries.nextElement();
+                if ( nextLog.getLevel() <= minLogLevel )
+                {
+                    logJson( jw, nextLog, index++ );
+                }
+            }
+
+            jw.endArray();
+
+            jw.endObject();
+
+        }
+        catch ( JSONException je )
+        {
+            throw new IOException( je.toString() );
+        }
+
+    }
+
+
+    private int extractLogLevel( String minLevel )
+    {
+        if ( minLevel == null )
+            return LogService.LOG_DEBUG;
+
+        int minLogLevel = LogService.LOG_DEBUG;;
+        try
+        {
+            minLogLevel = Integer.parseInt( minLevel );
+        }
+        catch ( Throwable t )
+        {
+            minLogLevel = LogService.LOG_DEBUG;
+        }
+        return minLogLevel;
+    }
+
+
+    protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException,
+        IOException
+    {
+        final String minLevel = getParameter( request, "minLevel" );
+        final String info = request.getPathInfo();
+        if ( info.endsWith( ".json" ) )
+        {
+            response.setContentType( "application/json" );
+            response.setCharacterEncoding( "UTF-8" );
+
+            PrintWriter pw = response.getWriter();
+            this.renderJSON( pw, extractLogLevel( minLevel ) );
+            return;
+        }
+        super.doGet( request, response );
+    }
+
+
+    protected void renderContent( HttpServletRequest request, HttpServletResponse response ) throws ServletException,
+        IOException
+    {
+        final PrintWriter pw = response.getWriter();
+
+        final String appRoot = ( String ) request.getAttribute( OsgiManager.ATTR_APP_ROOT );
+        Util.script( pw, appRoot, "logs.js" );
+
+        pw.println( "<div id='plugin_content'/>" );
+
+        Util.startScript( pw );
+        pw.println( "renderLogs( );" );
+        Util.endScript( pw );
+    }
+
+
+    private void logJson( JSONWriter jw, LogEntry info, int index ) throws JSONException
+    {
+        jw.object();
+        jw.key( "id" );
+        jw.value( String.valueOf( index ) );
+        jw.key( "received" );
+        jw.value( info.getTime() );
+        jw.key( "level" );
+        jw.value( logLevel( info.getLevel() ) );
+        jw.key( "message" );
+        jw.value( info.getMessage() );
+        jw.key( "service" );
+        jw.value( serviceDescription( info.getServiceReference() ) );
+        jw.key( "exception" );
+        jw.value( exceptionMessage( info.getException() ) );
+        jw.endObject();
+    }
+
+
+    private String serviceDescription( ServiceReference serviceReference )
+    {
+        if ( serviceReference == null )
+            return "";
+        else
+            return serviceReference.toString();
+    }
+
+
+    private String logLevel( int level )
+    {
+        switch ( level )
+        {
+            case LogService.LOG_INFO:
+                return "INFO";
+            case LogService.LOG_WARNING:
+                return "WARNING";
+            case LogService.LOG_ERROR:
+                return "ERROR";
+            case LogService.LOG_DEBUG:
+            default:
+                return "DEBUG";
+        }
+    }
+
+
+    private String exceptionMessage( Throwable e )
+    {
+        if ( e == null )
+            return "";
+        else
+            return e.getClass().getName()+": "+e.getMessage();
+    }
+
+}

Propchange: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/LogServlet.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/LogServlet.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Modified: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java?rev=766306&r1=766305&r2=766306&view=diff
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java (original)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java Sat Apr 18 12:07:10 2009
@@ -116,6 +116,7 @@
         { "org.apache.felix.webconsole.internal.compendium.ComponentConfigurationPrinter",
             "org.apache.felix.webconsole.internal.compendium.ComponentsServlet",
             "org.apache.felix.webconsole.internal.compendium.ConfigManager",
+            "org.apache.felix.webconsole.internal.compendium.LogServlet",
             "org.apache.felix.webconsole.internal.core.BundlesServlet",
             "org.apache.felix.webconsole.internal.core.InstallAction",
             "org.apache.felix.webconsole.internal.core.SetStartLevelAction",

Modified: felix/trunk/webconsole/src/main/resources/res/ui/admin.css
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/resources/res/ui/admin.css?rev=766306&r1=766305&r2=766306&view=diff
==============================================================================
--- felix/trunk/webconsole/src/main/resources/res/ui/admin.css (original)
+++ felix/trunk/webconsole/src/main/resources/res/ui/admin.css Sat Apr 18 12:07:10 2009
@@ -572,6 +572,15 @@
     vertical-align: middle;
     padding-right: 10px;
     padding-top: 8px;
+    color: #F0F0F0;
+    font-size: 10px;
+}
+div.buttons select {
+    font-family: Verdana, Arial, Helvetica, san-serif;
+    font-size: 9px;
+    font-weight: normal;
+    display: inline;
+    float:none;
 }
 div.button {
     display: inline-block;

Added: felix/trunk/webconsole/src/main/resources/res/ui/logs.js
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/resources/res/ui/logs.js?rev=766306&view=auto
==============================================================================
--- felix/trunk/webconsole/src/main/resources/res/ui/logs.js (added)
+++ felix/trunk/webconsole/src/main/resources/res/ui/logs.js Sat Apr 18 12:07:10 2009
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+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>" );
+}
+
+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");
+}
+
+function entry( /* Object */ dataEntry ) {
+    var trElement = tr( null, { id: "entry" + dataEntry.id } );
+    entryInternal( trElement,  dataEntry );
+	$("#plugin_table > tbody").append(trElement);	
+}
+
+function entryInternal( /* Element */ parent, /* Object */ dataEntry ) {
+    var id = dataEntry.id;
+    var message = dataEntry.message;
+    var level = dataEntry.level;
+    var exception = dataEntry.exception;
+    var service = dataEntry.service;
+
+    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( exception ) ] ) );
+}
+
+/* displays a date in the user's local timezone */
+function printDate(time) {
+    var date = time ? new Date(time) : new Date();
+    return date.toLocaleString();
+}
+
+function loadData() {
+	$.get(pluginRoot + "/data.json", { "minLevel":$("#minLevel").val()}, function(data) {
+	    renderData(data);
+	}, "json");	
+}
+
+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

Propchange: felix/trunk/webconsole/src/main/resources/res/ui/logs.js
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: felix/trunk/webconsole/src/main/resources/res/ui/logs.js
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url