logging-log4j-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Matt Sicker <boa...@gmail.com>
Subject Re: logging-log4j2 git commit: FastConsoleAppender
Date Thu, 26 May 2016 21:23:24 GMT
Is there any place the factory method version is documented? I could add
the info there. Otherwise, I'll have to figure out an appropriate place for
it (perhaps in the manual).

On 26 May 2016 at 13:35, Matt Sicker <boards@gmail.com> wrote:

> Sure. I can't believe I forgot to document that better.
>
> On 26 May 2016 at 12:06, Ralph Goers <ralph.goers@dslextreme.com> wrote:
>
>> Can you provide documentation on using the builder?  I tried to implement
>> something a few months ago using a builder and couldn’t quite figure it all
>> out so I went back to using a factory.
>>
>> Ralph
>>
>> On May 26, 2016, at 8:31 AM, Matt Sicker <boards@gmail.com> wrote:
>>
>> I prefer builders when you have more than 2 arguments to the factory.
>> This is based on Item 2 from Effective Java (prefer builders for
>> constructors that take a lot of arguments).
>>
>> On 26 May 2016 at 10:24, Mikael Ståldal <mikael.staldal@magine.com>
>> wrote:
>>
>>> Which one of builder and factory is preferred?
>>>
>>> On Thu, May 26, 2016 at 5:22 PM, Matt Sicker <boards@gmail.com> wrote:
>>>
>>>> Just FYI, if you make a plugin builder, you don't need to make a plugin
>>>> factory as well. The builder is used first if available followed by the
>>>> factory method. Classes that have both are mainly for backwards
>>>> compatibility.
>>>>
>>>> ---------- Forwarded message ----------
>>>> From: <mikes@apache.org>
>>>> Date: 26 May 2016 at 10:12
>>>> Subject: logging-log4j2 git commit: FastConsoleAppender
>>>> To: commits@logging.apache.org
>>>>
>>>>
>>>> Repository: logging-log4j2
>>>> Updated Branches:
>>>>   refs/heads/LOG4J2-1395 [created] 06c554689
>>>>
>>>>
>>>> FastConsoleAppender
>>>>
>>>>
>>>> Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
>>>> Commit:
>>>> http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/06c55468
>>>> Tree:
>>>> http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/06c55468
>>>> Diff:
>>>> http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/06c55468
>>>>
>>>> Branch: refs/heads/LOG4J2-1395
>>>> Commit: 06c55468948efdce95a591801d5f9e2ffdb69dd4
>>>> Parents: e012269
>>>> Author: Mikael Ståldal <mikael.staldal@magine.com>
>>>> Authored: Thu May 26 17:12:33 2016 +0200
>>>> Committer: Mikael Ståldal <mikael.staldal@magine.com>
>>>> Committed: Thu May 26 17:12:33 2016 +0200
>>>>
>>>> ----------------------------------------------------------------------
>>>>  .../core/appender/FastConsoleAppender.java      | 227
>>>> +++++++++++++++++++
>>>>  .../jmh/Log4j2AppenderComparisonBenchmark.java  |  18 ++
>>>>  .../resources/log4j2-appenderComparison.xml     |   6 +
>>>>  3 files changed, 251 insertions(+)
>>>> ----------------------------------------------------------------------
>>>>
>>>>
>>>>
>>>> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/06c55468/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/FastConsoleAppender.java
>>>> ----------------------------------------------------------------------
>>>> diff --git
>>>> a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/FastConsoleAppender.java
>>>> b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/FastConsoleAppender.java
>>>> new file mode 100644
>>>> index 0000000..a7cd905
>>>> --- /dev/null
>>>> +++
>>>> b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/FastConsoleAppender.java
>>>> @@ -0,0 +1,227 @@
>>>> +/*
>>>> + * 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.
>>>> + */
>>>> +package org.apache.logging.log4j.core.appender;
>>>> +
>>>> +import java.io.FileDescriptor;
>>>> +import java.io.FileOutputStream;
>>>> +import java.io.OutputStream;
>>>> +import java.io.Serializable;
>>>> +import java.util.concurrent.atomic.AtomicInteger;
>>>> +
>>>> +import org.apache.logging.log4j.core.Filter;
>>>> +import org.apache.logging.log4j.core.Layout;
>>>> +import org.apache.logging.log4j.core.config.plugins.Plugin;
>>>> +import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
>>>> +import
>>>> org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
>>>> +import
>>>> org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
>>>> +import org.apache.logging.log4j.core.config.plugins.PluginElement;
>>>> +import org.apache.logging.log4j.core.config.plugins.PluginFactory;
>>>> +import
>>>> org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
>>>> +import org.apache.logging.log4j.core.layout.PatternLayout;
>>>> +import org.apache.logging.log4j.core.util.CloseShieldOutputStream;
>>>> +
>>>> +/**
>>>> + * Appends log events to <code>System.out</code> or
>>>> <code>System.err</code> using a layout specified by the user.
The
>>>> + * default target is <code>System.out</code>.
>>>> + */
>>>> +@Plugin(name = "FastConsole", category = "Core", elementType =
>>>> "appender", printObject = true)
>>>> +public final class FastConsoleAppender extends
>>>> AbstractOutputStreamAppender<OutputStreamManager> {
>>>> +
>>>> +    private static ConsoleManagerFactory factory = new
>>>> ConsoleManagerFactory();
>>>> +    private static final Target DEFAULT_TARGET = Target.SYSTEM_OUT;
>>>> +    private static final AtomicInteger COUNT = new AtomicInteger();
>>>> +
>>>> +    private final Target target;
>>>> +
>>>> +    /**
>>>> +     * Enumeration of console destinations.
>>>> +     */
>>>> +    public enum Target {
>>>> +        /** Standard output. */
>>>> +        SYSTEM_OUT,
>>>> +        /** Standard error output. */
>>>> +        SYSTEM_ERR
>>>> +    }
>>>> +
>>>> +    private FastConsoleAppender(final String name, final Layout<?
>>>> extends Serializable> layout, final Filter filter,
>>>> +                                final OutputStreamManager manager,
>>>> final boolean ignoreExceptions, Target target) {
>>>> +        super(name, layout, filter, ignoreExceptions, true, manager);
>>>> +        this.target = target;
>>>> +    }
>>>> +
>>>> +    /**
>>>> +     * Creates a Console Appender.
>>>> +     *
>>>> +     * @param layout The layout to use (required).
>>>> +     * @param filter The Filter or null.
>>>> +     * @param target The target (SYSTEM_OUT or SYSTEM_ERR). The
>>>> default is SYSTEM_OUT.
>>>> +     * @param name The name of the Appender (required).
>>>> +     * @param ignoreExceptions If {@code "true"} (default) exceptions
>>>> encountered when appending events are logged; otherwise they
>>>> +     *            are propagated to the caller.
>>>> +     * @return The ConsoleAppender.
>>>> +     */
>>>> +    @PluginFactory
>>>> +    public static FastConsoleAppender createAppender(
>>>> +            // @formatter:off
>>>> +            @PluginElement("Layout") Layout<? extends Serializable>
>>>> layout,
>>>> +            @PluginElement("Filter") final Filter filter,
>>>> +            @PluginAttribute(value = "target") Target target,
>>>> +            @PluginAttribute("name") final String name,
>>>> +            @PluginAttribute(value = "ignoreExceptions",
>>>> defaultBoolean = true) final boolean ignoreExceptions) {
>>>> +            // @formatter:on
>>>> +        if (name == null) {
>>>> +            LOGGER.error("No name provided for ConsoleAppender");
>>>> +            return null;
>>>> +        }
>>>> +        if (layout == null) {
>>>> +            layout = PatternLayout.createDefaultLayout();
>>>> +        }
>>>> +        target = target == null ? Target.SYSTEM_OUT : target;
>>>> +        return new FastConsoleAppender(name, layout, filter,
>>>> getManager(target, layout), ignoreExceptions, target);
>>>> +    }
>>>> +
>>>> +    public static FastConsoleAppender
>>>> createDefaultAppenderForLayout(final Layout<? extends Serializable>
layout)
>>>> {
>>>> +        // this method cannot use the builder class without
>>>> introducing an infinite loop due to DefaultConfiguration
>>>> +        return new FastConsoleAppender("DefaultConsole-" +
>>>> COUNT.incrementAndGet(), layout, null,
>>>> +                getDefaultManager(DEFAULT_TARGET, layout), true,
>>>> DEFAULT_TARGET);
>>>> +    }
>>>> +
>>>> +    @PluginBuilderFactory
>>>> +    public static Builder newBuilder() {
>>>> +        return new Builder();
>>>> +    }
>>>> +
>>>> +    /**
>>>> +     * Builds ConsoleAppender instances.
>>>> +     */
>>>> +    public static class Builder implements
>>>> org.apache.logging.log4j.core.util.Builder<FastConsoleAppender> {
>>>> +
>>>> +        @PluginElement("Layout")
>>>> +        @Required
>>>> +        private Layout<? extends Serializable> layout =
>>>> PatternLayout.createDefaultLayout();
>>>> +
>>>> +        @PluginElement("Filter")
>>>> +        private Filter filter;
>>>> +
>>>> +        @PluginBuilderAttribute
>>>> +        @Required
>>>> +        private Target target = DEFAULT_TARGET;
>>>> +
>>>> +        @PluginBuilderAttribute
>>>> +        @Required
>>>> +        private String name;
>>>> +
>>>> +        @PluginBuilderAttribute
>>>> +        private boolean ignoreExceptions = true;
>>>> +
>>>> +        public Builder setLayout(final Layout<? extends Serializable>
>>>> aLayout) {
>>>> +            this.layout = aLayout;
>>>> +            return this;
>>>> +        }
>>>> +
>>>> +        public Builder setFilter(final Filter aFilter) {
>>>> +            this.filter = aFilter;
>>>> +            return this;
>>>> +        }
>>>> +
>>>> +        public Builder setTarget(final Target aTarget) {
>>>> +            this.target = aTarget;
>>>> +            return this;
>>>> +        }
>>>> +
>>>> +        public Builder setName(final String aName) {
>>>> +            this.name = aName;
>>>> +            return this;
>>>> +        }
>>>> +
>>>> +        public Builder setIgnoreExceptions(final boolean
>>>> shouldIgnoreExceptions) {
>>>> +            this.ignoreExceptions = shouldIgnoreExceptions;
>>>> +            return this;
>>>> +        }
>>>> +
>>>> +        @Override
>>>> +        public FastConsoleAppender build() {
>>>> +            return new FastConsoleAppender(name, layout, filter,
>>>> getManager(target, layout), ignoreExceptions, target);
>>>> +        }
>>>> +    }
>>>> +
>>>> +    private static OutputStreamManager getDefaultManager(final Target
>>>> target, final Layout<? extends Serializable> layout) {
>>>> +        final OutputStream os = getOutputStream(target);
>>>> +
>>>> +        // LOG4J2-1176 DefaultConfiguration should not share
>>>> OutputStreamManager instances to avoid memory leaks.
>>>> +        final String managerName = target.name() + '-' + COUNT.get();
>>>> +        return OutputStreamManager.getManager(managerName, new
>>>> FactoryData(os, managerName, layout), factory);
>>>> +    }
>>>> +
>>>> +    private static OutputStreamManager getManager(final Target target,
>>>> final Layout<? extends Serializable> layout) {
>>>> +        final OutputStream os = getOutputStream(target);
>>>> +        final String managerName = target.name();
>>>> +        return OutputStreamManager.getManager(managerName, new
>>>> FactoryData(os, managerName, layout), factory);
>>>> +    }
>>>> +
>>>> +    private static OutputStream getOutputStream(final Target target) {
>>>> +        OutputStream outputStream = target == Target.SYSTEM_OUT
>>>> +            ? new FileOutputStream(FileDescriptor.out)
>>>> +            : new FileOutputStream(FileDescriptor.err);
>>>> +        return new CloseShieldOutputStream(outputStream);
>>>> +    }
>>>> +
>>>> +    /**
>>>> +     * Data to pass to factory method.
>>>> +     */
>>>> +    private static class FactoryData {
>>>> +        private final OutputStream os;
>>>> +        private final String name;
>>>> +        private final Layout<? extends Serializable> layout;
>>>> +
>>>> +        /**
>>>> +         * Constructor.
>>>> +         *
>>>> +         * @param os The OutputStream.
>>>> +         * @param type The name of the target.
>>>> +         * @param layout A Serializable layout
>>>> +         */
>>>> +        public FactoryData(final OutputStream os, final String type,
>>>> final Layout<? extends Serializable> layout) {
>>>> +            this.os = os;
>>>> +            this.name = type;
>>>> +            this.layout = layout;
>>>> +        }
>>>> +    }
>>>> +
>>>> +    /**
>>>> +     * Factory to create the Appender.
>>>> +     */
>>>> +    private static class ConsoleManagerFactory implements
>>>> ManagerFactory<OutputStreamManager, FactoryData> {
>>>> +
>>>> +        /**
>>>> +         * Create an OutputStreamManager.
>>>> +         *
>>>> +         * @param name The name of the entity to manage.
>>>> +         * @param data The data required to create the entity.
>>>> +         * @return The OutputStreamManager
>>>> +         */
>>>> +        @Override
>>>> +        public OutputStreamManager createManager(final String name,
>>>> final FactoryData data) {
>>>> +            return new OutputStreamManager(data.os, data.name,
>>>> data.layout, true);
>>>> +        }
>>>> +    }
>>>> +
>>>> +    public Target getTarget() {
>>>> +        return target;
>>>> +    }
>>>> +
>>>> +}
>>>>
>>>>
>>>> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/06c55468/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/Log4j2AppenderComparisonBenchmark.java
>>>> ----------------------------------------------------------------------
>>>> diff --git
>>>> a/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/Log4j2AppenderComparisonBenchmark.java
>>>> b/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/Log4j2AppenderComparisonBenchmark.java
>>>> index 0527709..a4ea02e 100644
>>>> ---
>>>> a/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/Log4j2AppenderComparisonBenchmark.java
>>>> +++
>>>> b/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/Log4j2AppenderComparisonBenchmark.java
>>>> @@ -57,12 +57,14 @@ public class Log4j2AppenderComparisonBenchmark {
>>>>      private Logger rafLogger;
>>>>      private Logger mmapLogger;
>>>>      private Logger consoleLogger;
>>>> +    private Logger fastConsoleLogger;
>>>>      private Logger noopLogger;
>>>>      private Logger rewriteLogger;
>>>>      private Appender fileAppender;
>>>>      private Appender rafAppender;
>>>>      private Appender mmapAppender;
>>>>      private Appender consoleAppender;
>>>> +    private Appender fastConsoleAppender;
>>>>      private Appender noopAppender;
>>>>      private Appender rewriteAppender;
>>>>
>>>> @@ -102,6 +104,7 @@ public class Log4j2AppenderComparisonBenchmark {
>>>>          rafLogger = LogManager.getLogger("RAFLogger");
>>>>          mmapLogger = LogManager.getLogger("MMapLogger");
>>>>          consoleLogger = LogManager.getLogger("ConsoleLogger");
>>>> +        fastConsoleLogger = LogManager.getLogger("FastConsoleLogger");
>>>>          noopLogger = LogManager.getLogger("NoopLogger");
>>>>          rewriteLogger = LogManager.getLogger("RewriteLogger");
>>>>
>>>> @@ -109,6 +112,7 @@ public class Log4j2AppenderComparisonBenchmark {
>>>>          rafAppender = ((org.apache.logging.log4j.core.Logger)
>>>> rafLogger).getAppenders().get("RandomAccessFile");
>>>>          mmapAppender = ((org.apache.logging.log4j.core.Logger)
>>>> mmapLogger).getAppenders().get("MemoryMappedFile");
>>>>          consoleAppender = ((org.apache.logging.log4j.core.Logger)
>>>> consoleLogger).getAppenders().get("Console");
>>>> +        fastConsoleAppender = ((org.apache.logging.log4j.core.Logger)
>>>> fastConsoleLogger).getAppenders().get("FastConsole");
>>>>          noopAppender = ((org.apache.logging.log4j.core.Logger)
>>>> noopLogger).getAppenders().get("NoOp");
>>>>          rewriteAppender = ((org.apache.logging.log4j.core.Logger)
>>>> rewriteLogger).getAppenders().get("Rewrite");
>>>>      }
>>>> @@ -218,4 +222,18 @@ public class Log4j2AppenderComparisonBenchmark {
>>>>      public void appenderConsole() {
>>>>          consoleAppender.append(EVENT);
>>>>      }
>>>> +
>>>> +    @BenchmarkMode(Mode.Throughput)
>>>> +    @OutputTimeUnit(TimeUnit.SECONDS)
>>>> +    @Benchmark
>>>> +    public void end2endFastConsole() {
>>>> +        fastConsoleLogger.debug(MESSAGE);
>>>> +    }
>>>> +
>>>> +    @BenchmarkMode(Mode.Throughput)
>>>> +    @OutputTimeUnit(TimeUnit.SECONDS)
>>>> +    @Benchmark
>>>> +    public void appenderFastConsole() {
>>>> +        fastConsoleAppender.append(EVENT);
>>>> +    }
>>>>  }
>>>>
>>>>
>>>> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/06c55468/log4j-perf/src/main/resources/log4j2-appenderComparison.xml
>>>> ----------------------------------------------------------------------
>>>> diff --git
>>>> a/log4j-perf/src/main/resources/log4j2-appenderComparison.xml
>>>> b/log4j-perf/src/main/resources/log4j2-appenderComparison.xml
>>>> index 741a225..8ad6327 100644
>>>> --- a/log4j-perf/src/main/resources/log4j2-appenderComparison.xml
>>>> +++ b/log4j-perf/src/main/resources/log4j2-appenderComparison.xml
>>>> @@ -21,6 +21,9 @@
>>>>          <Console name="Console" target="SYSTEM_OUT">
>>>>              <PatternLayout pattern="%d %p [%t] %c{1} %X{transactionId}
>>>> - %m%n"/>
>>>>          </Console>
>>>> +        <FastConsole name="FastConsole" target="SYSTEM_OUT">
>>>> +            <PatternLayout pattern="%d %p [%t] %c{1} %X{transactionId}
>>>> - %m%n"/>
>>>> +        </FastConsole>
>>>>          <File name="File" fileName="target/testlog4j2.log"
>>>> immediateFlush="false">
>>>>              <PatternLayout pattern="%d %p [%t] %c{1} %X{transactionId}
>>>> - %m%n"/>
>>>>          </File>
>>>> @@ -55,6 +58,9 @@
>>>>          <Logger name="ConsoleLogger" level="debug" additivity="false">
>>>>              <AppenderRef ref="Console"/>
>>>>          </Logger>
>>>> +        <Logger name="FastConsoleLogger" level="debug"
>>>> additivity="false">
>>>> +            <AppenderRef ref="FastConsole"/>
>>>> +        </Logger>
>>>>          <Logger name="NoopLogger" level="debug" additivity="false">
>>>>              <AppenderRef ref="NoOp"/>
>>>>          </Logger>
>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Matt Sicker <boards@gmail.com>
>>>>
>>>
>>>
>>>
>>> --
>>> [image: MagineTV]
>>>
>>> *Mikael Ståldal*
>>> Senior software developer
>>>
>>> *Magine TV*
>>> mikael.staldal@magine.com
>>> Grev Turegatan 3  | 114 46 Stockholm, Sweden  |   www.magine.com
>>> <http://www.magine.com/>
>>>
>>> Privileged and/or Confidential Information may be contained in this
>>> message. If you are not the addressee indicated in this message
>>> (or responsible for delivery of the message to such a person), you may
>>> not copy or deliver this message to anyone. In such case,
>>> you should destroy this message and kindly notify the sender by reply
>>> email.
>>>
>>
>>
>>
>> --
>> Matt Sicker <boards@gmail.com>
>>
>>
>>
>
>
> --
> Matt Sicker <boards@gmail.com>
>



-- 
Matt Sicker <boards@gmail.com>

Mime
View raw message