.net – 使用Enterprise Library登录滚动CSV文件

我需要登录到:

>滚动文件,避免1大日志文件.
> CSV格式,便于查找.

我可以看到EntLib(5.0)有Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.RollingFlatFileTraceListener来记录滚动日志文件.

为了使日志条目看起来像CSV行,我可以更改Formatters.TextFormatter.Template以在值周围加上双引号,并且还将监听器的页脚和标题更改为空,因此不会输出它们.

在正常情况下,这将给我一个格式良好的CSV文件.但是,如果模板中的标记值包含双引号,则不会对其进行转义.因此,日志文件将成为无效的CSV文件.

有什么方法可以解决这个问题吗?

这个问题还有其他解决办法吗?

最佳答案 见
http://msdn.microsoft.com/en-us/library/ff650608.aspx.

结果添加一个自定义格式化器并不难,我添加了一个CSVTextFormattter来处理按摩消息和扩展属性,这对我有用.

注意我使用bult-in TextFormatter来完成所有繁重的工作.

示例配置:

<loggingConfiguration name="" tracingEnabled="true" defaultCategory="General">
...
    <formatters>
      <add type="<your namespace>.CSVTextFormatter, <your dll>"
          template="{timestamp(local)},{severity},{category},{message},{property(ActivityId)},{eventid},{win32ThreadId},{threadName},{dictionary({key} - {value}{newline})}"
          name="CSV Text Formatter" />
    </formatters>...
</loggingConfiguration>

这个类是这样的:

Public Class CSVTextFormatter
    Implements ILogFormatter

    Private Const csTemplateAttributeName As String = "template"

    Private moTextFormatter As TextFormatter
    Private Property TextFormatter() As TextFormatter
        Get
            Return moTextFormatter
        End Get
        Set(ByVal value As TextFormatter)
            moTextFormatter = value
        End Set
    End Property

    Private moConfigData As System.Collections.Specialized.NameValueCollection
    Private Property ConfigData() As System.Collections.Specialized.NameValueCollection
        Get
            Return moConfigData
        End Get
        Set(ByVal value As System.Collections.Specialized.NameValueCollection)
            moConfigData = value
            If moConfigData.AllKeys.Contains(csTemplateAttributeName) Then
                TextFormatter = New TextFormatter(moConfigData(csTemplateAttributeName))
            Else
                TextFormatter = New TextFormatter()
            End If
        End Set
    End Property

    Public Sub New()
        TextFormatter = New TextFormatter()
    End Sub

    Public Sub New(ByVal configData As System.Collections.Specialized.NameValueCollection)
        Me.ConfigData = configData
    End Sub

    Public Function Format(ByVal log As Microsoft.Practices.EnterpriseLibrary.Logging.LogEntry) As String Implements Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.ILogFormatter.Format
        Dim oLog As Microsoft.Practices.EnterpriseLibrary.Logging.LogEntry = log.Clone()
        With oLog
            .Message = NormalizeToCSVValue(.Message)
            For Each sKey In .ExtendedProperties.Keys
                Dim sValue As String = TryCast(.ExtendedProperties(sKey), String)
                If Not String.IsNullOrEmpty(sValue) Then
                    .ExtendedProperties(sKey) = NormalizeToCSVValue(sValue)
                End If
            Next
        End With
        Return TextFormatter.Format(oLog)
    End Function

    Private Shared Function NormalizeToCSVValue(ByVal text As String) As String
        Dim bWrapLogText = False
        Dim oQualifiers = New String() {""""}
        For Each sQualifier In oQualifiers
            If text.Contains(sQualifier) Then
                text = text.Replace(sQualifier, String.Format("""{0}""", sQualifier))
                bWrapLogText = True
            End If
        Next
        Dim oDelimiters = New String() {",", vbLf, vbCr, vbCrLf}
        If text.Contains(oDelimiters) Then
            bWrapLogText = True
        End If
        If bWrapLogText Then
            text = String.Format("""{0}""", text)
        End If
        Return text
    End Function

End Class
点赞