2015-12-17 41 views
3

NLog是否可以發出多行消息,以便根據當前佈局格式化每行?例如。使用NLog打印多行消息

2015-12-17 11:37:38.0845 | 64 | INFO | ----------------------------------- 
2015-12-17 11:37:38.0845 | 64 | INFO | Statistics: 
2015-12-17 11:37:38.0845 | 64 | INFO | Crawling Requests 46887 /min 
2015-12-17 11:37:38.0845 | 64 | INFO | Stored Documents 9910 /min 
2015-12-17 11:37:38.0845 | 64 | INFO | ----------------------------------- 

備選地,是否有可能與NLOG以發射多個消息作爲在多線程環境中的單個,非間斷塊?

回答

1

你可以從你的配置中完成這一切。

<variable name="statData" value="${longdate} | 64 | ${level} | "/> 
<variable name="line" value="-----------------------------------"/> 
<targets> 
    <target xsi:type="Console" 
     name="Console" 
     layout=" 
     ${statData}${line}${newline} 
     ${statData}Statistics:${newline} 
     ${statData} Crawling Requests 46887 /min ${newline} 
     ${statData} Stored Documents 9910 /min ${newline} 
     ${statData}${line}${newline}"/> 

不完全確定你的64是什麼或你在哪裏得到你的每分鐘數據。可能是一個變量或其他東西插入。這應該也適用於如果你登錄到文件而不是控制檯。

至於你的第二個問題,如果你想從多個線程的單個日誌消息,我認爲你將不得不這樣做的代碼端。你將不得不收集你的線程,獲得你想要的日誌數據,並將它發送給nLog。我可能會誤解,但

+0

感謝您的輸入。統計消息是通過程序生成的,所以我無法在配置文件中格式化消息。至於我的第二個問題,我正在尋找的是一種將N條消息寫入NLog的方式,以保證這些消息一次寫入,而不會傳播來自其他線程的其他消息。 –

+1

你是說你的統計資料中的行數可能因您生成的內容而異?我嘗試使用replace-newlines佈局渲染,但我有一個奇怪的問題。看起來替換不會接受另一個佈局渲染,只是文本。你可能會有更好的結果。還有一個正則表達式替換佈局。基本上,我打算用您的統計數據替換您的消息中的每一行返回信息 layout =「$ {replace-newlines:replacement = $ {statData}:$ {message}}」/> –

+0

是的,統計塊完全是內置的通過代碼,特別是行數可能會有所不同。我的問題實際上是一個普遍問題:如何以原子方式輸出N行日誌。我不知道'replace-newlines'佈局渲染器。看起來它可能是解決方案,如果它能工作的話。 –

1

似乎還沒有功能上做到這一點(截至NLog 4.2.3)。一個可能的解決方案是創建您自己的包裝佈局渲染器,以改進渲染器的替換函數。

所以更換,換行更換包裝不會採取佈局渲染他們的替換字符串。查看其他包裝器,渲染器和目標的NLog源代碼,可以使用Layout type屬性接受帶有(或不帶)佈局渲染器的字符串。提供佈局渲染器時,內置替換包裝失敗,因爲它們的Replacement屬性類型爲string。 xml解析器僅查找純文本,但所提供的佈局渲染器的}過早地結束了包裝器的替換。

以下自定義包裝將替換類型從string更改爲Layout。然後需要通過在某些上下文中調用其Render方法來呈現替換佈局(LogEventInfo)。這可以在覆蓋的Append方法中完成,其中LogEventInfo可用。渲染後的輸出可以保存在Transform方法中供以後使用。

using System; 
using System.Text; 
using NLog.Config; 
using NLog.LayoutRenderers; 
using NLog.LayoutRenderers.Wrappers; 
using NLog.Layouts; 

namespace My.Namespace 
{ 
    [LayoutRenderer("replace-newlines-withlayout")] 
    [ThreadAgnostic] 
    public class ReplaceNewLinesFormatLayoutRendererWrapper : WrapperLayoutRendererBase 
    { 
     private string m_replacementString = " "; 

     public ReplaceNewLinesFormatLayoutRendererWrapper() 
     { 
      // Changed from 
      // Replacement = " "; 
      Replacement = Layout.FromString(" "); 
     } 

     // Changed from 
     // public string Replacement { get; set; } 
     public Layout Replacement { get; set; } 

     // Override Append in order to render the replacement. 
     protected override void Append(StringBuilder builder, NLog.LogEventInfo logEvent) 
     { 
      // Render... 
      m_replacementString = Replacement.Render(logEvent); 

      // The base functionality of append is fine. 
      base.Append(builder, logEvent); 
     } 

     // Called from base.Append() 
     protected override string Transform(string text) 
     { 
      // Changed from 
      // return text.Replace(Environment.NewLine, Replacement); 

      // Now just put in the rendered replacement string. 
      return text.Replace(Environment.NewLine, m_replacementString); 
     } 
    } 
} 

然後,例如,用它作爲

<target 
    ... 
    layout=${replace-newlines-withlayout:replacement=${newline}${time}:${message}} 
    ... 
    /> 

在這種簡化的情況下,假定$ {消息}具有換行符,每一個新的生產線將帶有時間戳作爲前綴。只需用所需的前綴佈局替換$ {time}即可。