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/01/28 08:01:56 UTC

svn commit: r738382 - in /felix/trunk/configadmin/src: main/java/org/apache/felix/cm/impl/ConfigurationManager.java test/java/org/apache/felix/cm/MockLogService.java test/java/org/apache/felix/cm/impl/ConfigurationManagerTest.java

Author: fmeschbe
Date: Wed Jan 28 07:01:55 2009
New Revision: 738382

URL: http://svn.apache.org/viewvc?rev=738382&view=rev
Log:
FELIX-903 add felix.cm.loglevel property to limit the log output
in the absence of an OSGi LogService

Added:
    felix/trunk/configadmin/src/test/java/org/apache/felix/cm/MockLogService.java   (with props)
    felix/trunk/configadmin/src/test/java/org/apache/felix/cm/impl/ConfigurationManagerTest.java   (with props)
Modified:
    felix/trunk/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java

Modified: felix/trunk/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java?rev=738382&r1=738381&r2=738382&view=diff
==============================================================================
--- felix/trunk/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java (original)
+++ felix/trunk/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java Wed Jan 28 07:01:55 2009
@@ -73,9 +73,24 @@
      */
     public static final String CM_CONFIG_DIR = "felix.cm.dir";
 
+    /**
+     * The name of the bundle context property defining the maximum log level
+     * (value is "felix.cm.loglevel"). The log level setting is only used if
+     * there is no OSGi LogService available. Otherwise this setting is ignored.
+     * <p>
+     * This value of this property is expected to be an integer number
+     * corresponding to the log level values of the OSGi LogService. That is 1
+     * for errors, 2 for warnings, 3 for informational messages and 4 for debug
+     * messages. The default value is 2, such that only warnings and errors are
+     * logged in the absence of a LogService.
+     */
+    public static final String CM_LOG_LEVEL = "felix.cm.loglevel";
+
     // The name of the LogService (not using the class, which might be missing)
     private static final String LOG_SERVICE_NAME = "org.osgi.service.log.LogService";
 
+    private static final int CM_LOG_LEVEL_DEFAULT = 2;
+    
     // random number generator to create configuration PIDs for factory
     // configurations
     private static SecureRandom numberGenerator;
@@ -125,12 +140,32 @@
     // the cache of Configuration instances mapped by their PID
     private Map configurations;
 
