(EventLogAppender)我们可以在运行时设置事件类别,而无需重新创建appender吗?

时间:2015-08-30 09:59:51

标签: log4net log4net-appender

这是一个基类,所以我在运行时完全配置EventLogAppender,如下所示:

Public MustInherit Class EventLogger
  Public Sub Test(EventSource As String)
    Dim oAppender As IAppender

    oAppender = New EventLogAppender

    With DirectCast(oAppender, EventLogAppender)
      .ApplicationName = EventSource
      .Category = 0 ' <========== Would like to set this value when logging 
      .EventId = 0
      .Layout = New PatternLayout("%level: {0} %message%newline".ToFormat(EventSource))
      .ActivateOptions()
    End With

    BasicConfigurator.Configure(oAppender)
    Me.Logger = LogManager.GetLogger(Me.GetType)
    Me.Logger.Info("Test")
  End Sub

  Private Logger As ILog
End Class

Public Module Extensions
  <Extension>
  Public Function ToFormat(Template As String, ParamArray Values As Object()) As String
    Return String.Format(Template, Values)
  End Function
End Module

在构建appender时设置事件类别很容易,但我希望类别与日志级别相对应。

有没有办法在调用记录器时不必为每个日志级别构建特殊的appender?这肯定会成为性能杀手。

它看起来不像,但我可能错了。它曾经发生在我身上。

1 个答案:

答案 0 :(得分:0)

好的,明白了。感谢Stafford提供解决方案...为每个类别添加IAppender并相应地设置其过滤器。性能不会受到影响,因为这只会发生一次。

以下是:

Public Class EvAppender
  Inherits EventLogAppender

  Private Sub New(ApplicationName As String, Category As Categories)
    Me.ApplicationName = ApplicationName
    Me.Category = Category
    Me.EventId = 0
    Me.Layout = New PatternLayout("Level: %level%newlineSource: %logger.%M()%newlineMessage: %message%newline%exception")
    Me.Name = "{0}Appender".ToFormat(Category.ToString)

    Me.AddMapping(Me.GetMapping(Level.Debug))
    Me.AddMapping(Me.GetMapping(Level.Info))
    Me.AddMapping(Me.GetMapping(Level.Warn))
    Me.AddMapping(Me.GetMapping(Level.Error))
    Me.AddMapping(Me.GetMapping(Level.Fatal))

    Me.AddFilter(New LevelRangeFilter With
                 {
                  .LevelMin = Me.LogLevel(Category),
                  .LevelMax = Me.LogLevel(Category)
                 })

    Me.ActivateOptions()
  End Sub



  Public Shared Function Build(ApplicationName As String) As List(Of EvAppender)
    Build = New List(Of EvAppender)
    Build.Add(New EvAppender(ApplicationName, Categories.Debug))
    Build.Add(New EvAppender(ApplicationName, Categories.Info))
    Build.Add(New EvAppender(ApplicationName, Categories.Warn))
    Build.Add(New EvAppender(ApplicationName, Categories.Error))
    Build.Add(New EvAppender(ApplicationName, Categories.Fatal))
  End Function



  Private Function GetMapping(LogLevel As Level) As EventLogAppender.Level2EventLogEntryType
    GetMapping = New EventLogAppender.Level2EventLogEntryType
    GetMapping.Level = LogLevel

    Select Case GetMapping.Level
      Case Level.Debug : GetMapping.EventLogEntryType = EventLogEntryType.Information
      Case Level.Info : GetMapping.EventLogEntryType = EventLogEntryType.Information
      Case Level.Warn : GetMapping.EventLogEntryType = EventLogEntryType.Warning
      Case Level.Error : GetMapping.EventLogEntryType = EventLogEntryType.Error
      Case Level.Fatal : GetMapping.EventLogEntryType = EventLogEntryType.Error
    End Select
  End Function



  Private Function GetLogLevel(Category As Categories) As Level
    Select Case Category
      Case Categories.Debug : LogLevel = Level.Debug
      Case Categories.Info : LogLevel = Level.Info
      Case Categories.Warn : LogLevel = Level.Warn
      Case Categories.Error : LogLevel = Level.Error
      Case Categories.Fatal : LogLevel = Level.Fatal
      Case Else : LogLevel = Level.All
    End Select
  End Function



  Private Enum Categories
    Debug = 3
    Info = 4
    Warn = 6
    [Error] = 7
    Fatal = 11
  End Enum
End Class

像这样使用:

BasicConfigurator.Configure(EvAppender.Build(ApplicationName).ToArray)
Logger = LogManager.GetLogger(ApplicationName)