zoukankan      html  css  js  c++  java
  • 开源分析——Log4J

     

    LogManager -> getLoggerRepository


    RepositorySelector.getLoggerRepository

    Hierarchy h = new Hierarchy(new RootLogger((Level) Level.DEBUG)); = RepositorySelector 

    DefaultRepositorySelector(NOPLoggerRepository)

    NOPLoggerRepository->NOPLogger

    写入分析 

    -------------------------

    Logger.warn -> 

    Category.warn

    Category.forcelog

    category.callAppenders

    AppenderAttachableImpl.appendLoopOnAppenders

    Appender.doAppend

    这里实际上交给了各种的appender实现日志记录,这些appender在配置的时候注入

    ----------------------------

    WriterAppender

    AppenderSkeleton.doAPpend

    WriterAppender.append -subAppend -this.qw.write

    QuietWriter.write

    这个狗屁writer又是靠外界插入write,在WRiterAppender.setWriter

      WriterAppender(Layout layout, OutputStream os) {
        this(layout, new OutputStreamWriter(os));


    ---------------------------

    添加appender

    AppenderAttachableImpl.addAppender

    Category.addAPpender

    这里就到了PropertyConfigurator


    -------------------------

    找了半天,终于找到了入口,在FileAppender,这里调用了

    WriterAppender.createWriter()

    初始化 

    -------------------------

    代码
      public
      
    synchronized
      
    void setFile(String fileName, boolean append, boolean bufferedIO, int bufferSize)
                                                                
    throws IOException {
        LogLog.debug("setFile called: "+fileName+""+append);

        
    // It does not make sense to have immediate flush and bufferedIO.
        if(bufferedIO) {
          setImmediateFlush(false);
        }

        reset();
        FileOutputStream ostream = null;
        
    try {
              
    //
              
    //   attempt to create file
              
    //
              ostream = new FileOutputStream(fileName, append);
        } catch(FileNotFoundException ex) {
              
    //
              
    //   if parent directory does not exist then
              
    //      attempt to create it and try to create file
              
    //      see bug 9150
              
    //
              String parentName = new File(fileName).getParent();
              
    if (parentName != null) {
                 File parentDir = new File(parentName);
                 
    if(!parentDir.exists() && parentDir.mkdirs()) {
                    ostream = new FileOutputStream(fileName, append);
                 } else {
                    
    throw ex;
                 }
              } else {
                 
    throw ex;
              }
        }
        Writer fw = createWriter(ostream);
        
    if(bufferedIO) {
          fw = new BufferedWriter(fw, bufferSize);
        }
        
    this.setQWForFiles(fw);
        
    this.fileName = fileName;
        
    this.fileAppend = append;
        
    this.bufferedIO = bufferedIO;
        
    this.bufferSize = bufferSize;
        writeHeader();
        LogLog.debug("setFile ended");
      }
    代码
      protected
      OutputStreamWriter createWriter(OutputStream os) {
        OutputStreamWriter retval = null;

        String enc = getEncoding();
        
    if(enc != null) {
          
    try {
        retval = new OutputStreamWriter(os, enc);
          } catch(IOException e) {
              
    if (e instanceof InterruptedIOException) {
                  Thread.currentThread().interrupt();
              }
              LogLog.warn("Error initializing output writer.");
              LogLog.warn("Unsupported encoding?");
          }
        }
        
    if(retval == null) {
          retval = new OutputStreamWriter(os);
        }
        
    return retval;
      }

    什么时候flush???

    。每次操作完,都会flush

    。WriterAppender.subAppend  

        if(shouldFlush(event)) {

          this.qw.flush();

    这里shouldFlush默认=true

    文件操作是每次new,还是new了之后一直使用?

    。 获取logger的方法是:Logger.getLogger => LogManager->DefaultRepositorySelector(Hierarchy) -> Hierarchy.getLogger ->

    .logger = factory.makeNewLoggerInstance(name);  DefaultCategoryFactory..makeNewLoggerInstance(name) =

    。new Logger() extends Category

    .  这里使 Category的Loggerrepository = Hierarchy

    .  这里开始看不出来如何初始化实际写日志的模块,实际上是config的时候,已经初始化了appender,因此get的时候已经是取初始化的了。 

    。如果没有在配置文件注明的,就是初始化为console的日志。 

    。    void configure() {

        Logger root = Logger.getRootLogger();

        root.addAppender(new ConsoleAppender(

               new PatternLayout(PatternLayout.TTCC_CONVERSION_PATTERN)));

    如果没有配置,则整个日志系统根本无法运行,所以只有配置了才有效。

    写入日志的时候,使用了迭代,最终回到了rootLogger。 而getLogger的时候,输入仅仅是一个string标签,作为log的写入,log最终还是由config初始化

    初始化FileAppender的方法:

    LogManager.static 

    PropertySetter.activated 

    DailyRollingFileAppener.activateOptions 

    FileAppender.activateOptions. 

    代码中可以看出,是初始化的时候stream就初始了。 

    -------------------------------------

    小结:

    Logger在初始化的时候,就对stream等全部初始了。 涉及到的关键类包括:

    FileOutputStream(fileName, append); 

    OutputStreamWriter(OutputStream):: Writer

    FilterWriter(Writer) 

    写入的时候: FilterWriter.out.write(); 

  • 相关阅读:
    1059. Prime Factors (25)
    mybatis中resultType和resultMap的区别
    Spring Boot中使用Swagger2构建强大的RESTful API文档
    ES6之6种遍历对象属性的方法
    QQ授权登录
    nodejs爬虫入门
    nrm -- NPM registry 管理工具(附带测速功能)
    Sublime Text 3 使用MarkDown编写带预览的文本
    js中字符串函数indexOf与search的区别
    linux基础入门
  • 原文地址:https://www.cnblogs.com/zc22/p/1791057.html
Copyright © 2011-2022 走看看