2 // XmlWriterTraceListener.cs
5 // Atsushi Enomoto <atsushi@ximian.com>
7 // Copyright (C) 2007 Novell, Inc http://www.novell.com
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 #if NET_2_0 && XML_DEP
35 using System
.Diagnostics
;
36 using System
.Threading
;
39 namespace System
.Diagnostics
41 public class XmlWriterTraceListener
: TextWriterTraceListener
43 static readonly string e2e_ns
= "http://schemas.microsoft.com/2004/06/E2ETraceEvent";
44 static readonly string sys_ns
= "http://schemas.microsoft.com/2004/06/windows/eventlog/system";
45 static readonly string default_name
= "XmlWriter";
48 public XmlWriterTraceListener (string filename
)
49 : this (filename
, default_name
)
53 public XmlWriterTraceListener (string filename
, string name
)
54 : this (new StreamWriter (new FileStream (filename
, FileMode
.Append
, FileAccess
.Write
, FileShare
.ReadWrite
)), name
)
58 public XmlWriterTraceListener (Stream stream
)
59 : this (stream
, default_name
)
63 public XmlWriterTraceListener (Stream writer
, string name
)
64 : this (new StreamWriter (writer
), name
)
68 public XmlWriterTraceListener (TextWriter writer
)
69 : this (writer
, default_name
)
73 public XmlWriterTraceListener (TextWriter writer
, string name
)
76 XmlWriterSettings settings
= new XmlWriterSettings ();
77 settings
.OmitXmlDeclaration
= true;
78 w
= XmlWriter
.Create (writer
, settings
);
81 public override void Close ()
86 public override void Fail (string message
, string detailMessage
)
88 TraceEvent (null, null, TraceEventType
.Error
,
89 0, String
.Concat (message
, " ", detailMessage
));
92 public override void TraceData (TraceEventCache eventCache
,
93 string source
, TraceEventType eventType
, int id
,
96 TraceCore (eventCache
, source
, eventType
, id
, false,
97 Guid
.Empty
, 2, true, data
);
100 [MonoLimitation ("level is not always correct")]
101 public override void TraceData (TraceEventCache eventCache
,
102 string source
, TraceEventType eventType
, int id
,
103 params object [] data
)
105 // FIXME: what is the correct level?
106 TraceCore (eventCache
, source
, eventType
, id
, false,
107 Guid
.Empty
, 2, true, data
);
110 [MonoLimitation ("level is not always correct")]
111 public override void TraceEvent (TraceEventCache eventCache
,
112 string source
, TraceEventType eventType
, int id
,
115 // FIXME: what is the correct level?
116 TraceCore (eventCache
, source
, TraceEventType
.Transfer
,
117 id
, false, Guid
.Empty
, 2, true, message
);
120 [MonoLimitation ("level is not always correct")]
121 public override void TraceEvent (TraceEventCache eventCache
,
122 string source
, TraceEventType eventType
, int id
,
123 string format
, params object [] args
)
125 // FIXME: what is the correct level?
126 TraceCore (eventCache
, source
, TraceEventType
.Transfer
,
127 id
, false, Guid
.Empty
, 2, true, String
.Format (format
, args
));
130 public override void TraceTransfer (TraceEventCache eventCache
,
131 string source
, int id
, string message
,
132 Guid relatedActivityId
)
134 TraceCore (eventCache
, source
, TraceEventType
.Transfer
,
135 id
, true, relatedActivityId
, 255, true, message
);
138 public override void Write (string message
)
143 [MonoLimitation ("level is not always correct")]
144 public override void WriteLine (string message
)
146 // FIXME: what is the correct level?
147 TraceCore (null, "Trace", TraceEventType
.Information
,
148 0, false, Guid
.Empty
, 8, false, message
);
151 void TraceCore (TraceEventCache eventCache
,
152 string source
, TraceEventType eventType
, int id
,
153 bool hasRelatedActivity
, Guid relatedActivity
,
154 int level
, bool wrapData
, params object [] data
)
156 Process p
= eventCache
!= null ?
157 Process
.GetProcessById (eventCache
.ProcessId
) :
158 Process
.GetCurrentProcess ();
160 w
.WriteStartElement ("E2ETraceEvent", e2e_ns
);
163 w
.WriteStartElement ("System", sys_ns
);
164 w
.WriteStartElement ("EventID", sys_ns
);
165 w
.WriteString (XmlConvert
.ToString (id
));
166 w
.WriteEndElement ();
167 // FIXME: find out what should be written
168 w
.WriteStartElement ("Type", sys_ns
);
170 w
.WriteEndElement ();
171 w
.WriteStartElement ("SubType", sys_ns
);
172 // FIXME: it does not seem always to match eventType value ...
173 w
.WriteAttributeString ("Name", eventType
.ToString ());
174 // FIXME: find out what should be written
176 w
.WriteEndElement ();
177 // FIXME: find out what should be written
178 w
.WriteStartElement ("Level", sys_ns
);
179 w
.WriteString (level
.ToString ());
180 w
.WriteEndElement ();
181 w
.WriteStartElement ("TimeCreated", sys_ns
);
182 w
.WriteAttributeString ("SystemTime", XmlConvert
.ToString (eventCache
!= null ? eventCache
.DateTime
: DateTime
.Now
));
183 w
.WriteEndElement ();
184 w
.WriteStartElement ("Source", sys_ns
);
185 w
.WriteAttributeString ("Name", source
);
186 w
.WriteEndElement ();
187 w
.WriteStartElement ("Correlation", sys_ns
);
188 w
.WriteAttributeString ("ActivityID", String
.Concat ("{", Guid.Empty, "}"));
189 w
.WriteEndElement ();
190 w
.WriteStartElement ("Execution", sys_ns
);
191 // FIXME: which should I use here?
192 //w.WriteAttributeString ("ProcessName", p.ProcessName);
193 w
.WriteAttributeString ("ProcessName", p
.MainModule
.ModuleName
);
194 w
.WriteAttributeString ("ProcessID", p
.Id
.ToString ());
195 w
.WriteAttributeString ("ThreadID", eventCache
!= null ? eventCache
.ThreadId
: Thread
.CurrentThread
.ManagedThreadId
.ToString ());
196 w
.WriteEndElement ();
197 w
.WriteStartElement ("Channel", sys_ns
);
198 // FIXME: find out what should be written.
199 w
.WriteEndElement ();
200 w
.WriteStartElement ("Computer");
201 w
.WriteString (p
.MachineName
);
202 w
.WriteEndElement ();
204 w
.WriteEndElement ();
207 w
.WriteStartElement ("ApplicationData", e2e_ns
);
208 foreach (object o
in data
) {
210 w
.WriteStartElement ("TraceData", e2e_ns
);
212 w
.WriteString (o
.ToString ());
214 w
.WriteEndElement ();
216 w
.WriteEndElement ();
218 w
.WriteEndElement ();