You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by Matt Sicker <bo...@gmail.com> on 2014/04/14 16:55:20 UTC

Intention to modify API

I was thinking about how to best support strange class loader environments
(like OSGi or Servlets), and in order to support a LoggerContextFactory, we
should have a registry of sorts for it. This way, a new LCF can dynamically
add or remove itself at runtime. Ideally, we'd fall back to the
SimpleLogger implementation when none are registered. There may be an added
issue with Loggers being tied to their factories and such.

Anyway, the main thing to address is the ability to change (or add)
providers at runtime. Whether or not we can support a more dynamic system
is more of a technical issue. Scanning for a default provider at
initialization still makes sense to pre-load the registry, but imagine the
scenario where a server like Tomcat uses Log4j but allows individual web
apps to provide custom providers.

I'd like to at least implement the necessary API changes before 2.0 so that
this may be possible down the line. Even if we don't use OSGi, it should
still be possible to use log4j in an OSGi framework (core or as a regular
bundle). This will certainly help adoption by the container projects.



-- 
Matt Sicker <bo...@gmail.com>

Re: Intention to modify API

Posted by Matt Sicker <bo...@gmail.com>.
On 15 April 2014 04:44, Łukasz Dywicki <lu...@code-house.org> wrote:

> Hey,
> My replies inline:
>
> Wiadomość napisana przez Matt Sicker <bo...@gmail.com> w dniu 15 kwi
> 2014, o godz. 03:08:
>
> It would defeat the purpose of using OSGi. Plus, how would that work if
> you wanted to use log4j-to-slf4j?
>
> Currently with pax-logging implementation (provides OSGi "LogService")
> slf4j bridges are completelly ignored because it requires real logging
> backend to work. I did not thing about this yet, but bridge could help here
> to forward all slf4j calls to log4j without any troubles. Only one thing
> which will be left is MDC.
>
> The log4j-to-slf4j is a JAR that makes calls to the log4j-api use slf4j as
the backend. The log4j-slf4j-impl JAR is for making slf4j-api calls use
log4j-core as the backend.

Matt, you are right about initialization - we can’t be 100% sure if all
> things are present at the boot time, however in OSGi we can set up start
> level which lets start up things in certain order and logging is regular
> "core service” you usually depend on. You can start up without logging
> backend (ie. without slf4j bridge), then install it, but it’s normal in
> this case to refresh some bundles and force re-initialization. From other
> hand, if we have backend present then bundle activation is synchronous and
> we can rely on that. I think LoggerContextFactory is so far sufficient.
>
> Oh, that makes sense. The scenario I was thinking about in regards to
plugins can be easily handled by an alternative plugin manager
implementation for OSGi that uses a service tracker or bundle tracker. I'm
looking more into this.

***

As a separate proposal, I'm thinking we should move the core SPI classes
(i.e., Appender, Filter, etc.) into its own core.spi package. This could
also be split out into its own module, but really, there isn't much point
in doing so as any plugins to Log4j will most likely need classes from
log4j-core as it is. Either way, putting them in an spi package would make
sense.

The reasoning behind this is also due to the fact that several SPI-like
classes are scattered about in core and are usually in the same package as
its implementations. Also, if we were to split off a log4j-spi module, then
OSGi users could query for services using those interfaces (and the usual
LDAP-style filters) to get information about the logging runtime. This can
allow better decoupling as the programmer would only need to use classes
from log4j-api and log4j-spi to get concrete instances for configuration
information without us having to worry about maintaining any log4j-core
backwards compatibility (other than implementing the interfaces). Thoughts?
-- 
Matt Sicker <bo...@gmail.com>

Re: Intention to modify API

Posted by Łukasz Dywicki <lu...@code-house.org>.
Hey,
My replies inline:

Wiadomość napisana przez Matt Sicker <bo...@gmail.com> w dniu 15 kwi 2014, o godz. 03:08:

> It would defeat the purpose of using OSGi. Plus, how would that work if you wanted to use log4j-to-slf4j?
Currently with pax-logging implementation (provides OSGi "LogService") slf4j bridges are completelly ignored because it requires real logging backend to work. I did not thing about this yet, but bridge could help here to forward all slf4j calls to log4j without any troubles. Only one thing which will be left is MDC.

