2017-06-21 170 views
5

我有一個多線程環境,其中應用程序從WPF啓動,它啓動2個後臺工作線程的Web套接字服務器和Web API服務器。在多線程環境中使用Log4Net

我想在一個日誌文件中記錄所有事件。我正在使用log4Net(第一次)。

我正在創建3個記錄器實例,並假定文件appender會明白它只能寫入單個文件。

代碼:

記錄器類:

public class Logger :ILogger 
{ 
    private static ILog log = null; 
    static Logger() 
    { 
     log = LogManager.GetLogger(typeof(Logger)); 
     GlobalContext.Properties["host"] = Environment.MachineName; 
    } 
    public Logger(Type logClass) 
    { 
     log = LogManager.GetLogger(logClass); 
    } 

    #region ILogger Members 
    public void LogException(Exception exception) 
    { 
     if (log.IsErrorEnabled) 
      log.Error(string.Format(CultureInfo.InvariantCulture, "{0}", exception.Message), exception); 
    } 
    public void LogError(string message) 
    { 
     if (log.IsErrorEnabled) 
      log.Error(string.Format(CultureInfo.InvariantCulture, "{0}", message)); 
    } 
    public void LogWarningMessage(string message) 
    { 
     if (log.IsWarnEnabled) 
      log.Warn(string.Format(CultureInfo.InvariantCulture, "{0}", message)); 
    } 
    public void LogInfoMessage(string message) 
    { 
     if (log.IsInfoEnabled) 
      log.Info(string.Format(CultureInfo.InvariantCulture, "{0}", message)); 
    } 
    #endregion 
} 

日誌配置:

<log4net debug="true"> 
    <appender name="RollingLogFileAppender" 
       type="log4net.Appender.RollingFileAppender"> 
    <file value="/pathToLogFile" /> 
    <staticLogFileName value="false"/> 
    <appendToFile value="true" /> 
    <rollingStyle value="Date" /> 
    <datePattern value=" yyyy-MM-dd&quot;.txt&quot;"/> 
    <layout type="log4net.Layout.PatternLayout"> 
     <!--<param name="ConversionPattern" 
       value="%d [%t] %-5p %c %m%n" />--> 
     <conversionPattern 
     value="%date [%thread] %-5level %logger ==> %message%newline"/> 
    </layout> 
    </appender> 

    <root> 
    <level value="INFO" /> 
    <appender-ref ref="RollingLogFileAppender" /> 
    <appender-ref ref="AdoNetAppender" /> 
    </root> 
</log4net> 

我創造記錄儀的3個實例,在3個不同的項目,如:

static ILogger logger = new Logger(typeof(MainWindow)); 
static ILogger logger = new Logger(typeof(DefaultApiController)); 
static ILogger logger = new Logger(typeof(WebSocket)); 

但是, 日誌文件只有WebSocket日誌。我的理解有沒有漏洞?我哪裏錯了?

基本上,有3個線程在運行,所以我絕對不能將相同的Logger對象從一個傳遞給另一個。

+1

爲什麼包裝?它看起來只是複製log4net中已經存在的功能(按日誌級別過濾) - 您甚至可以使用log4net的配置來執行此操作。 – Adrian

回答

7

您的主要問題是您正在使用靜態記錄器,但試圖在實例的構造函數中分配3個不同時間的靜態變量,最後一個將永遠贏。項目數量無關緊要,如果所有項目都託管在同一個正在運行的可執行文件中,則只會有一個Logger::log假設您未創建多個應用程序域)的實例。

public class Logger :ILogger 
{ 
    private static ILog log = null; 
    static Logger() 
    { 
     log = LogManager.GetLogger(typeof(Logger)); 
     GlobalContext.Properties["host"] = Environment.MachineName; 
    } 
    public Logger(Type logClass) 
    { 
     log = LogManager.GetLogger(logClass); 
    } 

應該

public class Logger :ILogger 
{ 
    private ILog log = null; 
    public Logger(Type logClass) 
    { 
     log = LogManager.GetLogger(logClass); 
    } 

這就是說,我不知道爲什麼你正在嘗試這種方式設置。在需要任何類的課程中提供靜態記錄器要容易得多。例如:

public class SomeInterestingType { 
    private static readonly ILog Logger = LogManager.GetLogger(typeof(SomeInterestingType)); 

    public void DoSomething() { 
    Logger.Info("Busy doing something"); 
    } 
} 

然後只是重複該模式。