Author: chetanm Date: Fri Nov 15 11:09:02 2013 New Revision: 1542230 URL: http://svn.apache.org/r1542230 Log: SLING-3070 - Update Log help document with Logback related details
Initial documentation Added: sling/site/trunk/content/documentation/development/logging-new.mdtext (with props) sling/site/trunk/content/documentation/development/sling-log-support.png (with props) Added: sling/site/trunk/content/documentation/development/logging-new.mdtext URL: http://svn.apache.org/viewvc/sling/site/trunk/content/documentation/development/logging-new.mdtext?rev=1542230&view=auto ============================================================================== --- sling/site/trunk/content/documentation/development/logging-new.mdtext (added) +++ sling/site/trunk/content/documentation/development/logging-new.mdtext Fri Nov 15 11:09:02 2013 @@ -0,0 +1,254 @@ +Title: Logging + +<div class="note"> +Work in progress as part of SLING-3070 +</div> + +<div class="note"> +This document is for new 4.x release of Sling Commons Log components. For older version refer to +</div> + +## Introduction + +Logging in Sling is supported by the `org.apache.sling.commons.log` bundle, which is one of the first bundles installed +and started by the Sling Launcher. This bundle along with other bundles manage the Sling Logging and provide following +features + +* Implements the OSGi Log Service Specification and registers the `LogService` and `LogReader` services +* Exports three commonly used logging APIs: + * [Simple Logging Facade for Java (SLF4J)](http://www.slf4j.org) + * [Apache Commons Logging](http://jakarta.apache.org/commons/logging) + * [log4j](http://logging.apache.org/log4j/index.html) + * [java.util.logging](http://download.oracle.com/javase/6/docs/api/java/util/logging/package-summary.html) +* Configures logging through Logback which is integrated with the OSGi environment + +## Logback Integration + +Logback integration provides following features + +* LogBack configuration can be provided via Logback config xml +* Supports Appenders registered as OSGi Services +* Supports Filters and TurboFilters registered as OSGi Services +* Support providing Logback config as fragments through OSGi Service Registry +* Support for referring to Appenders registered as OSGi services from with Logback + config +* Exposing Logback runtime state through Felix WebConsole Plugin + +Following sections would provide more details around these features + +### TurboFilters as OSGi Service + +[Logback TurboFilter][3] operate globally and invoked for every Logback call. To register a `TurboFilter` as OSGi service +the bundle just need to register a service against `ch.qos.logback.classic.turbo.TurboFilter` class + + import import ch.qos.logback.classic.turbo.MatchingFilter; + + SimpleTurboFilter stf = new SimpleTurboFilter(); + ServiceRegistration sr = bundleContext.registerService(TurboFilter.class.getName(), stf, null); + + private static class SimpleTurboFilter extends MatchingFilter { + @Override + public FilterReply decide(Marker marker, Logger logger, Level level, String format, + Object[] params, Throwable t) { + if(logger.getName().equals("turbofilter.foo.bar")){ + return FilterReply.DENY; + } + return FilterReply.NEUTRAL; + } + } + +As these filters are invoked for every call they must not take much time to execute. + +### Filter as OSGi service + +[Logback Filters][1] are attached to appenders and are used to determine if any LoggingEvent needs to +be passed to the appender. When registering a filter the bundle needs to configure a service property +`appenders` which refers to list of appender names to which the Filter must be attached + + + import ch.qos.logback.core.filter.Filter; + + SimpleFilter stf = new SimpleFilter(); + Dictionary<String, Object> props = new Hashtable<String, Object>(); + props.put("appenders", "TestAppender"); + ServiceRegistration sr = bundleContext.registerService(Filter.class.getName(), stf, props); + + private static class SimpleFilter extends Filter<ILoggingEvent> { + + @Override + public FilterReply decide(ILoggingEvent event) { + if(event.getLoggerName().equals("filter.foo.bar")){ + return FilterReply.DENY; + } + return FilterReply.NEUTRAL; + } + } + +### Appenders as OSGi service + +[Logback Appenders][2] handle the logging events produced by Logback. To register an `Appender` as OSGi service +the bundle just need to register a service against `ch.qos.logback.core.Appender` class. When registering an +appender the bundle needs to configure a service property `loggers` which refers to list of logger names to which +the Appender must be attached + + + Dictionary<String,Object> props = new Hashtable<String, Object>(); + + String[] loggers = { + "foo.bar:DEBUG", + "foo.bar.zoo:INFO", + }; + + props.put("loggers",loggers); + sr = bundleContext.registerService(Appender.class.getName(),this,props); + +### Logback Config Fragment Support + +Logback supports including parts of a configuration file from another file (See [File Inclusion][4]). This module +extends that support by allowing other bundles to provide config fragments. There are two ways to achieve that + +#### Exposing fragment as String objects + +If you have the config as string then you can register that String instance as a service with property `logbackConfig` +set to true. Sling Logback Extension would monitor such objects and pass them to logback + + + Properties props = new Properties(); + props.setProperty("logbackConfig","true"); + + String config = "<included>\n" + + " <appender name=\"FOOFILE\" class=\"ch.qos.logback.core.FileAppender\">\n" + + " <file>${sling.home}/logs/foo.log</file>\n" + + " <encoder>\n" + + " <pattern>%d %-5level %logger{35} - %msg %n</pattern>\n" + + " </encoder>\n" + + " </appender>\n" + + "\n" + + " <logger name=\"foo.bar.include\" level=\"INFO\">\n" + + " <appender-ref ref=\"FOOFILE\" />\n" + + " </logger>\n" + + "\n" + + "</included>"; + + registration = context.registerService(String.class.getName(),config,props); + + +If the config needs to be updated just re-register the service and change would be picked up + +#### Exposing fragment as ConfigProvider instance + +Another way to provide config fragment is by providing an implementation of `org.apache.sling.commons.log.logback.ConfigProvider` + + + @Component + @Service + public class ConfigProviderExample implements ConfigProvider { + public InputSource getConfigSource() { + return new InputSource(getClass().getClassLoader().getResourceAsStream("foo-config.xml")); + } + } + +If the config changes then sending an event to `org/apache/sling/commons/log/RESET` would reset the listener + + + eventAdmin.sendEvent(new Event("org/apache/sling/commons/log/RESET",new Properties())); + +### External Config File + +Logback can be configured with an external file. The file name can be specified through + +1. OSGi config - Look for config with name `Apache Sling Logging Configuration` and specify the path for + config file property +2. OSGi Framework Properties - Logback supports also looks for file name with property name + `org.apache.sling.commons.log.configurationFile` + +If you are providing an external config file then to support OSGi integration you would need to add following +action entry + + + <newRule pattern="*/configuration/osgi" + actionClass="org.apache.sling.commons.log.logback.OsgiAction"/> + <newRule pattern="*/configuration/appender-ref-osgi" + actionClass="org.apache.sling.commons.log.logback.OsgiAppenderRefAction"/> + <osgi/> + +The `osgi` element enables the OSGi integration support + +### Java Util Logging (JUL) Integration + +The bundle also support [SLF4JBridgeHandler][9]. To enable JUL integration following two steps +needs to be done. This features allows routing logging messages from JUL to the Logbback appenders + +1. Set framework property `org.apache.sling.commons.log.julenabled` to true +2. Set the [LevelChangePropagator][8] in LogbackConfig + + <configuration> + <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"/> + ... + </configuration> + +### Configuring OSGi based appenders in Logback Config + +So far Sling used to configure the appenders based on OSGi config. That mode only provide a very limited +set to configuration options. To make use of other Logback features you can override the OSGi config +from within the Logback config file. OSGi config based appenders are named based on the file name + +For example for following OSGi config + + org.apache.sling.commons.log.file="logs/error.log" + org.apache.sling.commons.log.level="info" + org.apache.sling.commons.log.file.size="'.'yyyy-MM-dd" + org.apache.sling.commons.log.file.number=I"7" + org.apache.sling.commons.log.pattern="{0,date,dd.MM.yyyy HH:mm:ss.SSS} *{4}* [{2}] {3} {5}" + + +The Logback appender would be named as `logs/error.log`. To extend/override the config in Logback config +create an appender with name `logs/error.log` + + + <appender name="/logs/error.log" class="ch.qos.logback.core.FileAppender"> + <file>${sling.home}/logs/error.log</file> + <encoder> + <pattern>%d %-5level %X{sling.userId:-NA} [%thread] %logger{30} %marker- %msg %n</pattern> + <immediateFlush>true</immediateFlush> + </encoder> + </appender> + + +In this case then Log module would create appender based on Logback config instead of OSGi config. This can +be used to move the application from OSGi based config to Logback based config easily + +## Initial Configuration + +The `org.apache.sling.commons.log` bundle gets the initial configuration from the following `BundleContext` properties: + + +| Property | Default | Description | +|--|--|--| +| `org.apache.sling.commons.log.level` | `INFO` | Sets the initial logging level of the root logger. This may be any of the defined logging levels `DEBUG`, `INFO`, `WARN`, `ERROR` and `FATAL`. | +| `org.apache.sling.commons.log.file` | undefined | Sets the log file to which log messages are written. If this property is empty or missing, log messages are written to `System.out`. | +| `org.apache.sling.commons.log.file.number` | 5 | The number of rotated files to keep. | +| `org.apache.sling.commons.log.file.size` | '.'yyyy-MM-dd | Defines how the log file is rotated (by schedule or by size) and when to rotate. See the section *Log File Rotation* below for full details on log file rotation. | +| `org.apache.sling.commons.log.pattern` | \{0,date,dd.MM.yyyy HH:mm:ss.SSS\} \*\{4\}\* \[\{2\}\]({{ refs.-2.path }}) \{3\} \{5\} | The `MessageFormat` pattern to use for formatting log messages with the root logger. | +| `org.apache.sling.commons.log.julenabled` | n/a | Enables the `java.util.logging` support. | +| `org.apache.sling.commons.log.configurationFile` | n/a | Path for the Logback config file which would be used to configure logging. If the path is not absolute then it would be resolved against Sling Home | + + +## WebConsole Plugin enhancements + +The web Console Plugin supports following features + +* Displays list of loggers which have level or appender configured +* List of File appenders with location of current active files +* Content of LogBack config file +* Content of various Logback config fragment +* Logback Status logs + +<img src="sling-log-support.png" /> + +[1]: http://logback.qos.ch/manual/filters.html +[2]: http://logback.qos.ch/manual/appenders.html +[3]: http://logback.qos.ch/manual/filters.html#TurboFilter +[4]: http://logback.qos.ch/manual/configuration.html#fileInclusion +[8]: http://logback.qos.ch/manual/configuration.html#LevelChangePropagator +[9]: http://www.slf4j.org/api/org/slf4j/bridge/SLF4JBridgeHandler.html \ No newline at end of file Propchange: sling/site/trunk/content/documentation/development/logging-new.mdtext ------------------------------------------------------------------------------ svn:eol-style = native Added: sling/site/trunk/content/documentation/development/sling-log-support.png URL: http://svn.apache.org/viewvc/sling/site/trunk/content/documentation/development/sling-log-support.png?rev=1542230&view=auto ============================================================================== Binary file - no diff available. Propchange: sling/site/trunk/content/documentation/development/sling-log-support.png ------------------------------------------------------------------------------ svn:mime-type = image/png