> On 14 April 2014 19:06, Remko Popma <re...@gmail.com> wrote:
> If the separation between log4j-api and log4j-core causes issues for OSGi, then would it be an option to combine these two into a single bundle for OSGi? Would that avoid the need for registry complexity? 

Separation between core and api is good. People who wants to use loggers just depend on log4j-api and Logger class, which is great because changes of logging implementation will not cause any changes to users. Issue I currently see is how the logger is obtained. Logger.getLogger calls private/concrete class which makes hard to configure things at the runtime without classpath/class overriding.
Now log4j allows to put log levels over JMX, but it’s self contained in library. Not sure if this direct class calls will not complicate possibility to manage log4j externaly.


> On 2014/04/15, at 9:45, Matt Sicker <bo...@gmail.com> wrote:
> 
>> It's mainly to add OSGi support. Since log4j-core (or any of the providers) might not be available at the same time as log4j-api, there needs to be a way to add a LoggerContextFactory afterward to take over. This is due to how OSGi works where you can dynamically add or remove bundles at runtime. Basically, you can't depend on what's available at initialisation to be everything that's there. Plus, you can remove bundles, so you can't rely on classes being there forever (although OSGi won't take them away from you, so it's not that big a deal in that case).
>> 
>> Another example use case would be something like Tomcat or Karaf using Log4j2 internally, but allowing for installed applications (webapps or bundles in these cases) to add more plugins, a different LoggerContextFactory to override, etc.

Matt, you are right about initialization - we can’t be 100% sure if all things are present at the boot time, however in OSGi we can set up start level which lets start up things in certain order and logging is regular "core service” you usually depend on. You can start up without logging backend (ie. without slf4j bridge), then install it, but it’s normal in this case to refresh some bundles and force re-initialization. From other hand, if we have backend present then bundle activation is synchronous and we can rely on that. I think LoggerContextFactory is so far sufficient.

Kind regards,
Łukasz Dywicki
--
luke@code-house.org
Twitter: ldywicki
Blog: http://dywicki.pl
Code-House - http://code-house.org

Re: Intention to modify API

Posted by Matt Sicker <bo...@gmail.com>.
It would defeat the purpose of using OSGi. Plus, how would that work if you
wanted to use log4j-to-slf4j?


On 14 April 2014 19:06, Remko Popma <re...@gmail.com> wrote:

