Uploaded image for project: 'Log4j 2'
  1. Log4j 2
  2. LOG4J2-743

How to add a custom appender

    XMLWordPrintableJSON

    Details

    • Type: Question
    • Status: Resolved
    • Priority: Major
    • Resolution: Duplicate
    • Affects Version/s: 2.0
    • Fix Version/s: 2.0.1
    • Component/s: Appenders
    • Labels:
    • Environment:

      Windows Server 2003,jdk1.6.0_43,Eclipse Kepler Service Release 1

      Description

      I was writing a log system in my project with log4j2.I want output logs into memory. I write a MemoryAppender referring to the manual of log4j2,but an error occured when starting the application.
      I doubt that my custom appender doesn't exist in Log4j2Plugin.dat ?
      In the log4j-2.0-rc1,I found PluginManager class,containing a main method which can generate binary file Log4j2Plugin.dat, but this method is deprecated in the latest version.I wonder if there is another way to do this ?

      Log

      2014-07-25 09:25:43,052 DEBUG Starting configuration XmlConfiguration[location=D:\gitlab\project\src\main\webapp\WEB-INF\classes\log4j2.xml]
      2014-07-25 09:25:43,052 DEBUG Found Plugin Map at jar:file:/D:/gitlab/project/lib/log4j-core-2.0.jar!/META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat
      2014-07-25 09:25:43,052 ERROR Error processing element Memory: CLASS_NOT_FOUND
      2014-07-25 09:25:43,068 DEBUG Building Plugin[name=appenders, class=org.apache.logging.log4j.core.config.AppendersPlugin]. Searching for builder factory method...
      2014-07-25 09:25:43,068 DEBUG No builder factory method found in class org.apache.logging.log4j.core.config.AppendersPlugin. Going to try finding a factory method instead.
      2014-07-25 09:25:43,068 DEBUG Still building Plugin[name=appenders, class=org.apache.logging.log4j.core.config.AppendersPlugin]. Searching for factory method...
      2014-07-25 09:25:43,068 DEBUG Found factory method [createAppenders]: public static java.util.concurrent.ConcurrentMap org.apache.logging.log4j.core.config.AppendersPlugin.createAppenders(org.apache.logging.log4j.core.Appender[]).
      2014-07-25 09:25:43,068 DEBUG Calling createAppenders on class org.apache.logging.log4j.core.config.AppendersPlugin for element Appenders with params(={})
      2014-07-25 09:25:43,068 DEBUG Built Plugin[name=appenders] OK from factory method.
      2014-07-25 09:25:43,068 DEBUG Building Plugin[name=AppenderRef, class=org.apache.logging.log4j.core.config.AppenderRef]. Searching for builder factory method...
      2014-07-25 09:25:43,068 DEBUG No builder factory method found in class org.apache.logging.log4j.core.config.AppenderRef. Going to try finding a factory method instead.
      2014-07-25 09:25:43,068 DEBUG Still building Plugin[name=AppenderRef, class=org.apache.logging.log4j.core.config.AppenderRef]. Searching for factory method...
      2014-07-25 09:25:43,068 DEBUG Found factory method [createAppenderRef]: public static org.apache.logging.log4j.core.config.AppenderRef org.apache.logging.log4j.core.config.AppenderRef.createAppenderRef(java.lang.String,org.apache.logging.log4j.Level,org.apache.logging.log4j.core.Filter).
      2014-07-25 09:25:43,084 DEBUG Calling createAppenderRef on class org.apache.logging.log4j.core.config.AppenderRef for element AppenderRef with params(ref="Memory", level="null", null)
      2014-07-25 09:25:43,084 DEBUG Built Plugin[name=AppenderRef] OK from factory method.
      2014-07-25 09:25:43,084 DEBUG Building Plugin[name=root, class=org.apache.logging.log4j.core.config.LoggerConfig$RootLogger]. Searching for builder factory method...
      2014-07-25 09:25:43,084 DEBUG No builder factory method found in class org.apache.logging.log4j.core.config.LoggerConfig$RootLogger. Going to try finding a factory method instead.
      2014-07-25 09:25:43,084 DEBUG Still building Plugin[name=root, class=org.apache.logging.log4j.core.config.LoggerConfig$RootLogger]. Searching for factory method...
      2014-07-25 09:25:43,084 DEBUG Found factory method [createLogger]: public static org.apache.logging.log4j.core.config.LoggerConfig org.apache.logging.log4j.core.config.LoggerConfig$RootLogger.createLogger(java.lang.String,org.apache.logging.log4j.Level,java.lang.String,org.apache.logging.log4j.core.config.AppenderRef[],org.apache.logging.log4j.core.config.Property[],org.apache.logging.log4j.core.config.Configuration,org.apache.logging.log4j.core.Filter).
      2014-07-25 09:25:43,099 DEBUG Calling createLogger on class org.apache.logging.log4j.core.config.LoggerConfig$RootLogger for element Root with params(additivity="null", level="INFO", includeLocation="null", ={Memory}, ={}, Configuration(D:\gitlab\project\src\main\webapp\WEB-INF\classes\log4j2.xml), null)
      2014-07-25 09:25:43,099 DEBUG Built Plugin[name=root] OK from factory method.
      2014-07-25 09:25:43,099 DEBUG Building Plugin[name=loggers, class=org.apache.logging.log4j.core.config.LoggersPlugin]. Searching for builder factory method...
      2014-07-25 09:25:43,099 DEBUG No builder factory method found in class org.apache.logging.log4j.core.config.LoggersPlugin. Going to try finding a factory method instead.
      2014-07-25 09:25:43,099 DEBUG Still building Plugin[name=loggers, class=org.apache.logging.log4j.core.config.LoggersPlugin]. Searching for factory method...
      2014-07-25 09:25:43,099 DEBUG Found factory method [createLoggers]: public static org.apache.logging.log4j.core.config.Loggers org.apache.logging.log4j.core.config.LoggersPlugin.createLoggers(org.apache.logging.log4j.core.config.LoggerConfig[]).
      2014-07-25 09:25:43,099 DEBUG Calling createLoggers on class org.apache.logging.log4j.core.config.LoggersPlugin for element Loggers with params(={root})
      2014-07-25 09:25:43,099 DEBUG Built Plugin[name=loggers] OK from factory method.
      2014-07-25 09:25:43,099 ERROR Unable to locate appender Memory for logger 
      2014-07-25 09:25:43,099 DEBUG Started configuration XmlConfiguration[location=D:\gitlab\project\src\main\webapp\WEB-INF\classes\log4j2.xml] OK.
      2014-07-25 09:25:43,099 TRACE Stopping org.apache.logging.log4j.core.config.DefaultConfiguration@bf1d3b...
      2014-07-25 09:25:43,099 TRACE AbstractConfiguration stopped 0 AsyncLoggerConfigs.
      2014-07-25 09:25:43,099 TRACE AbstractConfiguration stopped 0 AsyncAppenders.
      2014-07-25 09:25:43,099 DEBUG Shutting down OutputStreamManager SYSTEM_OUT
      2014-07-25 09:25:43,099 TRACE AbstractConfiguration stopped 1 Appenders.
      2014-07-25 09:25:43,099 TRACE AbstractConfiguration stopped 0 Loggers.
      2014-07-25 09:25:43,099 DEBUG Stopped org.apache.logging.log4j.core.config.DefaultConfiguration@bf1d3b OK
      2014-07-25 09:25:43,146 DEBUG Registering MBean org.apache.logging.log4j2:type=sun.misc.Launcher$AppClassLoader@192d342
      2014-07-25 09:25:43,146 DEBUG Registering MBean org.apache.logging.log4j2:type=sun.misc.Launcher$AppClassLoader@192d342,component=StatusLogger
      2014-07-25 09:25:43,146 DEBUG Registering MBean org.apache.logging.log4j2:type=sun.misc.Launcher$AppClassLoader@192d342,component=ContextSelector
      2014-07-25 09:25:43,146 DEBUG Registering MBean org.apache.logging.log4j2:type=sun.misc.Launcher$AppClassLoader@192d342,component=Loggers,name=
      2014-07-25 09:25:43,146 DEBUG Reconfiguration complete for context[name=sun.misc.Launcher$AppClassLoader@192d342] at null (org.apache.logging.log4j.core.LoggerContext@10c3a08)
      2014-07-25 09:25:43,146 DEBUG Shutdown hook enabled. Registering a new one.
      2014-07-25 09:25:43,146 DEBUG LoggerContext[name=sun.misc.Launcher$AppClassLoader@192d342, org.apache.logging.log4j.core.LoggerContext@10c3a08] started OK.
      2014-07-25 09:25:43,177 DEBUG Using default SystemClock for timestamps
      

      Code

      @Plugin(name = "Memory", category = "Core", elementType = "appender", printObject = true)
      public final class MemoryAppender extends AbstractOutputStreamAppender<OutputStreamManager> {
          private static MemoryManagerFactory factory = new MemoryManagerFactory();
      
          private MemoryAppender(final String name, final Layout<? extends Serializable> layout, final Filter filter,
                  final OutputStreamManager manager, final boolean ignoreExceptions) {
              super(name, layout, filter, ignoreExceptions, true, manager);
          }
      
          @PluginFactory
          public static MemoryAppender createAppender(@PluginElement("Layout") Layout<? extends Serializable> layout,
                  @PluginElement("Filters") final Filter filter, @PluginAttribute("name") final String name,
                  @PluginAttribute(value = "ignoreExceptions", defaultBoolean = true) final String ignore) {
              if (name == null) {
                  LOGGER.error("No name provided for MemoryAppender");
                  return null;
              }
              if (layout == null) {
                  layout = PatternLayout.createDefaultLayout();
              }
      
              final boolean ignoreExceptions = Booleans.parseBoolean(ignore, true);
      
              final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
      
              return new MemoryAppender(name, layout, filter, getManager(outputStream, name, layout), ignoreExceptions);
          }
      
          private static OutputStreamManager getManager(final ByteArrayOutputStream outputStream, final String name,
                  final Layout<? extends Serializable> layout) {
              final OutputStream os = getOutputStream(outputStream);
              return OutputStreamManager.getManager(name, new FactoryData(os, layout), factory);
          }
      
          private static OutputStream getOutputStream(final ByteArrayOutputStream outputStream) {
              return new MemoryStream(outputStream);
          }
      
          private static class MemoryStream extends OutputStream {
              private final ByteArrayOutputStream output;
      
              public MemoryStream(ByteArrayOutputStream outputStream) {
                  this.output = outputStream;
              }
      
              @Override
              public void write(final int b) {
                  output.write(b);
              }
          }
      
          private static class FactoryData {
              private final OutputStream os;
              private final Layout<? extends Serializable> layout;
      
              public FactoryData(final OutputStream os, final Layout<? extends Serializable> layout) {
                  this.os = os;
                  this.layout = layout;
              }
          }
      
          private static class MemoryManagerFactory implements ManagerFactory<OutputStreamManager, FactoryData> {
      
              @Override
              public OutputStreamManager createManager(final String name, final FactoryData data) {
                  return new MemoryOutputStreamManager(data.os, name, data.layout);
              }
          }
      
          private static class MemoryOutputStreamManager extends OutputStreamManager {
              public MemoryOutputStreamManager(OutputStream os, String streamName, Layout<?> layout) {
                  super(os, streamName, layout);
              }
          }
      }
      

      Configuration

      <?xml version="1.0" encoding="UTF-8"?>
      <Configuration status="ALL" packages="com.xxx.project.log">
      <Appenders> 
          <Memory name="Memory">
              <PatternLayout charset="GBK" pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
          </Memory>
      </Appenders>
      <Loggers>
          <Root level="info">
              <AppenderRef ref="Memory"/>
          </Root>
      </Loggers>
      </Configuration>
      

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                Unassigned
                Reporter:
                zhoutuo Zhou Tuo
              • Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: