incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From build...@apache.org
Subject svn commit: r886967 - in /websites/staging/sling/trunk/content: ./ documentation/development/logging-new.html
Date Sun, 17 Nov 2013 14:50:11 GMT
Author: buildbot
Date: Sun Nov 17 14:50:11 2013
New Revision: 886967

Log:
Staging update by buildbot for sling

Modified:
    websites/staging/sling/trunk/content/   (props changed)
    websites/staging/sling/trunk/content/documentation/development/logging-new.html

Propchange: websites/staging/sling/trunk/content/
------------------------------------------------------------------------------
--- cms:source-revision (original)
+++ cms:source-revision Sun Nov 17 14:50:11 2013
@@ -1 +1 @@
-1542739
+1542740

Modified: websites/staging/sling/trunk/content/documentation/development/logging-new.html
==============================================================================
--- websites/staging/sling/trunk/content/documentation/development/logging-new.html (original)
+++ websites/staging/sling/trunk/content/documentation/development/logging-new.html Sun Nov 17 14:50:11 2013
@@ -107,186 +107,6 @@ features</p>
 <li>Configures logging through Logback which is integrated with the OSGi environment</li>
 <li>Logging can be configured both via editing Logback xml or via OSGi Configurations</li>
 </ul>
-<h2 id="logback-integration">Logback Integration</h2>
-<p>Logback integration provides following features</p>
-<ul>
-<li>LogBack configuration can be provided via Logback config xml</li>
-<li>Supports Appenders registered as OSGi Services</li>
-<li>Supports Filters and TurboFilters registered as OSGi Services</li>
-<li>Support providing Logback config as fragments through OSGi Service Registry</li>
-<li>Support for referring to Appenders registered as OSGi services from with Logback
-  config</li>
-<li>Exposing Logback runtime state through Felix WebConsole Plugin</li>
-</ul>
-<p>Following sections would provide more details around these features</p>
-<h3 id="turbofilters-as-osgi-service">TurboFilters as OSGi Service</h3>
-<p><a href="http://logback.qos.ch/manual/filters.html#TurboFilter">Logback TurboFilter</a> operate globally and invoked for every Logback call. To register a <code>TurboFilter</code> as OSGi service
-the bundle just need to register a service  against <code>ch.qos.logback.classic.turbo.TurboFilter</code> class</p>
-<div class="codehilite"><pre><span class="kn">import</span> <span class="nn">import</span> <span class="n">ch</span><span class="o">.</span><span class="na">qos</span><span class="o">.</span><span class="na">logback</span><span class="o">.</span><span class="na">classic</span><span class="o">.</span><span class="na">turbo</span><span class="o">.</span><span class="na">MatchingFilter</span><span class="o">;</span>
-
-<span class="n">SimpleTurboFilter</span> <span class="n">stf</span> <span class="o">=</span> <span class="k">new</span> <span class="n">SimpleTurboFilter</span><span class="o">();</span>
-<span class="n">ServiceRegistration</span> <span class="n">sr</span>  <span class="o">=</span> <span class="n">bundleContext</span><span class="o">.</span><span class="na">registerService</span><span class="o">(</span><span class="n">TurboFilter</span><span class="o">.</span><span class="na">class</span><span class="o">.</span><span class="na">getName</span><span class="o">(),</span> <span class="n">stf</span><span class="o">,</span> <span class="kc">null</span><span class="o">);</span>
-
-<span class="kd">private</span> <span class="kd">static</span> <span class="kd">class</span> <span class="nc">SimpleTurboFilter</span> <span class="kd">extends</span> <span class="n">MatchingFilter</span> <span class="o">{</span>
-    <span class="nd">@Override</span>
-    <span class="kd">public</span> <span class="n">FilterReply</span> <span class="nf">decide</span><span class="o">(</span><span class="n">Marker</span> <span class="n">marker</span><span class="o">,</span> <span class="n">Logger</span> <span class="n">logger</span><span class="o">,</span> <span class="n">Level</span> <span class="n">level</span><span class="o">,</span> <span class="n">String</span> <span class="n">format</span><span class="o">,</span>
-     <span class="n">Object</span><span class="o">[]</span> <span class="n">params</span><span class="o">,</span> <span class="n">Throwable</span> <span class="n">t</span><span class="o">)</span> <span class="o">{</span>
-        <span class="k">if</span><span class="o">(</span><span class="n">logger</span><span class="o">.</span><span class="na">getName</span><span class="o">().</span><span class="na">equals</span><span class="o">(</span><span class="s">&quot;turbofilter.foo.bar&quot;</span><span class="o">)){</span>
-                <span class="k">return</span> <span class="n">FilterReply</span><span class="o">.</span><span class="na">DENY</span><span class="o">;</span>
-        <span class="o">}</span>
-        <span class="k">return</span> <span class="n">FilterReply</span><span class="o">.</span><span class="na">NEUTRAL</span><span class="o">;</span>
-    <span class="o">}</span>
-<span class="o">}</span>
-</pre></div>
-
-
-<p>As these filters are invoked for every call they must not take much time to execute.</p>
-<h3 id="filter-as-osgi-service">Filter as OSGi service</h3>
-<p><a href="http://logback.qos.ch/manual/filters.html">Logback Filters</a> 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
-<code>appenders</code> which refers to list of appender names to which the Filter must be attached</p>
-<div class="codehilite"><pre><span class="kn">import</span> <span class="nn">ch.qos.logback.core.filter.Filter</span><span class="o">;</span>
-
-<span class="n">SimpleFilter</span> <span class="n">stf</span> <span class="o">=</span> <span class="k">new</span> <span class="n">SimpleFilter</span><span class="o">();</span>
-<span class="n">Dictionary</span><span class="o">&lt;</span><span class="n">String</span><span class="o">,</span> <span class="n">Object</span><span class="o">&gt;</span> <span class="n">props</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Hashtable</span><span class="o">&lt;</span><span class="n">String</span><span class="o">,</span> <span class="n">Object</span><span class="o">&gt;();</span>
-<span class="n">props</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">&quot;appenders&quot;</span><span class="o">,</span> <span class="s">&quot;TestAppender&quot;</span><span class="o">);</span>
-<span class="n">ServiceRegistration</span> <span class="n">sr</span>  <span class="o">=</span> <span class="n">bundleContext</span><span class="o">.</span><span class="na">registerService</span><span class="o">(</span><span class="n">Filter</span><span class="o">.</span><span class="na">class</span><span class="o">.</span><span class="na">getName</span><span class="o">(),</span> <span class="n">stf</span><span class="o">,</span> <span class="n">props</span><span class="o">);</span>
-
-<span class="kd">private</span> <span class="kd">static</span> <span class="kd">class</span> <span class="nc">SimpleFilter</span> <span class="kd">extends</span> <span class="n">Filter</span><span class="o">&lt;</span><span class="n">ILoggingEvent</span><span class="o">&gt;</span> <span class="o">{</span>
-
-    <span class="nd">@Override</span>
-    <span class="kd">public</span> <span class="n">FilterReply</span> <span class="nf">decide</span><span class="o">(</span><span class="n">ILoggingEvent</span> <span class="n">event</span><span class="o">)</span> <span class="o">{</span>
-        <span class="k">if</span><span class="o">(</span><span class="n">event</span><span class="o">.</span><span class="na">getLoggerName</span><span class="o">().</span><span class="na">equals</span><span class="o">(</span><span class="s">&quot;filter.foo.bar&quot;</span><span class="o">)){</span>
-            <span class="k">return</span> <span class="n">FilterReply</span><span class="o">.</span><span class="na">DENY</span><span class="o">;</span>
-        <span class="o">}</span>
-        <span class="k">return</span> <span class="n">FilterReply</span><span class="o">.</span><span class="na">NEUTRAL</span><span class="o">;</span>
-    <span class="o">}</span>
-<span class="o">}</span>
-</pre></div>
-
-
-<h3 id="appenders-as-osgi-service">Appenders as OSGi service</h3>
-<p><a href="http://logback.qos.ch/manual/appenders.html">Logback Appenders</a> handle the logging events produced by Logback. To register an <code>Appender</code> as OSGi service
-the bundle just need to register a service  against <code>ch.qos.logback.core.Appender</code> class.  When registering an
-appender the bundle needs to configure a service property <code>loggers</code> which refers to list of logger names to which
-the Appender must be attached</p>
-<div class="codehilite"><pre><span class="n">Dictionary</span><span class="o">&lt;</span><span class="n">String</span><span class="o">,</span><span class="n">Object</span><span class="o">&gt;</span> <span class="n">props</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Hashtable</span><span class="o">&lt;</span><span class="n">String</span><span class="o">,</span> <span class="n">Object</span><span class="o">&gt;();</span>
-
-<span class="n">String</span><span class="o">[]</span> <span class="n">loggers</span> <span class="o">=</span> <span class="o">{</span>
-        <span class="s">&quot;foo.bar:DEBUG&quot;</span><span class="o">,</span>
-        <span class="s">&quot;foo.bar.zoo:INFO&quot;</span><span class="o">,</span>
-<span class="o">};</span>
-
-<span class="n">props</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">&quot;loggers&quot;</span><span class="o">,</span><span class="n">loggers</span><span class="o">);</span>
-<span class="n">sr</span> <span class="o">=</span> <span class="n">bundleContext</span><span class="o">.</span><span class="na">registerService</span><span class="o">(</span><span class="n">Appender</span><span class="o">.</span><span class="na">class</span><span class="o">.</span><span class="na">getName</span><span class="o">(),</span><span class="k">this</span><span class="o">,</span><span class="n">props</span><span class="o">);</span>
-</pre></div>
-
-
-<h3 id="logback-config-fragment-support">Logback Config Fragment Support</h3>
-<p>Logback supports including parts of a configuration file from another file (See <a href="http://logback.qos.ch/manual/configuration.html#fileInclusion">File Inclusion</a>). This module
-extends that support by allowing other bundles to provide config fragments. There are two ways to achieve that</p>
-<h4 id="exposing-fragment-as-string-objects">Exposing fragment as String objects</h4>
-<p>If you have the config as string then you can register that String instance as a service with property <code>logbackConfig</code>
-set to true. Sling Logback Extension would monitor such objects and pass them to logback</p>
-<div class="codehilite"><pre>Properties props = new Properties();
-props.setProperty(&quot;logbackConfig&quot;,&quot;true&quot;);
-
-String config = &quot;<span class="nt">&lt;included&gt;</span>\n&quot; +
-        &quot;  <span class="nt">&lt;appender</span> <span class="na">name=</span><span class="s">\&quot;FOOFILE\&quot;</span> <span class="na">class=</span><span class="s">\&quot;ch.qos.logback.core.FileAppender\&quot;</span><span class="nt">&gt;</span>\n&quot; +
-        &quot;    <span class="nt">&lt;file&gt;</span><span class="cp">${</span><span class="n">sling</span><span class="o">.</span><span class="n">home</span><span class="cp">}</span>/logs/foo.log<span class="nt">&lt;/file&gt;</span>\n&quot; +
-        &quot;    <span class="nt">&lt;encoder&gt;</span>\n&quot; +
-        &quot;      <span class="nt">&lt;pattern&gt;</span>%d %-5level %logger{35} - %msg %n<span class="nt">&lt;/pattern&gt;</span>\n&quot; +
-        &quot;    <span class="nt">&lt;/encoder&gt;</span>\n&quot; +
-        &quot;  <span class="nt">&lt;/appender&gt;</span>\n&quot; +
-        &quot;\n&quot; +
-        &quot;  <span class="nt">&lt;logger</span> <span class="na">name=</span><span class="s">\&quot;foo.bar.include\&quot;</span> <span class="na">level=</span><span class="s">\&quot;INFO\&quot;</span><span class="nt">&gt;</span>\n&quot; +
-        &quot;       <span class="nt">&lt;appender</span><span class="err">-ref</span> <span class="na">ref=</span><span class="s">\&quot;FOOFILE\&quot;</span> <span class="nt">/&gt;</span>\n&quot; +
-        &quot;  <span class="nt">&lt;/logger&gt;</span>\n&quot; +
-        &quot;\n&quot; +
-        &quot;<span class="nt">&lt;/included&gt;</span>&quot;;
-
-registration = context.registerService(String.class.getName(),config,props);
-</pre></div>
-
-
-<p>If the config needs to be updated just re-register the service and change would be picked up</p>
-<h4 id="exposing-fragment-as-configprovider-instance">Exposing fragment as ConfigProvider instance</h4>
-<p>Another way to provide config fragment is by providing an implementation of <code>org.apache.sling.commons.log.logback.ConfigProvider</code></p>
-<div class="codehilite"><pre><span class="p">@</span><span class="n">Component</span>
-<span class="p">@</span><span class="n">Service</span>
-<span class="n">public</span> <span class="n">class</span> <span class="n">ConfigProviderExample</span> <span class="n">implements</span> <span class="n">ConfigProvider</span> <span class="p">{</span>
-    <span class="n">public</span> <span class="n">InputSource</span> <span class="n">getConfigSource</span><span class="p">()</span> <span class="p">{</span>
-        <span class="k">return</span> <span class="n">new</span> <span class="n">InputSource</span><span class="p">(</span><span class="n">getClass</span><span class="p">().</span><span class="n">getClassLoader</span><span class="p">().</span><span class="n">getResourceAsStream</span><span class="p">(</span>&quot;<span class="n">foo</span><span class="o">-</span><span class="n">config</span><span class="p">.</span><span class="n">xml</span>&quot;<span class="p">));</span>
-    <span class="p">}</span>
-<span class="p">}</span>
-</pre></div>
-
-
-<p>If the config changes then sending an event to <code>org/apache/sling/commons/log/RESET</code> would reset the Logback runtime</p>
-<div class="codehilite"><pre><span class="n">eventAdmin</span><span class="p">.</span><span class="n">sendEvent</span><span class="p">(</span><span class="n">new</span> <span class="n">Event</span><span class="p">(</span>&quot;<span class="n">org</span><span class="o">/</span><span class="n">apache</span><span class="o">/</span><span class="n">sling</span><span class="o">/</span><span class="n">commons</span><span class="o">/</span><span class="nb">log</span><span class="o">/</span><span class="n">RESET</span>&quot;<span class="p">,</span><span class="n">new</span> <span class="n">Properties</span><span class="p">()));</span>
-</pre></div>
-
-
-<h3 id="external-config-file">External Config File</h3>
-<p>Logback can be configured with an external file. The file name can be specified through</p>
-<ol>
-<li>OSGi config - Look for config with name <code>Apache Sling Logging Configuration</code> and specify the path for
-   config file property</li>
-<li>OSGi Framework Properties - Logback supports also looks for file name with property name
-   <code>org.apache.sling.commons.log.configurationFile</code></li>
-</ol>
-<p>If you are providing an external config file then to support OSGi integration you would need to add following
-action entry</p>
-<div class="codehilite"><pre><span class="nt">&lt;newRule</span> <span class="na">pattern=</span><span class="s">&quot;*/configuration/osgi&quot;</span>
-         <span class="na">actionClass=</span><span class="s">&quot;org.apache.sling.commons.log.logback.OsgiAction&quot;</span><span class="nt">/&gt;</span>
-<span class="nt">&lt;newRule</span> <span class="na">pattern=</span><span class="s">&quot;*/configuration/appender-ref-osgi&quot;</span>
-         <span class="na">actionClass=</span><span class="s">&quot;org.apache.sling.commons.log.logback.OsgiAppenderRefAction&quot;</span><span class="nt">/&gt;</span>
-<span class="nt">&lt;osgi/&gt;</span>
-</pre></div>
-
-
-<p>The <code>osgi</code> element enables the OSGi integration support</p>
-<h3 id="java-util-logging-jul-integration">Java Util Logging (JUL) Integration</h3>
-<p>The bundle also support <a href="http://www.slf4j.org/api/org/slf4j/bridge/SLF4JBridgeHandler.html">SLF4JBridgeHandler</a>. To enable JUL integration following two steps
-needs to be done. This features allows routing logging messages from JUL to the Logbback appenders</p>
-<ol>
-<li>Set framework property <code>org.apache.sling.commons.log.julenabled</code> to true</li>
-<li>
-<p>Set the <a href="http://logback.qos.ch/manual/configuration.html#LevelChangePropagator">LevelChangePropagator</a> in LogbackConfig</p>
-<p>:::xml
-<configuration>
-  <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"/>
-  ...
-</configuration></p>
-</li>
-</ol>
-<h3 id="wzxhzdk11wzxhzdk12configuring-osgi-based-appenders-in-logback-config"><a name="config-override"></a>Configuring OSGi based appenders in Logback Config</h3>
-<p>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</p>
-<p>For example for following OSGi config</p>
-<div class="codehilite"><pre><span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">sling</span><span class="p">.</span><span class="n">commons</span><span class="p">.</span><span class="nb">log</span><span class="p">.</span><span class="n">file</span><span class="p">=</span>&quot;<span class="n">logs</span><span class="o">/</span><span class="n">error</span><span class="p">.</span><span class="nb">log</span>&quot;
-<span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">sling</span><span class="p">.</span><span class="n">commons</span><span class="p">.</span><span class="nb">log</span><span class="p">.</span><span class="n">level</span><span class="p">=</span>&quot;<span class="n">info</span>&quot;
-<span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">sling</span><span class="p">.</span><span class="n">commons</span><span class="p">.</span><span class="nb">log</span><span class="p">.</span><span class="n">file</span><span class="p">.</span><span class="nb">size</span><span class="p">=</span>&quot;<span class="s">&#39;.&#39;</span><span class="n">yyyy</span><span class="o">-</span><span class="n">MM</span><span class="o">-</span><span class="n">dd</span>&quot;
-<span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">sling</span><span class="p">.</span><span class="n">commons</span><span class="p">.</span><span class="nb">log</span><span class="p">.</span><span class="n">file</span><span class="p">.</span><span class="n">number</span><span class="p">=</span><span class="n">I</span>&quot;7&quot;
-<span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">sling</span><span class="p">.</span><span class="n">commons</span><span class="p">.</span><span class="nb">log</span><span class="p">.</span><span class="n">pattern</span><span class="p">=</span>&quot;<span class="p">{</span>0<span class="p">,</span><span class="n">date</span><span class="p">,</span><span class="n">dd</span><span class="p">.</span><span class="n">MM</span><span class="p">.</span><span class="n">yyyy</span> <span class="n">HH</span><span class="p">:</span><span class="n">mm</span><span class="p">:</span><span class="n">ss</span><span class="p">.</span><span class="n">SSS</span><span class="p">}</span> <span class="o">*</span><span class="p">{</span>4<span class="p">}</span><span class="o">*</span> <span class="p">[{</span>2<span class="p">}]</span> <span class="p">{</span>3<span class="p">}</span> <span class="p">{</span>5<span class="p">}</span>&quo
 t;
