Log4j log output detailed

Detailed explanation of Log4j initialization: http://donald-draper.iteye.com/blog/2332385
Detailed explanation of Log4j log output: http://donald-draper.iteye.com/blog/2332395
Use of slf4j + Log4j: http://donald -draper.iteye.com/blog/2332407 In
the last article, we talked about the initialization of log4j. The instance of Logger is NOPLogger, and all Appenders are delegated to
rootLogger for management. Today, let's take a look at the print output of the log.
The source of the log output is the next sentence
log.info("========test daily level info=========");

Let's see, what does this sentence do?
public final class NOPLogger extends Logger
public class Logger extends Category

And NOPLogger, Logger, there is no info method, look at Category
//Category
public class Category
    implements AppenderAttachable
{
  AppenderAttachableImpl aai;
  static
    {
        FQCN = (org.apache.log4j.Category.class).getName();
    }
    // output log
    public void info(Object message)
    {
        //Check the info log, whether it is enabled
        if(repository.isDisabled(20000))
            return;
	 //If INFO, greater than or equal to the valid log level, output the log
        if(Level.INFO.isGreaterOrEqual(getEffectiveLevel()))
            forcedLog(FQCN, Level.INFO, message, null);
    }
    // According to the log level, output the log
    protected void forcedLog(String fqcn, Priority level, Object message, Throwable t)
    {
        //Delegate LoggingEvent to AppenderS for processing,
        callAppenders(new LoggingEvent(fqcn, this, level, message, t));
    }
    public void callAppenders(LoggingEvent event)
    {
        int writes;
        Category c;
        writes = 0;
        c = this;
_L3:
label0:
        {
            if(c == null)
                break; /* Loop/switch isn't completed */
            synchronized(c)
            {
                if(c.aai != null)
		    //Appenders handle log output events
                    writes += c.aai.appendLoopOnAppenders(event);
                if(c.additive)
                    break label0;
            }
            break; /* Loop/switch isn't completed */
        }
        category;
        JVM INSTR monitorexit ;
          goto _L1
        exception;
        throw exception;
_L1:
        c = c.parent;
        if(true) goto _L3; else goto _L2
_L2:
        if(writes == 0)
            repository.emitNoAppenderWarning(this);
        return;
    }
}

//AppenderAttachableImpl
public class AppenderAttachableImpl
    implements AppenderAttachable
{
protected Vector appenderList;
 // Traverse rootLooger's Appenders, each Appenders handles log output events separately
 public int appendLoopOnAppenders(LoggingEvent event)
    {
        int size = 0;
        if(appenderList != null)
        {
            size = appenderList.size();
            for(int i = 0; i < size; i++)
            {
                Appender appender = (Appender)appenderList.elementAt(i);
                appender.doAppend(event);
            }

        }
        return size;
    }
}

Here we take a look at DailyRollingFileAppender
//DailyRollingFileAppender
public class DailyRollingFileAppender extends FileAppender
{
    static final int TOP_OF_TROUBLE = -1;
    static final int TOP_OF_MINUTE = 0;
    static final int TOP_OF_HOUR = 1;
    static final int HALF_DAY = 2;
    static final int TOP_OF_DAY = 3;
    static final int TOP_OF_WEEK = 4;
    static final int TOP_OF_MONTH = 5;
    private String datePattern;
    private String scheduledFilename;
    private long nextCheck;
    Date now;
    SimpleDateFormat sdf;
    RollingCalendar rc;
    int checkPeriod;
    static final TimeZone gmtTimeZone = TimeZone.getTimeZone("GMT");
    public DailyRollingFileAppender(Layout layout, String filename, String datePattern)
        throws IOException
    {
        super(layout, filename, true);
        this.datePattern = "'.'yyyy-MM-dd";
        nextCheck = System.currentTimeMillis() - 1L;
        now = new Date();
        rc = new RollingCalendar();
        checkPeriod = -1;
        this.datePattern = datePattern;
	//The construction is to call the activation configuration method
        activateOptions();
    }
}

//AppenderSkeleton
public abstract class AppenderSkeleton
    implements Appender, OptionHandler
{
   // handle log events
public synchronized void doAppend(LoggingEvent event)
    {
        append(event);
    }
    //to be extended by subclass
   protected abstract void append(LoggingEvent loggingevent);
}

