LOG4J2-1802: Convert programmatic config manual page to asciidoc

Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/77a3712d
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/77a3712d
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/77a3712d

Branch: refs/heads/master
Commit: 77a3712df0364e73ae5aa7bbfaaab58c2f738efb
Parents: de9e42e
Author: Matt Sicker <boa...@gmail.com>
Authored: Sun Apr 8 15:22:57 2018 -0500
Committer: Matt Sicker <boa...@gmail.com>
Committed: Sun Apr 8 16:03:36 2018 -0500

----------------------------------------------------------------------
 src/site/asciidoc/manual/customconfig.adoc | 386 ++++++++++++++++++++++++
 src/site/xdoc/manual/customconfig.xml      | 375 -----------------------
 2 files changed, 386 insertions(+), 375 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/77a3712d/src/site/asciidoc/manual/customconfig.adoc
----------------------------------------------------------------------
diff --git a/src/site/asciidoc/manual/customconfig.adoc 
b/src/site/asciidoc/manual/customconfig.adoc
new file mode 100644
index 0000000..7f4c9ea
--- /dev/null
+++ b/src/site/asciidoc/manual/customconfig.adoc
@@ -0,0 +1,386 @@
+////
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements. See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License. You may obtain a copy of the License at
+
+        https://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+////
+= Programmatic Configuration
+Ralph Goers <rgo...@apache.org>
+
+Log4j 2 provides a few ways for applications to create their own
+programmatic configuration:
+
+* Specify a custom `ConfigurationFactory` to start Log4j with a
+programmatic configuration
+* Use the `Configurator` to replace the configuration after Log4j started
+* Initialize Log4j with a combination of a configuration file and
+programmatic configuration
+* Modify the current `Configuration` after initialization
+
+[#ConfigurationBuilder]
+== The ConfigurationBuilder API
+
+Starting with release 2.4, Log4j provides a `ConfigurationBuilder` and a
+set of component builders that allow a `Configuration` to be created
+fairly easily. Actual configuration objects like `LoggerConfig` or
+`Appender` can be unwieldy; they require a lot of knowledge about Log4j
+internals which makes them difficult to work with if all you want is to
+create a `Configuration`.
+
+The new `ConfigurationBuilder` API (in the
+`org.apache.logging.log4j.core.config.builder.api` package) allows users
+to create Configurations in code by constructing component
+_definitions_. There is no need to work directly with actual
+configuration objects. Component definitions are added to the
+`ConfigurationBuilder`, and once all the definitions have been collected
+all the actual configuration objects (like Loggers and Appenders) are
+constructed.
+
+`ConfigurationBuilder` has convenience methods for the base components
+that can be configured such as Loggers, Appenders, Filter, Properties,
+etc. However, Log4j 2's plugin mechanism means that users can create any
+number of custom components. As a trade-off, the `ConfigurationBuilder`
+API provides only a limited number of "strongly typed" convenience
+methods like `newLogger()`, `newLayout()` etc. The generic
+`builder.newComponent()` method can be used if no convenience method
+exists for the component you want to configure.
+
+For example, the builder does not know what sub-components can be
+configured on specific components such as the RollingFileAppender vs.
+the RoutingAppender. To specify a triggering policy on a
+RollingFileAppender you would use builder.newComponent().
+
+Examples of using the `ConfigurationBuilder` API are in the sections that
+follow.
+
+[#ConfigurationFactory]
+== Understanding ConfigurationFactory
+
+During initialization, Log4j 2 will search for available
+link:extending.html#ConfigurationFactory[ConfigurationFactories] and
+then select the one to use. The selected `ConfigurationFactory` creates
+the `Configuration` that Log4j will use. Here is how Log4j finds the
+available ConfigurationFactories:
+
+1.  A system property named `log4j2.configurationFactory` can be set
+with the name of the ConfigurationFactory to be used.
+2.  `ConfigurationFactory.setConfigurationFactory(ConfigurationFactory)`
+can be called with the instance of the `ConfigurationFactory` to be used.
+This must be called before any other calls to Log4j.
+3.  A `ConfigurationFactory` implementation can be added to the classpath
+and configured as a plugin in the "ConfigurationFactory" category. The
+`@Order` annotation can be used to specify the relative priority when
+multiple applicable ConfigurationFactories are found.
+
+ConfigurationFactories have the concept of "supported types", which
+basically maps to the file extension of the configuration file that the
+ConfigurationFactory can handle. If a configuration file location is
+specified, ConfigurationFactories whose supported type does not include
+"*" or the matching file extension will not be used.
+
+[#Example]
+== Initialize Log4j Using ConfigurationBuilder with a Custom 
ConfigurationFactory
+
+One way to programmatically configure Log4j 2 is to create a custom
+`ConfigurationFactory` that uses the
+link:#ConfigurationBuilder[`ConfigurationBuilder`] to create a
+Configuration. The below example overrides the `getConfiguration()`
+method to return a `Configuration` created by the `ConfigurationBuilder`.
+This will cause the `Configuration` to automatically be hooked into Log4j
+when the `LoggerContext` is created. In the example below, because it
+specifies a supported type of "*" it will override any configuration
+files provided.
+
+[source,java]
+----
+@Plugin(name = "CustomConfigurationFactory", category = 
ConfigurationFactory.CATEGORY)
+@Order(50)
+public class CustomConfigurationFactory extends ConfigurationFactory {
+
+    static Configuration createConfiguration(final String name, 
ConfigurationBuilder<BuiltConfiguration> builder) {
+        builder.setConfigurationName(name);
+        builder.setStatusLevel(Level.ERROR);
+        builder.add(builder.newFilter("ThresholdFilter", Filter.Result.ACCEPT, 
Filter.Result.NEUTRAL).
+            addAttribute("level", Level.DEBUG));
+        AppenderComponentBuilder appenderBuilder = 
builder.newAppender("Stdout", "CONSOLE").
+            addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT);
+        appenderBuilder.add(builder.newLayout("PatternLayout").
+            addAttribute("pattern", "%d [%t] %-5level: %msg%n%throwable"));
+        appenderBuilder.add(builder.newFilter("MarkerFilter", 
Filter.Result.DENY,
+            Filter.Result.NEUTRAL).addAttribute("marker", "FLOW"));
+        builder.add(appenderBuilder);
+        builder.add(builder.newLogger("org.apache.logging.log4j", Level.DEBUG).
+            add(builder.newAppenderRef("Stdout")).
+            addAttribute("additivity", false));
+        
builder.add(builder.newRootLogger(Level.ERROR).add(builder.newAppenderRef("Stdout")));
+        return builder.build();
+    }
+
+    @Override
+    public Configuration getConfiguration(final LoggerContext loggerContext, 
final ConfigurationSource source) {
+        return getConfiguration(loggerContext, source.toString(), null);
+    }
+
+    @Override
+    public Configuration getConfiguration(final LoggerContext loggerContext, 
final String name, final URI configLocation) {
+        ConfigurationBuilder<BuiltConfiguration> builder = 
newConfigurationBuilder();
+        return createConfiguration(name, builder);
+    }
+
+    @Override
+    protected String[] getSupportedTypes() {
+        return new String[] {"*"};
+    }
+}
+----
+
+As of version 2.7, the `ConfigurationFactory.getConfiguration()` methods
+take an additional `LoggerContext` parameter.
+
+[#Configurator]
+== Reconfigure Log4j Using ConfigurationBuilder with the Configurator
+
+An alternative to a custom `ConfigurationFactory` is to configure with the
+`Configurator`. Once a `Configuration` object has been constructed, it can
+be passed to one of the `Configurator.initialize` methods to set up the
+Log4j configuration.
+
+Using the `Configurator` in this manner allows the application control
+over when Log4j is initialized. However, should any logging be attempted
+before `Configurator.initialize()` is called then the default
+configuration will be used for those log events.
+
+[source,java]
+----
+ConfigurationBuilder<BuiltConfiguration> builder = 
ConfigurationBuilderFactory.newConfigurationBuilder();
+builder.setStatusLevel(Level.ERROR);
+builder.setConfigurationName("BuilderTest");
+builder.add(builder.newFilter("ThresholdFilter", Filter.Result.ACCEPT, 
Filter.Result.NEUTRAL)
+    .addAttribute("level", Level.DEBUG));
+AppenderComponentBuilder appenderBuilder = builder.newAppender("Stdout", 
"CONSOLE").addAttribute("target",
+    ConsoleAppender.Target.SYSTEM_OUT);
+appenderBuilder.add(builder.newLayout("PatternLayout")
+    .addAttribute("pattern", "%d [%t] %-5level: %msg%n%throwable"));
+appenderBuilder.add(builder.newFilter("MarkerFilter", Filter.Result.DENY, 
Filter.Result.NEUTRAL)
+    .addAttribute("marker", "FLOW"));
+builder.add(appenderBuilder);
+builder.add(builder.newLogger("org.apache.logging.log4j", Level.DEBUG)
+    .add(builder.newAppenderRef("Stdout")).addAttribute("additivity", false));
+builder.add(builder.newRootLogger(Level.ERROR).add(builder.newAppenderRef("Stdout")));
+ctx = Configurator.initialize(builder.build());
+----
+
+This example shows how to create a configuration that includes a
+RollingFileAppender.
+
+[source,java]
+----
+ConfigurationBuilder<BuiltConfiguration> builder = 
ConfigurationBuilderFactory.newConfigurationBuilder();
+
+builder.setStatusLevel(Level.ERROR);
+builder.setConfigurationName("RollingBuilder");
+// create a console appender
+AppenderComponentBuilder appenderBuilder = builder.newAppender("Stdout", 
"CONSOLE").addAttribute("target",
+    ConsoleAppender.Target.SYSTEM_OUT);
+appenderBuilder.add(builder.newLayout("PatternLayout")
+    .addAttribute("pattern", "%d [%t] %-5level: %msg%n%throwable"));
+builder.add(appenderBuilder);
+// create a rolling file appender
+LayoutComponentBuilder layoutBuilder = builder.newLayout("PatternLayout")
+    .addAttribute("pattern", "%d [%t] %-5level: %msg%n");
+ComponentBuilder triggeringPolicy = builder.newComponent("Policies")
+    
.addComponent(builder.newComponent("CronTriggeringPolicy").addAttribute("schedule",
 "0 0 0 * * ?"))
+    
.addComponent(builder.newComponent("SizeBasedTriggeringPolicy").addAttribute("size",
 "100M"));
+appenderBuilder = builder.newAppender("rolling", "RollingFile")
+    .addAttribute("fileName", "target/rolling.log")
+    .addAttribute("filePattern", "target/archive/rolling-%d{MM-dd-yy}.log.gz")
+    .add(layoutBuilder)
+    .addComponent(triggeringPolicy);
+builder.add(appenderBuilder);
+
+// create the new logger
+builder.add(builder.newLogger("TestLogger", Level.DEBUG)
+    .add(builder.newAppenderRef("rolling"))
+    .addAttribute("additivity", false));
+
+builder.add(builder.newRootLogger(Level.DEBUG)
+    .add(builder.newAppenderRef("rolling")));
+LoggerContext ctx = Configurator.initialize(builder.build());
+----
+
+[#Hybrid]
+== Initialize Log4j by Combining Configuration File with Programmatic 
Configuration
+
+Sometimes you want to configure with a configuration file but do some
+additional programmatic configuration. A possible use case might be that
+you want to allow for a flexible configuration using XML but at the same
+time make sure there are a few configuration elements that are always
+present that can't be removed.
+
+The easiest way to achieve this is to extend one of the standard
+`Configuration` classes (`XMLConfiguration`, `JSONConfiguration`) and then
+create a new `ConfigurationFactory` for the extended class. After the
+standard configuration completes the custom configuration can be added
+to it.
+
+The example below shows how to extend `XMLConfiguration` to manually add
+an `Appender` and a `LoggerConfig` to the configuration.
+
+[source,java]
+----
+@Plugin(name = "MyXMLConfigurationFactory", category = "ConfigurationFactory")
+@Order(10)
+public class MyXMLConfigurationFactory extends ConfigurationFactory {
+
+    /**
+     * Valid file extensions for XML files.
+     */
+    public static final String[] SUFFIXES = new String[] {".xml", "*"};
+
+    /**
+     * Return the Configuration.
+     * @param source The InputSource.
+     * @return The Configuration.
+     */
+    public Configuration getConfiguration(InputSource source) {
+        return new MyXMLConfiguration(source, configFile);
+    }
+
+    /**
+     * Returns the file suffixes for XML files.
+     * @return An array of File extensions.
+     */
+    public String[] getSupportedTypes() {
+        return SUFFIXES;
+    }
+}
+
+public class MyXMLConfiguration extends XMLConfiguration {
+    public MyXMLConfiguration(final ConfigurationFactory.ConfigurationSource 
configSource) {
+      super(configSource);
+    }
+
+    @Override
+    protected void doConfigure() {
+        super.doConfigure();
+        final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
+        final Layout layout = 
PatternLayout.createLayout(PatternLayout.SIMPLE_CONVERSION_PATTERN, config, 
null,
+              null,null, null);
+        final Appender appender = 
FileAppender.createAppender("target/test.log", "false", "false", "File", "true",
+              "false", "false", "4000", layout, null, "false", null, config);
+        appender.start();
+        addAppender(appender);
+        LoggerConfig loggerConfig = LoggerConfig.createLogger("false", "info", 
"org.apache.logging.log4j",
+              "true", refs, null, config, null );
+        loggerConfig.addAppender(appender, null, null);
+        addLogger("org.apache.logging.log4j", loggerConfig);
+    }
+}
+----
+
+[#AddingToCurrent]
+== Programmatically Modifying the Current Configuration after Initialization
+
+Applications sometimes have the need to customize logging separate from
+the actual configuration. Log4j allows this although it suffers from a
+few limitations:
+
+1.  If the configuration file is changed the configuration will be
+reloaded and the manual changes will be lost.
+2.  Modification to the running configuration requires that all the
+methods being called (addAppender and addLogger) be synchronized.
+
+As such, the recommended approach for customizing a configuration is to
+extend one of the standard Configuration classes, override the setup
+method to first do super.setup() and then add the custom Appenders,
+Filters and LoggerConfigs to the configuration before it is registered
+for use.
+
+The following example adds an Appender and a new LoggerConfig using that
+Appender to the current configuration.
+
+//TODO: update code example below with new plugin API
+[source,java]
+----
+        final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
+        final Configuration config = ctx.getConfiguration();
+        Layout layout = 
PatternLayout.createLayout(PatternLayout.SIMPLE_CONVERSION_PATTERN, config, 
null,
+            null,null, null);
+        Appender appender = FileAppender.createAppender("target/test.log", 
"false", "false", "File", "true",
+            "false", "false", "4000", layout, null, "false", null, config);
+        appender.start();
+        config.addAppender(appender);
+        AppenderRef ref = AppenderRef.createAppenderRef("File", null, null);
+        AppenderRef[] refs = new AppenderRef[] {ref};
+        LoggerConfig loggerConfig = LoggerConfig.createLogger("false", "info", 
"org.apache.logging.log4j",
+            "true", refs, null, config, null );
+        loggerConfig.addAppender(appender, null, null);
+        config.addLogger("org.apache.logging.log4j", loggerConfig);
+        ctx.updateLoggers();
+}
+----
+
+[#AppendingToWritersAndOutputStreams]
+== Appending Log Events to Writers and OutputStreams Programmatically
+
+Log4j 2.5 provides facilities to append log events to Writers and
+OutputStreams. For example, this provides simple integration for JDBC
+Driver implementors that use Log4j internally and still want to support
+the JDBC APIs `CommonDataSource.setLogWriter(PrintWriter)`,
+`java.sql.DriverManager.setLogWriter(PrintWriter)`, and
+`java.sql.DriverManager.setLogStream(PrintStream)`.
+
+Given any `Writer`, like a `PrintWriter`, you tell Log4j to append
+events to that writer by creating a `WriterAppender` and updating the
+Log4j configuration:
+
+[source,java]
+----
+void addAppender(final Writer writer, final String writerName) {
+    final LoggerContext context = LoggerContext.getContext(false);
+    final Configuration config = context.getConfiguration();
+    final PatternLayout layout = PatternLayout.createDefaultLayout(config);
+    final Appender appender = WriterAppender.createAppender(layout, null, 
writer, writerName, false, true);
+    appender.start();
+    config.addAppender(appender);
+    updateLoggers(appender, config);
+}
+
+private void updateLoggers(final Appender appender, final Configuration 
config) {
+    final Level level = null;
+    final Filter filter = null;
+    for (final LoggerConfig loggerConfig : config.getLoggers().values()) {
+        loggerConfig.addAppender(appender, level, filter);
+    }
+    config.getRootLogger().addAppender(appender, level, filter);
+}
+----
+
+You can achieve the same effect with an `OutputStream`, like a
+`PrintStream`:
+
+[source,java]
+----
+void addAppender(final OutputStream outputStream, final String 
outputStreamName) {
+    final LoggerContext context = LoggerContext.getContext(false);
+    final Configuration config = context.getConfiguration();
+    final PatternLayout layout = PatternLayout.createDefaultLayout(config);
+    final Appender appender = OutputStreamAppender.createAppender(layout, 
null, outputStream, outputStreamName, false, true);
+    appender.start();
+    config.addAppender(appender);
+    updateLoggers(appender, config);
+}
+----
+
+The difference is the use of `OutputStreamAppender` instead of
+`WriterAppender`.

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/77a3712d/src/site/xdoc/manual/customconfig.xml
----------------------------------------------------------------------
diff --git a/src/site/xdoc/manual/customconfig.xml 
b/src/site/xdoc/manual/customconfig.xml
deleted file mode 100644
index e57af39..0000000
--- a/src/site/xdoc/manual/customconfig.xml
+++ /dev/null
@@ -1,375 +0,0 @@
-<?xml version="1.0"?>
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-
-<document xmlns="http://maven.apache.org/XDOC/2.0";
-          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
-          xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 
http://maven.apache.org/xsd/xdoc-2.0.xsd";>
-    <properties>
-        <title>Extending Log4j 2 Configuration</title>
-        <author email="rgo...@apache.org">Ralph Goers</author>
-    </properties>
-
-    <body>
-      <section name="Programmatic Configuration">
-        <p>
-          Log4j 2 provides a few ways for applications to create their own 
programmatic configuration:
-        </p>
-        <ul>
-          <li>Specify a custom ConfigurationFactory to start Log4j with a 
programmatic configuration</li>
-          <li>Use the Configurator to replace the configuration after Log4j 
started</li>
-          <li>Initialize Log4j with a combination of a configuration file and 
programmatic configuration</li>
-          <li>Modify the current Configuration after initialization</li>
-        </ul>
-        <a name="ConfigurationBuilder"/>
-          <subsection name="The ConfigurationBuilder API">
-            <p>
-              Starting with release 2.4, Log4j provides a ConfigurationBuilder 
and a set of component builders that
-              allow a Configuration to be created fairly easily.
-              Actual configuration objects like LoggerConfig or Appender can 
be unwieldy; they require a lot
-              of knowledge about Log4j internals which makes them difficult to 
work with if all you want is to
-              create a Configuration.
-            </p>
-            <p>
-              The new ConfigurationBuilder API (in the 
<code>org.apache.logging.log4j.core.config.builder.api</code> package)
-              allows users to create Configurations in code by constructing 
component <i>definitions</i>.
-              There is no need to work directly with actual configuration 
objects.
-              Component definitions are added to the ConfigurationBuilder, and 
once all the definitions have
-              been collected all the actual configuration objects (like 
Loggers and Appenders) are constructed.
-            </p>
-            <p>
-              ConfigurationBuilder has convenience methods for the base 
components that can be configured such as
-              Loggers, Appenders, Filter, Properties, etc. 
-              However, Log4j 2's plugin mechanism means that users can create 
any number of custom components.
-              As a trade-off, the ConfigurationBuilder API provides only a 
limited number of "strongly typed"
-              convenience methods like <code>newLogger()</code>, 
<code>newLayout()</code> etc.
-              The generic <code>builder.newComponent()</code> method can be 
used if no convenience method exists
-              for the component you want to configure.
-            </p>
-            <p>
-              For example, the builder does not know what sub-components can 
be configured on specific components
-              such as the RollingFileAppender vs. the RoutingAppender. To 
specify a triggering policy on a 
-              RollingFileAppender you would use builder.newComponent().
-            </p>
-            <p>
-              Examples of using the ConfigurationBuilder API are in the 
sections that follow.
-            </p>
-          </subsection>
-          <a name="ConfigurationFactory"/>
-          <subsection name="Understanding ConfigurationFactory">
-            <p>
-              During initialization, Log4j 2 will search for available <a 
href="extending.html#ConfigurationFactory">ConfigurationFactories</a>
-              and then select the one to use. The
-              selected ConfigurationFactory creates the Configuration that 
Log4j will use. Here is how Log4j finds
-              the available ConfigurationFactories:
-            </p>
-            <ol>
-              <li>A system property named <tt>log4j2.configurationFactory</tt> 
can be set with the name of the ConfigurationFactory to be used.</li>
-              
<li><code>ConfigurationFactory.setConfigurationFactory(ConfigurationFactory)</code>
 can be called with the instance of the
-              ConfigurationFactory to be used. This must be called before any 
other calls to Log4j.</li>
-              <li>A ConfigurationFactory implementation can be added to the 
classpath and configured as a plugin
-                in the "ConfigurationFactory" category.
-                The Order annotation can be used to specify the relative 
priority when multiple applicable 
-                ConfigurationFactories are found.</li>
-            </ol>
-            <p>
-              ConfigurationFactories have the concept of "supported types", 
which basically maps to the
-              file extension of the configuration file that the 
ConfigurationFactory can handle. 
-              If a configuration file location is specified, 
ConfigurationFactories whose supported type
-              does not include "*" or the matching file extension will not be 
used.
-            </p>
-          </subsection>
-          <a name="Example"/>
-          <subsection name="Initialize Log4j Using ConfigurationBuilder with a 
Custom ConfigurationFactory">
-            <p>
-              One way to programmatically configure Log4j 2 is to create a 
custom ConfigurationFactory
-              that uses the <a 
href="#ConfigurationBuilder">ConfigurationBuilder</a> to create a Configuration.
-              The below example overrides the <code>getConfiguration()</code> 
method to return a
-              Configuration created by the ConfigurationBuilder.
-              This will cause the Configuration to automatically be hooked 
into Log4j when the LoggerContext is created.
-              In the example below, because it specifies a supported type of 
"*" it will override any configuration files provided.
-            </p>
-            <pre class="prettyprint linenum"><![CDATA[
-@Plugin(name = "CustomConfigurationFactory", category = 
ConfigurationFactory.CATEGORY)
-@Order(50)
-public class CustomConfigurationFactory extends ConfigurationFactory {
-
-    static Configuration createConfiguration(final String name, 
ConfigurationBuilder<BuiltConfiguration> builder) {
-        builder.setConfigurationName(name);
-        builder.setStatusLevel(Level.ERROR);
-        builder.add(builder.newFilter("ThresholdFilter", Filter.Result.ACCEPT, 
Filter.Result.NEUTRAL).
-            addAttribute("level", Level.DEBUG));
-        AppenderComponentBuilder appenderBuilder = 
builder.newAppender("Stdout", "CONSOLE").
-            addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT);
-        appenderBuilder.add(builder.newLayout("PatternLayout").
-            addAttribute("pattern", "%d [%t] %-5level: %msg%n%throwable"));
-        appenderBuilder.add(builder.newFilter("MarkerFilter", 
Filter.Result.DENY,
-            Filter.Result.NEUTRAL).addAttribute("marker", "FLOW"));
-        builder.add(appenderBuilder);
-        builder.add(builder.newLogger("org.apache.logging.log4j", Level.DEBUG).
-            add(builder.newAppenderRef("Stdout")).
-            addAttribute("additivity", false));
-        
builder.add(builder.newRootLogger(Level.ERROR).add(builder.newAppenderRef("Stdout")));
-        return builder.build();
-    }
-
-    @Override
-    public Configuration getConfiguration(final LoggerContext loggerContext, 
final ConfigurationSource source) {
-        return getConfiguration(loggerContext, source.toString(), null);
-    }
-
-    @Override
-    public Configuration getConfiguration(final LoggerContext loggerContext, 
final String name, final URI configLocation) {
-        ConfigurationBuilder<BuiltConfiguration> builder = 
newConfigurationBuilder();
-        return createConfiguration(name, builder);
-    }
-
-    @Override
-    protected String[] getSupportedTypes() {
-        return new String[] {"*"};
-    }
-}]]></pre>
-            <p>
-              As of version 2.7, the 
<code>ConfigurationFactory.getConfiguration()</code> methods take an 
-              additional <code>LoggerContext</code> parameter.
-            </p>
-          </subsection>
-        <a name="Configurator"/>
-          <subsection name="Reconfigure Log4j Using ConfigurationBuilder with 
the Configurator">
-            <p>
-              An alternative to a custom ConfigurationFactory is to configure 
with the <code>Configurator</code>.
-              Once a Configuration object has been constructed, it can be 
passed to one of the 
-              <code>Configurator.initialize</code> methods to set up the Log4j 
configuration.
-            </p>
-            <p>
-              Using the Configurator in this manner allows the application 
control over when Log4j is initialized.
-              However, should any logging be attempted before 
Configurator.initialize() is called then the
-              default configuration will be used for those log events.
-            </p>
-            <pre class="prettyprint linenum"><![CDATA[
-ConfigurationBuilder<BuiltConfiguration> builder = 
ConfigurationBuilderFactory.newConfigurationBuilder();
-builder.setStatusLevel(Level.ERROR);
-builder.setConfigurationName("BuilderTest");
-builder.add(builder.newFilter("ThresholdFilter", Filter.Result.ACCEPT, 
Filter.Result.NEUTRAL)
-    .addAttribute("level", Level.DEBUG));
-AppenderComponentBuilder appenderBuilder = builder.newAppender("Stdout", 
"CONSOLE").addAttribute("target",
-    ConsoleAppender.Target.SYSTEM_OUT);
-appenderBuilder.add(builder.newLayout("PatternLayout")
-    .addAttribute("pattern", "%d [%t] %-5level: %msg%n%throwable"));
-appenderBuilder.add(builder.newFilter("MarkerFilter", Filter.Result.DENY, 
Filter.Result.NEUTRAL)
-    .addAttribute("marker", "FLOW"));
-builder.add(appenderBuilder);
-builder.add(builder.newLogger("org.apache.logging.log4j", Level.DEBUG)
-    .add(builder.newAppenderRef("Stdout")).addAttribute("additivity", false));
-builder.add(builder.newRootLogger(Level.ERROR).add(builder.newAppenderRef("Stdout")));
-ctx = Configurator.initialize(builder.build());
-]]></pre>
-            <p>This example shows how to create a configuration that includes 
a RollingFileAppender.</p>
-            <pre class="prettyprint linenum"><![CDATA[
-ConfigurationBuilder< BuiltConfiguration > builder = 
ConfigurationBuilderFactory.newConfigurationBuilder();
-
-builder.setStatusLevel( Level.ERROR);
-builder.setConfigurationName("RollingBuilder");
-// create a console appender
-AppenderComponentBuilder appenderBuilder = builder.newAppender("Stdout", 
"CONSOLE").addAttribute("target",
-    ConsoleAppender.Target.SYSTEM_OUT);
-appenderBuilder.add(builder.newLayout("PatternLayout")
-    .addAttribute("pattern", "%d [%t] %-5level: %msg%n%throwable"));
-builder.add( appenderBuilder );
-// create a rolling file appender
-LayoutComponentBuilder layoutBuilder = builder.newLayout("PatternLayout")
-    .addAttribute("pattern", "%d [%t] %-5level: %msg%n");
-ComponentBuilder triggeringPolicy = builder.newComponent("Policies")
-    
.addComponent(builder.newComponent("CronTriggeringPolicy").addAttribute("schedule",
 "0 0 0 * * ?"))
-    
.addComponent(builder.newComponent("SizeBasedTriggeringPolicy").addAttribute("size",
 "100M"));
-appenderBuilder = builder.newAppender("rolling", "RollingFile")
-    .addAttribute("fileName", "target/rolling.log")
-    .addAttribute("filePattern", "target/archive/rolling-%d{MM-dd-yy}.log.gz")
-    .add(layoutBuilder)
-    .addComponent(triggeringPolicy);
-builder.add(appenderBuilder);
-
-// create the new logger
-builder.add( builder.newLogger( "TestLogger", Level.DEBUG )
-    .add( builder.newAppenderRef( "rolling" ) )
-    .addAttribute( "additivity", false ) );
-
-builder.add( builder.newRootLogger( Level.DEBUG )
-    .add( builder.newAppenderRef( "rolling" ) ) );
-LoggerContext ctx = Configurator.initialize(builder.build());
-]]></pre>
-        </subsection>
-
-          <a name="Hybrid"/>
-          <subsection name="Initialize Log4j by Combining Configuration File 
with Programmatic Configuration">
-            <p>
-              Sometimes you want to configure with a configuration file but do 
some additional programmatic
-              configuration. A possible use case might be that you want to 
allow for a flexible configuration using XML 
-              but at the same time make sure there are a few configuration 
elements that are always present that can't be removed.
-            </p>
-            <p>
-              The easiest way to achieve this is to extend one of the standard 
Configuration classes
-              (XMLConfiguration, JSONConfiguration) and then create a new 
ConfigurationFactory for the extended class.
-              After the standard configuration completes the custom 
configuration can be added to it.
-            </p>
-            <p>
-              The example below shows how to extend XMLConfiguration to 
manually add an Appender and a LoggerConfig
-              to the configuration.
-            </p>
-            <pre class="prettyprint linenums">
-@Plugin(name = "MyXMLConfigurationFactory", category = "ConfigurationFactory")
-@Order(10)
-public class MyXMLConfigurationFactory extends ConfigurationFactory {
-
-    /**
-     * Valid file extensions for XML files.
-     */
-    public static final String[] SUFFIXES = new String[] {".xml", "*"};
-
-    /**
-     * Return the Configuration.
-     * @param source The InputSource.
-     * @return The Configuration.
-     */
-    public Configuration getConfiguration(InputSource source) {
-        return new MyXMLConfiguration(source, configFile);
-    }
-
-    /**
-     * Returns the file suffixes for XML files.
-     * @return An array of File extensions.
-     */
-    public String[] getSupportedTypes() {
-        return SUFFIXES;
-    }
-}
-
-public class MyXMLConfiguration extends XMLConfiguration {
-    public MyXMLConfiguration(final ConfigurationFactory.ConfigurationSource 
configSource) {
-      super(configSource);
-    }
-
-    @Override
-    protected void doConfigure() {
-        super.doConfigure();
-        final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
-        final Layout layout = 
PatternLayout.createLayout(PatternLayout.SIMPLE_CONVERSION_PATTERN, config, 
null,
-              null,null, null);
-        final Appender appender = 
FileAppender.createAppender("target/test.log", "false", "false", "File", "true",
-              "false", "false", "4000", layout, null, "false", null, config);
-        appender.start();
-        addAppender(appender);
-        LoggerConfig loggerConfig = LoggerConfig.createLogger("false", "info", 
"org.apache.logging.log4j",
-              "true", refs, null, config, null );
-        loggerConfig.addAppender(appender, null, null);
-        addLogger("org.apache.logging.log4j", loggerConfig);
-    }
-}</pre>
-          </subsection>
-        <a name="AddingToCurrent"/>
-        <subsection name="Programmatically Modifying the Current Configuration 
after Initialization">
-            <p>
-              Applications sometimes have the need to customize logging 
separate from the actual configuration.
-              Log4j allows this although it suffers from a few limitations:
-            </p>
-              <ol>
-                <li>If the configuration file is changed the configuration 
will be reloaded and the manual changes
-                will be lost.</li>
-                <li>Modification to the running configuration requires that 
all the methods being called (addAppender
-                  and addLogger) be synchronized.</li>
-              </ol>
-            <p>
-              As such, the recommended approach for customizing a 
configuration is to extend one of the standard
-              Configuration classes, override the setup method to first do 
super.setup() and then add the custom
-              Appenders, Filters and LoggerConfigs to the configuration before 
it is registered for use.
-            </p>
-            <p>
-              The following example adds an Appender and a new LoggerConfig 
using that Appender to the current
-              configuration.
-            </p>
-            <!-- TODO: update code example below with new plugin API -->
-            <pre class="prettyprint linenums"><![CDATA[
-        final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
-        final Configuration config = ctx.getConfiguration();
-        Layout layout = 
PatternLayout.createLayout(PatternLayout.SIMPLE_CONVERSION_PATTERN, config, 
null,
-            null,null, null);
-        Appender appender = FileAppender.createAppender("target/test.log", 
"false", "false", "File", "true",
-            "false", "false", "4000", layout, null, "false", null, config);
-        appender.start();
-        config.addAppender(appender);
-        AppenderRef ref = AppenderRef.createAppenderRef("File", null, null);
-        AppenderRef[] refs = new AppenderRef[] {ref};
-        LoggerConfig loggerConfig = LoggerConfig.createLogger("false", "info", 
"org.apache.logging.log4j",
-            "true", refs, null, config, null );
-        loggerConfig.addAppender(appender, null, null);
-        config.addLogger("org.apache.logging.log4j", loggerConfig);
-        ctx.updateLoggers();
-}]]></pre>
-          </subsection>
-        <a name="AppendingToWritersAndOutputStreams"/>
-        <subsection name="Appending Log Events to Writers and OutputStreams 
Programmatically">
-            <p>
-              Log4j 2.5 provides facilities to append log events to Writers 
and OutputStreams. For example, this 
-              provides simple integration for JDBC Driver implementors that 
use Log4j internally and still want 
-              to support the JDBC APIs 
<code>CommonDataSource.setLogWriter(PrintWriter)</code>, 
-              <code>java.sql.DriverManager.setLogWriter(PrintWriter)</code>, 
and 
-              <code>java.sql.DriverManager.setLogStream(PrintStream)</code>.   
           
-            </p>
-            <p>
-              Given any <code>Writer</code>, like a <code>PrintWriter</code>, 
you tell Log4j to append events to 
-              that writer by creating a <code>WriterAppender</code> and 
updating the Log4j configuration:
-            </p>
-            <pre class="prettyprint linenums"><![CDATA[
-void addAppender(final Writer writer, final String writerName) {
-    final LoggerContext context = LoggerContext.getContext(false);
-    final Configuration config = context.getConfiguration();
-    final PatternLayout layout = PatternLayout.createDefaultLayout(config);
-    final Appender appender = WriterAppender.createAppender(layout, null, 
writer, writerName, false, true);
-    appender.start();
-    config.addAppender(appender);
-    updateLoggers(appender, config);
-}
-
-private void updateLoggers(final Appender appender, final Configuration 
config) {
-    final Level level = null;
-    final Filter filter = null;
-    for (final LoggerConfig loggerConfig : config.getLoggers().values()) {
-        loggerConfig.addAppender(appender, level, filter);
-    }
-    config.getRootLogger().addAppender(appender, level, filter);
-}]]></pre>
-            <p>
-              You can achieve the same effect with an 
<code>OutputStream</code>, like a <code>PrintStream</code>:
-            </p>            
-            <pre class="prettyprint linenums"><![CDATA[
-void addAppender(final OutputStream outputStream, final String 
outputStreamName) {
-    final LoggerContext context = LoggerContext.getContext(false);
-    final Configuration config = context.getConfiguration();
-    final PatternLayout layout = PatternLayout.createDefaultLayout(config);
-    final Appender appender = OutputStreamAppender.createAppender(layout, 
null, outputStream, outputStreamName, false, true);
-    appender.start();
-    config.addAppender(appender);
-    updateLoggers(appender, config);
-}]]></pre>
-        </subsection>
-            <p>
-              The difference is the use of <code>OutputStreamAppender</code> 
instead of <code>WriterAppender</code>.
-            </p>            
-      </section>
-
-    </body>
-</document>

Reply via email to