log4j 動態改變日志的輸出路徑


 

實際背景

  客戶有客戶端多台,每個客戶端有自己的唯一編號。輸出的日志要根據每個客戶端的編號生成,例如10001_demo.log,10002_demo.log

方法

  1.網上給出的第一種方法是:

    在log4j的配置文件中log4j.appender.file.File=${log.dir}/${log.file}中,使用${}形式定義變量,在后台使用

    System.setProperty("log.dir","/home/..."),來設置變量值。但我測試了多次,這樣是不起作用的,可能是我自己配置的問題。

    2.第二種方法,親測可用:  

1    Logger log = Logger.getLogger(ZhzhcxCtl.class);//獲取log對象
2   FileAppender fileAppender = (FileAppender) Logger.getRootLogger().getAppender("file");//獲取FileAppender對象
3   fileAppender.setFile("/home/log/gcds.log");//重新設置輸出日志的路徑和文件名
4   fileAppender.activateOptions();//使設置的FileAppender起作用
5   log.info("index.........");

          但是這樣的話,每次調用log.info()方法之前都要添加第2--4行這幾段代碼,這樣寫代碼冗余比較大。或許這時可以想到用代理的方法,但是如果代理了,這時log.info()出現的地方就不是原來的那個類里面了,而是現在這個代理的類了。這樣出現的問題就是log4j.properties配置文件中定義的輸出格式%c打印的類的名字永遠都是代理的那個類了,就永遠看不到到底是哪個類調用的log.info方法。所以這種方法也是不可行的。

  3.第三種方法:重寫FileAppender的subAppend方法。

    通過看log4j的FileAppender源碼,我們可以發現,FileAppender是繼承WriterAppender類的,而WriterAppender有一個subAppend方法,我們看一下subAppend方法源碼:

protected void subAppend(LoggingEvent event)
  {
    this.qw.write(this.layout.format(event));
    if (this.layout.ignoresThrowable())
    {
      String[] s = event.getThrowableStrRep();
      if (s != null)
      {
        int len = s.length;
        for (int i = 0; i < len; i++)
        {
          this.qw.write(s[i]);
          this.qw.write(Layout.LINE_SEP);
        }
      }
    }
    if (shouldFlush(event)) {
      this.qw.flush();
    }
  }

 

   對,沒看錯,這個方法就是往日志文件里寫東西的。因為FileAppender是繼承WriterAppender類的,所以subAppend也是FileAppender的。這時我們只要在subAppend之前,吧文件名改成我們想要的,就可以了。

FileAppender有2個setFile方法,是用來設置輸出日志文件的路徑的。我們可以subAppend之前調用一次setFile就可以了。我們知道,每一次http請求,到后台都是對應一個線程。如果要做到每個終端對應一個日志的話,我們就要每一個線程都要帶一個終端號,然后把輸出的文件名改成其終端對應的。我們可以這樣想一下,線程A調用log.info()-->調用FileAppender的對象FA--->FA.subAppend寫日志。我們要改成:線程A調用log.info()-->調用FileAppender的對象FA--->FA.setFile(線程A對應終端的日志路徑)-->FA.subAppend寫日志。而現在的問題是我們用什么來存放線程A對應終端的日志路徑,如何根據每個線程來找其對應的日志路徑。這里我么可以想象一個對象,他里面有無數個線程,這個線程對應的路徑,這里ThreadLocal了解一下。當然現在每個終端的日志都存放到一個文件里,如果再加上一個每個終端的日志都存放到一個文件里,第二天這個文件名字要改成前一天的,要如何做呢?

    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM