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 "Bart S. (JIRA)" <ji...@apache.org> on 2015/08/18 14:40:45 UTC

[jira] [Comment Edited] (LOG4J2-1095) How can we have multiple Configurations?

    [ https://issues.apache.org/jira/browse/LOG4J2-1095?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14701188#comment-14701188 ] 

Bart S. edited comment on LOG4J2-1095 at 8/18/15 12:39 PM:
-----------------------------------------------------------

It depends, taking a builder would be ugly. You can pretty much only take a builder when it is in a half-complete state (build hasn't been called on it yet). So either you would have to specify parameters on the 'command line', since it is a specification it would or will never take a real Appender. So what you are left with is either:

- actual parameters you need (the minimum, perhaps) to construct an Appender (name, type) (or name, type, pattern)
- the AppenderSpecification that you mention. That would mean the specification would then (ostensibly) result from a Specification Builder (for Appender) that would then take those same parameters.

That said, ideally you would probably follow the actual model of objects:

{code}
addLayout("name", PATTERN, "pattern");
addAppender("name", CONSOLE, "layoutname");
{code}

or you need a method for every type:
{code}
addPatternLayout("name", "pattern");
addConsoleAppender("name", "layoutname");
{code}

or, indeed if you were to use something more extensive for certain types of things, you would require a SpecificationBuilder for that subtype:

{code}
addSyslogAppender( sb.getSyslogBuilder("name").setXXX().setYYY().setZZZ().build() );
{code}

because the alternative is to have a really lengthy method call like we have now. Also, whatever method call you devise, unless it sports ALL of the possible arguments, it would either not be very powerful a method, having only the minimum required parameters, or it would be very lengthy. A builder (specification builder in this case) would get around that:

{code}addSyslogAppender(String appenderName, String host, final int port,
        String protocol, String appName, String facilityName, int enterpriseNumber,
        String clientHostName){code}

(taken from Behrooz' code).


If you can easily receive builders and pass their results (specification types) as a parameter to the {{add}} methods, that's not so bad. But it does convolute the system a bit. Ideally your methods take a minimum of parameters.

But the builder (SpecBuilder) is really the only way to pass more than the required minimum while still having it be good.

Like I mentioned in [LOG4J2-952|https://issues.apache.org/jira/browse/LOG4J2-952] there are to my mind at least (I might be ignorant of some things) only three ways to enable this spec construction:

# {{addSyslogAppender(...., ...., ...., ...., ...., .... ,... ,.. ,...)}} // many parameters
# {{addSyslogAppender( sb.newSyslogSpecBuilder("name").setX().setY().build() );}} // separate spec builder completion as parameter
# {{addSyslogAppender("name").setX().setY()}}; // first method returns a SyslogSpecBuilder but breaks the builder pattern for itself.


was (Author: xennex82):
It depends, taking a builder would be ugly. You can pretty much only take a builder when it is in a half-complete state (build hasn't been called on it yet). So either you would have to specify parameters on the 'command line', since it is a specification it would or will never take a real Appender. So what you are left with is either:

- actual parameters you need (the minimum, perhaps) to construct an Appender (name, type) (or name, type, pattern)
- the AppenderSpecification that you mention. That would mean the specification would then (ostensibly) result from a Specification Builder (for Appender) that would then take those same parameters.

That said, ideally you would probably follow the actual model of objects:

{code}
addLayout("name", PATTERN, "pattern");
addAppender("name", CONSOLE, "layoutname");
{code}

or you need a method for every type:
{code}
addPatternLayout("name", "pattern");
addConsoleAppender("name", "layoutname");
{code}

or, indeed if you were to use something more extensive for certain types of things, you would require a SpecificationBuilder for that subtype:

{code}
addSyslogAppender( sb.getSyslogBuilder("name").setXXX().setYYY().setZZZ().build() );
{code}

because the alternative is to have a really lengthy method call like we have now. Also, whatever method call you devise, unless it sports ALL of the possible arguments, it would either not be very powerful a method, having only the minimum required parameters, or it would be very lengthy. A builder (specification builder in this case) would get around that:

{code}addSyslogAppender(String appenderName, String host, final int port,
        String protocol, String appName, String facilityName, int enterpriseNumber,
        String clientHostName){code}

(taken from Behrooz' code).


If you can easily receive builders and pass their results (specification types) as a parameter to the {{add}} methods, that's not so bad. But it does convolute the system a bit. Ideally your methods take a minimum of parameters.

But the builder (SpecBuilder) is really the only way to pass more than the required minimum while still having it be good.

Like I mentioned in [LOG4J2-952|https://issues.apache.org/jira/browse/LOG4J2-952] there are to my mind at least (I might be ignorant of some things) only three ways to enable this spec construction:

# addSyslogAppender(...., ...., ...., ...., ...., .... ,... ,.. ,...) // many parameters
# addSyslogAppender( sb.newSyslogSpecBuilder("name").setX().setY().build() ); // separate spec builder completion as parameter
# addSyslogAppender("name").setX().setY(); // first method returns a SyslogSpecBuilder but breaks the builder pattern for itself.

> How can we have multiple Configurations?
> ----------------------------------------
>
>                 Key: LOG4J2-1095
>                 URL: https://issues.apache.org/jira/browse/LOG4J2-1095
>             Project: Log4j 2
>          Issue Type: Brainstorming
>          Components: Configurators
>    Affects Versions: 2.4
>            Reporter: Bart S.
>              Labels: features
>             Fix For: 2.4
>
>         Attachments: log4j-xen-configurationbuilder-uml.jpg
>
>
> So the question is how can a user maintain multiple configurations that he can then establish or activate at will.
> The idea is to break away from using files as the only case, to both using files and using custom programmatic control, as both special cases of configuration.
> While thinking of it I created an UML diagram:
> !log4j-xen-configurationbuilder-uml.jpg!
> I believe this should be the setup. Our new Factory can be fed a Specification instead of a ConfigurationSource/file location.
> That would make these two sources equivalent.
> Programmatically what you might get is:
> {code}
> Specification a1 = SpecificationBuilder.newInstance()
>     .addAppender(....)
>     .addConfig(...)
>     .addTo(..., ....)
>     .build();
> Specification a2 = SpecificationBuilder.newInstance()
>     .addAppender(....)
>     .addConfig(...)
>     .addTo(..., ....)
>     .build();
> Configuration c1 =
>     CustomConfigurationFactory.getInstance().getConfiguration( a1 );
> Configuration c2 =
>     CustomConfigurationFactory.getInstance().getConfiguration( a2 );
> {code}
> Or alternatively
> {code}
> CustomConfigurationFactory ccf = CustomConfigurationFactory.getInstance();
> ccf.setSpecification( a1 );
> LogManager.setFactory( ccf );
> {code}
> The Factory only needs to be given to the system because the system wants to do static initialisation at some point in the beginning. After that setting a new configuration should not require the factory, but indeed be something directly:
> {{Configurator.setConfiguration(Configuration)}}
> or
> {{LoggerContext.set/start/update(Configuration)}}
> It is unclear to me how a new configuration can be fed to the context. There are two methods that might work: updateLoggers and start.
> I believe there can be mutlple contexts; if there are or could be indeed multiple contexts in a logging system, then it becomes adamant to give the Configuration to the right one; in other cases I don't really know what {{initialize()}} does, in fact it _returns_ a LoggerContext. It would seem required to use this LoggerContext to change the current configuration?



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org