Hello

Here's new readme.adoc I prepared for pax-logging (probably a good
candidate for PAXLOGGING wiki):

= PAX-LOGGING
>
> The goal of this project is to allow users and bundles to use well known
> Logging APIs like SLF4J or Commons-Logging.
>
> There should be a distinction between _Logging API_ which, by itself,
> doesn't do any log, but instead requires specific logging implementation
> (and related configuration) and the _Logging implementation_ itself.
>
> Logging APIs (or _Facades_) matching the above distinction include:
>
> * https://www.slf4j.org/[SLF4J]
> * https://commons.apache.org/proper/commons-logging/[Commons Logging]
> * https://osgi.org/specification/osgi.cmpn/7.0.0/service.log.html[OSGi
> Compendium Log Service]
> *
> http://docs.jboss.org/hibernate/orm/4.3/topical/html/logging/Logging.html[JBoss
> Logging]
>
> Logging implementations always provide their own _APIs_ and can be used
> without any of the above facades. These include:
>
> * https://logging.apache.org/log4j/1.2/[Apache Log4j]
> * https://logging.apache.org/log4j/2.x/[Apache Log4j2]
> * https://logback.qos.ch/[Logback]
>
> However usage of Logback _without_ SLF4J is very rare and won't be
> implemented in pax-logging.
>
> And the above three (with their specific configuration file syntax) are
> supported by (respectively):
>
> * pax-logging-service (log4j1)
> * pax-logging-log4j2 (log4j2)
> * pax-logging-logback (logoback)
>
> `pax-logging-service` is not called `pax-logging-log4j1` due to backward
> compatibility.
>
> == Different Logging APIs
>
> The fundamental interface is `org.osgi.service.log.LogService` from
> Chapter 101 of OSGi Compendium specification.
> The history of `org.osgi.service.log` package versions is:
>
> * `1.0`: OSGi R1
> * `1.1`: OSGi R2
> * `1.2`: OSGi R3
> * `1.3`: OSGi R4, R4.1, R4.2, R4.3, R5, R6
> * `1.4`: OSGi R7
>
> pax-logging-api uses version `1.3` from OSGi Compendium R6.
>
> Each class that's an entry point to specific Logging framework (like
> `org.slf4j.LoggerFactory`) interacts with pax-logging using
> `org.ops4j.pax.logging.PaxLoggingManager`. This _manager_ tracks instances
> of framework-specific `org.ops4j.pax.logging.PaxLoggingService` services
> that eventually delegate to particular framework (like Log4j2).
>
> This indirection allows to plug-in OSGi specific mechanism (like replacing
> `org.ops4j.pax.logging.PaxLoggingService` implementation at runtime.
>
> === SLF4J
>
> `slf4j-api-1.7.26-sources.jar` contains more sources than
> `slf4j-api-1.7.26.jar` has classes - in particular, `org.slf4j.impl`
> package is removed from the jar and the responsibility to provide:
>
> * `org.ops4j.impl.StaticLoggerBinder`
> * `org.ops4j.impl.StaticMDCBinder`
> * `org.ops4j.impl.StaticMarkerBinder`
>
> classes lies on the side of _binding library_ for SLF4J API. Such classes
> are provided by (among others):
>
> * `logback-classic-1.2.3.jar`
> * `log4j-slf4j-impl-2.11.2.jar`
> * `slf4j-nop-1.7.26.jar`
> * `slf4j-log4j12-1.7.26.jar`
> * `slf4j-simple-1.7.26.jar`
>
> pax-logging-api provides own implementation of these three classes. All
> other classes are directly repackaged (using bndlib) from
> `slf4j-api-1.7.26.jar` - classes that don't have to be changed are no
> longer shipped in pax-logging-api source directory.
>
> === Commons Logging
>
> While SLF4J takes simple and elegant approach for finding the actual
> implementation (`StaticLoggerBinder`), Commons Logging uses old school
> discovery through various ClassLoader and ServiceLoader tricks.
>
> In pax-logging, all this discovery is not needed, so the only
> reimplemented class is `org.apache.commons.logging.LogFactory` with all the
> discovery code removed.
>
> === Apache JULI
>
> Apache JULI is specialized (and repackaged) version of Commons Logging
> with original discovery mechanism already removed for Tomcat's internal
> logging mechanism purposes.
>
> In pax-logging, there was less work to do - discovery mechanism was
> already removed, only
> `org.apache.juli.logging.LogFactory.getInstance(java.lang.String)` method
> was changed to delegate to `PaxLoggingManager`.
>
> === Avalon Logging
>
> Ancient Avalon framework predates most (if not all) Java server frameworks
> aiming to provide code and component organization patterns and programming
> model. Without dealing much with archeology, pax-logging-api provides
> support for `org.apache.avalon.framework.logger` package where the ultimate
> _source of truth_ is
> https://svn.apache.org/repos/asf/excalibur/tags/avalon-framework-api-4.3-Release/framework/api/src/java/org/apache/avalon/framework/logger/[this
> SVN tag and directory].
>
> There are no _factory methods_ to access Avalong loggers as we know from
> SLF4J or even from Commons Logging. There's simply new instance creation,
> where the reference may be assigned to
> `org.apache.avalon.framework.logger.Logger` interface. Thus pax-logging-api
> doesn't include any source from Avalon Framework. Simply implementation of
> `org.apache.avalon.framework.logger.Logger` is provided.
>
> Excalibur (actual library/framework using Avalon) simply provides concrete
> implementations of `org.apache.avalon.framework.logger.Logger`, like:
>
> * `org.apache.avalon.excalibur.logger.Log4JLogger`
> * `org.apache.avalon.framework.logger.NullLogger`
> * `org.apache.avalon.framework.logger.CommonsLogger`
> * `org.apache.avalon.excalibur.logger.ServletLogger`
> * `org.apache.avalon.framework.logger.Jdk14Logger`
> * `org.apache.avalon.framework.logger.ConsoleLogger`
>
> To achieve _factory method_ approach, pax-logging-api exports
> `org.ops4j.pax.logging.avalon` package with special (not implied from
> Avalon Framework design) factory class for Avalon loggers. For other
> facades, package with factory classes is not `org.ops4j.pax.logging.*`.
>
> === JBoss Logging
>
> JBoss started to use dedicated logging _bridge_ (facade) with
> http://docs.jboss.org/hibernate/orm/4.3/topical/html/logging/Logging.html[Hibernate
> 4.0]. Similarly to e.g., Commons Logging, actual logging framework is
> discovered at runtime.
>
> JBoss Logging can delegate to either concrete logging implementation (like
> Log4j1, Log4j2) or another logging facade (like SLF4J or Commons Logging).
> It uses discovery (ClassLoader + ServiceLoader) mechanism to find the
> framework to delegate to.
>
> Originally, `org.jboss.logging.provider` property may be set to one of
> these values:
>
> * jboss
> * jdk
> * log4j2
> * log4j
> * slf4j
>
> Then discovery checks ServiceLoader for `org.jboss.logging.Provider`
> provider (`/META-INF/services/org.jboss.logging.Provider`).
>
> pax-logging API doesn't yet delegate JBoss Logging API to pax-logging OSGi
> manager.
> https://ops4j1.jira.com/browse/PAXLOGGING-251[PAXLOGGING-251] tracks
> issue.
>
> === Knopflerfish
>
> https://www.knopflerfish.org/archive.html[This page] shows Knopflerfish
> releases groupped by OSGi release version.
>
> Knopflerfish 6 matches OSGi R6 and `org.osgi.service.log` version `1.3`.
>
> Knopflerfish is not yet another Logging facade/bridge. It's fully-fledged
> OSGi framework while specifically `org.knopflerfish.kf6:log-API` JAR
> provides specific package `org.knopflerfish.service.log`, where
> `org.knopflerfish.service.log.LogService` is an extension of standard
> `org.osgi.service.log.LogService` OSGi service.
>
> What's interesting here is that there's no need to provide special bridge
> to pax-logging delegation mechanism.
> `org.ops4j.pax.logging.PaxLoggingService` already extends
> `org.knopflerfish.service.log.LogService`.
>
> `org.knopflerfish.service.log` provides nice utility
> `org.knopflerfish.service.log.LogRef` which is effectively a
> `org.osgi.util.tracker.ServiceTracker` that makes it easier to deal with
> OSGi LogService.
>
> === Log4j
>
> Ah, the grandfather of all configurable Logging frameworks. Created when
> there was no logging bridges/facades around. Actually first facades
> (Commons Logging) was created to bridge common logging API to one of
> different logging frameworks (back then, it was only Log4j1 and Java Util
> Logging (JUL) from JDK1.4).
>
> Because its origins are in pre-logging bridge times, Log4j1's API was used
> directly by very large amount of code. That's why pax-logging fully
> supports its native API.
>
> Also, this was the first logging framework embraced by pax-logging project
> itself.
>
> === Logback
>
> As mentioned on https://logback.qos.ch/[project's web page], Logback
> _picks up where log4j leaves off_.
>
> Logback was created after the logging-bridge (r)evolution and even if it
> may be used without any logging facade/bridge, it is very uncommon to do
> so. That's why there are no special API classes in pax-logging-api related
> to Logback. Logback is handled by pax-logging _only_ through implementation
> of `org.ops4j.pax.logging.PaxLoggingService`.
>
> Logback is mostly used behind SLF4J facade and both logger factory and
> MDC/NDC API comes from SLF4J itself when dealing with Logback.
>
> === Log4j2
>
> After huge (in my humble, subjective opinion) success of Logback, Log4j2
> was created as modernized version of original Log4j project with full
> awareness of logging bridges/facades and weird properties file syntax.
>
> pax-logging provides dedicated implementation of
> `org.ops4j.pax.logging.PaxLoggingService` that delegates to Log4j2.
>
> Again, Log4j2 itself may be used without bridge/facade and (differently
> than with Logback) pax-logging fully supports its native API.
>

