[logback-user] Avoid pre-initialization upon the first LoggerFactory.getILoggerFactory();

Adam Gent adam.gent at snaphop.com
Wed Jun 29 14:47:57 UTC 2016


To your point though the real issue is initialization of slf4j.

Unfortunately it is extremely static for performance reasons.
I wanted to push to put some sort of initialization hook in slf4j
similar to logbacks Service Loader but I thought it was out of scope.

Of course one of the tricks is to write your own logging wrapper also
known as a slf4j bridge on top of an existing logging framework.
Except that framework **better not support slf4j natively** otherwise
you will have to basically fork the entire logging framework.

I do think SLF4J is somewhat inherently flawed because of this or at
least libraries that do not separate the bridge portion (logback being
one of them). I understand the extremely minor albeit I suppose
performance issues with an additional method call as to why native is
a good thing.

Regardless I am of the strong opinion given the cloud world we live in
that configuration should load first and not the logging framework.
Frameworks that control boot up should allow a hook for initialization
that either does no logging or uses its own internal logging framework
(I'm looking at you Spring).

It is a good thing to have to separate logging implementations for
phases. One that is responsible for boot up of the config
framework.... in the case of Tomcat JULI works nice. And then slf4j
for post config boot up. The problem is every library is getting SL4J
support foisted on them. If all libraries switch to SL4J it becomes
harder to do a two stage approach.

-Adam



On Mon, Jun 27, 2016 at 12:47 PM, Brice Dutheil <brice.dutheil at gmail.com> wrote:
> Thanks Adam, interesting project. However in the end I abandoned this way of
> initializing logs.
>
> Too bad logback / slf4j does'nt allow a way to give a configuration supplier
> or some configuration hook.
>
> -- Brice
>
> On Mon, Jun 13, 2016 at 3:39 PM, Adam Gent <adam.gent at snaphop.com> wrote:
>>
>> I will tell you how we deal with this but you will have to first
>> listen to my soap box rant :)
>>
>> This is a common problem with almost all Java logging where you have a
>> chicken or the egg issue of logging or configuration (respectively).
>>
>> Right now Logging almost always wins (ie loads before configuration)
>> and because it loads first it thus must have its own configuration
>> framework. This is extremely annoying if you want to use a distributed
>> configuration management system (e.g. Archaius, Etc.d, Consul, etc...)
>> as the clients to these systems will invariable load up logging and
>> thus you cannot configure your logging system with these systems.
>>
>> I have known about this issue for quite some time and I have been
>> meaning to email Ceki about it and ask what his thoughts are.
>> This is in fact one of the reasons why I pushed to add the Service
>> Loader mechanism to control initialization (see
>> https://github.com/qos-ch/logback/pull/181) and is one way you could
>> solve this problem.
>>
>>
>> The other way as David alluded to is just to load your configuration
>> before any logging happens. The trick to do that in a servlet
>> container I have found is to use a ServletContextListener as the entry
>> point and to do your loading of your configuration there. Make sure to
>> register the listener before any other listeners (ie further up on the
>> web.xml). You would do this for both web apps. I do this for other
>> reasons besides logging for legacy libraries that use system
>> properties. Passing system properties on the command line is IMO a
>> security hazard so I load them up from an external properties file.
>>
>> I have been meaning to opensource more of our companies internal
>> configuration library that does not use any logging and thus is safe
>> to preload before logging does. I had started it here but had not
>> finished it:
>> https://github.com/agentgt/configfacade
>>
>> -Adam
>>
>>
>> On Mon, Jun 13, 2016 at 5:24 AM, Brice Dutheil <brice.dutheil at gmail.com>
>> wrote:
>> > Hi David,
>> >
>> > Thanks for the reply, but I’m speaking about 2 web-apps (i.e. 2 war
>> > files)
>> > that are deployed by a single tomcat instance. That means I don’t have
>> > access to the main and as it is a single JVM I cannot use the system
>> > property, because both web-apps will now have the same value for
>> > app.name.
>> >
>> > Cheers,
>> > — Brice
>> >
>> > On Fri, Jun 10, 2016 at 12:36 PM, David Roussel
>> > <nabble at diroussel.xsmail.com> wrote:
>> >>
>> >> Hi,
>> >>
>> >> There are two ways to deal with this.
>> >>
>> >> 1) Put your log initialisation at the top of your main() method, so
>> >> nothing else can run first.
>> >>
>> >> 2) Specify the app name as a system property on the command line:
>> >>
>> >>   java -Dapp.name=MyApp -jar myappjar
>> >>
>> >> Thanks
>> >>
>> >> David
>> >>
>> >> On 10 Jun 2016, at 10:20, Brice Dutheil <brice.dutheil at gmail.com>
>> >> wrote:
>> >>
>> >> Hi,
>> >>
>> >> I would like share a single log configuration for two web-apps that run
>> >> on
>> >> the same container. Yet I want each web-app to log in separate files.
>> >>
>> >> I tried different approach the best one is actually very close to some
>> >> solution I later found on the FAQ :
>> >> http://logback.qos.ch/faq.html#sharedConfiguration
>> >>
>> >> LoggerContext loggerContext = (LoggerContext)
>> >> LoggerFactory.getILoggerFactory();
>> >> JoranConfigurator jc = new JoranConfigurator();
>> >> jc.setContext(loggerContext);
>> >> loggerContext.reset();
>> >> loggerContext.setName(appName); // use ${CONTEXT_NAME} in logback.xml
>> >> jc.doConfigure(Objects.requireNonNull(source, "Logback configuration is
>> >> missing"));
>> >>
>> >> However for operation reasons we pass the configuration via the system
>> >> property logback.configurationFile, so what happens is that the first
>> >> call
>> >> to LoggerFactory.getILoggerFactory() initialise the LoggerContext and
>> >> creates files with non initialised variables.
>> >>
>> >> As I’m using the context name, the file names have default in their
>> >> name
>> >> (this is the default value of the context name), if using variable I
>> >> get a
>> >> filename with my-var-name_IS_UNDEFINED.
>> >>
>> >> The question is : Is there proper way anyway to avoid this
>> >> pre-initialisation to avoid creating this empty file ?
>> >>
>> >> I didn’t found any way to hook in the org.slf4j.LoggerFactory or
>> >> org.slf4j.impl.StaticLoggerBinder (of logback-classic).
>> >>
>> >> — Brice
>> >>
>> >> _______________________________________________
>> >> logback-user mailing list
>> >> logback-user at qos.ch
>> >> http://mailman.qos.ch/mailman/listinfo/logback-user
>> >>
>> >>
>> >>
>> >> _______________________________________________
>> >> logback-user mailing list
>> >> logback-user at qos.ch
>> >> http://mailman.qos.ch/mailman/listinfo/logback-user
>> >
>> >
>> > _______________________________________________
>> > logback-user mailing list
>> > logback-user at qos.ch
>> > http://mailman.qos.ch/mailman/listinfo/logback-user
>>
>>
>>
>> --
>> CTO
>> SnapHop (snaphop.com)
>> (twitter) @agentgt (linkedin) http://www.linkedin.com/in/agentgt
>> (cell) 781-883-5182
>> _______________________________________________
>> logback-user mailing list
>> logback-user at qos.ch
>> http://mailman.qos.ch/mailman/listinfo/logback-user
>
>
>
> _______________________________________________
> logback-user mailing list
> logback-user at qos.ch
> http://mailman.qos.ch/mailman/listinfo/logback-user



-- 
CTO
SnapHop (snaphop.com)
(twitter) @agentgt (linkedin) http://www.linkedin.com/in/agentgt
(cell) 781-883-5182


More information about the logback-user mailing list