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