regards
Grzegorz Grzybek

pt., 19 kwi 2019 o 11:55 Grzegorz Grzybek <[email protected]> napisał(a):

> Hello
>
> Also, I've found, that pax-logging's org.jboss.logging.LoggerProviders
> simply instantiates static org.jboss.logging.Log4j2LoggerProvider which
> doesn't delegate further to PaxLoggingManager / PaxLoggingService. I think
> I can handle this.
>
> regards
> Grzegorz Grzybek
>
> pt., 19 kwi 2019 o 06:49 Grzegorz Grzybek <[email protected]>
> napisał(a):
>
>> Hello
>>
>> pt., 19 kwi 2019 o 04:19 Niclas Hedhman <[email protected]> napisał(a):
>>
>>> For your last point; OSGIPaxLoggingManager becoming a singleton... The
>>> amount of memory or other overhead you save with that is minimal, and I
>>> recommend against the proposed change. In general, we don't try to maximize
>>> the utilization of trackers in OSGi, but let each client handle its own
>>> tracker to keep responsibilities near the usages. IF you decide to do it
>>> anyway, you will still need to keep the public constructor as it is part of
>>> the official API and don't want to break compatibility over such a minor
>>> thing.
>>>
>>
>> Thanks for technical suggestions. I already started checking the
>> "singleton" version of OSGIPaxLoggingManager. I wasn't that much concerned
>> about number of trackers created, but with general code organization.
>> There are six _clients_ but OSGIPaxLoggingManager was not created once
>> for every client - for example with SLF4J, the manager was created both
>> inside Slf4jLoggerFactory and in Slf4jMDCAdapter. That's one thing. Another
>> was that most (not all) of these "manager keepers" were holding Map<String,
>> ClientSpecificLogger> m_loggers - only to ensure that loggers created
>> between static client/factory was created and OSGIPaxLoggingManager was set.
>> For now, I extracted "setPaxLoggingManager" method to
>> PaxLoggingManagerAwareLogger interface and I can keep single Map<String,
>> PaxLoggingManagerAwareLogger> m_loggers map in the Activator itself (I can
>> think of moving it somewhere else) - so far, all _clients_ contains the
>> same code related to m_loggers.
>>
>> So less optimization (because it's not a problem here), but code cleanup,
>> comments and consistency.
>>
>> In addition, I was able (so far) to:
>> - keep only those sources from slf4j/commons-logging/... that are needed,
>> other classes from original _clients_ are simply private-packaged (and
>> exported)
>> - enforce a convention that _client_ specific overrides are in their
>> original package and supporting classes (like
>> org.ops4j.pax.logging.slf4j.Slf4jLoggerFactory) are kept in
>> org.ops4j.pax.logging._clientid_. IMO these packages should not be exported
>> (I have to be delicate here) - org.ops4j.pax.logging.slf4j is exported but
>> org.ops4j.pax.logging.log4jv2 not.
>> - additionally, I added pax-logging-api-test project which has
>> maven-invoker based tests to show different API usages and ensure that
>> pax-logging-api adheres to these idioms. For example (no pax-logging-api
>> usage, just awareness of the implementation):
>>
>> package org.ops4j.pax.logging.test.slf4j;
>>
>> import org.junit.Test;
>> import org.slf4j.Logger;
>> import org.slf4j.LoggerFactory;
>> import org.slf4j.MDC;
>>
>> import static org.junit.Assert.assertTrue;
>>
>> public class FactoryTest {
>>
>>     @Test
>>     public void paxLoggingSpecificSlf4jFactory() {
>>         Logger log = LoggerFactory.getLogger(this.getClass());
>>         log.info("Factory: {}", LoggerFactory.getILoggerFactory());
>>
>>
>> assertTrue(LoggerFactory.getILoggerFactory().getClass().getName().startsWith("
>> *org.ops4j.pax.logging.slf4j*"));
>>     }
>>
>>     @Test
>>     public void paxLoggingSpecificMDC() {
>>         assertTrue(MDC.getMDCAdapter().getClass().getName().startsWith("
>> *org.ops4j.pax.logging.slf4j*"));
>>     }
>>
>> }
>>
>> pax-logging didn't have maven-bundle-plugin:baseline verification (like
>> pax-web) and I'm not (yet) sure if adding new interface (and not touching
>> previous exported packages) requires bumping version to 2.0 (I don't think
>> so). There's no pax-logging 1.11.0 yet, so minor version upgrade allows
>> _some_ API changes.
>> I'll keep you informed.
>>
>> Also there's this PAXLOGGING-240 ("ClassCastException with log4j2 on
>> org.apache.logging.log4j.core.LoggerContext") issue which _may_ require
>> some API reorganization.
>>
>> I just have some time now and want to do some maintenance work for pax
>> project (I'm working on https://ops4j1.jira.com/browse/PAXWEB-1190 as
>> well).
>>
>> regards
>> Grzegorz Grzybek
>>
>>
>>>
>>> Cheers
>>> Niclas
>>>
>>> On Thu, Apr 18, 2019 at 1:54 PM Grzegorz Grzybek <[email protected]>
>>> wrote:
>>>
>>>> Hello
>>>>
>>>> I have few issues backlogged for PAXLOGGING Jira:
>>>>  – PAXLOGGING-243: Incorrect bundle names in the logs in case of the
>>>> logs come from embeded lib
>>>>  – PAXLOGGING-247: pax-logging-api/Slf4jMDCAdapter uses stale MDC after
>>>> refreshing service bundle
>>>>  – PAXLOGGING-249: JUL loggers are not properly configured if used
>>>> before calling PaxLoggingServiceImpl#setJULLevel
>>>>  – PAXLOGGING-250: Log4j2 - JNDI based JDBC appender should be more lazy
>>>>
>>>> So I started to review the code (licenses, deps, upgrading from old
>>>> org.ops4j:master:3.3.0, ...).
>>>>
>>>> I see some code could be refreshed and improved. Here are my concerns
>>>> which I'll try to handle if I won't get any feedback):
>>>>  – should we switch compiler settings to Java8? Not necessary
>>>>  – I want to upgrade log4j2, slf4j, logback and jboss logging deps
>>>>  – I want to get rid of those source files from external libs which can
>>>> be simply private packaged
>>>>  – I want to switch org.ops4j.pax.logging.OSGIPaxLoggingManager usage
>>>> to singleton - now, each logging facade uses own copy of this manager,
>>>> which is effectively a tracker for given PaxLoggingService.
>>>>
>>>> What do you think?
>>>>
>>>> regards
>>>> Grzegorz Grzybek
>>>>
>>>> --
>>>> --
>>>> ------------------
>>>> OPS4J - http://www.ops4j.org - [email protected]
>>>>
>>>> ---
>>>> You received this message because you are subscribed to the Google
>>>> Groups "OPS4J" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>> an email to [email protected].
>>>> For more options, visit https://groups.google.com/d/optout.
>>>>
>>>
>>>
>>> --
>>> Niclas Hedhman, Software Developer
>>> http://polygene.apache.org - New Energy for Java
>>>
>>> --
>>> --
>>> ------------------
>>> OPS4J - http://www.ops4j.org - [email protected]
>>>
>>> ---
>>> You received this message because you are subscribed to the Google
>>> Groups "OPS4J" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to [email protected].
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>

-- 
-- 
------------------
OPS4J - http://www.ops4j.org - [email protected]

--- 
You received this message because you are subscribed to the Google Groups 
"OPS4J" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to