> If the separation between log4j-api and log4j-core causes issues for OSGi,
> then would it be an option to combine these two into a single bundle for
> OSGi? Would that avoid the need for registry complexity?
>
> Sent from my iPhone
>
> On 2014/04/15, at 9:45, Matt Sicker <bo...@gmail.com> wrote:
>
> It's mainly to add OSGi support. Since log4j-core (or any of the
> providers) might not be available at the same time as log4j-api, there
> needs to be a way to add a LoggerContextFactory afterward to take over.
> This is due to how OSGi works where you can dynamically add or remove
> bundles at runtime. Basically, you can't depend on what's available at
> initialisation to be everything that's there. Plus, you can remove bundles,
> so you can't rely on classes being there forever (although OSGi won't take
> them away from you, so it's not that big a deal in that case).
>
> Another example use case would be something like Tomcat or Karaf using
> Log4j2 internally, but allowing for installed applications (webapps or
> bundles in these cases) to add more plugins, a different
> LoggerContextFactory to override, etc.
>
>
> On 14 April 2014 17:40, Remko Popma <re...@gmail.com> wrote:
>
>> To be honest, it all sounds pretty complex to me. What is the use case?
>> You mention you want to dynamically add/remove logger context factories at
>> runtime but I'm not clear on why this is desired/required.
>>
>> If there are class loader issues we should focus on that. If there is an
>> issue that prevents OSGi from working we should work on that, but I here I
>> don't see what problem you are trying to solve. Is this for OSGi?
>>
>> Instead if diving into the solution, could you provide a clear
>> description of the problem?
>>
>> Remko
>>
>> Sent from my iPhone
>>
>> On 2014/04/15, at 8:09, Matt Sicker <bo...@gmail.com> wrote:
>>
>> Alright, here's what I'm thinking so far:
>>
>> Add a class named something like LoggerContextFactoryRegistry (yeah I
>> hate that name already). Make it a singleton class. It should keep a
>> SortedMap of int -> LoggerContextFactory (similar to how they're scanned in
>> LogManager). This class should also keep a volatile LoggerContextFactory
>> containing the current factory so it doesn't have to be recalculated every
>> time. It can be updated instead when a new factory is registered.
>>
>> Method-wise, it should have a getFactory() and a register(int,
>> LoggerContextFactory) (or call it registerFactory?) method. A lot of the
>> static initialisation of LogManager can be moved to the constructor in this
>> class.
>>
>> Being able to register the class instance itself (or the class?) works
>> better than just scanning files due to class loader differences in other
>> environments. We can't rely on the TCCL or anything like that for every
>> factory.
>>
>> Any feedback? I may end up submitting this as a patch first to get more
>> feedback, but this part of the implementation may be rather simple overall.
>>
>>
>> On 14 April 2014 11:50, Matt Sicker <bo...@gmail.com> wrote:
>>
>>> Will do. The main thing I'd like to change is the LogManager
>>> initialisation. I'd prefer that to keep a registry of
>>> LoggerContextFactories so that a different factory can be registered later
>>> on (for instance, in OSGi, you could install log4j-api, then log4j-core,
>>> and core would register itself and take over as the default factory).
>>>
>>> Anything more complex than that (like being able to use multiple
>>> factories concurrently like you can with contexts), while not necessarily
>>> requiring API changes, will require some thought as to how and if it's
>>> feasible. Of course, it would be more of an API addition for that (e.g.,
>>> selecting the non-default provider chooser or something like that).
>>> Basically, that part shouldn't be hard to make backwards compatible.
>>>
>>>
>>> On 14 April 2014 10:25, Ralph Goers <ra...@dslextreme.com> wrote:
>>>
>>>> Hopefully the changes won’t be too significant.  Can you please post
>>>> what you intend to do before commit?
>>>>
>>>> Ralph
>>>>
>>>> On Apr 14, 2014, at 7:55 AM, Matt Sicker <bo...@gmail.com> wrote:
>>>>
>>>> I was thinking about how to best support strange class loader
>>>> environments (like OSGi or Servlets), and in order to support a
>>>> LoggerContextFactory, we should have a registry of sorts for it. This way,
>>>> a new LCF can dynamically add or remove itself at runtime. Ideally, we'd
>>>> fall back to the SimpleLogger implementation when none are registered.
>>>> There may be an added issue with Loggers being tied to their factories and
>>>> such.
>>>>
>>>> Anyway, the main thing to address is the ability to change (or add)
>>>> providers at runtime. Whether or not we can support a more dynamic system
>>>> is more of a technical issue. Scanning for a default provider at
>>>> initialization still makes sense to pre-load the registry, but imagine the
>>>> scenario where a server like Tomcat uses Log4j but allows individual web
>>>> apps to provide custom providers.
>>>>
>>>> I'd like to at least implement the necessary API changes before 2.0 so
>>>> that this may be possible down the line. Even if we don't use OSGi, it
>>>> should still be possible to use log4j in an OSGi framework (core or as a
>>>> regular bundle). This will certainly help adoption by the container
>>>> projects.
>>>>
>>>>
>>>>
>>>> --
>>>> Matt Sicker <bo...@gmail.com>
>>>>
>>>>
>>>>
>>>
>>>
>>> --
>>> Matt Sicker <bo...@gmail.com>
>>>
>>
>>
>>
>> --
>> Matt Sicker <bo...@gmail.com>
>>
>>
>
>
> --
> Matt Sicker <bo...@gmail.com>
>
>


-- 
Matt Sicker <bo...@gmail.com>

Re: Intention to modify API

Posted by Remko Popma <re...@gmail.com>.
If the separation between log4j-api and log4j-core causes issues for OSGi, then would it be an option to combine these two into a single bundle for OSGi? Would that avoid the need for registry complexity? 

