2010-01-16 48 views
24

我正在嘗試創建一個日誌解決方案,涉及多個機器上的多個進程。我計劃使用UDPAppender將所有日誌消息發送到可管理它們的單臺機器。我有幾個有關patterntrings與patternlayouts的問題。log4net進程ID信息

因爲我需要知道哪臺機器和哪個進程的日誌信息來自哪裏,所以我想將它包含在日誌中。我發現%property {log4net:HostName}用於主機名,並且工作得很好。但是,我沒有在PatternLayouts中看到任何進程ID。當然,我在PatternString中看到類似的東西。從常見問題:

<appender name="LogFileAppender" type="log4net.Appender.FileAppender"> 
    <file type="log4net.Util.PatternString" value="log-file-[%processid].txt" /> 

    <layout type="log4net.Layout.PatternLayout" value="%date [%thread] %-5level %logger - %message%newline" /> 
</appender> 

但我不知道是否或如何混搭兩個(或者即使這是規範的方法來做到這一點)。

所以,我的問題是:

  1. 是什麼PatternString和的PatternLayout之間的區別?爲什麼都有?

  2. 我在PatternString中看到%processid,我怎麼在PatternLayout中得到相同的結果?這裏是我的測試佈局:

    <layout type="log4net.Layout.PatternLayout"> 
        <conversionPattern value="%date [%thread] [%property{log4net:HostName}] %-5level %logger - %message%newline" /> 
    </layout> 
    
  3. 最後,是有意義的使用XML佈局爲UDP附加目的地。它看起來像XmlLayoutSchemaLog4j已經將HostNameProperty添加到XML消息。如果我不想將這個新的進程ID(也可能是進程名稱)添加到XML消息中,那麼執行此操作的最佳方法是什麼?我應該只複製src \ Layouts \ XmlLayoutSchemaLog4j.cs,修改它,讓log4net知道我創建了這個新的佈局(如SampleLayoutsApp)?

感謝您的幫助

回答

39

您可以將所需的任何屬性添加到GlobalContext中。我用這個背景下存儲進程ID,像這樣:

log4net.GlobalContext.Properties["pid"] = Process.GetCurrentProcess().Id; 

然後你從你的appender使用的是常規模式引用此屬性,像這樣:

<layout type="log4net.Layout.PatternLayout"> 
    <conversionPattern value="%date %property{pid} %level %logger - %message%newline" /> 
</layout> 

您可以添加儘可能多的屬性你想要的,但是由於它是全局性的,它對於在應用程序執行期間不會改變的屬性來說效果最好。

+0

嘗試一切%PID,%進程ID和更多的人,毫無效果。你的解決方案有效謝謝。 – Nemo 2015-06-18 20:45:54

3

顯然PatternString只能用於創建日誌名稱(即文件名等),而佈局可以讓你格式化實際的消息進入日誌。如果在流程佈局中沒有內置的進程ID模式,那麼您可以輕鬆添加它。這比創建整個佈局要簡單得多。

這裏是如何做到這一點:

創建自己的自定義模式轉換器(下面的例子試圖獲取應用程序的名稱,不管贏或網絡):

internal sealed class ApplicationNamePatternConverter : PatternLayoutConverter 
{ 
    /// <summary> 
    /// Write the event application name to the output 
    override protected void Convert(TextWriter writer, LoggingEvent loggingEvent) 
    { 
     string name = string.Empty; 
     if(System.Web.HttpContext.Current != null) 
     { 
      string[] applicationPath = System.Web.HttpContext.Current.Request.ApplicationPath.Split('/'); 
      name = applicationPath[applicationPath.Length - 1]; 
     } 
     else 
     { 
      if(System.Reflection.Assembly.GetEntryAssembly() != null) 
      { 
       name = System.Reflection.Assembly.GetEntryAssembly().GetName().Name; 
      } 
     } 
     writer.Write(name); 
    } 
} 

添加條目您轉換器的PatternLayout類

static PatternLayout() 
{ 
... 
    s_globalRulesRegistry.Add("ApplicationName", typeof(ApplicationNamePatternConverter)); 
} 

的註冊表現在你可以使用%ApplicationName中的PatternLayout價值得到你所需要的。

我建議不要使用XmlLayoutSchemaLog4j佈局,因爲它非常沉重,如果經常使用,可能會降低應用程序的性能。

15

可以養活一個PatternString成的PatternLayout:

<layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern type="log4net.Util.PatternString" value="%processid" /> 
    </layout> 
+0

這實際上工作。謝謝。 – 2010-11-18 22:37:25

+3

記住要逃避要從事件中提取的屬性的百分比字符,例如將進程ID包含爲日誌文件之一列 – Pelle 2012-07-24 07:12:31