You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by fm...@apache.org on 2008/04/16 11:33:15 UTC
svn commit: r648644 - in /incubator/sling/trunk/osgi/log: ./
src/main/java/org/apache/sling/osgi/log/
src/main/java/org/apache/sling/osgi/log/slf4j/ src/main/java/org/slf4j/
src/main/java/org/slf4j/impl/ src/main/resources/
src/main/resources/OSGI-INF/...
Author: fmeschbe
Date: Wed Apr 16 02:33:11 2008
New Revision: 648644
URL: http://svn.apache.org/viewvc?rev=648644&view=rev
Log:
SLING-384 Replace LogBack by our own simple implementation of the SLF4J API
Added:
incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/LogManager.java
- copied, changed from r647691, incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/LogbackManager.java
incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/slf4j/
incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/slf4j/SlingLogFileWriter.java
incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/slf4j/SlingLogWriter.java
incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/slf4j/SlingLogger.java
incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/slf4j/SlingLoggerFactory.java
incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/slf4j/SlingLoggerLevel.java
incubator/sling/trunk/osgi/log/src/main/java/org/slf4j/
incubator/sling/trunk/osgi/log/src/main/java/org/slf4j/impl/
incubator/sling/trunk/osgi/log/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
incubator/sling/trunk/osgi/log/src/main/java/org/slf4j/impl/StaticMarkerBinder.java
incubator/sling/trunk/osgi/log/src/test/
incubator/sling/trunk/osgi/log/src/test/java/
incubator/sling/trunk/osgi/log/src/test/java/org/
incubator/sling/trunk/osgi/log/src/test/java/org/apache/
incubator/sling/trunk/osgi/log/src/test/java/org/apache/sling/
incubator/sling/trunk/osgi/log/src/test/java/org/apache/sling/osgi/
incubator/sling/trunk/osgi/log/src/test/java/org/apache/sling/osgi/log/
incubator/sling/trunk/osgi/log/src/test/java/org/apache/sling/osgi/log/slf4j/
incubator/sling/trunk/osgi/log/src/test/java/org/apache/sling/osgi/log/slf4j/SlingLogFileWriterTest.java
incubator/sling/trunk/osgi/log/src/test/java/org/apache/sling/osgi/log/slf4j/SlingLoggerTest.java
Removed:
incubator/sling/trunk/osgi/log/LICENSE.logback
incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/LogbackManager.java
incubator/sling/trunk/osgi/log/src/main/resources/log4j.dtd
incubator/sling/trunk/osgi/log/src/main/resources/log4j.properties
incubator/sling/trunk/osgi/log/src/main/resources/log4j.xml
Modified:
incubator/sling/trunk/osgi/log/pom.xml
incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/Activator.java
incubator/sling/trunk/osgi/log/src/main/resources/OSGI-INF/metatype/metatype.properties
incubator/sling/trunk/osgi/log/src/main/resources/OSGI-INF/metatype/metatype.xml
Modified: incubator/sling/trunk/osgi/log/pom.xml
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/osgi/log/pom.xml?rev=648644&r1=648643&r2=648644&view=diff
==============================================================================
--- incubator/sling/trunk/osgi/log/pom.xml (original)
+++ incubator/sling/trunk/osgi/log/pom.xml Wed Apr 16 02:33:11 2008
@@ -1,21 +1,21 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
- 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.
+ 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
@@ -64,34 +64,22 @@
org.apache.commons.logging;version=1.0.4,
org.apache.log4j;version=1.2.15,
org.slf4j;version=1.4.3,
- org.osgi.service.cm,
- org.osgi.service.log
+ org.osgi.service.cm, org.osgi.service.log
</Export-Package>
<Private-Package>
- !ch.qos.logback.classic.db,
- !ch.qos.logback.core.db,
- !ch.qos.logback.classic.selector.servlet,
- ch.qos.logback.*,
org.apache.commons.logging.impl,
- org.apache.sling.osgi.log, org.slf4j.helpers,
- org.slf4j.impl, org.slf4j.spi
+ org.apache.sling.osgi.log.*,
+ org.slf4j.helpers, org.slf4j.impl,
+ org.slf4j.spi
</Private-Package>
- <DynamicImport-Package>
- javax.jms, javax.mail, javax.mail.internet,
- javax.management, javax.naming,
- javax.xml.parsers, org.codehaus.janino,
- org.xml.sax, org.xml.sax.helpers
- </DynamicImport-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
- <!--
- Core Logging by logback and redirection of commons logging and log4j to SLF4J
- -->
<dependencies>
+ <!-- Redirection of commons logging and log4j to SLF4J -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl104-over-slf4j</artifactId>
@@ -110,20 +98,6 @@
<scope>compile</scope>
<optional>true</optional>
</dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-core</artifactId>
- <version>0.9.8</version>
- <scope>compile</scope>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- <version>0.9.8</version>
- <scope>compile</scope>
- <optional>true</optional>
- </dependency>
<!-- OSGi Libraries not included here -->
<dependency>
@@ -135,6 +109,12 @@
<artifactId>org.osgi.compendium</artifactId>
<scope>compile</scope>
<optional>true</optional>
+ </dependency>
+
+ <!-- testing -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
</dependency>
</dependencies>
</project>
Modified: incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/Activator.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/Activator.java?rev=648644&r1=648643&r2=648644&view=diff
==============================================================================
--- incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/Activator.java (original)
+++ incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/Activator.java Wed Apr 16 02:33:11 2008
@@ -33,19 +33,19 @@
*/
public class Activator implements BundleActivator {
- private LogbackManager logbackManager;
+ private LogManager logManager;
private LogSupport logSupport;
public void start(BundleContext context) throws Exception {
- this.logbackManager = new LogbackManager(context);
+ logManager = new LogManager(context);
- this.logSupport = new LogSupport();
- context.addBundleListener(this.logSupport);
- context.addFrameworkListener(this.logSupport);
- context.addServiceListener(this.logSupport);
+ logSupport = new LogSupport();
+ context.addBundleListener(logSupport);
+ context.addFrameworkListener(logSupport);
+ context.addServiceListener(logSupport);
- LogServiceFactory lsf = new LogServiceFactory(this.logSupport);
+ LogServiceFactory lsf = new LogServiceFactory(logSupport);
Dictionary<String, String> props = new Hashtable<String, String>();
props.put(Constants.SERVICE_PID, lsf.getClass().getName());
props.put(Constants.SERVICE_DESCRIPTION,
@@ -53,7 +53,7 @@
props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
context.registerService(LogService.class.getName(), lsf, props);
- LogReaderServiceFactory lrsf = new LogReaderServiceFactory(this.logSupport);
+ LogReaderServiceFactory lrsf = new LogReaderServiceFactory(logSupport);
props = new Hashtable<String, String>();
props.put(Constants.SERVICE_PID, lrsf.getClass().getName());
props.put(Constants.SERVICE_DESCRIPTION,
@@ -63,7 +63,14 @@
}
public void stop(BundleContext context) throws Exception {
- this.logSupport.shutdown();
- this.logbackManager.shutdown();
+ if (logSupport != null) {
+ logSupport.shutdown();
+ logSupport = null;
+ }
+
+ if (logManager != null) {
+ logManager.shutdown();
+ logManager = null;
+ }
}
}
Copied: incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/LogManager.java (from r647691, incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/LogbackManager.java)
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/LogManager.java?p2=incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/LogManager.java&p1=incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/LogbackManager.java&r1=647691&r2=648644&rev=648644&view=diff
==============================================================================
--- incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/LogbackManager.java (original)
+++ incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/LogManager.java Wed Apr 16 02:33:11 2008
@@ -17,48 +17,37 @@
package org.apache.sling.osgi.log;
import java.io.File;
-import java.io.StringReader;
-import java.net.URL;
+import java.io.IOException;
+import java.text.MessageFormat;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
+import org.apache.sling.osgi.log.slf4j.SlingLogFileWriter;
+import org.apache.sling.osgi.log.slf4j.SlingLogWriter;
+import org.apache.sling.osgi.log.slf4j.SlingLogger;
+import org.apache.sling.osgi.log.slf4j.SlingLoggerFactory;
+import org.apache.sling.osgi.log.slf4j.SlingLoggerLevel;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.cm.ManagedService;
import org.slf4j.LoggerFactory;
-import org.xml.sax.InputSource;
-
-import ch.qos.logback.classic.Level;
-import ch.qos.logback.classic.Logger;
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.PatternLayout;
-import ch.qos.logback.classic.joran.JoranConfigurator;
-import ch.qos.logback.classic.spi.LoggingEvent;
-import ch.qos.logback.core.Appender;
-import ch.qos.logback.core.ConsoleAppender;
-import ch.qos.logback.core.rolling.FixedWindowRollingPolicy;
-import ch.qos.logback.core.rolling.RollingFileAppender;
-import ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy;
/**
- * The <code>LogbackManager</code> manages the loggers used by the LogService
+ * The <code>LogManager</code> manages the loggers used by the LogService
* and the rest of the system.
*/
-public class LogbackManager implements ManagedService {
+public class LogManager implements ManagedService {
/**
- * Initial configuration property specifying whether Logback should be
+ * Initial configuration property specifying whether logging should be
* initialized here or not (value is "org.apache.sling.osgi.log.intialize").
* If this property is missing or set to <code>true</code>, this class
- * will reset and configure Logback. Otherwise, Logback is neither reset nor
+ * will reset and configure logging. Otherwise, logging is neither reset nor
* configured by this class.
- * <p>
- * This property may be used to prevent resetting Logback which might be
- * configured by a container and reused by the Framework.
*/
public static final String LOG_INITIALIZE = "org.apache.sling.osgi.log.intialize";
@@ -74,11 +63,11 @@
public static final String LOG_CONFIG_URL = "org.apache.sling.osgi.log.url";
- public static final String LOG_PATTERN_DEFAULT = "%d{dd.MM.yyyy HH:mm:ss} *%-5p* %c{1}: %m%n";
+ public static final String LOG_PATTERN_DEFAULT = "{0,date,dd.MM.yyyy HH:mm:ss.SSS} *{4}* [{2}] {3} {5}";
public static final int LOG_FILE_NUMBER_DEFAULT = 5;
- public static final String LOG_FILE_SIZE_DEFAULT = "10MB";
+ public static final String LOG_FILE_SIZE_DEFAULT = "10M";
/**
* default log category - set during init()
@@ -87,59 +76,58 @@
private File rootDir;
- private ServiceRegistration logbackConfigurable;
+ private ServiceRegistration loggingConfigurable;
- /* package */LogbackManager(final BundleContext context) {
+ LogManager(final BundleContext context) {
// the base for relative path names
String root = context.getProperty("sling.home");
- this.rootDir = new File((root == null) ? "" : root).getAbsoluteFile();
+ rootDir = new File((root == null) ? "" : root).getAbsoluteFile();
// set initial default configuration
- this.configureLogback(new ConfigProperties() {
+ configureLogging(new ConfigProperties() {
public String getProperty(String name) {
return context.getProperty(name);
}
});
// get our own logger
- this.log = LoggerFactory.getLogger(LogServiceFactory.class);
-
- this.log.info("LogbackManager: Logging set up from context");
+ log = LoggerFactory.getLogger(LogServiceFactory.class);
+ log.info("LogManager: Logging set up from context");
// register for official configuration now
Dictionary<String, String> props = new Hashtable<String, String>();
- props.put(Constants.SERVICE_PID, LogbackManager.class.getName());
+ props.put(Constants.SERVICE_PID, LogManager.class.getName());
props.put(Constants.SERVICE_DESCRIPTION,
- "LogbackManager Configuration Admin support");
+ "LogManager Configuration Admin support");
props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
- this.logbackConfigurable = context.registerService(
+ loggingConfigurable = context.registerService(
ManagedService.class.getName(), this, props);
}
- /* package */void shutdown() {
- if (this.logbackConfigurable != null) {
- this.logbackConfigurable.unregister();
- this.logbackConfigurable = null;
+ void shutdown() {
+ if (loggingConfigurable != null) {
+ loggingConfigurable.unregister();
+ loggingConfigurable = null;
}
// shutdown the log manager
- LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
- loggerContext.shutdownAndReset();
+ SlingLoggerFactory loggerFactory = SlingLoggerFactory.getInstance();
+ loggerFactory.close();
}
// ---------- ManagedService interface -------------------------------------
/*
* (non-Javadoc)
- *
+ *
* @see org.osgi.service.cm.ManagedService#updated(java.util.Dictionary)
*/
@SuppressWarnings("unchecked")
public void updated(final Dictionary properties) { // unchecked
if (properties != null) {
- this.configureLogback(new ConfigProperties() {
+ configureLogging(new ConfigProperties() {
public String getProperty(String name) {
final Object obj = properties.get(name);
return (obj == null) ? null : obj.toString();
@@ -153,52 +141,48 @@
/**
* Start this service. Nothing to be done here.
*/
- public void reconfigure(URL configLocation) throws Exception {
- // reset logging first
- LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
- loggerContext.shutdownAndReset();
-
- // get the configurator
- JoranConfigurator configuration = new JoranConfigurator();
- configuration.setContext(loggerContext);
-
- // check for log configuration URL and try that first
- try {
- configuration.doConfigure(configLocation);
- } catch (Throwable t) {
- this.log.error("reconfigure: Cannot configure from {}",
- configLocation);
- // well then, fall back to simple configuration
- }
-
- this.log.info("reconfigure: Logging reconfigured from ", configLocation);
- }
-
- void reconfigure(String data) {
- LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
- loggerContext.shutdownAndReset();
-
- // get the configurator
- JoranConfigurator configuration = new JoranConfigurator();
- configuration.setContext(loggerContext);
-
- InputSource source = new InputSource();
- source.setCharacterStream(new StringReader(data));
- }
-
+ // public void reconfigure(URL configLocation) throws Exception {
+ // // reset logging first
+ // LoggerContext loggerContext = (LoggerContext)
+ // LoggerFactory.getILoggerFactory();
+ // loggerContext.shutdownAndReset();
+ //
+ // // get the configurator
+ // JoranConfigurator configuration = new JoranConfigurator();
+ // configuration.setContext(loggerContext);
+ //
+ // // check for log configuration URL and try that first
+ // try {
+ // configuration.doConfigure(configLocation);
+ // } catch (Throwable t) {
+ // this.log.error("reconfigure: Cannot configure from {}",
+ // configLocation);
+ // // well then, fall back to simple configuration
+ // }
+ //
+ // this.log.info("reconfigure: Logging reconfigured from ", configLocation);
+ // }
+ // void reconfigure(String data) {
+ // LoggerContext loggerContext = (LoggerContext)
+ // LoggerFactory.getILoggerFactory();
+ // loggerContext.shutdownAndReset();
+ //
+ // // get the configurator
+ // JoranConfigurator configuration = new JoranConfigurator();
+ // configuration.setContext(loggerContext);
+ //
+ // InputSource source = new InputSource();
+ // source.setCharacterStream(new StringReader(data));
+ // }
public String[] getLoggers() {
Set<String> loggerSet = new TreeSet<String>();
- LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
- List<Logger> loggers = loggerContext.getLoggerList();
- for (Logger logger : loggers) {
- loggerSet.add(logger.getName() + ", level=" + logger.getLevel());
+ SlingLoggerFactory loggerFactory = SlingLoggerFactory.getInstance();
+ List<SlingLogger> loggers = loggerFactory.getLoggerList();
+ for (SlingLogger logger : loggers) {
+ loggerSet.add(logger.getName() + ", level=" + logger.getLogLevel());
}
- // prepend the root logger
- Logger root = loggerContext.getLogger(LoggerContext.ROOT_NAME);
- loggerSet.add("__root__, level=" + root.getLevel());
-
return loggerSet.toArray(new String[loggerSet.size()]);
}
@@ -208,13 +192,12 @@
return "Logger name required to set logging level";
}
- LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
- Logger log = loggerContext.getLogger(logger);
+ SlingLoggerFactory loggerFactory = SlingLoggerFactory.getInstance();
+ SlingLogger log = loggerFactory.getSlingLogger(logger);
if (log != null) {
- Level level = Level.toLevel(levelName, log.getLevel());
- log.setLevel(level);
+ log.setLogLevel(levelName);
- return "Set level '" + level + "' on logger '" + log.getName()
+ return "Set level '" + levelName + "' on logger '" + log.getName()
+ "'";
}
@@ -223,17 +206,17 @@
}
/**
- * Configures Logback from the given properties. This is intended as an
- * initial configuration. <p/> Sets up the initial Logback properties for
+ * Configures logging from the given properties. This is intended as an
+ * initial configuration. <p/> Sets up the initial logging properties for
* the logging support until the real logging configuration file can be read
* from the ContentBus.
- *
+ *
* @param properties The <code>Properties</code> containing the initial
* configuration.
* @throws NullPointerException if <code>properties</code> is
* <code>null</code>.
*/
- protected void configureLogback(ConfigProperties context) {
+ protected void configureLogging(ConfigProperties context) {
// check whether we should configure logging at all
String initialize = context.getProperty(LOG_INITIALIZE);
@@ -242,39 +225,21 @@
return;
}
- // reset logging first
- LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
- loggerContext.shutdownAndReset();
-
- // get the configurator
- JoranConfigurator configuration = new JoranConfigurator();
- configuration.setContext(loggerContext);
-
// check for log configuration URL and try that first
- String logConfig = context.getProperty(LOG_CONFIG_URL);
- if (logConfig != null && logConfig.length() > 0) {
- try {
- URL logConfigURL = new URL(logConfig);
- configuration.doConfigure(logConfigURL);
- return;
- } catch (Throwable t) {
- // well then, fall back to simple configuration
- }
- }
-
- // set the log appender message pattern
- String pattern = context.getProperty(LOG_PATTERN);
- if (pattern == null || pattern.length() == 0) {
- pattern = LOG_PATTERN_DEFAULT;
- }
- PatternLayout pl = new PatternLayout();
- pl.setPattern(pattern);
- pl.setContext(loggerContext);
- pl.start();
+ // String logConfig = context.getProperty(LOG_CONFIG_URL);
+ // if (logConfig != null && logConfig.length() > 0) {
+ // try {
+ // URL logConfigURL = new URL(logConfig);
+ // configuration.doConfigure(logConfigURL);
+ // return;
+ // } catch (Throwable t) {
+ // // well then, fall back to simple configuration
+ // }
+ // }
// if a log file is defined, use the file appender
String logFileName = context.getProperty(LOG_FILE);
- Appender<LoggingEvent> appender;
+ SlingLogWriter output;
if (logFileName != null && logFileName.length() > 0) {
// ensure proper separator in the path
@@ -283,7 +248,7 @@
// ensure absolute path
File logFile = new File(logFileName);
if (!logFile.isAbsolute()) {
- logFile = new File(this.rootDir, logFileName);
+ logFile = new File(rootDir, logFileName);
logFileName = logFile.getAbsolutePath();
}
@@ -307,64 +272,51 @@
fileNum = LOG_FILE_NUMBER_DEFAULT;
}
- // keep the number old log files
- FixedWindowRollingPolicy rolling = new FixedWindowRollingPolicy();
- rolling.setFileNamePattern(logFileName + ".%i");
- rolling.setMinIndex(0);
- rolling.setMaxIndex(fileNum - 1);
- rolling.setContext(loggerContext);
-
// get the log file size
String fileSize = context.getProperty(LOG_FILE_SIZE);
if (fileSize == null || fileSize.length() == 0) {
fileSize = LOG_FILE_SIZE_DEFAULT;
}
- // switch log file after 1MB
- SizeBasedTriggeringPolicy trigger = new SizeBasedTriggeringPolicy();
- trigger.setMaxFileSize(fileSize);
- trigger.setContext(loggerContext);
-
- // define the default appender
- RollingFileAppender<LoggingEvent> fa = new RollingFileAppender<LoggingEvent>();
- fa.setFile(logFileName);
- fa.setAppend(true);
- fa.setRollingPolicy(rolling);
- fa.setTriggeringPolicy(trigger);
-
- // link the roller to the file appender
- rolling.setParent(fa);
- rolling.start();
- trigger.start();
-
- appender = fa;
+ try {
+ output = new SlingLogFileWriter(logFileName, fileNum, fileSize);
+ } catch (IOException ioe) {
+ SlingLoggerFactory.internalFailure("Cannot creat log file "
+ + logFileName, ioe);
+ SlingLoggerFactory.internalFailure("Logging to the console",
+ null);
+ output = new SlingLogWriter();
+ }
} else {
// fall back to console if no log file defined
- appender = new ConsoleAppender<LoggingEvent>();
+ output = new SlingLogWriter();
}
- // finalize the appender setup
- appender.setContext(loggerContext);
- appender.setLayout(pl);
- appender.start();
-
// check for the log level setting in the web app properties
String logLevel = context.getProperty(LOG_LEVEL);
+ if (logLevel == null || logLevel.length() == 0) {
+ logLevel = SlingLoggerLevel.INFO.toString();
+ } else {
+ logLevel = logLevel.toUpperCase();
+ }
- // add the appender for the root logger
- Logger rootLogger = loggerContext.getLogger(LoggerContext.ROOT_NAME);
- rootLogger.addAppender(appender);
- rootLogger.setLevel(Level.toLevel(logLevel, Level.WARN));
-
- // do not go up the line if root is the prefixed-logger, otherwise if
- // root is the real root, this has no effect
- rootLogger.setAdditive(false);
+ // set the log appender message pattern
+ String messageFormatString = context.getProperty(LOG_PATTERN);
+ if (messageFormatString == null || messageFormatString.length() == 0) {
+ messageFormatString = LOG_PATTERN_DEFAULT;
+ }
+ MessageFormat messageFormat = new MessageFormat(messageFormatString);
+
+ // configure the logger factory now from the setup
+ SlingLoggerFactory loggerFactory = SlingLoggerFactory.getInstance();
+ loggerFactory.configure(logLevel, output, messageFormat);
}
protected static interface ConfigProperties {
String getProperty(String name);
}
+
}
Added: incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/slf4j/SlingLogFileWriter.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/slf4j/SlingLogFileWriter.java?rev=648644&view=auto
==============================================================================
--- incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/slf4j/SlingLogFileWriter.java (added)
+++ incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/slf4j/SlingLogFileWriter.java Wed Apr 16 02:33:11 2008
@@ -0,0 +1,168 @@
+/*
+ * 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.sling.osgi.log.slf4j;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+
+public class SlingLogFileWriter extends SlingLogWriter {
+
+ private static final long FACTOR_KB = 1024;
+ private static final long FACTOR_MB = 1024 * FACTOR_KB;
+ private static final long FACTOR_GB = 1024 * FACTOR_MB;
+ private static final long DEFAULT_MAX_SIZE = 10 * FACTOR_GB;
+
+ private final File file;
+
+ private final String path;
+
+ private final long maxSize;
+
+ private final int maxNum;
+
+ public SlingLogFileWriter(String logFileName, int fileNum, String fileSize) throws IOException {
+ this(logFileName, fileNum, convertMaxSizeSpec(fileSize));
+ }
+
+ public SlingLogFileWriter(String logFileName, int fileNum, long fileSize) throws IOException {
+
+ // make sure the file is absolute and derive the path from there
+ File file = new File(logFileName);
+ if (!file.isAbsolute()) {
+ file = file.getAbsoluteFile();
+ }
+
+ this.path = file.getAbsolutePath();
+ this.file = file;
+
+ this.maxNum = fileNum;
+ this.maxSize = fileSize;
+
+ setDelegatee(createFile());
+ }
+
+ @Override
+ public void flush() throws IOException {
+ super.flush();
+
+ checkRotate();
+ }
+
+ private Writer createFile() throws IOException {
+ // ensure parent path of the file to create
+ file.getParentFile().mkdirs();
+
+ // open the file in append mode to not overwrite an existing
+ // log file from a previous instance running
+ return new OutputStreamWriter(new FileOutputStream(file, true));
+ }
+
+ private void checkRotate() throws IOException {
+ if (file.length() > maxSize) {
+ synchronized (lock) {
+
+ getDelegatee().close();
+
+ if (maxNum >= 0) {
+
+ // remove oldest file
+ File dstFile = new File(path + "." + maxNum);
+ if (dstFile.exists()) {
+ dstFile.delete();
+ }
+
+ // rename next files
+ for (int i = maxNum - 1; i >= 0; i--) {
+ File srcFile = new File(path + "." + i);
+ if (srcFile.exists()) {
+ srcFile.renameTo(dstFile);
+ }
+ dstFile = srcFile;
+ }
+
+ // rename youngest file
+ file.renameTo(dstFile);
+
+ } else {
+
+ // just remove the old file if we don't keep backups
+ file.delete();
+
+ }
+
+ // create new file
+ setDelegatee(createFile());
+ }
+ }
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public long getMaxSize() {
+ return maxSize;
+ }
+
+ public static long convertMaxSizeSpec(String maxSize) {
+ long factor;
+ int len = maxSize.length() - 1;
+
+ maxSize = maxSize.toUpperCase();
+
+ if (maxSize.endsWith("G")) {
+ factor = FACTOR_GB;
+ } else if (maxSize.endsWith("GB")) {
+ factor = FACTOR_GB;
+ len--;
+ } else if (maxSize.endsWith("M")) {
+ factor = FACTOR_MB;
+ } else if (maxSize.endsWith("MB")) {
+ factor = FACTOR_MB;
+ len--;
+ } else if (maxSize.endsWith("K")) {
+ factor = FACTOR_KB;
+ } else if (maxSize.endsWith("KB")) {
+ factor = FACTOR_KB;
+ len--;
+ } else {
+ factor = 1;
+ len = -1;
+ }
+
+ if (len > 0) {
+ maxSize = maxSize.substring(0, len);
+ }
+
+ try {
+ return factor * Long.parseLong(maxSize);
+ } catch (NumberFormatException nfe) {
+ return 10 * 1024 * 1024;
+ }
+ }
+
+ public int getMaxNum() {
+ return maxNum;
+ }
+
+}
Added: incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/slf4j/SlingLogWriter.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/slf4j/SlingLogWriter.java?rev=648644&view=auto
==============================================================================
--- incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/slf4j/SlingLogWriter.java (added)
+++ incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/slf4j/SlingLogWriter.java Wed Apr 16 02:33:11 2008
@@ -0,0 +1,128 @@
+/*
+ * 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.sling.osgi.log.slf4j;
+
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+
+public class SlingLogWriter extends Writer {
+
+ private String lineSeparator;
+
+ private Writer delegatee;
+
+ protected final Object lock = new Object();
+
+ public SlingLogWriter() {
+ delegatee = new OutputStreamWriter(System.out) {
+ @Override
+ public void close() {
+ // not really !!
+ }
+ };
+
+ lineSeparator = System.getProperty("line.separator");
+ }
+
+ protected void setDelegatee(Writer delegatee) {
+ synchronized (lock) {
+ this.delegatee = delegatee;
+ }
+ }
+
+ protected Writer getDelegatee() {
+ synchronized (lock) {
+ return delegatee;
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ synchronized (lock) {
+ if (delegatee != null) {
+ flush();
+
+ delegatee.close();
+ delegatee = null;
+ }
+ }
+ }
+
+ @Override
+ public void flush() throws IOException {
+ synchronized (lock) {
+ if (delegatee != null) {
+ delegatee.flush();
+ }
+ }
+ }
+
+ @Override
+ public void write(int c) throws IOException {
+ synchronized (lock) {
+ if (delegatee != null) {
+ delegatee.write(c);
+ }
+ }
+ }
+
+ @Override
+ public void write(char[] cbuf) throws IOException {
+ synchronized (lock) {
+ if (delegatee != null) {
+ delegatee.write(cbuf);
+ }
+ }
+ }
+
+ @Override
+ public void write(char[] cbuf, int off, int len) throws IOException {
+ synchronized (lock) {
+ if (delegatee != null) {
+ delegatee.write(cbuf, off, len);
+ }
+ }
+ }
+
+ @Override
+ public void write(String str) throws IOException {
+ synchronized (lock) {
+ if (delegatee != null) {
+ delegatee.write(str);
+ }
+ }
+ }
+
+ @Override
+ public void write(String str, int off, int len) throws IOException {
+ synchronized (lock) {
+ if (delegatee != null) {
+ delegatee.write(str, off, len);
+ }
+ }
+ }
+
+ public void writeln() throws IOException {
+ synchronized (lock) {
+ write(lineSeparator);
+ flush();
+ }
+ }
+}
Added: incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/slf4j/SlingLogger.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/slf4j/SlingLogger.java?rev=648644&view=auto
==============================================================================
--- incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/slf4j/SlingLogger.java (added)
+++ incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/slf4j/SlingLogger.java Wed Apr 16 02:33:11 2008
@@ -0,0 +1,515 @@
+/*
+ * 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.sling.osgi.log.slf4j;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.text.FieldPosition;
+import java.text.MessageFormat;
+import java.util.Date;
+
+import org.slf4j.Logger;
+import org.slf4j.Marker;
+import org.slf4j.helpers.MessageFormatter;
+
+public class SlingLogger implements Logger {
+
+ private final String name;
+
+ private SlingLoggerLevel level;
+
+ private SlingLogWriter output;
+
+ private MessageFormat format;
+
+ public SlingLogger(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Configures this logger with the given log level, output and message
+ * format. None of these is allowed to be <code>null</code>.
+ */
+ void configure(SlingLoggerLevel level, SlingLogWriter output,
+ MessageFormat messageFormat) {
+ this.level = level;
+ this.output = output;
+ this.format = messageFormat;
+ }
+
+ // ---------- Actual Loger Entry writing -----------------------------------
+
+ private void log(Marker marker, SlingLoggerLevel level, String msg,
+ Throwable t) {
+ StringWriter writer = new StringWriter();
+
+ // create the formatted log line; use a local copy because the field
+ // may be exchanged while we are trying to use it
+ MessageFormat myFormat = format;
+ synchronized (myFormat) {
+ myFormat.format(new Object[] { new Date(), marker,
+ Thread.currentThread().getName(), getName(), level.toString(),
+ msg }, writer.getBuffer(), new FieldPosition(0));
+ }
+
+ // marker indicating whether a line terminator is to be written after
+ // the message: If a throwable is given, the stacktrace generator
+ // writes a final line terminator and hence we do need to do it
+ // ourselves
+ boolean needsEOL = true;
+
+ // append stacktrace if throwable is not null
+ if (t != null) {
+ writer.write(' ');
+ PrintWriter pw = new PrintWriter(writer);
+ t.printStackTrace(pw);
+ pw.flush();
+
+ // just flush the output, no EOL needed
+ needsEOL = false;
+ }
+
+ // use a local copy because the field may be exchanged while we are
+ // trying to use it
+ SlingLogWriter myOutput = output;
+ synchronized (myOutput) {
+ String message = writer.toString();
+ try {
+ myOutput.write(message);
+
+ // write line termination or flush, whatever is needed
+ if (needsEOL) {
+ myOutput.writeln();
+ } else {
+ myOutput.flush();
+ }
+
+ } catch (IOException ioe) {
+ SlingLoggerFactory.internalFailure("Failed logging message: " + message, ioe);
+ }
+ }
+ }
+
+ // ---------- Log Level support --------------------------------------------
+
+ public void setLogLevel(String levelString ) {
+ try {
+ // ensure upper case level name
+ levelString = levelString.toUpperCase();
+
+ // try to convert to a SlingLoggerLevel instance,
+ // throws if the string is invalid
+ SlingLoggerLevel level = SlingLoggerLevel.valueOf(levelString);
+
+ // finally set the level
+ this.setLogLevel(level);
+ } catch (Exception e) {
+ warn("Cannot set loglevel to " + level, e);
+ }
+ }
+
+ public void setLogLevel(SlingLoggerLevel level) {
+ this.level = level;
+ }
+
+ public SlingLoggerLevel getLogLevel() {
+ return level;
+ }
+
+ private boolean isLevel(SlingLoggerLevel reference) {
+ return level.compareTo(reference) <= 0;
+ }
+
+ // ---------- Logger interface ---------------------------------------------
+
+ public String getName() {
+ return name;
+ }
+
+ public void trace(String msg) {
+ if (isTraceEnabled()) {
+ log(null, SlingLoggerLevel.TRACE, msg, null);
+ }
+ }
+
+ public void trace(String format, Object arg) {
+ if (isTraceEnabled()) {
+ log(null, SlingLoggerLevel.TRACE, MessageFormatter.format(format,
+ arg), null);
+ }
+ }
+
+ public void trace(String format, Object[] argArray) {
+ if (isTraceEnabled()) {
+ log(null, SlingLoggerLevel.TRACE, MessageFormatter.arrayFormat(
+ format, argArray), null);
+ }
+ }
+
+ public void trace(String msg, Throwable t) {
+ if (isTraceEnabled()) {
+ log(null, SlingLoggerLevel.TRACE, msg, t);
+ }
+ }
+
+ public void trace(String format, Object arg1, Object arg2) {
+ if (isTraceEnabled()) {
+ log(null, SlingLoggerLevel.TRACE, MessageFormatter.format(format,
+ arg1, arg2), null);
+ }
+ }
+
+ public void trace(Marker marker, String msg) {
+ if (isTraceEnabled(marker)) {
+ log(marker, SlingLoggerLevel.TRACE, msg, null);
+ }
+ }
+
+ public void trace(Marker marker, String format, Object arg) {
+ if (isTraceEnabled(marker)) {
+ log(marker, SlingLoggerLevel.TRACE, MessageFormatter.format(format,
+ arg), null);
+ }
+ }
+
+ public void trace(Marker marker, String format, Object[] argArray) {
+ if (isTraceEnabled(marker)) {
+ log(marker, SlingLoggerLevel.TRACE, MessageFormatter.arrayFormat(
+ format, argArray), null);
+ }
+ }
+
+ public void trace(Marker marker, String msg, Throwable t) {
+ if (isTraceEnabled(marker)) {
+ log(marker, SlingLoggerLevel.TRACE, msg, t);
+ }
+ }
+
+ public void trace(Marker marker, String format, Object arg1, Object arg2) {
+ if (isTraceEnabled(marker)) {
+ log(marker, SlingLoggerLevel.TRACE, MessageFormatter.format(format,
+ arg1, arg2), null);
+ }
+ }
+
+ public void debug(String msg) {
+ if (isDebugEnabled()) {
+ log(null, SlingLoggerLevel.DEBUG, msg, null);
+ }
+ }
+
+ public void debug(String format, Object arg) {
+ if (isDebugEnabled()) {
+ log(null, SlingLoggerLevel.DEBUG, MessageFormatter.format(format,
+ arg), null);
+ }
+ }
+
+ public void debug(String format, Object[] argArray) {
+ if (isDebugEnabled()) {
+ log(null, SlingLoggerLevel.DEBUG, MessageFormatter.arrayFormat(
+ format, argArray), null);
+ }
+ }
+
+ public void debug(String msg, Throwable t) {
+ if (isDebugEnabled()) {
+ log(null, SlingLoggerLevel.DEBUG, msg, t);
+ }
+ }
+
+ public void debug(String format, Object arg1, Object arg2) {
+ if (isDebugEnabled()) {
+ log(null, SlingLoggerLevel.DEBUG, MessageFormatter.format(format,
+ arg1, arg2), null);
+ }
+ }
+
+ public void debug(Marker marker, String msg) {
+ if (isDebugEnabled(marker)) {
+ log(marker, SlingLoggerLevel.DEBUG, msg, null);
+ }
+ }
+
+ public void debug(Marker marker, String format, Object arg) {
+ if (isDebugEnabled(marker)) {
+ log(marker, SlingLoggerLevel.DEBUG, MessageFormatter.format(format,
+ arg), null);
+ }
+ }
+
+ public void debug(Marker marker, String format, Object[] argArray) {
+ if (isDebugEnabled(marker)) {
+ log(marker, SlingLoggerLevel.DEBUG, MessageFormatter.arrayFormat(
+ format, argArray), null);
+ }
+ }
+
+ public void debug(Marker marker, String msg, Throwable t) {
+ if (isDebugEnabled(marker)) {
+ log(marker, SlingLoggerLevel.DEBUG, msg, t);
+ }
+ }
+
+ public void debug(Marker marker, String format, Object arg1, Object arg2) {
+ if (isDebugEnabled(marker)) {
+ log(marker, SlingLoggerLevel.DEBUG, MessageFormatter.format(format,
+ arg1, arg2), null);
+ }
+ }
+
+ public void info(String msg) {
+ if (isInfoEnabled()) {
+ log(null, SlingLoggerLevel.INFO, msg, null);
+ }
+ }
+
+ public void info(String format, Object arg) {
+ if (isInfoEnabled()) {
+ log(null, SlingLoggerLevel.INFO, MessageFormatter.format(format,
+ arg), null);
+ }
+ }
+
+ public void info(String format, Object[] argArray) {
+ if (isInfoEnabled()) {
+ log(null, SlingLoggerLevel.INFO, MessageFormatter.arrayFormat(
+ format, argArray), null);
+ }
+ }
+
+ public void info(String msg, Throwable t) {
+ if (isInfoEnabled()) {
+ log(null, SlingLoggerLevel.INFO, msg, t);
+ }
+ }
+
+ public void info(String format, Object arg1, Object arg2) {
+ if (isInfoEnabled()) {
+ log(null, SlingLoggerLevel.INFO, MessageFormatter.format(format,
+ arg1, arg2), null);
+ }
+ }
+
+ public void info(Marker marker, String msg) {
+ if (isInfoEnabled(marker)) {
+ log(marker, SlingLoggerLevel.INFO, msg, null);
+ }
+ }
+
+ public void info(Marker marker, String format, Object arg) {
+ if (isInfoEnabled(marker)) {
+ log(marker, SlingLoggerLevel.INFO, MessageFormatter.format(format,
+ arg), null);
+ }
+ }
+
+ public void info(Marker marker, String format, Object[] argArray) {
+ if (isInfoEnabled(marker)) {
+ log(marker, SlingLoggerLevel.INFO, MessageFormatter.arrayFormat(
+ format, argArray), null);
+ }
+ }
+
+ public void info(Marker marker, String msg, Throwable t) {
+ if (isInfoEnabled(marker)) {
+ log(marker, SlingLoggerLevel.INFO, msg, t);
+ }
+ }
+
+ public void info(Marker marker, String format, Object arg1, Object arg2) {
+ if (isInfoEnabled(marker)) {
+ log(marker, SlingLoggerLevel.INFO, MessageFormatter.format(format,
+ arg1, arg2), null);
+ }
+ }
+
+ public void warn(String msg) {
+ if (isWarnEnabled()) {
+ log(null, SlingLoggerLevel.WARN, msg, null);
+ }
+ }
+
+ public void warn(String format, Object arg) {
+ if (isWarnEnabled()) {
+ log(null, SlingLoggerLevel.WARN, MessageFormatter.format(format,
+ arg), null);
+ }
+ }
+
+ public void warn(String format, Object[] argArray) {
+ if (isWarnEnabled()) {
+ log(null, SlingLoggerLevel.WARN, MessageFormatter.arrayFormat(
+ format, argArray), null);
+ }
+ }
+
+ public void warn(String msg, Throwable t) {
+ if (isWarnEnabled()) {
+ log(null, SlingLoggerLevel.WARN, msg, t);
+ }
+ }
+
+ public void warn(String format, Object arg1, Object arg2) {
+ if (isWarnEnabled()) {
+ log(null, SlingLoggerLevel.WARN, MessageFormatter.format(format,
+ arg1, arg2), null);
+ }
+ }
+
+ public void warn(Marker marker, String msg) {
+ if (isWarnEnabled(marker)) {
+ log(marker, SlingLoggerLevel.WARN, msg, null);
+ }
+ }
+
+ public void warn(Marker marker, String format, Object arg) {
+ if (isWarnEnabled(marker)) {
+ log(marker, SlingLoggerLevel.WARN, MessageFormatter.format(format,
+ arg), null);
+ }
+ }
+
+ public void warn(Marker marker, String format, Object[] argArray) {
+ if (isWarnEnabled(marker)) {
+ log(marker, SlingLoggerLevel.WARN, MessageFormatter.arrayFormat(
+ format, argArray), null);
+ }
+ }
+
+ public void warn(Marker marker, String msg, Throwable t) {
+ if (isWarnEnabled(marker)) {
+ log(marker, SlingLoggerLevel.WARN, msg, t);
+ }
+ }
+
+ public void warn(Marker marker, String format, Object arg1, Object arg2) {
+ if (isWarnEnabled(marker)) {
+ log(marker, SlingLoggerLevel.WARN, MessageFormatter.format(format,
+ arg1, arg2), null);
+ }
+ }
+
+ public void error(String msg) {
+ if (isErrorEnabled()) {
+ log(null, SlingLoggerLevel.ERROR, msg, null);
+ }
+ }
+
+ public void error(String format, Object arg) {
+ if (isErrorEnabled()) {
+ log(null, SlingLoggerLevel.ERROR, MessageFormatter.format(format,
+ arg), null);
+ }
+ }
+
+ public void error(String format, Object[] argArray) {
+ if (isErrorEnabled()) {
+ log(null, SlingLoggerLevel.ERROR, MessageFormatter.arrayFormat(
+ format, argArray), null);
+ }
+ }
+
+ public void error(String msg, Throwable t) {
+ if (isErrorEnabled()) {
+ log(null, SlingLoggerLevel.ERROR, msg, t);
+ }
+ }
+
+ public void error(String format, Object arg1, Object arg2) {
+ if (isErrorEnabled()) {
+ log(null, SlingLoggerLevel.ERROR, MessageFormatter.format(format,
+ arg1, arg2), null);
+ }
+ }
+
+ public void error(Marker marker, String msg) {
+ if (isErrorEnabled(marker)) {
+ log(marker, SlingLoggerLevel.ERROR, msg, null);
+ }
+ }
+
+ public void error(Marker marker, String format, Object arg) {
+ if (isErrorEnabled(marker)) {
+ log(marker, SlingLoggerLevel.ERROR, MessageFormatter.format(format,
+ arg), null);
+ }
+ }
+
+ public void error(Marker marker, String format, Object[] argArray) {
+ if (isErrorEnabled(marker)) {
+ log(marker, SlingLoggerLevel.ERROR, MessageFormatter.arrayFormat(
+ format, argArray), null);
+ }
+ }
+
+ public void error(Marker marker, String msg, Throwable t) {
+ if (isErrorEnabled(marker)) {
+ log(marker, SlingLoggerLevel.ERROR, msg, t);
+ }
+ }
+
+ public void error(Marker marker, String format, Object arg1, Object arg2) {
+ if (isErrorEnabled(marker)) {
+ log(marker, SlingLoggerLevel.ERROR, MessageFormatter.format(format,
+ arg1, arg2), null);
+ }
+ }
+
+ public boolean isTraceEnabled() {
+ return isLevel(SlingLoggerLevel.TRACE);
+ }
+
+ public boolean isTraceEnabled(Marker marker) {
+ return isLevel(SlingLoggerLevel.TRACE);
+ }
+
+ public boolean isDebugEnabled() {
+ return isLevel(SlingLoggerLevel.DEBUG);
+ }
+
+ public boolean isDebugEnabled(Marker marker) {
+ return isLevel(SlingLoggerLevel.DEBUG);
+ }
+
+ public boolean isInfoEnabled() {
+ return isLevel(SlingLoggerLevel.INFO);
+ }
+
+ public boolean isInfoEnabled(Marker marker) {
+ return isLevel(SlingLoggerLevel.INFO);
+ }
+
+ public boolean isWarnEnabled() {
+ return isLevel(SlingLoggerLevel.WARN);
+ }
+
+ public boolean isWarnEnabled(Marker marker) {
+ return isLevel(SlingLoggerLevel.WARN);
+ }
+
+ public boolean isErrorEnabled() {
+ return isLevel(SlingLoggerLevel.ERROR);
+ }
+
+ public boolean isErrorEnabled(Marker marker) {
+ return isLevel(SlingLoggerLevel.ERROR);
+ }
+}
Added: incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/slf4j/SlingLoggerFactory.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/slf4j/SlingLoggerFactory.java?rev=648644&view=auto
==============================================================================
--- incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/slf4j/SlingLoggerFactory.java (added)
+++ incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/slf4j/SlingLoggerFactory.java Wed Apr 16 02:33:11 2008
@@ -0,0 +1,171 @@
+/*
+ * 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.sling.osgi.log.slf4j;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.sling.osgi.log.LogManager;
+import org.slf4j.ILoggerFactory;
+import org.slf4j.Logger;
+
+public final class SlingLoggerFactory implements ILoggerFactory {
+
+ private static final SlingLoggerFactory instance = new SlingLoggerFactory();
+
+ private final Map<String, SlingLogger> loggers = new HashMap<String, SlingLogger>();
+
+ /**
+ * The logger level currently configured to this factory. Before
+ * configuration, this is set to {@link SlingLoggerLevel#INFO}.
+ */
+ private SlingLoggerLevel level = SlingLoggerLevel.INFO;
+
+ /**
+ * The currently active log output. Before configuration, logging output is
+ * set to go to the console.
+ */
+ private SlingLogWriter output = new SlingLogWriter();
+
+ /**
+ * The currently active message format to generate the log message entries.
+ * Before configuration this is set to
+ * {@value LogManager#LOG_PATTERN_DEFAULT}.
+ */
+ private MessageFormat messageFormat = new MessageFormat(
+ LogManager.LOG_PATTERN_DEFAULT);
+
+ /**
+ * Returns the singleton instance of this class.
+ */
+ public static SlingLoggerFactory getInstance() {
+ return instance;
+ }
+
+ /**
+ * Logs a message an optional stack trace to error output. This method
+ * is used by the logging system in case of errors writing to the
+ * correct logging output.
+ */
+ public static void internalFailure(String message, Throwable t) {
+ System.err.println(message);
+ if (t != null) {
+ t.printStackTrace(System.err);
+ }
+ }
+
+ // private constructor to prevent instantiation. This is a singleton class
+ private SlingLoggerFactory() {
+ }
+
+ // ---------- ILoggerFactory interface -------------------------------------
+
+ /**
+ * Returns a logger for the given name. If such a logger already exists the
+ * same logger is returned. Otherwise a new instance is created and
+ * configured with the current logging level, output and message format.
+ *
+ * @param name The name of the logger to return
+ */
+ public Logger getLogger(String name) {
+ synchronized (loggers) {
+ SlingLogger logger = loggers.get(name);
+ if (logger == null) {
+ logger = createLogger(name);
+ loggers.put(name, logger);
+ }
+ return logger;
+ }
+ }
+
+ // ---------- Sling specific ILoggerFactory stuff --------------------------
+
+ /**
+ * Configures this factory and all existing loggers with the new log level,
+ * output and message format.
+ *
+ * @param logLevel The log level to be set. If this is not a valid
+ * {@link SlingLoggerLevel} value, the default <code>INFO</code>
+ * is assumed.
+ * @param output The new ouptut channel
+ * @param messageFormat The new message format
+ */
+ public void configure(String logLevel, SlingLogWriter output,
+ MessageFormat messageFormat) {
+
+ // close the old output if existing
+ if (this.output != null) {
+ try {
+ this.output.close();
+ } catch (IOException ioe) {
+ internalFailure("Problem closing old output", ioe);
+ }
+ }
+
+ try {
+ this.level = SlingLoggerLevel.valueOf(logLevel);
+ } catch (Exception e) {
+ this.level = SlingLoggerLevel.INFO;
+ }
+
+ this.output = output;
+ this.messageFormat = messageFormat;
+
+ synchronized (loggers) {
+ for (SlingLogger logger : loggers.values()) {
+ logger.configure(level, output, messageFormat);
+ }
+ }
+ }
+
+ public void close() {
+ if (output != null) {
+ try {
+ output.close();
+ } catch (IOException ioe) {
+ internalFailure("Problem closing the output", ioe);
+ }
+ }
+ }
+
+ public List<SlingLogger> getLoggerList() {
+ synchronized (loggers) {
+ return new ArrayList<SlingLogger>(loggers.values());
+ }
+ }
+
+ public SlingLogger getSlingLogger(String name) {
+ synchronized (loggers) {
+ return loggers.get(name);
+ }
+ }
+
+ private SlingLogger createLogger(String name) {
+ SlingLogger logger = new SlingLogger(name);
+ logger.configure(level, output, messageFormat);
+ return logger;
+ }
+
+}
Added: incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/slf4j/SlingLoggerLevel.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/slf4j/SlingLoggerLevel.java?rev=648644&view=auto
==============================================================================
--- incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/slf4j/SlingLoggerLevel.java (added)
+++ incubator/sling/trunk/osgi/log/src/main/java/org/apache/sling/osgi/log/slf4j/SlingLoggerLevel.java Wed Apr 16 02:33:11 2008
@@ -0,0 +1,29 @@
+/*
+ * 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.sling.osgi.log.slf4j;
+
+public enum SlingLoggerLevel {
+
+ TRACE,
+ DEBUG,
+ INFO,
+ WARN,
+ ERROR
+
+}
Added: incubator/sling/trunk/osgi/log/src/main/java/org/slf4j/impl/StaticLoggerBinder.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/osgi/log/src/main/java/org/slf4j/impl/StaticLoggerBinder.java?rev=648644&view=auto
==============================================================================
--- incubator/sling/trunk/osgi/log/src/main/java/org/slf4j/impl/StaticLoggerBinder.java (added)
+++ incubator/sling/trunk/osgi/log/src/main/java/org/slf4j/impl/StaticLoggerBinder.java Wed Apr 16 02:33:11 2008
@@ -0,0 +1,56 @@
+/*
+ * 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.slf4j.impl;
+
+import org.apache.sling.osgi.log.slf4j.SlingLoggerFactory;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MarkerFactory;
+import org.slf4j.ILoggerFactory;
+import org.slf4j.IMarkerFactory;
+import org.slf4j.spi.LoggerFactoryBinder;
+
+/**
+ * This <code>StaticLoggerBinder</code> class returns the
+ * {@link SlingLoggerFactory} singleton instance as the SLF4J logger factory.
+ */
+public class StaticLoggerBinder implements LoggerFactoryBinder {
+
+ /**
+ * The unique instance of this class.
+ */
+ public static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder();
+
+ /**
+ * The ILoggerFactory instance returned by the {@link #getLoggerFactory}
+ * method should always be the same object
+ */
+ private final ILoggerFactory loggerFactory;
+
+ private StaticLoggerBinder() {
+ loggerFactory = SlingLoggerFactory.getInstance();
+ }
+
+ public ILoggerFactory getLoggerFactory() {
+ return loggerFactory;
+ }
+
+ public String getLoggerFactoryClassStr() {
+ return getLoggerFactory().getClass().getName();
+ }
+}
\ No newline at end of file
Added: incubator/sling/trunk/osgi/log/src/main/java/org/slf4j/impl/StaticMarkerBinder.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/osgi/log/src/main/java/org/slf4j/impl/StaticMarkerBinder.java?rev=648644&view=auto
==============================================================================
--- incubator/sling/trunk/osgi/log/src/main/java/org/slf4j/impl/StaticMarkerBinder.java (added)
+++ incubator/sling/trunk/osgi/log/src/main/java/org/slf4j/impl/StaticMarkerBinder.java Wed Apr 16 02:33:11 2008
@@ -0,0 +1,49 @@
+/*
+ * 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.slf4j.impl;
+
+import org.slf4j.IMarkerFactory;
+import org.slf4j.helpers.BasicMarkerFactory;
+import org.slf4j.spi.MarkerFactoryBinder;
+
+/**
+ * This <code>StaticMarkerBinder</code> class returns an instance of the SLF4J
+ * <code>BasicMarkerFactory</code> as the marker factory.
+ */
+public class StaticMarkerBinder implements MarkerFactoryBinder {
+
+ /**
+ * The unique instance of this class.
+ */
+ public static final StaticMarkerBinder SINGLETON = new StaticMarkerBinder();
+
+ final IMarkerFactory markerFactory = new BasicMarkerFactory();
+
+ private StaticMarkerBinder() {
+ }
+
+ public IMarkerFactory getMarkerFactory() {
+ return markerFactory;
+ }
+
+ public String getMarkerFactoryClassStr() {
+ return getMarkerFactory().getClass().getName();
+ }
+
+}
\ No newline at end of file
Modified: incubator/sling/trunk/osgi/log/src/main/resources/OSGI-INF/metatype/metatype.properties
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/osgi/log/src/main/resources/OSGI-INF/metatype/metatype.properties?rev=648644&r1=648643&r2=648644&view=diff
==============================================================================
--- incubator/sling/trunk/osgi/log/src/main/resources/OSGI-INF/metatype/metatype.properties (original)
+++ incubator/sling/trunk/osgi/log/src/main/resources/OSGI-INF/metatype/metatype.properties Wed Apr 16 02:33:11 2008
@@ -37,11 +37,17 @@
reached the log file is copied and a new log file is created. This size \
may be specified with size indicators KB, MB and GB. The default is 10MB.
log.pattern.name = Message Pattern
-log.pattern.description = Message Pattern for the Pattern Layout. See \
- http://logback.qos.ch/manual/layouts.html#ClassicPatternLayout for more \
- information on the pattern.
-log.url.name = Configuration
-log.url.description = URL to a Logback configuration file. This URL must be \
- accessible to the Sling server, which is important in the case of file: URLs. \
- If this property is set and the configuration file succeeds configuring \
- Logback, the other configuration properties are actually ignored.
\ No newline at end of file
+log.pattern.description = Message Pattern for formatting the log messages. \
+ This is a java.util.MessageFormat pattern supporting up to five arguments: \
+ {0} The timestamp of type java.util.Date, {1} the log marker, {2} the name \
+ of the current thread, {3} the name of the logger, {4} the debug level and \
+ {5} the actual debug message. If the log call includes a Throwable, the \
+ stacktrace is just appended to the message.
+
+# Log File configuration is not supported at the moment
+# log.url.name = Configuration
+# log.url.description = URL to a configuration file. This URL must be \
+# accessible to the Sling server, which is important in the case of file: URLs. \
+# If this property is set and can successfully be used to configure logging, \
+# the other configuration properties are actually ignored. Currently \
+# this setting is ignored alltogether.
\ No newline at end of file
Modified: incubator/sling/trunk/osgi/log/src/main/resources/OSGI-INF/metatype/metatype.xml
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/osgi/log/src/main/resources/OSGI-INF/metatype/metatype.xml?rev=648644&r1=648643&r2=648644&view=diff
==============================================================================
--- incubator/sling/trunk/osgi/log/src/main/resources/OSGI-INF/metatype/metatype.xml (original)
+++ incubator/sling/trunk/osgi/log/src/main/resources/OSGI-INF/metatype/metatype.xml Wed Apr 16 02:33:11 2008
@@ -20,7 +20,7 @@
<metatype:MetaData
xmlns:metatype="http://www.osgi.org/xmlns/metatype/v1.0.0"
localization="metatype">
- <metatype:OCD id="org.apache.sling.osgi.log.LogbackManager"
+ <metatype:OCD id="org.apache.sling.osgi.log.LogManager"
name="%log.name" description="%log.description">
<metatype:AD id="org.apache.sling.osgi.log.level" type="String"
default="info" name="%log.level.name"
@@ -40,14 +40,19 @@
default="10mb" name="%log.file.size.name"
description="%log.file.size.description" />
<metatype:AD id="org.apache.sling.osgi.log.pattern" type="String"
- default="%d{dd.MM.yyyy HH:mm:ss} *%-5p* %c{1}: %m%n"
+ default="{0\,date\,dd.MM.yyyy HH:mm:ss.SSS} *{4}* [{2}] {3} {5}"
name="%log.pattern.name"
description="%log.pattern.description" />
+
+<!--
+ Log File configuration is not supported at the moment
<metatype:AD id="org.apache.sling.osgi.log.url" type="String"
default="" name="%log.url.name"
description="%log.url.description" />
+-->
+
</metatype:OCD>
- <metatype:Designate pid="org.apache.sling.osgi.log.LogbackManager">
- <metatype:Object ocdref="org.apache.sling.osgi.log.LogbackManager" />
+ <metatype:Designate pid="org.apache.sling.osgi.log.LogManager">
+ <metatype:Object ocdref="org.apache.sling.osgi.log.LogManager" />
</metatype:Designate>
</metatype:MetaData>
Added: incubator/sling/trunk/osgi/log/src/test/java/org/apache/sling/osgi/log/slf4j/SlingLogFileWriterTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/osgi/log/src/test/java/org/apache/sling/osgi/log/slf4j/SlingLogFileWriterTest.java?rev=648644&view=auto
==============================================================================
--- incubator/sling/trunk/osgi/log/src/test/java/org/apache/sling/osgi/log/slf4j/SlingLogFileWriterTest.java (added)
+++ incubator/sling/trunk/osgi/log/src/test/java/org/apache/sling/osgi/log/slf4j/SlingLogFileWriterTest.java Wed Apr 16 02:33:11 2008
@@ -0,0 +1,163 @@
+/*
+ * 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.sling.osgi.log.slf4j;
+
+import java.io.File;
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+public class SlingLogFileWriterTest extends TestCase {
+
+ private String base;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ File baseFile = new File("target/" + System.currentTimeMillis() + "/" + getClass().getSimpleName());
+ baseFile.getParentFile().mkdirs();
+ base = baseFile.getAbsolutePath();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testNoRotateSize() throws IOException {
+
+ SlingLogFileWriter slfw = new SlingLogFileWriter(base, -1, 10);
+
+ // only base file should exist with size 0 (for now)
+ File test = new File(base);
+ assertTrue(test.exists() && test.length() == 0);
+
+ File test0 = new File(base + ".0");
+ assertFalse(test0.exists());
+ File testn1 = new File(base + ".-1");
+ assertFalse(testn1.exists());
+
+ // write some bytes and ensure size
+ slfw.write("012345");
+ slfw.writeln();
+ assertTrue(test.exists() && test.length() > 0);
+ assertFalse(test0.exists());
+ assertFalse(testn1.exists());
+
+ // write some more, ensuring rotation does happen
+ slfw.write("012345");
+ slfw.writeln();
+ assertTrue(test.exists() && test.length() == 0);
+ assertFalse(test0.exists());
+ assertFalse(testn1.exists());
+ }
+
+ public void testRotate0Size() throws IOException {
+
+ SlingLogFileWriter slfw = new SlingLogFileWriter(base, 0, 10);
+
+ // only base file should exist with size 0 (for now)
+ File test = new File(base);
+ assertTrue(test.exists() && test.length() == 0);
+
+ File test0 = new File(base + ".0");
+ assertFalse(test0.exists());
+ File test1 = new File(base + ".1");
+ assertFalse(test1.exists());
+ File testn1 = new File(base + ".-1");
+ assertFalse(testn1.exists());
+
+ // write some bytes and ensure size
+ slfw.write("012345");
+ slfw.writeln();
+ assertTrue(test.exists() && test.length() > 0);
+ assertFalse(test0.exists());
+ assertFalse(testn1.exists());
+
+ // write some more, ensuring rotation does happen
+ slfw.write("012345");
+ slfw.writeln();
+ assertTrue(test.exists() && test.length() == 0);
+ assertTrue(test0.exists());
+ assertFalse(test1.exists());
+ assertFalse(testn1.exists());
+ }
+
+ public void testRotate1Size() throws IOException {
+
+ SlingLogFileWriter slfw = new SlingLogFileWriter(base, 1, 10);
+
+ // only base file should exist with size 0 (for now)
+ File test = new File(base);
+ assertTrue(test.exists() && test.length() == 0);
+
+ File test0 = new File(base + ".0");
+ assertFalse(test0.exists());
+ File test1 = new File(base + ".1");
+ assertFalse(test1.exists());
+ File testn1 = new File(base + ".-1");
+ assertFalse(testn1.exists());
+
+ // write some bytes and ensure size
+ slfw.write("012345");
+ slfw.writeln();
+ assertTrue(test.exists() && test.length() > 0);
+ assertFalse(test0.exists());
+ assertFalse(testn1.exists());
+
+ // write some more, ensuring rotation does happen
+ slfw.write("012345");
+ slfw.writeln();
+ assertTrue(test.exists() && test.length() == 0);
+ assertTrue(test0.exists());
+ assertFalse(test1.exists());
+ assertFalse(testn1.exists());
+
+ // write bytes to rotate in onw fell swoop
+ slfw.write("0123456789 - more");
+ slfw.writeln();
+ assertTrue(test.exists() && test.length() == 0);
+ assertTrue(test0.exists());
+ assertTrue(test1.exists());
+ assertFalse(testn1.exists());
+ }
+
+ public void testMaxSizeConversion() {
+ assertEquals(1, SlingLogFileWriter.convertMaxSizeSpec("1"));
+
+ // kilo
+ assertEquals(1*1024, SlingLogFileWriter.convertMaxSizeSpec("1K"));
+ assertEquals(1*1024, SlingLogFileWriter.convertMaxSizeSpec("1k"));
+ assertEquals(1*1024, SlingLogFileWriter.convertMaxSizeSpec("1KB"));
+ assertEquals(1*1024, SlingLogFileWriter.convertMaxSizeSpec("1kb"));
+
+ // mega
+ assertEquals(1*1024*1024, SlingLogFileWriter.convertMaxSizeSpec("1M"));
+ assertEquals(1*1024*1024, SlingLogFileWriter.convertMaxSizeSpec("1m"));
+ assertEquals(1*1024*1024, SlingLogFileWriter.convertMaxSizeSpec("1MB"));
+ assertEquals(1*1024*1024, SlingLogFileWriter.convertMaxSizeSpec("1mb"));
+
+ // giga
+ assertEquals(1*1024*1024*1024, SlingLogFileWriter.convertMaxSizeSpec("1G"));
+ assertEquals(1*1024*1024*1024, SlingLogFileWriter.convertMaxSizeSpec("1g"));
+ assertEquals(1*1024*1024*1024, SlingLogFileWriter.convertMaxSizeSpec("1GB"));
+ assertEquals(1*1024*1024*1024, SlingLogFileWriter.convertMaxSizeSpec("1gb"));
+ }
+}
Added: incubator/sling/trunk/osgi/log/src/test/java/org/apache/sling/osgi/log/slf4j/SlingLoggerTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/osgi/log/src/test/java/org/apache/sling/osgi/log/slf4j/SlingLoggerTest.java?rev=648644&view=auto
==============================================================================
--- incubator/sling/trunk/osgi/log/src/test/java/org/apache/sling/osgi/log/slf4j/SlingLoggerTest.java (added)
+++ incubator/sling/trunk/osgi/log/src/test/java/org/apache/sling/osgi/log/slf4j/SlingLoggerTest.java Wed Apr 16 02:33:11 2008
@@ -0,0 +1,200 @@
+/*
+ * 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.sling.osgi.log.slf4j;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.text.MessageFormat;
+
+import junit.framework.TestCase;
+
+public class SlingLoggerTest extends TestCase {
+
+ private static final String LOGGER_NAME = "test.log";
+
+ private SlingLogWriter output = new SlingLogWriter() {
+ public void writeln() throws IOException {
+ // just flush, no end of line
+ flush();
+ }
+ };
+
+ private MessageFormat messageOnly = new MessageFormat("{5}");
+
+ private SlingLogger logger;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ logger = new SlingLogger(LOGGER_NAME);
+ logger.configure(SlingLoggerLevel.DEBUG, output, messageOnly);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ output.close();
+ super.tearDown();
+ }
+
+ public void testSetLogLevel() {
+
+ // prevent real output, set output delegatee to null
+ try {
+ output.getDelegatee().close();
+ } catch (IOException ignore) {
+ }
+ output.setDelegatee(null);
+
+ // initial assertion
+ logger.setLogLevel(SlingLoggerLevel.DEBUG);
+ assertEquals(SlingLoggerLevel.DEBUG, logger.getLogLevel());
+
+ // valid as is
+ logger.setLogLevel("INFO");
+ assertEquals(SlingLoggerLevel.INFO, logger.getLogLevel());
+
+ // valid internal conversion to upper case
+ logger.setLogLevel("warn");
+ assertEquals(SlingLoggerLevel.WARN, logger.getLogLevel());
+ logger.setLogLevel("ErrOr");
+ assertEquals(SlingLoggerLevel.ERROR, logger.getLogLevel());
+
+ // reset log level to debug
+ logger.setLogLevel(SlingLoggerLevel.DEBUG);
+ assertEquals(SlingLoggerLevel.DEBUG, logger.getLogLevel());
+
+ // invalid, last level is still set
+ logger.setLogLevel((String) null);
+ assertEquals(SlingLoggerLevel.DEBUG, logger.getLogLevel());
+
+ // invalid, last level is still set
+ logger.setLogLevel("");
+ assertEquals(SlingLoggerLevel.DEBUG, logger.getLogLevel());
+
+ // invalid, last level is still set
+ logger.setLogLevel("gurk");
+ assertEquals(SlingLoggerLevel.DEBUG, logger.getLogLevel());
+ }
+
+ public void testCheckLogLevelTrace() {
+ // initial assertion
+ logger.setLogLevel(SlingLoggerLevel.TRACE);
+ assertEquals(SlingLoggerLevel.TRACE, logger.getLogLevel());
+
+ // ensure logging disabled
+ // none for trace
+
+ // ensure logging enabled
+ assertTrue(logger.isTraceEnabled());
+ assertTrue(logger.isDebugEnabled());
+ assertTrue(logger.isInfoEnabled());
+ assertTrue(logger.isWarnEnabled());
+ assertTrue(logger.isErrorEnabled());
+ }
+
+ public void testCheckLogLevelDebug() {
+ // initial assertion
+ logger.setLogLevel(SlingLoggerLevel.DEBUG);
+ assertEquals(SlingLoggerLevel.DEBUG, logger.getLogLevel());
+
+ // ensure logging disabled
+ assertFalse(logger.isTraceEnabled());
+
+ // ensure logging enabled
+ assertTrue(logger.isDebugEnabled());
+ assertTrue(logger.isInfoEnabled());
+ assertTrue(logger.isWarnEnabled());
+ assertTrue(logger.isErrorEnabled());
+ }
+
+ public void testCheckLogLevelInfo() {
+ // initial assertion
+ logger.setLogLevel(SlingLoggerLevel.INFO);
+ assertEquals(SlingLoggerLevel.INFO, logger.getLogLevel());
+
+ // ensure logging disabled
+ assertFalse(logger.isTraceEnabled());
+ assertFalse(logger.isDebugEnabled());
+
+ // ensure logging enabled
+ assertTrue(logger.isInfoEnabled());
+ assertTrue(logger.isWarnEnabled());
+ assertTrue(logger.isErrorEnabled());
+ }
+
+ public void testCheckLogLevelWarn() {
+ // initial assertion
+ logger.setLogLevel(SlingLoggerLevel.WARN);
+ assertEquals(SlingLoggerLevel.WARN, logger.getLogLevel());
+
+ // ensure logging disabled
+ assertFalse(logger.isTraceEnabled());
+ assertFalse(logger.isDebugEnabled());
+ assertFalse(logger.isInfoEnabled());
+
+ // ensure logging enabled
+ assertTrue(logger.isWarnEnabled());
+ assertTrue(logger.isErrorEnabled());
+ }
+
+ public void testCheckLogLevelError() {
+ // initial assertion
+ logger.setLogLevel(SlingLoggerLevel.ERROR);
+ assertEquals(SlingLoggerLevel.ERROR, logger.getLogLevel());
+
+ // ensure logging disabled
+ assertFalse(logger.isTraceEnabled());
+ assertFalse(logger.isDebugEnabled());
+ assertFalse(logger.isInfoEnabled());
+ assertFalse(logger.isWarnEnabled());
+
+ // ensure logging enabled
+ assertTrue(logger.isErrorEnabled());
+ }
+
+ public void testFormat() {
+ StringWriter w = new StringWriter();
+ output.setDelegatee(w);
+
+ // a single message
+ logger.configure(SlingLoggerLevel.DEBUG, output, messageOnly);
+
+ String message = "This is a message";
+ logger.warn(message);
+ assertEquals(message, w.toString());
+
+ // reset output buffer and format with logger name and message
+ w.getBuffer().delete(0, w.getBuffer().length());
+ logger.configure(SlingLoggerLevel.DEBUG, output, new MessageFormat(
+ "{3}|{5}"));
+
+ logger.warn(message);
+ assertEquals(logger.getName() + "|" + message, w.toString());
+
+ // reset output buffer and format with logger name, level, thread and
+ // message
+ w.getBuffer().delete(0, w.getBuffer().length());
+ logger.configure(SlingLoggerLevel.DEBUG, output, new MessageFormat(
+ "{2}|{3}|{4}|{5}"));
+ logger.warn(message);
+ assertEquals(Thread.currentThread().getName() + "|" + logger.getName()
+ + "|" + SlingLoggerLevel.WARN + "|" + message, w.toString());
+ }
+}