2010-02-08 85 views
-1

我在java中創建了一個小型web應用程序。現在我想將記錄功能添加到它。但我不想使用Log4j或其他任何可用的Logging框架,而是想創建自己的日誌記錄框架,這在將來也是可以消耗的。因此,需要一些初步的推動,同樣,這是正確的地方。Java應用程序的日誌框架

謝謝。

+14

不要重新發明輪子。使用現有的框架。 ;) – Bozho 2010-02-08 11:19:59

+1

好奇你爲什麼不想使用Log4J或JDK Logger! – 2010-02-08 11:20:09

+0

我在jon的評論中給出了原因 – GuruKulki 2010-02-08 11:25:21

回答

18

我的建議是不要這樣做。使用久經考驗的日誌框架,如log4j。你爲什麼要重新發明輪子?

在現有框架上花費了大量時間 - 使它們在各種不同的環境下快速工作等等。您真的想浪費時間來複制這些工作,因爲您可以花費相同時間在用戶的功能上關心?

不要忘記,許多框架(如log4j,甚至是內置的java.util.logging)都可以用你自己的格式化器,處理程序等進行擴展。你應該真正搞清楚你想做什麼,沒有被現有的框架所覆蓋,並且看看你是否可以只創建而不是創建另一個日誌框架

如果當你計算出你的需求需要編寫一些額外的代碼,那麼你可以提出有關這些特定需求的問題,而不是你目前相當普遍的問題。

+3

+1建議不要重新發明車輪。 – Oded 2010-02-08 11:19:59

+0

謝謝喬恩。但它會對此產生依賴性。我的存儲問題有限。所以我想用我的應用程序需要多少,只有那些我會開發。 – GuruKulki 2010-02-08 11:22:48

+5

@gurukulki:如果你開發自己的框架,那也會佔用空間。你是多麼有限?你總是可以減少你發佈的log4j的哪些位 - 或者使用已經存在於JDK中的java.util.logging,所以不會添加新的依賴關係。 – 2010-02-08 11:24:12

1

如果你真的想使自己的日誌franmework(我強烈建議你不要),然後先寫下一些要求。它應該做什麼?它應該有什麼特點等等

例子是寫多張輸出能力 - 文件,控制檯,插座,串行端口等

而且多線程的寫作 - 你不想多線程在同一寫入日誌時間,否則你會最終得到垃圾。

日誌級別 - 多少?

然後你就可以開始編寫代碼....而已,至於建議,我不明白爲什麼你不使用的許多免費可用的日誌記錄framewroks在那裏的一個,,,

2

這些都是一些陷阱你可能會在嘗試創建自己的日誌記錄框架時陷入:

  • 併發問題:日誌框架可能由不同的線程同時訪問。您需要確保沒有衝突出現,並且消息以正確的順序記錄。
  • 實例化:框架必須實例化一次,然後可用於應用程序的其餘部分。你需要一個'Singleton'類,你必須小心執行。使用靜態方法是一種方法。
  • 您必須具有使用xml文件或註釋的配置機制。
  • 您的框架必須與第三方庫合作。我相信這對你來說是一個真正的障礙。你可能有你的代碼的日誌框架,但你使用的庫需要另外一個。
3

這是一件好事,因爲你會意識到爲什麼你應該使用衆多優秀的日誌框架之一。在你擺弄這一週之後,回去並使用log4j。

然而,在此之前,並讓你開始,這裏是一個我剛纔只是因爲我想要讓我的頭一輪複雜是什麼準備。這對於您的目的而言並不完整,我建議您僅使用它來決定您想要執行的操作,而不是基於您的實現。它應該給你什麼是必要的合理的想法,它提供了基本的單線程的日誌記錄...

/* 
* Created on Jun 11, 2005 
*/ 
package com.hupa.util; 

import java.io.*; 
import java.util.Date; 

/** 
* @author simonpalmer 
*/ 
public class MessageWriter implements ILog 
{ 
    public class e_LogLevel 
    { 
     public static final int e_log_error = 1; 
     public static final int e_log_warn = 2; 
     public static final int e_log_info = 4; 
     public static final int e_log_debug = 8; 
    } 
    public int m_iLogLevel = e_LogLevel.e_log_error; 
    public String m_strLogFile = new String(); 
    public String m_strLogPath = new String(); 
    public boolean m_bConsoleOut = true; 
    PrintStream m_ps; 
    public boolean m_bLogOpen = false; 
    private static Date dt = new Date(); 

