Domanda

I've got an XMLWriterTraceListener object added to my trace listeners like so,

System.Diagnostics.XmlWriterTraceListener xmlTrace = new 
    System.Diagnostics.XmlWriterTraceListener("Trace.xml");
xmlTrace.IndentLevel = 1;
xmlTrace.IndentSize = 4;

System.Diagnostics.Trace.Listeners.Add(xmlTrace);

and it is successfully receiving messages from Trace.WriteLine(), Trace.TraceInformation(), etc. The only problem isthat the Trace.xml file it is writing to is humanly unreadable since it contains no line breaks or indentation. Am I missing an intermediary step (XMLStreamWriter?) that will pretty up the output?

The current output reads:

<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent"><System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system"><EventID>0</EventID><Type>3</Type><SubType Name="Information">0</SubType><Level>8</Level><TimeCreated SystemTime="2014-03-20T18:05:43.2778822Z" /><Source Name="Program.vshost.exe" /><Correlation ActivityID="{00000000-0000-0000-0000-000000000000}" /><Execution ProcessName="Program.vshost" ProcessID="6840" ThreadID="9" /><Channel/><Computer>ODYSSEY</Computer></System><ApplicationData>Startup!</ApplicationData></E2ETraceEvent>

but I'd like it to read:

<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
    <System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
        <EventID>0</EventID>
        <Type>3</Type>
        <SubType Name="Information">0</SubType>
        <Level>8</Level>
        <TimeCreated SystemTime="2014-03-20T18:05:43.2778822Z" />
        <Source Name="Program.vshost.exe" />
        <Correlation ActivityID="{00000000-0000-0000-0000-000000000000}" />
        <Execution ProcessName="Program.vshost" ProcessID="6840" ThreadID="9" />
        <Channel/>
        <Computer>ODYSSEY</Computer>
    </System>
    <ApplicationData>Startup!</ApplicationData>
</E2ETraceEvent>
È stato utile?

Soluzione

Doesn't look like there is any way to do this, not even with reflection: http://dotnetinside.com/en/framework/v4.0.30319/System/XmlWriterTraceListener

You might be able to if you can get at the xml writer settings in the mono version: http://dotnetinside.com/en/framework/Mono+Framework/System/XmlWriterTraceListener

You can open XML trace with the Service Trace Viewer: http://msdn.microsoft.com/en-us/library/ms732023%28v=vs.110%29.aspx

Otherwise, copy & paste to your favorite IDE or XML editor.

Altri suggerimenti

A little late but if you want to do this in code, the below link shows very well how we can read the XML. You can read the subtree and then possibly deserialize into a class. Then serialize it back to XML with proper settings.

I have also created C# Classes from the E2ETraceEvent Xml Node for me to deserialize the Xml Fragment.

http://haishibai.blogspot.in/2009/04/monitoring-and-reading-svclog-file.html

Sample code:

using (var fileStream = new FileStream(logFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (XmlReader reader = new XmlTextReader(fileStream, XmlNodeType.Element, null))
{
    while (reader.Read())
    {
        if (reader.Name == "E2ETraceEvent" && reader.NodeType == XmlNodeType.Element)
        {
            using (XmlReader subReader = reader.ReadSubtree())
            {
                while (subReader.Read())
                {
                    var elementString = subReader.ReadOuterXml();
                    if (!string.IsNullOrWhiteSpace(elementString))
                    {
                        using (var xStream = this.GenerateStreamFromString(elementString))
                        {
                            XElement traceElement = XElement.Load(xStream);
                            var serializer = new XmlSerializer(typeof(E2ETraceEvent));
                            var traceObject = (E2ETraceEvent)serializer.Deserialize(traceElement.CreateReader());

                            var formattedXml = this.SerializeToXmlString<E2ETraceEvent>(traceObject); 
                        }
                    }
                }
            }
        }
    }
}
====================================

private Stream GenerateStreamFromString(string s)
{
    var stream = new MemoryStream();
    var writer = new StreamWriter(stream);
    writer.Write(s);
    writer.Flush();
    stream.Position = 0;
    return stream;
}
=====================================

private string SerializeToXmlString<T>(T objectToSerialize)
{
    XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
    var settings = new XmlWriterSettings
    {
        Indent = true,
        OmitXmlDeclaration = true
    };
    var xml = string.Empty;

    using (var sw = new StringWriter())
    {
        using (XmlWriter writer = XmlWriter.Create(sw, settings))
        {
            xmlSerializer.Serialize(writer, objectToSerialize);
            xml = sw.ToString();
        }
    }

    return xml;
}
======================================

Hope this helps!

You can use the Service Trace Viewer Tool (SvcTraceViewer.exe) to read the output of System.Diagnostics.XmlWriterTraceListener.

https://learn.microsoft.com/en-us/dotnet/framework/wcf/service-trace-viewer-tool-svctraceviewer-exe

It should be part of the Windows SDK (https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk)

And can be found somewhere under the Microsoft SDKs directory. eg:

C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\SvcTraceViewer.exe

Screenshot of the Service Trace Viewer Tool (SvcTraceViewer.exe)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top