+    // the maximum log level when no LogService is available
+    private int logLevel = CM_LOG_LEVEL_DEFAULT;
 
     public void start( BundleContext bundleContext )
     {
         // track the log service using a ServiceTracker
         logTracker = new ServiceTracker( bundleContext, LOG_SERVICE_NAME , null );
         logTracker.open();
+        
+        // assign the log level
+        String logLevelProp = bundleContext.getProperty( CM_LOG_LEVEL );
+        if ( logLevelProp == null )
+        {
+            logLevel = CM_LOG_LEVEL_DEFAULT;
+        }
+        else
+        {
+            try
+            {
+                logLevel = Integer.parseInt( logLevelProp );
+            }
+            catch ( NumberFormatException nfe )
+            {
+                logLevel = CM_LOG_LEVEL_DEFAULT;
+            }
+        }
 
         // set up some fields
         this.bundleContext = bundleContext;
@@ -784,6 +819,7 @@
 
     void log( int level, String message, Throwable t )
     {
+        // log using the LogService if available
         Object log = logTracker.getService();
         if ( log != null )
         {
@@ -791,30 +827,34 @@
             return;
         }
 
-        String code;
-        switch ( level )
+        // Otherwise only log if more serious than the configured level
+        if ( level <= logLevel )
         {
-            case LogService.LOG_INFO:
-                code = "*INFO *";
-                break;
+            String code;
+            switch ( level )
+            {
+                case LogService.LOG_INFO:
+                    code = "*INFO *";
+                    break;
 
-            case LogService.LOG_WARNING:
-                code = "*WARN *";
-                break;
+                case LogService.LOG_WARNING:
+                    code = "*WARN *";
+                    break;
 
-            case LogService.LOG_ERROR:
-                code = "*ERROR*";
-                break;
+                case LogService.LOG_ERROR:
+                    code = "*ERROR*";
+                    break;
 
-            case LogService.LOG_DEBUG:
-            default:
-                code = "*DEBUG*";
-        }
+                case LogService.LOG_DEBUG:
+                default:
+                    code = "*DEBUG*";
+            }
 
-        System.err.println( code + " " + message );
-        if ( t != null )
-        {
-            t.printStackTrace( System.err );
+            System.err.println( code + " " + message );
+            if ( t != null )
+            {
+                t.printStackTrace( System.err );
+            }
         }
     }
 

Added: felix/trunk/configadmin/src/test/java/org/apache/felix/cm/MockLogService.java
URL: http://svn.apache.org/viewvc/felix/trunk/configadmin/src/test/java/org/apache/felix/cm/MockLogService.java?rev=738382&view=auto
==============================================================================
--- felix/trunk/configadmin/src/test/java/org/apache/felix/cm/MockLogService.java (added)
+++ felix/trunk/configadmin/src/test/java/org/apache/felix/cm/MockLogService.java Wed Jan 28 07:01:55 2009
@@ -0,0 +1,84 @@
+/*
+ * 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.cm;
+
+
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogService;
+
+
+/**
+ * The <code>MockLogService</code> is a very simple log service, which just
+ * prints the loglevel and message to StdErr.
+ */
+public class MockLogService implements LogService
+{
+
+    public void log( int logLevel, String message )
+    {
+        System.err.print( toMessageLine( logLevel, message ) );
+    }
+
+
+    public void log( int logLevel, String message, Throwable t )
+    {
+        log( logLevel, message );
+    }
+
+
+    public void log( ServiceReference ref, int logLevel, String message )
+    {
+        log( logLevel, message );
+    }
+
+
+    public void log( ServiceReference ref, int logLevel, String message, Throwable t )
+    {
+        log( logLevel, message );
+    }
+
+
+    /**
+     * Helper method to format log level and log message exactly the same as the
+     * <code>ConfigurationManager.log()</code> does.
+     */
+    public static String toMessageLine( int level, String message )
+    {
+        String messageLine;
+        switch ( level )
+        {
+            case LogService.LOG_INFO:
+                messageLine = "*INFO *";
+                break;
+
+            case LogService.LOG_WARNING:
+                messageLine = "*WARN *";
+                break;
+
+            case LogService.LOG_ERROR:
+                messageLine = "*ERROR*";
+                break;
+
+            case LogService.LOG_DEBUG:
+            default:
+                messageLine = "*DEBUG*";
+        }
+        return messageLine + " " + message + System.getProperty( "line.separator" );
+    }
+}

Propchange: felix/trunk/configadmin/src/test/java/org/apache/felix/cm/MockLogService.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: felix/trunk/configadmin/src/test/java/org/apache/felix/cm/MockLogService.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: felix/trunk/configadmin/src/test/java/org/apache/felix/cm/impl/ConfigurationManagerTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/configadmin/src/test/java/org/apache/felix/cm/impl/ConfigurationManagerTest.java?rev=738382&view=auto
==============================================================================
--- felix/trunk/configadmin/src/test/java/org/apache/felix/cm/impl/ConfigurationManagerTest.java (added)
+++ felix/trunk/configadmin/src/test/java/org/apache/felix/cm/impl/ConfigurationManagerTest.java Wed Jan 28 07:01:55 2009
@@ -0,0 +1,237 @@
+/*
+ * 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.cm.impl;
+
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.lang.reflect.Field;
+
+import junit.framework.TestCase;
+
+import org.apache.felix.cm.MockBundleContext;
+import org.apache.felix.cm.MockLogService;
+import org.osgi.service.log.LogService;
+import org.osgi.util.tracker.ServiceTracker;
+
+
+public class ConfigurationManagerTest extends TestCase
+{
+
+    private PrintStream replacedStdErr;
+
+    private ByteArrayOutputStream output;
+
+
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+
+        replacedStdErr = System.err;
+
+        output = new ByteArrayOutputStream();
+        System.setErr( new PrintStream( output ) );
+    }
+
+
+    protected void tearDown() throws Exception
+    {
+        System.setErr( replacedStdErr );
+
+        super.tearDown();
+    }
+
+
+    public void testLogNoLogService()
+    {
+        ConfigurationManager configMgr = createConfigurationManager( null );
+
+        setLogLevel( configMgr, LogService.LOG_WARNING );
+        assertNoLog( configMgr, LogService.LOG_DEBUG, "Debug Test Message", null );
+        assertNoLog( configMgr, LogService.LOG_INFO, "Info Test Message", null );
+        assertLog( configMgr, LogService.LOG_WARNING, "Warning Test Message", null );
+        assertLog( configMgr, LogService.LOG_ERROR, "Error Test Message", null );
+
+        setLogLevel( configMgr, LogService.LOG_ERROR );
+        assertNoLog( configMgr, LogService.LOG_DEBUG, "Debug Test Message", null );
+        assertNoLog( configMgr, LogService.LOG_INFO, "Info Test Message", null );
+        assertNoLog( configMgr, LogService.LOG_WARNING, "Warning Test Message", null );
+        assertLog( configMgr, LogService.LOG_ERROR, "Error Test Message", null );
+
+        // lower than error -- no output
+        setLogLevel( configMgr, LogService.LOG_ERROR - 1 );
+        assertNoLog( configMgr, LogService.LOG_DEBUG, "Debug Test Message", null );
+        assertNoLog( configMgr, LogService.LOG_INFO, "Info Test Message", null );
+        assertNoLog( configMgr, LogService.LOG_WARNING, "Warning Test Message", null );
+        assertNoLog( configMgr, LogService.LOG_ERROR, "Error Test Message", null );
+
+        // minimal log level -- no output
+        setLogLevel( configMgr, Integer.MIN_VALUE );
+        assertNoLog( configMgr, LogService.LOG_DEBUG, "Debug Test Message", null );
+        assertNoLog( configMgr, LogService.LOG_INFO, "Info Test Message", null );
+        assertNoLog( configMgr, LogService.LOG_WARNING, "Warning Test Message", null );
+        assertNoLog( configMgr, LogService.LOG_ERROR, "Error Test Message", null );
+
+        setLogLevel( configMgr, LogService.LOG_INFO );
+        assertNoLog( configMgr, LogService.LOG_DEBUG, "Debug Test Message", null );
+        assertLog( configMgr, LogService.LOG_INFO, "Info Test Message", null );
+        assertLog( configMgr, LogService.LOG_WARNING, "Warning Test Message", null );
+        assertLog( configMgr, LogService.LOG_ERROR, "Error Test Message", null );
+
+        setLogLevel( configMgr, LogService.LOG_DEBUG );
+        assertLog( configMgr, LogService.LOG_DEBUG, "Debug Test Message", null );
+        assertLog( configMgr, LogService.LOG_INFO, "Info Test Message", null );
+        assertLog( configMgr, LogService.LOG_WARNING, "Warning Test Message", null );
+        assertLog( configMgr, LogService.LOG_ERROR, "Error Test Message", null );
+
+        // maximal log level -- all output
+        setLogLevel( configMgr, Integer.MAX_VALUE );
+        assertLog( configMgr, LogService.LOG_DEBUG, "Debug Test Message", null );
+        assertLog( configMgr, LogService.LOG_INFO, "Info Test Message", null );
+        assertLog( configMgr, LogService.LOG_WARNING, "Warning Test Message", null );
+        assertLog( configMgr, LogService.LOG_ERROR, "Error Test Message", null );
+    }
+
+
+    // this test always expects output since when using a LogService, the log
+    // level property is ignored
+    public void testLogWithLogService()
+    {
+        LogService logService = new MockLogService();
+        ConfigurationManager configMgr = createConfigurationManager( logService );
+
+        setLogLevel( configMgr, LogService.LOG_WARNING );
+        assertLog( configMgr, LogService.LOG_DEBUG, "Debug Test Message", null );
+        assertLog( configMgr, LogService.LOG_INFO, "Info Test Message", null );
+        assertLog( configMgr, LogService.LOG_WARNING, "Warning Test Message", null );
+        assertLog( configMgr, LogService.LOG_ERROR, "Error Test Message", null );
+
+        setLogLevel( configMgr, LogService.LOG_ERROR );
+        assertLog( configMgr, LogService.LOG_DEBUG, "Debug Test Message", null );
+        assertLog( configMgr, LogService.LOG_INFO, "Info Test Message", null );
+        assertLog( configMgr, LogService.LOG_WARNING, "Warning Test Message", null );
+        assertLog( configMgr, LogService.LOG_ERROR, "Error Test Message", null );
+
+        setLogLevel( configMgr, LogService.LOG_ERROR - 1 );
+        assertLog( configMgr, LogService.LOG_DEBUG, "Debug Test Message", null );
+        assertLog( configMgr, LogService.LOG_INFO, "Info Test Message", null );
+        assertLog( configMgr, LogService.LOG_WARNING, "Warning Test Message", null );
+        assertLog( configMgr, LogService.LOG_ERROR, "Error Test Message", null );
+
+        setLogLevel( configMgr, Integer.MIN_VALUE );
+        assertLog( configMgr, LogService.LOG_DEBUG, "Debug Test Message", null );
+        assertLog( configMgr, LogService.LOG_INFO, "Info Test Message", null );
+        assertLog( configMgr, LogService.LOG_WARNING, "Warning Test Message", null );
+        assertLog( configMgr, LogService.LOG_ERROR, "Error Test Message", null );
+
+        setLogLevel( configMgr, LogService.LOG_INFO );
+        assertLog( configMgr, LogService.LOG_DEBUG, "Debug Test Message", null );
+        assertLog( configMgr, LogService.LOG_INFO, "Info Test Message", null );
+        assertLog( configMgr, LogService.LOG_WARNING, "Warning Test Message", null );
+        assertLog( configMgr, LogService.LOG_ERROR, "Error Test Message", null );
+
+        setLogLevel( configMgr, LogService.LOG_DEBUG );
+        assertLog( configMgr, LogService.LOG_DEBUG, "Debug Test Message", null );
+        assertLog( configMgr, LogService.LOG_INFO, "Info Test Message", null );
+        assertLog( configMgr, LogService.LOG_WARNING, "Warning Test Message", null );
+        assertLog( configMgr, LogService.LOG_ERROR, "Error Test Message", null );
+
+        setLogLevel( configMgr, Integer.MAX_VALUE );
+        assertLog( configMgr, LogService.LOG_DEBUG, "Debug Test Message", null );
+        assertLog( configMgr, LogService.LOG_INFO, "Info Test Message", null );
+        assertLog( configMgr, LogService.LOG_WARNING, "Warning Test Message", null );
+        assertLog( configMgr, LogService.LOG_ERROR, "Error Test Message", null );
+    }
+
+
+    private void assertNoLog( ConfigurationManager configMgr, int level, String message, Throwable t )
+    {
+        try
+        {
+            configMgr.log( level, message, t );
+            assertTrue( "Expecting no log output", output.size() == 0 );
+        }
+        finally
+        {
+            // clear the output for future data
+            output.reset();
+        }
+    }
+
+
+    private void assertLog( ConfigurationManager configMgr, int level, String message, Throwable t )
+    {
+        try
+        {
+            configMgr.log( level, message, t );
+            assertTrue( "Expecting log output", output.size() > 0 );
+
+            final String expectedLog = MockLogService.toMessageLine( level, message );
+            final String actualLog = new String( output.toByteArray() );
+            assertEquals( "Log Message not correct", expectedLog, actualLog );
+
+        }
+        finally
+        {
+            // clear the output for future data
+            output.reset();
+        }
+    }
+
+
+    private static void setLogLevel( ConfigurationManager configMgr, int level )
+    {
+        final String fieldName = "logLevel";
+        try
+        {
+            Field field = configMgr.getClass().getDeclaredField( fieldName );
+            field.setAccessible( true );
+            field.setInt( configMgr, level );
+        }
+        catch ( Throwable ignore )
+        {
+            ignore.printStackTrace( System.out );
+        }
+    }
+
+
+    private static ConfigurationManager createConfigurationManager( final LogService logService )
+    {
+        ConfigurationManager configMgr = new ConfigurationManager();
+
+        try
+        {
+            Field field = configMgr.getClass().getDeclaredField( "logTracker" );
+            field.setAccessible( true );
+            field.set( configMgr, new ServiceTracker( new MockBundleContext(), "", null )
+            {
+                public Object getService()
+                {
+                    return logService;
+                }
+            } );
+        }
+        catch ( Throwable ignore )
+        {
+            ignore.printStackTrace( System.out );
+        }
+
+        return configMgr;
+    }
+}

Propchange: felix/trunk/configadmin/src/test/java/org/apache/felix/cm/impl/ConfigurationManagerTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: felix/trunk/configadmin/src/test/java/org/apache/felix/cm/impl/ConfigurationManagerTest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url