2011-07-18 130 views
2

我有一個數據庫我試圖寫我的消息並且想要使用$ {level}佈局,但我需要將它翻譯爲int值以供參考我自己的表存儲日誌級別。有可能可以在配置中將關卡強制轉換爲我的枚舉?任何其他想法?NLog自定義日誌級別值

回答

1

我還沒有檢查過這個,但我懷疑你應該能夠爲nLog寫你自己的佈局渲染器(插件)來做你想做的事情。 n日誌是非常可插拔:)

的佈局渲染可能怎麼看(未測試......)一個簡單的例子,

[LayoutRenderer("intLevel", UsingLogEventInfo = true)] public class IntLevel : LayoutRenderer { protected override int GetEstimatedBufferSize(LogEventInfo logEvent) { return 1; }

protected override void Append(StringBuilder builder, LogEventInfo logEvent) 
{ 
    switch(logEvent.Level.LowercaseName) 
    { 
     case "trace": 
      builder.Append(0); 
      break; 
     case "debug": 
      builder.Append(1); 
      break; 
     case "info": 
      builder.Append(2); 
      break; 
     case "warn": 
      builder.Append(3); 
      break; 
     case "error": 
      builder.Append(4); 
      break; 
     case "fatal": 
      builder.Append(5); 
      break; 
     default: 
      builder.Append(-1); 
      break; 
    } 
} 

}

0

這裏是一個測試的佈局渲染器日誌的記錄級作爲整數。我得到的日誌級別的方法可能是有點過分,但我會通過LINQ階段;-)

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

using NLog; 
using NLog.LayoutRenderers; 

namespace MyNLogExtensions.NLog 
{ 
    [LayoutRenderer("LogLevelOrdinal")] 
    class LogLevelOrdinalLayoutRenderer : LayoutRenderer 
    { 
    IDictionary<LogLevel, int> ordinals; 

    public override void Initialize() 
    { 
     base.Initialize(); 

     ordinals = GetLogLevels() 
        .OrderBy(level => level) 
        .Select((level, index) => new { Level = level, Ordinal = index }) 
        .ToDictionary(x => x.Level, x => x.Ordinal); 
    } 

    protected override void Append(StringBuilder builder, LogEventInfo logEvent) 
    { 
     int level = 0; 

     if (!ordinals.TryGetValue(logEvent.Level, out level)) level = 99; 

     builder.Append(level); 
    } 

    protected override int GetEstimatedBufferSize(LogEventInfo logEvent) 
    { 
     return 1; 
    } 

    // 
    // LogLevel is a static class with a static member for each of the different log levels. 
    // The LogLevel ordinal is not exposed publically (i.e. an ordinal indicating the relative 
    // "importance" of a LogLevel value). 
    // The implementation of LogLevel.GetHashCode actually does return the ordinal, but it doesn't 
    // seem right to rely on that implementation detail. 
    // In the end, this LayoutRenderer is really just to allow for producing a numeric value to represent 
    // a particular log level value's "position" relative to the other lob levels. As such, 
    // We can just get all of the known log level values, order them (they are sortable), and assign our 
    // own ordinal based on the position of the log level value in the resulting sorted list. 
    // 
    // This helper function exposes the known log level values as IEnumerable<LogLevel> so that we can 
    // easily use LINQ to build a dictionary to map LogLevel to ordinal. 
    // 
    internal IEnumerable<LogLevel> GetLogLevels() 
    { 
     yield return LogLevel.Trace; 
     yield return LogLevel.Debug; 
     yield return LogLevel.Info; 
     yield return LogLevel.Warn; 
     yield return LogLevel.Error; 
     yield return LogLevel.Fatal; 
    } 

    } 
} 
+0

無法獲取「簡化」版本爲我工作,因爲LogLevel是一個類而不是枚舉。也許這是v1.0和v2.0之間的差異,我仍然使用v1.0。 – Viktor

+0

@Viktor - 你是對的!我沒有經過測試就「簡化」了太多。我忘記了LogLevel是一個類而不是枚舉。我將刪除「簡化」以防止任何人感到困惑。 – wageoghe

1

嘗試這種解決方案:

[LayoutRenderer("levelInt")] 
public class NlogLevelToIntLayoutRenderer : LayoutRenderer 
{ 
    protected override void Append(StringBuilder builder, LogEventInfo logEvent) 
    { 
     builder.Append(logEvent.Level.Ordinal); 
    } 
} 
+0

工程就像一個魅力。在使用LayoutRenderer之前,不要忘記使用ConfigurationItemFactory.Default.LayoutRenderers.RegisterDefinition。 – niaher