I agree with Ralph that implementing the new SLF4J method and Log4j startup are separate topics.
So let's focus on SLF4J. What are our options? These are the ones I see: 1. We compile our log4j-slf4j-impl and log4j-to-slf4j modules with 1.7.13 2. We compile our log4j-slf4j-impl and log4j-to-slf4j modules with 1.7.21 but DON'T implement the log(org.slf4j.event.LoggingEvent) method 3. We compile our log4j-slf4j-impl and log4j-to-slf4j modules with 1.7.21 and DO implement the log(org.slf4j.event.LoggingEvent) method If doing 3 means we break some applications I would favour 2. On Sun, Apr 24, 2016 at 6:33 AM, Ralph Goers <[email protected]> wrote: > I would suggest others review the code in question, but here is what I see. > > LoggerFactory initializes dynamically. The first caller binds to the > implementation of the LoggerFactory by calling > StaticLoggerBinder.getSingleton(), but only if it is the first caller. > Other callers are given a substitute logger factory until the binding is > complete. Log4j’s implementation creates a Log4jLoggerFactory instance but > performs no initialization at this time, so the amount of time that SLF4J > would be in this state should be very small. Regardless, events could still > be routed to the substitute logger. If we want to ensure that these events > are not discarded then we have to implement the new method. > > Note that due to the way Log4j initializes we don’t have this kind of race > going on anywhere. Ceki seems to imply that the race is in the underlying > logging framework, but it is not. Or perhaps he is just assuming that all > log events are coming through SLF4J, which may or may not actually be the > case. The race is entirely within SLF4J’s initialization logic. Anyone > using just the Log4j API will not have this problem. > > As I said previously, A Log4j LoggerContext always has a configuration, at > least until it is shut down, and logging an event requires a constructed > LoggerContext. A LoggerContext has a default configuration until the actual > configuration file is processed and the full configuration constructed. The > default configuration logs errors to the console. So any log events that > actually make it to Log4j will have something done with them, but maybe not > what the user wants. If we wanted to have any events that occur before > configuration is completed subject to that configuration the default > configuration would have to capture them and then republish the events when > the configuration is stopped, which is similar in concept to what SLF4J is > doing. But we can’t rely on SLF4J’s substitute loggers for this as SLF4J > may not even be in the picture. > > So as I see it, the discussion on whether to implement the support for the > new SLF4J method is completely separate from enhancing support of Log4j > logging during startup. > > Ralph > > > > > On Apr 23, 2016, at 11:16 AM, Ceki Gulcu <[email protected]> wrote: > > > SLF4J will replay the events it captured during the initialization of the > underlying logging framework, log4j2 in this case, assuming log4j2 supports > SLF4J replay via the Logger.log(o.s.event.LoggingEvent) method. > > What Raplh seems to suggest is to duplicate the SLF4J replay functionality > within log4j2. However, given that SLF4J captures events generated during > initialization, log4j2 cannot see them unless it supports SLF4J replay. For > logging frameworks without replay support, i.e. those which lack the > Logger.log(o.s.event.LoggingEvent) method, slf4j will simply drop the > events it captured. Note that log4j1, logback prior to 1.1.4, and slf4j-jul > and slf4j-simple prior to version 1.7.15 all lacked replay support but > continue to work just fine under slf4j-api 1.7.15+. > > Also note that if N is the version of slf4j-api and M is the slf4j-api > version with which a binding is compiled, then slf4j ensures binary > compatibility for all N and M in the 1.6.x and the 1.7.x series. For > example, the slf4j-api-1.6.0.jar/slf4j-simple-1.7.21.jar combination will > work just fine, same goes for the > slf4j-simple-1.7.21.jar/slf4j-api-1.6.0.jar combination. > > Compatibility is broken when the binding voluntarily supports event > replay, as was the case with logback versions 1.1.4+ which require SLF4J > version 1.7.15+. The question is whether log4j2 wants to support event > replay at the cost of dropping compatibility with earlier versions of > slf4j-api. > > I hope this further clarifies the matter, > > -- > Ceki > > > > On 4/23/2016 19:00, Ralph Goers wrote: > > I suppose that depends on the definition of “event loss”. You can’t log > without a LoggerContext and the LoggerContext is initialized with a > default configuration, which means errors will be logged to the console. > We could create a default configuration that buffers the events and logs > then again when stop is called. > > Ralph > > On Apr 23, 2016, at 7:18 AM, Ceki Gulcu <[email protected] > <mailto:[email protected] <[email protected]>>> wrote: > > You are welcome. > > In the principle, the event loss issue (fixed by event replay > post-initialization) depends on the time it takes for the underlying > implementation to initialize. Unless you can guarantee that log4j2 > initializes instantly**, during SLF4J initialization event loss will > occur with log4j2 as well. Note the event loss issue is limited to > applications using slf4j which are multi-threaded early on. > > > Would you mind sharing which applications perform reflection on > > the org.slf4j.Logger implementation (and why)? > > The typical example is Spring which may do reflection on logger > instances. If the org.slg4j.Logger implementation offers the > log(org.slf4j.event.LoggingEvent) method, then the > org.slf4j.event.LoggingEvent interface must exist on the class path. > Otherwise, the Spring initialization will fail. The > org.slf4j.event.LoggingEvent interface was introduced in slf4j-api > version 1.7.15. It follows that if you decide to make use of the slf4j > replay feature, then log42 will de facto depend on slf4j version > 1.7.15 both at compile and runtime. > > -- > Ceki > > **I am presuming here that log4j2 initializes when it creates and > returns its first Logger. > > On 4/23/2016 15:54, Remko Popma wrote: > > ...and thank you for the info, Ceki, that is certainly helpful! > > Remko > > On Saturday, 23 April 2016, Remko Popma <[email protected] > <mailto:[email protected] <[email protected]>> > <mailto:[email protected] <[email protected]>>> wrote: > > Question: does the replay support solve a problem in SLF4J or in > Logback initialization? > > If the latter, then perhaps there's no need to implement the new > method since log4j-slf4j-impl binds to log4j2 anyway, no? > > Remko > > Sent from my iPhone > > > On 2016/04/23, at 22:12, Ceki Gulcu <[email protected] > <mailto:[email protected] <[email protected]>> <javascript:;>> > wrote: > > > > Hello, > > > > For your information, slf4j-api version 1.7.21 will work with > current versions of log4j2 just fine albeit without replay support. > For replay support, log4j2's implementation of org.slf4j.Logger > interface needs to have a method with the signature > log(org.slf4j.event.LoggingEvent) in which case events generated > during SLF4J initialization will be replayed. Note that if log4j2's > Logger implementation chooses to implement the aforementioned log > method, log42 will de facto depend on SLF4J version 1.7.15 and later > both at compile and *runtime*. > > > > The runtime dependency might seem surprising but some > applications perform reflection on the org.slf4j.Logger > implementation which will fail without slf4j-api 1.7.15 or later > being present on the classpath. > > > > I hope this helps, > > > > -- > > Ceki > > > >> On 4/23/2016 14:47, Ralph Goers wrote: > >> We are not fully compatible with this version of SLF4J. It > had some > >> initialization race conditions so Substitute Loggers were > invented. > >> Anyway, there is a new interface we need to implement. > >> > >> Ralph > >> > >> Begin forwarded message: > >> > >>> *From:* "Remko Popma (JIRA)" <[email protected] > <mailto:[email protected] <[email protected]>><javascript:;> > <mailto:[email protected] <[email protected]><javascript:;>>> > >>> *Date:* April 23, 2016 at 4:13:12 AM MST > >>> *To:*[email protected] > <mailto:[email protected] <[email protected]> > ><javascript:;> > <mailto:[email protected] <[email protected]> > <javascript:;>> > >>> *Subject:* *[jira] [Closed] (LOG4J2-1375) Update SLF4J from > 1.7.13 to > >>> 1.7.21* > >>> *Reply-To:* "Log4J Developers List" > <[email protected] > <mailto:[email protected] <[email protected]> > ><javascript:;> > >>> <mailto:[email protected] <[email protected]> > <javascript:;>>> > >>> > >>> > >>> [ > >>> > > https://issues.apache.org/jira/browse/LOG4J2-1375?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel > >>> ] > >>> > >>> Remko Popma closed LOG4J2-1375. > >>> ------------------------------- > >>> Resolution: Fixed > >>> > >>>> Update SLF4J from 1.7.13 to 1.7.21 > >>>> ---------------------------------- > >>>> > >>>> Key: LOG4J2-1375 > >>>> URL: > https://issues.apache.org/jira/browse/LOG4J2-1375 > >>>> Project: Log4j 2 > >>>> Issue Type: Improvement > >>>> Components: SLF4J Bridge > >>>> Affects Versions: 2.5 > >>>> Reporter: Remko Popma > >>>> Assignee: Remko Popma > >>>> Fix For: 2.6 > >>>> > >>>> > >>>> Update SLF4J from 1.7.13 to 1.7.21 > >>> > >>> > >>> > >>> -- > >>> This message was sent by Atlassian JIRA > >>> (v6.3.4#6332) > >>> > >>> > --------------------------------------------------------------------- > >>> To unsubscribe, e-mail: > [email protected] > <mailto:[email protected] > <[email protected]>><javascript:;> > >>> <mailto:[email protected] > <[email protected]><javascript:;>> > >>> For additional commands, e-mail: > [email protected] > <mailto:[email protected] > <[email protected]>><javascript:;> > >>> <mailto:[email protected] > <[email protected]><javascript:;>> > > > > > --------------------------------------------------------------------- > > To unsubscribe, e-mail:[email protected] > <mailto:[email protected] > <[email protected]>> > <javascript:;> > > For additional commands, e-mail: > [email protected] > <mailto:[email protected] > <[email protected]>><javascript:;> > > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail:[email protected] > <mailto:[email protected] > <[email protected]>> > For additional commands, e-mail:[email protected] > <mailto:[email protected] > <[email protected]>> > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [email protected] > For additional commands, e-mail: [email protected] > > >