    /** 
    * Output info level message 
    * @param strMess 
    */ 
    public void info(String strMess) 
    { 
     if ((m_iLogLevel & e_LogLevel.e_log_info) == e_LogLevel.e_log_info) 
     { 
      dt.setTime(System.currentTimeMillis()); 
      String strOut = dt.toString() + " inf: " + strMess; 
      if (m_bConsoleOut) System.out.println(strOut); 
      if (m_bLogOpen) m_ps.println(strOut); 
     } 
    } 
    public boolean bInfo(){return ((m_iLogLevel & e_LogLevel.e_log_info) == e_LogLevel.e_log_info);} 
    /** 
    * Output debug level message 
    * @param strMess 
    */ 
    public void debug(String strMess) 
    { 
     if ((m_iLogLevel & e_LogLevel.e_log_debug) == e_LogLevel.e_log_debug) 
     { 
      dt.setTime(System.currentTimeMillis()); 
      String strOut = dt.toString() + " dbg: " + strMess; 
      if (m_bConsoleOut) System.out.println(strOut); 
      if (m_bLogOpen) m_ps.println(strOut); 
     } 
    } 
    public boolean bDebug(){return ((m_iLogLevel & e_LogLevel.e_log_debug) == e_LogLevel.e_log_debug);} 
    /** 
    * Output warning level message 
    * @param strMess 
    */ 
    public void warn(String strMess) 
    { 
     if ((m_iLogLevel & e_LogLevel.e_log_warn) == e_LogLevel.e_log_warn) 
     { 
      dt.setTime(System.currentTimeMillis()); 
      String strOut = dt.toString() + " warn: " + strMess; 
      if (m_bConsoleOut) System.out.println(strOut); 
      if (m_bLogOpen) m_ps.println(strOut); 
     } 
    } 
    public boolean bWarn(){return ((m_iLogLevel & e_LogLevel.e_log_warn) == e_LogLevel.e_log_warn);} 
    /** 
    * Output error level message 
    * @param strMess 
    */ 
    public void error(String strMess) 
    { 
     if ((m_iLogLevel & e_LogLevel.e_log_error) == e_LogLevel.e_log_error) 
     { 
      dt.setTime(System.currentTimeMillis()); 
      String strOut = dt.toString() + " err: " + strMess; 
      if (m_bConsoleOut) System.out.println(strOut); 
      if (m_bLogOpen) m_ps.println(strOut); 
     } 
    } 
    public boolean bError(){return ((m_iLogLevel & e_LogLevel.e_log_error) == e_LogLevel.e_log_error);} 

    /** 
    * construst the log file name 
    * @return String, full file path and name 
    */ 
    public String GetLogFileName() 
    { 
     return m_strLogPath + m_strLogFile + ".log"; 
    } 

    /** 
    * Open the log file prescribed by the settings 
    * @return boolean, success 
    */ 
    public boolean OpenLog() 
    { 
     try 
     { 
      m_ps = new PrintStream(new FileOutputStream(GetLogFileName())); 
      m_bLogOpen = true; 
     } 
     catch (FileNotFoundException e) 
     { 
      // this means that the folder doesn't exist 
      if (MakeFolder(m_strLogPath)) 
      { 
       m_bLogOpen = true; 
       try 
       { 
        m_ps = new PrintStream(new FileOutputStream(GetLogFileName())); 
       } 
       catch (IOException e1) 
       { 
        e.printStackTrace(); 
        m_bLogOpen = false; 
       } 
      } 
     } 
     return m_bLogOpen; 
    } 

    public static boolean MakeFolder(String strFolder) 
    { 
     try 
     { 
      java.io.File f = new File(strFolder); 
      if (!f.mkdirs()) 
      { 
       return false; 
      } 
     } 
     catch (SecurityException e) 
     { 
      e.printStackTrace(); 
      return false; 
     } 
     return true; 
    } 

    /** 
    * Close the log file 
    * @return boolean, success 
    */ 
    public boolean CloseLog() 
    { 
     if (m_ps != null) 
     { 
      m_ps.flush(); 
      m_ps.close(); 
     } 
     m_bLogOpen = false; 
     return m_bLogOpen; 
    } 

    public void setConsoleOut(boolean b) 
    { 
     m_bConsoleOut = b; 
    } 
    public void setLogLevel(int i) 
    { 
     m_iLogLevel = i; 
    } 

} 

和這裏的接口

public interface ILog 
{ 
    abstract public void debug(String message); 
    abstract public void info(String message); 
    abstract public void warn(String message); 
    abstract public void error(String message); 

    abstract public void setLogLevel(int i); 
    abstract public void setConsoleOut(boolean b); 
    abstract public boolean CloseLog(); 
    abstract public boolean OpenLog(); 

    abstract public boolean bDebug(); 
} 
0

你想要一個小的內存佔用尚未擴展?避免過早優化,然後:嘗試log4j或java.util.logging,測量足跡(條件編譯),並查看是否真的可以通過滾動自己的分支或分支來實現。除了根據Visage的建議來定義要求,並且還能夠解決這些問題的時候,kgiannakakis指出,測量是您最好的朋友。