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

Remko Popma commented on LOG4J2-952:
------------------------------------

Finally had a chance to look at the patch. I like it. Looks clean and easy to 
read.

FYI (minor detail) there is still a compilation error in 
/log4j-core/src/test/java/org/apache/logging/log4j/core/config/assembler/CustomConfigurationFactory.java:
 "The method addAppenderRef(Component) in the type LoggerAssembler is not 
applicable for the arguments (String)"

The properties format support is also nice in that there is not much code. :-)

You provide some convenience methods to make it easy for users to add 
sub-components, like {{AppenderAssembler.addLayout}} and 
{{AppenderAssembler.addFilter}}. Otherwise, users need to call the 
{{addSubComponent}} method. Is this powerful enough to support complex nested 
constructions like needed for {{RoutingAppender}}?

For example, what would a RollingFile appender like the below look like in a 
code-based configuration?
{code}
  <Appenders>
    <RollingRandomAccessFile name="RollingRandomAccessFile" 
fileName="logs/app.log"
                 
filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
      <Policies>
        <TimeBasedTriggeringPolicy />
        <SizeBasedTriggeringPolicy size="250 MB"/>
      </Policies>
      <DefaultRolloverStrategy max="20"/>
    </RollingRandomAccessFile>
  </Appenders>
{code}

Would it look like this?
{code}
ConfigurationAssembler<AssembledConfiguration> cfgAssembler = 
getConfigurationAssembler();
AppenderAssembler appenderAssembler = cfgAssembler
    .getAppenderAssembler("rolling", "RollingRandomAccessFile")
        .addAttribute("fileName", "logs/app.log")
        .addAttribute("filePattern", 
"logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz");
appenderAssembler.addLayout(cfgAssembler.getLayoutAssembler("PatternLayout")
        .addAttribute("pattern", "%d %p %c{1.} [%t] %m%n").assemble());

ComponentAssembler policiesAssembler = cfgAssembler
    .getComponentAssembler("policies", "Policies");
ComponentAssembler timeBasedAssembler = cfgAssembler
    .getComponentAssembler("time", "TimeBasedTriggeringPolicy");
ComponentAssembler sizeBasedAssembler = cfgAssembler
    .getComponentAssembler("size", "SizeBasedTriggeringPolicy")
        .addAttribute("size", "250 MB");

policiesAssembler.addSubComponent(timeBasedAssembler.assemble());
policiesAssembler.addSubComponent(sizeBasedAssembler.assemble());

appenderAssembler.addSubComponent(policiesAssembler.assemble());

ComponentAssembler rollStrategyAssembler = cfgAssembler
    .getComponentAssembler("rollStrategy", "DefaultRolloverStrategy")
        .addAttribute("max", "20");
appenderAssembler.addSubComponent(rollStrategyAssembler.assemble());

cfgAssembler.addAppender(appenderAssembler.assemble());
{code}

Do components need to have a name? In XML, TimeBasedTriggeringPolicy does not 
need a name. Can names be null or empty strings or is anything ok?

Can we provide convenience methods for {{AsyncLogger}} and {{AsyncRootLogger}}?

Finally, we need to document what steps users need to take to use either a 
properties configuration or a code-based configuration. In addition, it would 
be good to have an extensive example (like CustomConfigurationFactory, with a 
Properties example and a RollingFile appender) for both properties and 
code-based config. 

> 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
>         Attachments: LOG4J2-952-2.patch, LOG4J2-952.patch
>
>
> 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: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to