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.
