2016-01-26 60 views
3

我在我寫的C#web服務中使用Log4net(v2.0.50727)。其配置爲創建2個appender。第一個是我監控的一般調試文件,以確保服務正常運行,第二個是我以各種間隔(手動現在,但可能會自動化)轉發給客戶的報告。Log4net xml appender不創建根元素

<log4net> 
    <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender"> 
    <file value="..\logs\Service.log.xml"/> 
    <appendToFile value="true"/> 
    <rollingStyle value="Size"/> 
    <maxSizeRollBackups value="20"/> 
    <maximumFileSize value="10000KB"/> 
    <staticLogFileName value="true"/> 
    <preserveLogFileNameExtension value="true" /> 
    <layout type="log4net.Layout.XmlLayoutSchemaLog4j"> 
     <conversionPattern value="%utcdate [%thread] %-5level %logger [%property{NDC}] - %message%newline"/> 
    </layout> 
    </appender> 
    <appender name="CustomerReportAppender" type="log4net.Appender.RollingFileAppender"> 
     <file value="..\logs\Customer.Report.xml"/> 
     <appendToFile value="true"/> 
     <rollingStyle value="Size"/> 
     <maxSizeRollBackups value="20"/> 
     <maximumFileSize value="10000KB"/> 
     <staticLogFileName value="true"/> 
     <preserveLogFileNameExtension value="true" /> 
     <layout type="log4net.Layout.XmlLayoutSchemaLog4j"> 
     <conversionPattern value="%utcdate [%thread] %-5level %logger [%property{NDC}] - %message%newline"/> 
     </layout> 
    </appender> 
    <root> 
    <level value="DEBUG"/> 
    <appender-ref ref="RollingFileAppender"/> 
    </root> 
    <logger name="CustomerReport"> 
    <level value="ALL" /> 
    <appender-ref ref="CustomerReportAppender" /> 
    </logger> 
</log4net> 

對兩個文件的記錄工作正常。問題是,如果我將Customer.Report.xml文件發送給我的客戶,它不會在Excel中作爲無效的XML打開。該文件由多行事件元素組成 -

<event logger="CustomerReport" timestamp="1453717399436" level="INFO" thread="8"> 
<message>Customer Info</message> 
<properties> 
<data name="UserName" value="IIS APPPOOL\Customer Service" /> 
<data name="log4jmachinename" value="MyServer" /> 
<data name="log4japp" value="/LM/W3SVC/3/ROOT-2-130981905203581113" /> 
<data name="HostName" value="MyServer" /> 
</properties> 
</event> 

我假設Excel抱怨,因爲它沒有1個根元素。如果我包裝整個文件 -

​​

然後Excel加載它OK。是否有可能讓Log4net爲我生成這個?或者Excel可以處理它?謝謝。

+0

您可以添加頁眉和頁腳元素到佈局(請注意,您的轉換模式被忽略爲[XmlLayoutSchemaLog4j沒有這樣的屬性](http://logging.apache.org/log4net/log4net-1.2.12/release/ sdk/log4net.Layout.XmlLayoutSchemaLog4jMembers.html)) - 或者您有多種選擇來對流程進行更多控制,例如自定義appender或自定義佈局, – stuartd

+0

Log4net無法自行處理,因爲RollingFileAppender沒有確定的結束。它不可能知道何時關閉根xml標記。如果您的用戶可以接受(您會收到這些病毒警告),則可以使用VBA從Excel處理此問題,否則您將不得不介入一些自定義代碼。 –

回答

1

PowerShell是快速解決這類問題的好工具。

不確定這是您尋找的答案的類型,但它會以中間方式解決您的問題。您已經提到您現在正在手動執行此操作,但將來可能會自動執行此操作--PowerShell也是一個很好的方法。

所以下面的腳本會要求你選擇的文件,然後您指定自動將根元素中的XML內容:

[CmdletBinding()] 
Param(
    [Parameter(ValueFromPipeline=$true)] 
    [ValidateScript({Test-Path $_ -PathType Container})] 
    [string] 
    $InitialDirectory, 

    [ValidateNotNullOrEmpty()] 
    [string] 
    $RootElementName = 'Report' 
) 

[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null 

$OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog 
$OpenFileDialog.InitialDirectory = $InitialDirectory 
$OpenFileDialog.Filter = "XML (*.xml)| *.xml" 
$OpenFileDialog.ShowDialog() | Out-Null 

$FileName = $OpenFileDialog.FileName 
$FileContent = Get-Content $FileName 

$FileContentXml = [Xml]$FileContent 

[XML.XMLDocument]$XMLDocument = New-Object System.XML.XMLDocument 
[XML.XMLElement]$XMLRoot = $XMLDocument.CreateElement($RootElementName) 
$XMLRoot.InnerXml = $FileContentXml.OuterXml 
$XMLDocument.AppendChild($XMLRoot) 

$XMLDocument.Save($FileName) 

你可以使用它在一個新的文件保存這個腳本,例如D:\Add-RootXmlElement.ps1,然後你可以從命令提示符像這樣運行:

@powershell D:\Add-RootXmlElement.ps1 -InitialDirectory "D:\Logs" -RootElementName "Report"

調整,以保存自己一些打字,將來在Param塊合適的默認值。

這是否解決您的問題?

編輯

當然,如果你想自動完成這個,你知道你調用腳本時的文件名,只是省略了整個$InitialDirectory$OpenFileDialog部分,簡單地設置$FileName目錄到要添加根元素的日誌文件的路徑。