//AppenderSkeleton
public class WriterAppender extends AppenderSkeleton
{
   // handle log events
   public void append(LoggingEvent event)
    {
        if(!checkEntryConditions())
        {
            return;
        } else
        {
            subAppend(event);
            return;
        }
    }
    protected void subAppend(LoggingEvent event)
    {
        qw.write(layout.format(event));
        if(layout.ignoresThrowable())
        {
            String s[] = event.getThrowableStrRep();
            if(s != null)
            {
                int len = s.length;
                for(int i = 0; i < len; i++)
                {
		    //Output log, the key is QuietWriter
                    qw.write(s[i]);
                    qw.write(Layout.LINE_SEP);
                }

            }
        }
        if(shouldFlush(event))
            qw.flush();
    }
    protected boolean immediateFlush;
    protected String encoding;
    protected QuietWriter qw;
}

Let's take a look at what is QuietWriter? How did it come?
Look at the constructor of DailyRollingFileAppender, a method is called to activate the configuration activateOptions
public DailyRollingFileAppender(Layout layout, String filename, String datePattern)
        throws IOException
    {
        super(layout, filename, true);
        this.datePattern = "'.'yyyy-MM-dd";
        nextCheck = System.currentTimeMillis() - 1L;
        now = new Date();
        rc = new RollingCalendar();
        checkPeriod = -1;
        this.datePattern = datePattern;
	// activate configuration
        activateOptions();
    }
     public void activateOptions()
    {
        super.activateOptions();
        if(datePattern != null && fileName != null)
        {
            now.setTime(System.currentTimeMillis());
            sdf = new SimpleDateFormat(datePattern);
            int type = computeCheckPeriod();
            printPeriodicity(type);
            rc.setType(type);
            File file = new File(fileName);
            scheduledFilename = fileName + sdf.format(new Date(file.lastModified()));
        } else
        {
            LogLog.error("Either File or DatePattern options are not set for appender [" + name + "].");
        }
    }

View FileAppender
public class FileAppender extends WriterAppender
{
public void activateOptions()
    {
        if(fileName != null)
        {
            try
            {
                setFile(fileName, fileAppend, bufferedIO, bufferSize);
            }
    }
    public synchronized void setFile(String fileName, boolean append, boolean bufferedIO, int bufferSize)
        throws IOException
    {
        LogLog.debug("setFile called: " + fileName + ", " + append);
        if(bufferedIO)
            setImmediateFlush(false);
        reset();
        FileOutputStream ostream = null;
        try
        {
            ostream = new FileOutputStream(fileName, append);
        }
	/ / According to the file stream, create a Writer
        Writer fw = createWriter(ostream);
        if(bufferedIO)
            fw = new BufferedWriter(fw, bufferSize);
	//Set the output stream of QuietWriter
        setQWForFiles(fw);
        this.fileName = fileName;
        fileAppend = append;
        this.bufferedIO = bufferedIO;
        this.bufferSize = bufferSize;
        writeHeader();
        LogLog.debug("setFile ended");
    }
    //Set the output stream of QuietWriter
    protected OutputStreamWriter createWriter(OutputStream os)
    {
        OutputStreamWriter retval = null;
        String enc = getEncoding();
        if(enc != null)
            try
            {
                retval = new OutputStreamWriter(os, enc);
            }
        if(retval == null)
            retval = new OutputStreamWriter(os);
        return retval;
    }
    //Set the output stream of QuietWriter
     protected void setQWForFiles(Writer writer)
    {
        qw = new QuietWriter(writer, errorHandler);
    }
}

Take another look at ConsoleAppender
//ConsoleAppender。
ublic class ConsoleAppender extends WriterAppender
{
    private static class SystemOutStream extends OutputStream
    {

        public void close()
        {
        }

        public void flush()
        {
            System.out.flush();
        }

        public void write(byte b[])
            throws IOException
        {
            System.out.write(b);
        }

        public void write(byte b[], int off, int len)
            throws IOException
        {
            System.out.write(b, off, len);
        }

        public void write(int b)
            throws IOException
        {
            System.out.write(b);
        }

        public SystemOutStream()
        {
        }
    }
     public ConsoleAppender(Layout layout, String target)
    {
        this.target = "System.out";
        follow = false;
        setLayout (layout);
        setTarget(target);
        activateOptions();
    }
    public void activateOptions()
    {
        if(follow)
        {
            if(target.equals("System.err"))
                setWriter(createWriter(new SystemErrStream()));
            else
	        //set the output stream
                setWriter(createWriter(new SystemOutStream()));
        } else
        if(target.equals("System.err"))
            setWriter(createWriter(System.err));
        else
            setWriter(createWriter(System.out));
        super.activateOptions();
    }
}

Summary:
From the above analysis, we can see that the output of the log log is to traverse the Appender of the rootLogger to process the log output event. The Appender first determines whether the log level is greater than the log level of the RootLogger. If it is greater, the log is processed, and the output of the log Delegate to QuietWriter, and QuietWriter from DailyRollingFileAppender,
ConsoleAppender.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326987051&siteId=291194637