-</pre></div>
-
-
-<p>The Logback appender would be named as <code>logs/error.log</code>. To extend/override the config in Logback config
-create an appender with name <code>logs/error.log</code></p>
-<div class="codehilite"><pre><span class="nt">&lt;appender</span> <span class="na">name=</span><span class="s">&quot;/logs/error.log&quot;</span> <span class="na">class=</span><span class="s">&quot;ch.qos.logback.core.FileAppender&quot;</span><span class="nt">&gt;</span>
-  <span class="nt">&lt;file&gt;</span>${sling.home}/logs/error.log<span class="nt">&lt;/file&gt;</span>
-  <span class="nt">&lt;encoder&gt;</span>
-    <span class="nt">&lt;pattern&gt;</span>%d %-5level %X{sling.userId:-NA} [%thread] %logger{30} %marker- %msg %n<span class="nt">&lt;/pattern&gt;</span>
-    <span class="nt">&lt;immediateFlush&gt;</span>true<span class="nt">&lt;/immediateFlush&gt;</span>
-  <span class="nt">&lt;/encoder&gt;</span>
-<span class="nt">&lt;/appender&gt;</span>
-</pre></div>
-
-
-<p>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</p>
 <h2 id="initial-configuration">Initial Configuration</h2>
 <p>The <code>org.apache.sling.commons.log</code> bundle gets the initial configuration from the following <code>BundleContext</code> properties:</p>
 <table>
@@ -483,6 +303,186 @@ is ignored and the meaning is probably o
 <p>When using Size Rotation, the <code>org.apache.sling.commons.log.file.number</code> defines the number of old log file generations
 to keep. For example to keep 5 old log files indexed by 0 through 4, set the <code>org.apache.sling.commons.log.file.number</code>
 to <code>5</code> (which happens to be the default).</p>
+<h2 id="logback-integration">Logback Integration</h2>
+<p>Logback integration provides following features</p>
+<ul>
+<li>LogBack configuration can be provided via Logback config xml</li>
+<li>Supports Appenders registered as OSGi Services</li>
+<li>Supports Filters and TurboFilters registered as OSGi Services</li>
+<li>Support providing Logback config as fragments through OSGi Service Registry</li>
+<li>Support for referring to Appenders registered as OSGi services from with Logback
+  config</li>
+<li>Exposing Logback runtime state through Felix WebConsole Plugin</li>
+</ul>
+<p>Following sections would provide more details around these features</p>
+<h3 id="turbofilters-as-osgi-service">TurboFilters as OSGi Service</h3>
+<p><a href="http://logback.qos.ch/manual/filters.html#TurboFilter">Logback TurboFilter</a> operate globally and invoked for every Logback call. To register a <code>TurboFilter</code> as OSGi service
+the bundle just need to register a service  against <code>ch.qos.logback.classic.turbo.TurboFilter</code> class</p>
+<div class="codehilite"><pre><span class="kn">import</span> <span class="nn">import</span> <span class="n">ch</span><span class="o">.</span><span class="na">qos</span><span class="o">.</span><span class="na">logback</span><span class="o">.</span><span class="na">classic</span><span class="o">.</span><span class="na">turbo</span><span class="o">.</span><span class="na">MatchingFilter</span><span class="o">;</span>
+
+<span class="n">SimpleTurboFilter</span> <span class="n">stf</span> <span class="o">=</span> <span class="k">new</span> <span class="n">SimpleTurboFilter</span><span class="o">();</span>
+<span class="n">ServiceRegistration</span> <span class="n">sr</span>  <span class="o">=</span> <span class="n">bundleContext</span><span class="o">.</span><span class="na">registerService</span><span class="o">(</span><span class="n">TurboFilter</span><span class="o">.</span><span class="na">class</span><span class="o">.</span><span class="na">getName</span><span class="o">(),</span> <span class="n">stf</span><span class="o">,</span> <span class="kc">null</span><span class="o">);</span>
+
+<span class="kd">private</span> <span class="kd">static</span> <span class="kd">class</span> <span class="nc">SimpleTurboFilter</span> <span class="kd">extends</span> <span class="n">MatchingFilter</span> <span class="o">{</span>
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="n">FilterReply</span> <span class="nf">decide</span><span class="o">(</span><span class="n">Marker</span> <span class="n">marker</span><span class="o">,</span> <span class="n">Logger</span> <span class="n">logger</span><span class="o">,</span> <span class="n">Level</span> <span class="n">level</span><span class="o">,</span> <span class="n">String</span> <span class="n">format</span><span class="o">,</span>
+     <span class="n">Object</span><span class="o">[]</span> <span class="n">params</span><span class="o">,</span> <span class="n">Throwable</span> <span class="n">t</span><span class="o">)</span> <span class="o">{</span>
+        <span class="k">if</span><span class="o">(</span><span class="n">logger</span><span class="o">.</span><span class="na">getName</span><span class="o">().</span><span class="na">equals</span><span class="o">(</span><span class="s">&quot;turbofilter.foo.bar&quot;</span><span class="o">)){</span>
+                <span class="k">return</span> <span class="n">FilterReply</span><span class="o">.</span><span class="na">DENY</span><span class="o">;</span>
+        <span class="o">}</span>
+        <span class="k">return</span> <span class="n">FilterReply</span><span class="o">.</span><span class="na">NEUTRAL</span><span class="o">;</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>As these filters are invoked for every call they must not take much time to execute.</p>
+<h3 id="filter-as-osgi-service">Filter as OSGi service</h3>
+<p><a href="http://logback.qos.ch/manual/filters.html">Logback Filters</a> 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
+<code>appenders</code> which refers to list of appender names to which the Filter must be attached</p>
+<div class="codehilite"><pre><span class="kn">import</span> <span class="nn">ch.qos.logback.core.filter.Filter</span><span class="o">;</span>
+
+<span class="n">SimpleFilter</span> <span class="n">stf</span> <span class="o">=</span> <span class="k">new</span> <span class="n">SimpleFilter</span><span class="o">();</span>
+<span class="n">Dictionary</span><span class="o">&lt;</span><span class="n">String</span><span class="o">,</span> <span class="n">Object</span><span class="o">&gt;</span> <span class="n">props</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Hashtable</span><span class="o">&lt;</span><span class="n">String</span><span class="o">,</span> <span class="n">Object</span><span class="o">&gt;();</span>
+<span class="n">props</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">&quot;appenders&quot;</span><span class="o">,</span> <span class="s">&quot;TestAppender&quot;</span><span class="o">);</span>
+<span class="n">ServiceRegistration</span> <span class="n">sr</span>  <span class="o">=</span> <span class="n">bundleContext</span><span class="o">.</span><span class="na">registerService</span><span class="o">(</span><span class="n">Filter</span><span class="o">.</span><span class="na">class</span><span class="o">.</span><span class="na">getName</span><span class="o">(),</span> <span class="n">stf</span><span class="o">,</span> <span class="n">props</span><span class="o">);</span>
+
+<span class="kd">private</span> <span class="kd">static</span> <span class="kd">class</span> <span class="nc">SimpleFilter</span> <span class="kd">extends</span> <span class="n">Filter</span><span class="o">&lt;</span><span class="n">ILoggingEvent</span><span class="o">&gt;</span> <span class="o">{</span>
+
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="n">FilterReply</span> <span class="nf">decide</span><span class="o">(</span><span class="n">ILoggingEvent</span> <span class="n">event</span><span class="o">)</span> <span class="o">{</span>
+        <span class="k">if</span><span class="o">(</span><span class="n">event</span><span class="o">.</span><span class="na">getLoggerName</span><span class="o">().</span><span class="na">equals</span><span class="o">(</span><span class="s">&quot;filter.foo.bar&quot;</span><span class="o">)){</span>
+            <span class="k">return</span> <span class="n">FilterReply</span><span class="o">.</span><span class="na">DENY</span><span class="o">;</span>
+        <span class="o">}</span>
+        <span class="k">return</span> <span class="n">FilterReply</span><span class="o">.</span><span class="na">NEUTRAL</span><span class="o">;</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<h3 id="appenders-as-osgi-service">Appenders as OSGi service</h3>
+<p><a href="http://logback.qos.ch/manual/appenders.html">Logback Appenders</a> handle the logging events produced by Logback. To register an <code>Appender</code> as OSGi service
+the bundle just need to register a service  against <code>ch.qos.logback.core.Appender</code> class.  When registering an
+appender the bundle needs to configure a service property <code>loggers</code> which refers to list of logger names to which
+the Appender must be attached</p>
+<div class="codehilite"><pre><span class="n">Dictionary</span><span class="o">&lt;</span><span class="n">String</span><span class="o">,</span><span class="n">Object</span><span class="o">&gt;</span> <span class="n">props</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Hashtable</span><span class="o">&lt;</span><span class="n">String</span><span class="o">,</span> <span class="n">Object</span><span class="o">&gt;();</span>
+
+<span class="n">String</span><span class="o">[]</span> <span class="n">loggers</span> <span class="o">=</span> <span class="o">{</span>
+        <span class="s">&quot;foo.bar:DEBUG&quot;</span><span class="o">,</span>
+        <span class="s">&quot;foo.bar.zoo:INFO&quot;</span><span class="o">,</span>
+<span class="o">};</span>
+
+<span class="n">props</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">&quot;loggers&quot;</span><span class="o">,</span><span class="n">loggers</span><span class="o">);</span>
+<span class="n">sr</span> <span class="o">=</span> <span class="n">bundleContext</span><span class="o">.</span><span class="na">registerService</span><span class="o">(</span><span class="n">Appender</span><span class="o">.</span><span class="na">class</span><span class="o">.</span><span class="na">getName</span><span class="o">(),</span><span class="k">this</span><span class="o">,</span><span class="n">props</span><span class="o">);</span>
+</pre></div>
+
+
+<h3 id="logback-config-fragment-support">Logback Config Fragment Support</h3>
+<p>Logback supports including parts of a configuration file from another file (See <a href="http://logback.qos.ch/manual/configuration.html#fileInclusion">File Inclusion</a>). This module
+extends that support by allowing other bundles to provide config fragments. There are two ways to achieve that</p>
+<h4 id="exposing-fragment-as-string-objects">Exposing fragment as String objects</h4>
+<p>If you have the config as string then you can register that String instance as a service with property <code>logbackConfig</code>
+set to true. Sling Logback Extension would monitor such objects and pass them to logback</p>
+<div class="codehilite"><pre><span class="n">Properties</span> <span class="n">props</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Properties</span><span class="o">();</span>
+<span class="n">props</span><span class="o">.</span><span class="na">setProperty</span><span class="o">(</span><span class="s">&quot;logbackConfig&quot;</span><span class="o">,</span><span class="s">&quot;true&quot;</span><span class="o">);</span>
+
+<span class="n">String</span> <span class="n">config</span> <span class="o">=</span> <span class="s">&quot;&lt;included&gt;\n&quot;</span> <span class="o">+</span>
+        <span class="s">&quot;  &lt;appender name=\&quot;FOOFILE\&quot; class=\&quot;ch.qos.logback.core.FileAppender\&quot;&gt;\n&quot;</span> <span class="o">+</span>
+        <span class="s">&quot;    &lt;file&gt;${sling.home}/logs/foo.log&lt;/file&gt;\n&quot;</span> <span class="o">+</span>
+        <span class="s">&quot;    &lt;encoder&gt;\n&quot;</span> <span class="o">+</span>
+        <span class="s">&quot;      &lt;pattern&gt;%d %-5level %logger{35} - %msg %n&lt;/pattern&gt;\n&quot;</span> <span class="o">+</span>
+        <span class="s">&quot;    &lt;/encoder&gt;\n&quot;</span> <span class="o">+</span>
+        <span class="s">&quot;  &lt;/appender&gt;\n&quot;</span> <span class="o">+</span>
+        <span class="s">&quot;\n&quot;</span> <span class="o">+</span>
+        <span class="s">&quot;  &lt;logger name=\&quot;foo.bar.include\&quot; level=\&quot;INFO\&quot;&gt;\n&quot;</span> <span class="o">+</span>
+        <span class="s">&quot;       &lt;appender-ref ref=\&quot;FOOFILE\&quot; /&gt;\n&quot;</span> <span class="o">+</span>
+        <span class="s">&quot;  &lt;/logger&gt;\n&quot;</span> <span class="o">+</span>
+        <span class="s">&quot;\n&quot;</span> <span class="o">+</span>
+        <span class="s">&quot;&lt;/included&gt;&quot;</span><span class="o">;</span>
+
+<span class="n">registration</span> <span class="o">=</span> <span class="n">context</span><span class="o">.</span><span class="na">registerService</span><span class="o">(</span><span class="n">String</span><span class="o">.</span><span class="na">class</span><span class="o">.</span><span class="na">getName</span><span class="o">(),</span><span class="n">config</span><span class="o">,</span><span class="n">props</span><span class="o">);</span>
+</pre></div>
+
+
+<p>If the config needs to be updated just re-register the service and change would be picked up</p>
+<h4 id="exposing-fragment-as-configprovider-instance">Exposing fragment as ConfigProvider instance</h4>
+<p>Another way to provide config fragment is by providing an implementation of <code>org.apache.sling.commons.log.logback.ConfigProvider</code></p>
+<div class="codehilite"><pre><span class="nd">@Component</span>
+<span class="nd">@Service</span>
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">ConfigProviderExample</span> <span class="kd">implements</span> <span class="n">ConfigProvider</span> <span class="o">{</span>
+    <span class="kd">public</span> <span class="n">InputSource</span> <span class="nf">getConfigSource</span><span class="o">()</span> <span class="o">{</span>
+        <span class="k">return</span> <span class="k">new</span> <span class="nf">InputSource</span><span class="o">(</span><span class="n">getClass</span><span class="o">().</span><span class="na">getClassLoader</span><span class="o">().</span><span class="na">getResourceAsStream</span><span class="o">(</span><span class="s">&quot;foo-config.xml&quot;</span><span class="o">));</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>If the config changes then sending an event to <code>org/apache/sling/commons/log/RESET</code> would reset the Logback runtime</p>
+<div class="codehilite"><pre><span class="n">eventAdmin</span><span class="o">.</span><span class="na">sendEvent</span><span class="o">(</span><span class="k">new</span> <span class="n">Event</span><span class="o">(</span><span class="s">&quot;org/apache/sling/commons/log/RESET&quot;</span><span class="o">,</span><span class="k">new</span> <span class="n">Properties</span><span class="o">()));</span>
+</pre></div>
+
+
+<h3 id="external-config-file">External Config File</h3>
+<p>Logback can be configured with an external file. The file name can be specified through</p>
+<ol>
+<li>OSGi config - Look for config with name <code>Apache Sling Logging Configuration</code> and specify the path for
+   config file property</li>
+<li>OSGi Framework Properties - Logback supports also looks for file name with property name
+   <code>org.apache.sling.commons.log.configurationFile</code></li>
+</ol>
+<p>If you are providing an external config file then to support OSGi integration you would need to add following
+action entry</p>
+<div class="codehilite"><pre><span class="nt">&lt;newRule</span> <span class="na">pattern=</span><span class="s">&quot;*/configuration/osgi&quot;</span>
+         <span class="na">actionClass=</span><span class="s">&quot;org.apache.sling.commons.log.logback.OsgiAction&quot;</span><span class="nt">/&gt;</span>
+<span class="nt">&lt;newRule</span> <span class="na">pattern=</span><span class="s">&quot;*/configuration/appender-ref-osgi&quot;</span>
+         <span class="na">actionClass=</span><span class="s">&quot;org.apache.sling.commons.log.logback.OsgiAppenderRefAction&quot;</span><span class="nt">/&gt;</span>
+<span class="nt">&lt;osgi/&gt;</span>
+</pre></div>
+
+
+<p>The <code>osgi</code> element enables the OSGi integration support</p>
+<h3 id="java-util-logging-jul-integration">Java Util Logging (JUL) Integration</h3>
+<p>The bundle also support <a href="http://www.slf4j.org/api/org/slf4j/bridge/SLF4JBridgeHandler.html">SLF4JBridgeHandler</a>. To enable JUL integration following two steps
+needs to be done. This features allows routing logging messages from JUL to the Logbback appenders</p>
+<ol>
+<li>Set framework property <code>org.apache.sling.commons.log.julenabled</code> to true</li>
+<li>
+<p>Set the <a href="http://logback.qos.ch/manual/configuration.html#LevelChangePropagator">LevelChangePropagator</a> in LogbackConfig</p>
+<p>:::xml
+<configuration>
+  <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"/>
+  ...
+</configuration></p>
+</li>
+</ol>
+<h3 id="wzxhzdk11wzxhzdk12configuring-osgi-based-appenders-in-logback-config"><a name="config-override"></a>Configuring OSGi based appenders in Logback Config</h3>
+<p>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</p>
+<p>For example for following OSGi config</p>
+<div class="codehilite"><pre><span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">sling</span><span class="p">.</span><span class="n">commons</span><span class="p">.</span><span class="nb">log</span><span class="p">.</span><span class="n">file</span><span class="p">=</span>&quot;<span class="n">logs</span><span class="o">/</span><span class="n">error</span><span class="p">.</span><span class="nb">log</span>&quot;
+<span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">sling</span><span class="p">.</span><span class="n">commons</span><span class="p">.</span><span class="nb">log</span><span class="p">.</span><span class="n">level</span><span class="p">=</span>&quot;<span class="n">info</span>&quot;
+<span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">sling</span><span class="p">.</span><span class="n">commons</span><span class="p">.</span><span class="nb">log</span><span class="p">.</span><span class="n">file</span><span class="p">.</span><span class="nb">size</span><span class="p">=</span>&quot;<span class="s">&#39;.&#39;</span><span class="n">yyyy</span><span class="o">-</span><span class="n">MM</span><span class="o">-</span><span class="n">dd</span>&quot;
+<span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">sling</span><span class="p">.</span><span class="n">commons</span><span class="p">.</span><span class="nb">log</span><span class="p">.</span><span class="n">file</span><span class="p">.</span><span class="n">number</span><span class="p">=</span><span class="n">I</span>&quot;7&quot;
+<span class="n">org</span><span class="p">.</span><span class="n">apache</span><span class="p">.</span><span class="n">sling</span><span class="p">.</span><span class="n">commons</span><span class="p">.</span><span class="nb">log</span><span class="p">.</span><span class="n">pattern</span><span class="p">=</span>&quot;<span class="p">{</span>0<span class="p">,</span><span class="n">date</span><span class="p">,</span><span class="n">dd</span><span class="p">.</span><span class="n">MM</span><span class="p">.</span><span class="n">yyyy</span> <span class="n">HH</span><span class="p">:</span><span class="n">mm</span><span class="p">:</span><span class="n">ss</span><span class="p">.</span><span class="n">SSS</span><span class="p">}</span> <span class="o">*</span><span class="p">{</span>4<span class="p">}</span><span class="o">*</span> <span class="p">[{</span>2<span class="p">}]</span> <span class="p">{</span>3<span class="p">}</span> <span class="p">{</span>5<span class="p">}</span>&quo
 t;
+</pre></div>
+
+
+<p>The Logback appender would be named as <code>logs/error.log</code>. To extend/override the config in Logback config
+create an appender with name <code>logs/error.log</code></p>
+<div class="codehilite"><pre><span class="nt">&lt;appender</span> <span class="na">name=</span><span class="s">&quot;/logs/error.log&quot;</span> <span class="na">class=</span><span class="s">&quot;ch.qos.logback.core.FileAppender&quot;</span><span class="nt">&gt;</span>
+  <span class="nt">&lt;file&gt;</span>${sling.home}/logs/error.log<span class="nt">&lt;/file&gt;</span>
+  <span class="nt">&lt;encoder&gt;</span>
+    <span class="nt">&lt;pattern&gt;</span>%d %-5level %X{sling.userId:-NA} [%thread] %logger{30} %marker- %msg %n<span class="nt">&lt;/pattern&gt;</span>
+    <span class="nt">&lt;immediateFlush&gt;</span>true<span class="nt">&lt;/immediateFlush&gt;</span>
+  <span class="nt">&lt;/encoder&gt;</span>
+<span class="nt">&lt;/appender&gt;</span>
+</pre></div>
+
+
+<p>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</p>
 <h2 id="webconsole-plugin-enhancements">WebConsole Plugin enhancements</h2>
 <p>The web Console Plugin supports following features</p>
 <ul>
@@ -494,7 +494,7 @@ to <code>5</code> (which happens to be t
 </ul>
 <p><img src="sling-log-support.png" /></p>
       <div class="timestamp" style="margin-top: 30px; font-size: 80%; text-align: right;">
-        Rev. 1542739 by chetanm on Sun, 17 Nov 2013 14:43:57 +0000
+        Rev. 1542740 by chetanm on Sun, 17 Nov 2013 14:50:04 +0000
       </div>
       <div class="trademarkFooter"> 
         Apache Sling, Sling, Apache, the Apache feather logo, and the Apache Sling project



Mime
View raw message