Oh and of course there's one more option: 4. We provide two versions of our log4j-slf4j-impl and log4j-to-slf4j modules: one that DOES and one that DOESN'T implement the log(org.slf4j.event.LoggingEvent) method
I don't like option 4 very much, I'm just mentioning this for completeness. At the moment I still think option 2 is the best trade-off. But I'm willing to be convinced otherwise. Thoughts? On Sunday, 24 April 2016, Remko Popma <[email protected]> wrote: > 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] > <javascript:_e(%7B%7D,'cvml','[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] >> <javascript:_e(%7B%7D,'cvml','[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] >> <javascript:_e(%7B%7D,'cvml','[email protected]');> >> <mailto:[email protected] <javascript:_e(%7B%7D,'cvml','[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] >> <javascript:_e(%7B%7D,'cvml','[email protected]');> >> <mailto:[email protected] >> <javascript:_e(%7B%7D,'cvml','[email protected]');>> >> <mailto:[email protected] >> <javascript:_e(%7B%7D,'cvml','[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] >> <javascript:_e(%7B%7D,'cvml','[email protected]');> >> <mailto:[email protected] <javascript:_e(%7B%7D,'cvml','[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] >> <javascript:_e(%7B%7D,'cvml','[email protected]');> >> <mailto:[email protected] <javascript:_e(%7B%7D,'cvml','[email protected]');> >> ><javascript:;> >> <mailto:[email protected] >> <javascript:_e(%7B%7D,'cvml','[email protected]');><javascript:;>>> >> >>> *Date:* April 23, 2016 at 4:13:12 AM MST >> >>> *To:*[email protected] >> <javascript:_e(%7B%7D,'cvml','[email protected]');> >> <mailto:[email protected] >> <javascript:_e(%7B%7D,'cvml','[email protected]');> >> ><javascript:;> >> <mailto:[email protected] >> <javascript:_e(%7B%7D,'cvml','[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] >> <javascript:_e(%7B%7D,'cvml','[email protected]');> >> <mailto:[email protected] >> <javascript:_e(%7B%7D,'cvml','[email protected]');> >> ><javascript:;> >> >>> <mailto:[email protected] >> <javascript:_e(%7B%7D,'cvml','[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] >> <javascript:_e(%7B%7D,'cvml','[email protected]');> >> <mailto:[email protected] >> <javascript:_e(%7B%7D,'cvml','[email protected]');> >> ><javascript:;> >> >>> <mailto:[email protected] >> <javascript:_e(%7B%7D,'cvml','[email protected]');> >> <javascript:;>> >> >>> For additional commands, e-mail: >> [email protected] >> <javascript:_e(%7B%7D,'cvml','[email protected]');> >> <mailto:[email protected] >> <javascript:_e(%7B%7D,'cvml','[email protected]');> >> ><javascript:;> >> >>> <mailto:[email protected] >> <javascript:_e(%7B%7D,'cvml','[email protected]');> >> <javascript:;>> >> > >> > >> --------------------------------------------------------------------- >> > To unsubscribe, e-mail:[email protected] >> <javascript:_e(%7B%7D,'cvml','[email protected]');> >> <mailto:[email protected] >> <javascript:_e(%7B%7D,'cvml','[email protected]');> >> > >> <javascript:;> >> > For additional commands, e-mail: >> [email protected] >> <javascript:_e(%7B%7D,'cvml','[email protected]');> >> <mailto:[email protected] >> <javascript:_e(%7B%7D,'cvml','[email protected]');> >> ><javascript:;> >> > >> >> >> --------------------------------------------------------------------- >> To unsubscribe, e-mail:[email protected] >> <javascript:_e(%7B%7D,'cvml','[email protected]');> >> <mailto:[email protected] >> <javascript:_e(%7B%7D,'cvml','[email protected]');> >> > >> For additional commands, e-mail:[email protected] >> <javascript:_e(%7B%7D,'cvml','[email protected]');> >> <mailto:[email protected] >> <javascript:_e(%7B%7D,'cvml','[email protected]');>> >> >> >> >> --------------------------------------------------------------------- >> To unsubscribe, e-mail: [email protected] >> <javascript:_e(%7B%7D,'cvml','[email protected]');> >> For additional commands, e-mail: [email protected] >> <javascript:_e(%7B%7D,'cvml','[email protected]');> >> >> >> >