Sent from my iPhone

> On 2014/04/15, at 9:45, Matt Sicker <bo...@gmail.com> wrote:
> 
> It's mainly to add OSGi support. Since log4j-core (or any of the providers) might not be available at the same time as log4j-api, there needs to be a way to add a LoggerContextFactory afterward to take over. This is due to how OSGi works where you can dynamically add or remove bundles at runtime. Basically, you can't depend on what's available at initialisation to be everything that's there. Plus, you can remove bundles, so you can't rely on classes being there forever (although OSGi won't take them away from you, so it's not that big a deal in that case).
> 
> Another example use case would be something like Tomcat or Karaf using Log4j2 internally, but allowing for installed applications (webapps or bundles in these cases) to add more plugins, a different LoggerContextFactory to override, etc.
> 
> 
>> On 14 April 2014 17:40, Remko Popma <re...@gmail.com> wrote:
>> To be honest, it all sounds pretty complex to me. What is the use case? You mention you want to dynamically add/remove logger context factories at runtime but I'm not clear on why this is desired/required. 
>> 
>> If there are class loader issues we should focus on that. If there is an issue that prevents OSGi from working we should work on that, but I here I don't see what problem you are trying to solve. Is this for OSGi?
>> 
>> Instead if diving into the solution, could you provide a clear description of the problem?
>> 
>> Remko
>> 
>> Sent from my iPhone
>> 
>>> On 2014/04/15, at 8:09, Matt Sicker <bo...@gmail.com> wrote:
>>> 
>>> Alright, here's what I'm thinking so far:
>>> 
>>> Add a class named something like LoggerContextFactoryRegistry (yeah I hate that name already). Make it a singleton class. It should keep a SortedMap of int -> LoggerContextFactory (similar to how they're scanned in LogManager). This class should also keep a volatile LoggerContextFactory containing the current factory so it doesn't have to be recalculated every time. It can be updated instead when a new factory is registered.
>>> 
>>> Method-wise, it should have a getFactory() and a register(int, LoggerContextFactory) (or call it registerFactory?) method. A lot of the static initialisation of LogManager can be moved to the constructor in this class.
>>> 
>>> Being able to register the class instance itself (or the class?) works better than just scanning files due to class loader differences in other environments. We can't rely on the TCCL or anything like that for every factory.
>>> 
>>> Any feedback? I may end up submitting this as a patch first to get more feedback, but this part of the implementation may be rather simple overall.
>>> 
>>> 
>>>> On 14 April 2014 11:50, Matt Sicker <bo...@gmail.com> wrote:
>>>> Will do. The main thing I'd like to change is the LogManager initialisation. I'd prefer that to keep a registry of LoggerContextFactories so that a different factory can be registered later on (for instance, in OSGi, you could install log4j-api, then log4j-core, and core would register itself and take over as the default factory).
>>>> 
>>>> Anything more complex than that (like being able to use multiple factories concurrently like you can with contexts), while not necessarily requiring API changes, will require some thought as to how and if it's feasible. Of course, it would be more of an API addition for that (e.g., selecting the non-default provider chooser or something like that). Basically, that part shouldn't be hard to make backwards compatible.
>>>> 
>>>> 
>>>>> On 14 April 2014 10:25, Ralph Goers <ra...@dslextreme.com> wrote:
>>>>> Hopefully the changes won’t be too significant.  Can you please post what you intend to do before commit?
>>>>> 
>>>>> Ralph
>>>>> 
>>>>>> On Apr 14, 2014, at 7:55 AM, Matt Sicker <bo...@gmail.com> wrote:
>>>>>> 
>>>>>> I was thinking about how to best support strange class loader environments (like OSGi or Servlets), and in order to support a LoggerContextFactory, we should have a registry of sorts for it. This way, a new LCF can dynamically add or remove itself at runtime. Ideally, we'd fall back to the SimpleLogger implementation when none are registered. There may be an added issue with Loggers being tied to their factories and such.
>>>>>> 
>>>>>> Anyway, the main thing to address is the ability to change (or add) providers at runtime. Whether or not we can support a more dynamic system is more of a technical issue. Scanning for a default provider at initialization still makes sense to pre-load the registry, but imagine the scenario where a server like Tomcat uses Log4j but allows individual web apps to provide custom providers.
>>>>>> 
>>>>>> I'd like to at least implement the necessary API changes before 2.0 so that this may be possible down the line. Even if we don't use OSGi, it should still be possible to use log4j in an OSGi framework (core or as a regular bundle). This will certainly help adoption by the container projects. 
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> -- 
>>>>>> Matt Sicker <bo...@gmail.com>
>>>>> 
>>>> 
>>>> 
>>>> 
>>>> -- 
>>>> Matt Sicker <bo...@gmail.com>
>>> 
>>> 
>>> 
>>> -- 
>>> Matt Sicker <bo...@gmail.com>
> 
> 
> 
> -- 
> Matt Sicker <bo...@gmail.com>

Re: Intention to modify API

Posted by Matt Sicker <bo...@gmail.com>.
It's mainly to add OSGi support. Since log4j-core (or any of the providers)
might not be available at the same time as log4j-api, there needs to be a
way to add a LoggerContextFactory afterward to take over. This is due to
how OSGi works where you can dynamically add or remove bundles at runtime.
Basically, you can't depend on what's available at initialisation to be
everything that's there. Plus, you can remove bundles, so you can't rely on
classes being there forever (although OSGi won't take them away from you,
so it's not that big a deal in that case).

Another example use case would be something like Tomcat or Karaf using
Log4j2 internally, but allowing for installed applications (webapps or
bundles in these cases) to add more plugins, a different
LoggerContextFactory to override, etc.


On 14 April 2014 17:40, Remko Popma <re...@gmail.com> wrote:

> To be honest, it all sounds pretty complex to me. What is the use case?
> You mention you want to dynamically add/remove logger context factories at
> runtime but I'm not clear on why this is desired/required.
>
> If there are class loader issues we should focus on that. If there is an
> issue that prevents OSGi from working we should work on that, but I here I
> don't see what problem you are trying to solve. Is this for OSGi?
>
> Instead if diving into the solution, could you provide a clear description
> of the problem?
>
> Remko
>
> Sent from my iPhone
>
> On 2014/04/15, at 8:09, Matt Sicker <bo...@gmail.com> wrote:
>
> Alright, here's what I'm thinking so far:
>
> Add a class named something like LoggerContextFactoryRegistry (yeah I hate
> that name already). Make it a singleton class. It should keep a SortedMap
> of int -> LoggerContextFactory (similar to how they're scanned in
> LogManager). This class should also keep a volatile LoggerContextFactory
> containing the current factory so it doesn't have to be recalculated every
> time. It can be updated instead when a new factory is registered.
>
> Method-wise, it should have a getFactory() and a register(int,
> LoggerContextFactory) (or call it registerFactory?) method. A lot of the
> static initialisation of LogManager can be moved to the constructor in this
> class.
>
> Being able to register the class instance itself (or the class?) works
> better than just scanning files due to class loader differences in other
> environments. We can't rely on the TCCL or anything like that for every
> factory.
>
> Any feedback? I may end up submitting this as a patch first to get more
> feedback, but this part of the implementation may be rather simple overall.
>
>
> On 14 April 2014 11:50, Matt Sicker <bo...@gmail.com> wrote:
>
>> Will do. The main thing I'd like to change is the LogManager
>> initialisation. I'd prefer that to keep a registry of
>> LoggerContextFactories so that a different factory can be registered later
>> on (for instance, in OSGi, you could install log4j-api, then log4j-core,
>> and core would register itself and take over as the default factory).
>>
>> Anything more complex than that (like being able to use multiple
>> factories concurrently like you can with contexts), while not necessarily
>> requiring API changes, will require some thought as to how and if it's
>> feasible. Of course, it would be more of an API addition for that (e.g.,
>> selecting the non-default provider chooser or something like that).
>> Basically, that part shouldn't be hard to make backwards compatible.
>>
>>
>> On 14 April 2014 10:25, Ralph Goers <ra...@dslextreme.com> wrote:
>>
>>> Hopefully the changes won’t be too significant.  Can you please post
>>> what you intend to do before commit?
>>>
>>> Ralph
>>>
>>> On Apr 14, 2014, at 7:55 AM, Matt Sicker <bo...@gmail.com> wrote:
>>>
>>> I was thinking about how to best support strange class loader
>>> environments (like OSGi or Servlets), and in order to support a
>>> LoggerContextFactory, we should have a registry of sorts for it. This way,
>>> a new LCF can dynamically add or remove itself at runtime. Ideally, we'd
>>> fall back to the SimpleLogger implementation when none are registered.
>>> There may be an added issue with Loggers being tied to their factories and
>>> such.
>>>
>>> Anyway, the main thing to address is the ability to change (or add)
>>> providers at runtime. Whether or not we can support a more dynamic system
>>> is more of a technical issue. Scanning for a default provider at
>>> initialization still makes sense to pre-load the registry, but imagine the
>>> scenario where a server like Tomcat uses Log4j but allows individual web
>>> apps to provide custom providers.
>>>
>>> I'd like to at least implement the necessary API changes before 2.0 so
>>> that this may be possible down the line. Even if we don't use OSGi, it
>>> should still be possible to use log4j in an OSGi framework (core or as a
>>> regular bundle). This will certainly help adoption by the container
>>> projects.
>>>
>>>
>>>
>>> --
>>> Matt Sicker <bo...@gmail.com>
>>>
>>>
>>>
>>
>>
>> --
>> Matt Sicker <bo...@gmail.com>
>>
>
>
>
> --
> Matt Sicker <bo...@gmail.com>
>
>


-- 
Matt Sicker <bo...@gmail.com>

Re: Intention to modify API

Posted by Remko Popma <re...@gmail.com>.
To be honest, it all sounds pretty complex to me. What is the use case? You mention you want to dynamically add/remove logger context factories at runtime but I'm not clear on why this is desired/required. 

If there are class loader issues we should focus on that. If there is an issue that prevents OSGi from working we should work on that, but I here I don't see what problem you are trying to solve. Is this for OSGi?

Instead if diving into the solution, could you provide a clear description of the problem?

Remko

Sent from my iPhone

> On 2014/04/15, at 8:09, Matt Sicker <bo...@gmail.com> wrote:
> 
> Alright, here's what I'm thinking so far:
> 
> Add a class named something like LoggerContextFactoryRegistry (yeah I hate that name already). Make it a singleton class. It should keep a SortedMap of int -> LoggerContextFactory (similar to how they're scanned in LogManager). This class should also keep a volatile LoggerContextFactory containing the current factory so it doesn't have to be recalculated every time. It can be updated instead when a new factory is registered.
> 
> Method-wise, it should have a getFactory() and a register(int, LoggerContextFactory) (or call it registerFactory?) method. A lot of the static initialisation of LogManager can be moved to the constructor in this class.
> 
> Being able to register the class instance itself (or the class?) works better than just scanning files due to class loader differences in other environments. We can't rely on the TCCL or anything like that for every factory.
> 
> Any feedback? I may end up submitting this as a patch first to get more feedback, but this part of the implementation may be rather simple overall.
> 
> 
>> On 14 April 2014 11:50, Matt Sicker <bo...@gmail.com> wrote:
>> Will do. The main thing I'd like to change is the LogManager initialisation. I'd prefer that to keep a registry of LoggerContextFactories so that a different factory can be registered later on (for instance, in OSGi, you could install log4j-api, then log4j-core, and core would register itself and take over as the default factory).
>> 
>> Anything more complex than that (like being able to use multiple factories concurrently like you can with contexts), while not necessarily requiring API changes, will require some thought as to how and if it's feasible. Of course, it would be more of an API addition for that (e.g., selecting the non-default provider chooser or something like that). Basically, that part shouldn't be hard to make backwards compatible.
>> 
>> 
>>> On 14 April 2014 10:25, Ralph Goers <ra...@dslextreme.com> wrote:
>>> Hopefully the changes won’t be too significant.  Can you please post what you intend to do before commit?
>>> 
>>> Ralph
>>> 
>>>> On Apr 14, 2014, at 7:55 AM, Matt Sicker <bo...@gmail.com> wrote:
>>>> 
>>>> I was thinking about how to best support strange class loader environments (like OSGi or Servlets), and in order to support a LoggerContextFactory, we should have a registry of sorts for it. This way, a new LCF can dynamically add or remove itself at runtime. Ideally, we'd fall back to the SimpleLogger implementation when none are registered. There may be an added issue with Loggers being tied to their factories and such.
>>>> 
>>>> Anyway, the main thing to address is the ability to change (or add) providers at runtime. Whether or not we can support a more dynamic system is more of a technical issue. Scanning for a default provider at initialization still makes sense to pre-load the registry, but imagine the scenario where a server like Tomcat uses Log4j but allows individual web apps to provide custom providers.
>>>> 
>>>> I'd like to at least implement the necessary API changes before 2.0 so that this may be possible down the line. Even if we don't use OSGi, it should still be possible to use log4j in an OSGi framework (core or as a regular bundle). This will certainly help adoption by the container projects. 
>>>> 
>>>> 
>>>> 
>>>> -- 
>>>> Matt Sicker <bo...@gmail.com>
>> 
>> 
>> 
>> -- 
>> Matt Sicker <bo...@gmail.com>
> 
> 
> 
> -- 
> Matt Sicker <bo...@gmail.com>

Re: Intention to modify API

Posted by Matt Sicker <bo...@gmail.com>.
Alright, here's what I'm thinking so far:

Add a class named something like LoggerContextFactoryRegistry (yeah I hate
that name already). Make it a singleton class. It should keep a SortedMap
of int -> LoggerContextFactory (similar to how they're scanned in
LogManager). This class should also keep a volatile LoggerContextFactory
containing the current factory so it doesn't have to be recalculated every
time. It can be updated instead when a new factory is registered.

Method-wise, it should have a getFactory() and a register(int,
LoggerContextFactory) (or call it registerFactory?) method. A lot of the
static initialisation of LogManager can be moved to the constructor in this
class.

Being able to register the class instance itself (or the class?) works
better than just scanning files due to class loader differences in other
environments. We can't rely on the TCCL or anything like that for every
factory.

Any feedback? I may end up submitting this as a patch first to get more
feedback, but this part of the implementation may be rather simple overall.


On 14 April 2014 11:50, Matt Sicker <bo...@gmail.com> wrote:

> Will do. The main thing I'd like to change is the LogManager
> initialisation. I'd prefer that to keep a registry of
> LoggerContextFactories so that a different factory can be registered later
> on (for instance, in OSGi, you could install log4j-api, then log4j-core,
> and core would register itself and take over as the default factory).
>
> Anything more complex than that (like being able to use multiple factories
> concurrently like you can with contexts), while not necessarily requiring
> API changes, will require some thought as to how and if it's feasible. Of
> course, it would be more of an API addition for that (e.g., selecting the
> non-default provider chooser or something like that). Basically, that part
> shouldn't be hard to make backwards compatible.
>
>
> On 14 April 2014 10:25, Ralph Goers <ra...@dslextreme.com> wrote:
>
>> Hopefully the changes won’t be too significant.  Can you please post what
>> you intend to do before commit?
>>
>> Ralph
>>
>> On Apr 14, 2014, at 7:55 AM, Matt Sicker <bo...@gmail.com> wrote:
>>
>> I was thinking about how to best support strange class loader
>> environments (like OSGi or Servlets), and in order to support a
>> LoggerContextFactory, we should have a registry of sorts for it. This way,
>> a new LCF can dynamically add or remove itself at runtime. Ideally, we'd
>> fall back to the SimpleLogger implementation when none are registered.
>> There may be an added issue with Loggers being tied to their factories and
>> such.
>>
>> Anyway, the main thing to address is the ability to change (or add)
>> providers at runtime. Whether or not we can support a more dynamic system
>> is more of a technical issue. Scanning for a default provider at
>> initialization still makes sense to pre-load the registry, but imagine the
>> scenario where a server like Tomcat uses Log4j but allows individual web
>> apps to provide custom providers.
>>
>> I'd like to at least implement the necessary API changes before 2.0 so
>> that this may be possible down the line. Even if we don't use OSGi, it
>> should still be possible to use log4j in an OSGi framework (core or as a
>> regular bundle). This will certainly help adoption by the container
>> projects.
>>
>>
>>
>> --
>> Matt Sicker <bo...@gmail.com>
>>
>>
>>
>
>
> --
> Matt Sicker <bo...@gmail.com>
>



-- 
Matt Sicker <bo...@gmail.com>

Re: Intention to modify API

Posted by Matt Sicker <bo...@gmail.com>.
Will do. The main thing I'd like to change is the LogManager
initialisation. I'd prefer that to keep a registry of
LoggerContextFactories so that a different factory can be registered later
on (for instance, in OSGi, you could install log4j-api, then log4j-core,
and core would register itself and take over as the default factory).

Anything more complex than that (like being able to use multiple factories
concurrently like you can with contexts), while not necessarily requiring
API changes, will require some thought as to how and if it's feasible. Of
course, it would be more of an API addition for that (e.g., selecting the
non-default provider chooser or something like that). Basically, that part
shouldn't be hard to make backwards compatible.


On 14 April 2014 10:25, Ralph Goers <ra...@dslextreme.com> wrote:

> Hopefully the changes won’t be too significant.  Can you please post what
> you intend to do before commit?
>
> Ralph
>
> On Apr 14, 2014, at 7:55 AM, Matt Sicker <bo...@gmail.com> wrote:
>
> I was thinking about how to best support strange class loader environments
> (like OSGi or Servlets), and in order to support a LoggerContextFactory, we
> should have a registry of sorts for it. This way, a new LCF can dynamically
> add or remove itself at runtime. Ideally, we'd fall back to the
> SimpleLogger implementation when none are registered. There may be an added
> issue with Loggers being tied to their factories and such.
>
> Anyway, the main thing to address is the ability to change (or add)
> providers at runtime. Whether or not we can support a more dynamic system
> is more of a technical issue. Scanning for a default provider at
> initialization still makes sense to pre-load the registry, but imagine the
> scenario where a server like Tomcat uses Log4j but allows individual web
> apps to provide custom providers.
>
> I'd like to at least implement the necessary API changes before 2.0 so
> that this may be possible down the line. Even if we don't use OSGi, it
> should still be possible to use log4j in an OSGi framework (core or as a
> regular bundle). This will certainly help adoption by the container
> projects.
>
>
>
> --
> Matt Sicker <bo...@gmail.com>
>
>
>


-- 
Matt Sicker <bo...@gmail.com>

Re: Intention to modify API

Posted by Ralph Goers <ra...@dslextreme.com>.
Hopefully the changes won’t be too significant.  Can you please post what you intend to do before commit?

Ralph

On Apr 14, 2014, at 7:55 AM, Matt Sicker <bo...@gmail.com> wrote:

> I was thinking about how to best support strange class loader environments (like OSGi or Servlets), and in order to support a LoggerContextFactory, we should have a registry of sorts for it. This way, a new LCF can dynamically add or remove itself at runtime. Ideally, we'd fall back to the SimpleLogger implementation when none are registered. There may be an added issue with Loggers being tied to their factories and such.
> 
> Anyway, the main thing to address is the ability to change (or add) providers at runtime. Whether or not we can support a more dynamic system is more of a technical issue. Scanning for a default provider at initialization still makes sense to pre-load the registry, but imagine the scenario where a server like Tomcat uses Log4j but allows individual web apps to provide custom providers.
> 
> I'd like to at least implement the necessary API changes before 2.0 so that this may be possible down the line. Even if we don't use OSGi, it should still be possible to use log4j in an OSGi framework (core or as a regular bundle). This will certainly help adoption by the container projects. 
> 
> 
> 
> -- 
> Matt Sicker <bo...@gmail.com>