logging-log4j-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Bart S. (JIRA)" <j...@apache.org>
Subject [jira] [Comment Edited] (LOG4J2-952) FAQ: How do I configure log4j2 programmatically in code without a configuration file?
Date Wed, 12 Aug 2015 19:31:46 GMT

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

Bart S. edited comment on LOG4J2-952 at 8/12/15 7:31 PM:
---------------------------------------------------------

I was writing this before all of your comments (the last 3, by Gary and Behrooz).

I've read the entire source file mostly. I'd suggest putting everything in Maps and Sets and
then generating the relevant objects out of that might not be the most.. pristine way of doing
it, but I guess... I would suggest mostly not to use the same method for creating file and
console loggers. I'd suggest a way to set additivity and a way to set level per config. Per
LoggerConfig. Personally I would prefer a directer way of dealing with these general objects,
except with the way of not having to "store" them directly (ie. requiring the imports and
all). That said, I'd prefer to see the structure of the generated objects reflected in the
method calls I do. For instance, I would want to generate LoggerConfigs and Appenders and
add the Appenders to the LoggerConfigs.

Something like.

addLoggerConfig("name", additivity);
addAppender("name", Appenders.CONSOLE, pattern);
addAppenderToConfig("name", "name");

The closer you stay to the inherit structure, the more powerful your system will be; ie. the
closer you stay to the actual configuration under the hood, the less you will run into impossibilities.
That also should mean you operate on a Configuration (or at least its objects) directly, but
I don't know how feasible that should be, given that many of these objects require a conf
parameter to begin with; you can't just create them floating in free air. In any way, that
is your specifics and mechanics, I'm free to not use it if I want ;-). That's all I'm saying
really. Mind you that you won't create a system that many users will not want to use for whatever
reasons. If it is then incorporated into Log4J proper we'd all be embarrassed ;-).

Ideally this should really be the Builder subclass (inner class) of Configuration itself.
But that might make Configuration a huge file. But if it was incorporated, Configuration itself
could have the newBuilder() method. That would indeed create a Configuration; after that comes
installing. Your code currently does the entire reconfiguration and of course also installs
the factory object. It essentially generates a config, gives it to the factory, the factory
is given to the init system of Log4J, which then simply requests back the config from it.
Maybe, generally, that couldn't be done if it was truly Configuration's Builder. Then you
wouldn't have the weird issue at least that essentially {{configure()}} is the main method
of the class, and not {{build()}} (kinda breaking the agreement or contract of that specification).
Maybe you want to isolate the builder itself from some wrapper thing that causes the injection
into the main system.

In other words, the thing that applies it and effectuates it would be a different class from
the Builder itself. I think that would be a better strategy, separation of concerns so to
speak. But still good implementation and concept.

That's all I wanted to say I guess. I'm just a bystander at this point but just concerning
myself with these things at the moment. Regards.


was (Author: xennex82):
I was writing this before all of your comments (the last 3, by Gary and Behrooz).

I've read the entire source file mostly. I'd suggest putting everything in Maps and Sets and
then generating the relevant objects out of that might not be the most.. pristine way of doing
it, but I guess... I would suggest mostly not to use the same method for creating file and
console loggers. I'd suggest a way to set additivity and a way to set level per config. Per
LoggerConfig. Personally I would prefer a directer way of dealing with these general objects,
except with the way of not having to "store" them directly (ie. requiring the imports and
all). That said, I'd prefer to see the structure of the generated objects reflected in the
method calls I do. For instance, I would want to generate LoggerConfigs and Appenders and
add the Appenders to the LoggerConfigs.

Something like.

{{addLoggerConfig("name", additivity);
addAppender("name", Appenders.CONSOLE, pattern);
addAppenderToConfig("name", "name");}}

The closer you stay to the inherit structure, the more powerful your system will be; ie. the
closer you stay to the actual configuration under the hood, the less you will run into impossibilities.
That also should mean you operate on a Configuration (or at least its objects) directly, but
I don't know how feasible that should be, given that many of these objects require a conf
parameter to begin with; you can't just create them floating in free air. In any way, that
is your specifics and mechanics, I'm free to not use it if I want ;-). That's all I'm saying
really. Mind you that you won't create a system that many users will not want to use for whatever
reasons. If it is then incorporated into Log4J proper we'd all be embarrassed ;-).

Ideally this should really be the Builder subclass (inner class) of Configuration itself.
But that might make Configuration a huge file. But if it was incorporated, Configuration itself
could have the newBuilder() method. That would indeed create a Configuration; after that comes
installing. Your code currently does the entire reconfiguration and of course also installs
the factory object. It essentially generates a config, gives it to the factory, the factory
is given to the init system of Log4J, which then simply requests back the config from it.
Maybe, generally, that couldn't be done if it was truly Configuration's Builder. Then you
wouldn't have the weird issue at least that essentially {{configure()}} is the main method
of the class, and not {{build()}} (kinda breaking the agreement or contract of that specification).
Maybe you want to isolate the builder itself from some wrapper thing that causes the injection
into the main system.

In other words, the thing that applies it and effectuates it would be a different class from
the Builder itself. I think that would be a better strategy, separation of concerns so to
speak. But still good implementation and concept.

That's all I wanted to say I guess. I'm just a bystander at this point but just concerning
myself with these things at the moment. Regards.

> FAQ: How do I configure log4j2 programmatically in code without a configuration file?
> -------------------------------------------------------------------------------------
>
>                 Key: LOG4J2-952
>                 URL: https://issues.apache.org/jira/browse/LOG4J2-952
>             Project: Log4j 2
>          Issue Type: Bug
>          Components: API, Configurators, Documentation
>    Affects Versions: 2.1
>            Reporter: Joe Merten
>
> I found [this link|http://logging.apache.org/log4j/2.x/faq.html#config_from_code] which
said:
> {quote}
> You could use the static method #initialize(String contextName, ClassLoader loader, String
configLocation) in org.apache.logging.log4j.core.config.Configurator. (You can pass null for
the class loader.) Be aware that this class is not part of the public API so your code may
break with any minor release.
> {quote}
> This documentation is unclear because it points to a member function which needs a filename
{{configLocation}} where as the topic is ┬╗without a configuration file┬ź.
> It shoud rather point to the member function {{org.apache.logging.log4j.core.config.Configurator.initialize(ClassLoader
loader, ConfigurationSource source)}}.
> Example:
> {code:java}
> import org.apache.logging.log4j.core.config.ConfigurationSource;
> import org.apache.logging.log4j.core.config.Configurator;
> final String hardCodedXmlConfig =
>         "<?xml version='1.0' encoding='UTF-8'?>\n" +
>         "<Configuration status='INFO'>\n" +
>         "  <Appenders>\n" +
>         "    <Console name='Console' target='SYSTEM_OUT'>\n" +
>         "      <PatternLayout pattern='%d{HH:mm:ss.SSS} [%t] %-5level %logger{36}
- %msg%n'/>\n" +
>         "    </Console>\n" +
>         "  </Appenders>\n" +
>         "  <Loggers>\n" +
>         "    <Root level='debug'>\n" +
>         "      <AppenderRef ref='Console'/>\n" +
>         "    </Root>\n" +
>         "  </Loggers>\n" +
>         "</Configuration>\n";
> try {
>     Configurator.initialize(null, new ConfigurationSource(new ByteArrayInputStream(hardCodedXmlConfig.getBytes())));
> } catch (IOException e) {
>     e.printStackTrace();
> }
> {code}



--
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


Mime
View raw message