2008-04-16 Marek Habersack <mhabersack@novell.com>
[mono.git] / mcs / class / System / System.Diagnostics / XmlWriterTraceListener.cs
1 //
2 // XmlWriterTraceListener.cs
3 //
4 // Author:
5 //      Atsushi Enomoto  <atsushi@ximian.com>
6 //
7 // Copyright (C) 2007 Novell, Inc  http://www.novell.com
8 //
9
10 //
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:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
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.
29 //
30
31 #if NET_2_0 && XML_DEP
32
33 using System;
34 using System.IO;
35 using System.Diagnostics;
36 using System.Threading;
37 using System.Xml;
38
39 namespace System.Diagnostics
40 {
41         public class XmlWriterTraceListener : TextWriterTraceListener
42         {
43                 const string e2e_ns = "http://schemas.microsoft.com/2004/06/E2ETraceEvent";
44                 const string sys_ns = "http://schemas.microsoft.com/2004/06/windows/eventlog/system";
45                 const string default_name = "XmlWriter";
46                 XmlWriter w;
47                 string name;
48
49                 public XmlWriterTraceListener (string filename)
50                         : this (filename, default_name)
51                 {
52                 }
53
54                 public XmlWriterTraceListener (string filename, string name)
55                         : this (new StreamWriter (new FileStream (filename, FileMode.Append, FileAccess.Write, FileShare.ReadWrite)), name)
56                 {
57                 }
58
59                 public XmlWriterTraceListener (Stream stream)
60                         : this (stream, default_name)
61                 {
62                 }
63
64                 public XmlWriterTraceListener (Stream writer, string name)
65                         : this (new StreamWriter (writer), name)
66                 {
67                 }
68
69                 public XmlWriterTraceListener (TextWriter writer)
70                         : this (writer, default_name)
71                 {
72                 }
73
74                 public XmlWriterTraceListener (TextWriter writer, string name)
75                 {
76                         XmlWriterSettings settings = new XmlWriterSettings ();
77                         settings.OmitXmlDeclaration = true;
78                         w = XmlWriter.Create (writer, settings);
79                         this.name = name;
80                 }
81
82                 public override void Close ()
83                 {
84                         w.Close ();
85                 }
86
87                 public override void Fail (string message, string detailMessage)
88                 {
89                         TraceEvent (null, null, TraceEventType.Error,
90                                     0, String.Concat (message, " ", detailMessage));
91                 }
92
93                 public override void TraceData (TraceEventCache eventCache,
94                         string source, TraceEventType eventType, int id,
95                         object data)
96                 {
97                         TraceCore (eventCache, source, eventType, id, false,
98                                    Guid.Empty, 2, true, data);
99                 }
100
101                 [MonoLimitation ("level is not always correct")]
102                 public override void TraceData (TraceEventCache eventCache,
103                         string source, TraceEventType eventType, int id,
104                         params object [] data)
105                 {
106                         // FIXME: what is the correct level?
107                         TraceCore (eventCache, source, eventType, id, false,
108                                    Guid.Empty, 2, true, data);
109                 }
110
111                 [MonoLimitation ("level is not always correct")]
112                 public override void TraceEvent (TraceEventCache eventCache,
113                         string source, TraceEventType eventType, int id,
114                         string message)
115                 {
116                         // FIXME: what is the correct level?
117                         TraceCore (eventCache, source, TraceEventType.Transfer,
118                                    id, false, Guid.Empty, 2, true, message);
119                 }
120
121                 [MonoLimitation ("level is not always correct")]
122                 public override void TraceEvent (TraceEventCache eventCache,
123                         string source, TraceEventType eventType, int id,
124                         string format, params object [] args)
125                 {
126                         // FIXME: what is the correct level?
127                         TraceCore (eventCache, source, TraceEventType.Transfer,
128                                    id, false, Guid.Empty, 2, true, String.Format (format, args));
129                 }
130
131                 public override void TraceTransfer (TraceEventCache eventCache,
132                         string source, int id, string message,
133                         Guid relatedActivityId)
134                 {
135                         TraceCore (eventCache, source, TraceEventType.Transfer,
136                                    id, true, relatedActivityId, 255, true, message);
137                 }
138
139                 public override void Write (string message)
140                 {
141                         WriteLine (message);
142                 }
143
144                 [MonoLimitation ("level is not always correct")]
145                 public override void WriteLine (string message)
146                 {
147                         // FIXME: what is the correct level?
148                         TraceCore (null, "Trace", TraceEventType.Information,
149                                    0, false, Guid.Empty, 8, false, message);
150                 }
151
152                 void TraceCore (TraceEventCache eventCache,
153                         string source, TraceEventType eventType, int id,
154                         bool hasRelatedActivity, Guid relatedActivity,
155                         int level, bool wrapData, params object [] data)
156                 {
157                         Process p = eventCache != null ?
158                                 Process.GetProcessById (eventCache.ProcessId) :
159                                 Process.GetCurrentProcess ();
160
161                         w.WriteStartElement ("E2ETraceEvent", e2e_ns);
162
163                         // <System>
164                         w.WriteStartElement ("System", sys_ns);
165                         w.WriteStartElement ("EventID", sys_ns);
166                         w.WriteString (XmlConvert.ToString (id));
167                         w.WriteEndElement ();
168                         // FIXME: find out what should be written
169                         w.WriteStartElement ("Type", sys_ns);
170                         w.WriteString ("3");
171                         w.WriteEndElement ();
172                         w.WriteStartElement ("SubType", sys_ns);
173                         // FIXME: it does not seem always to match eventType value ...
174                         w.WriteAttributeString ("Name", eventType.ToString ());
175                         // FIXME: find out what should be written
176                         w.WriteString ("0");
177                         w.WriteEndElement ();
178                         // FIXME: find out what should be written
179                         w.WriteStartElement ("Level", sys_ns);
180                         w.WriteString (level.ToString ());
181                         w.WriteEndElement ();
182                         w.WriteStartElement ("TimeCreated", sys_ns);
183                         w.WriteAttributeString ("SystemTime", XmlConvert.ToString (eventCache != null ? eventCache.DateTime : DateTime.Now));
184                         w.WriteEndElement ();
185                         w.WriteStartElement ("Source", sys_ns);
186                         w.WriteAttributeString ("Name", source);
187                         w.WriteEndElement ();
188                         w.WriteStartElement ("Correlation", sys_ns);
189                         w.WriteAttributeString ("ActivityID", String.Concat ("{", Guid.Empty, "}"));
190                         w.WriteEndElement ();
191                         w.WriteStartElement ("Execution", sys_ns);
192                         // FIXME: which should I use here?
193                         //w.WriteAttributeString ("ProcessName", p.ProcessName);
194                         w.WriteAttributeString ("ProcessName", p.MainModule.ModuleName);
195                         w.WriteAttributeString ("ProcessID", p.Id.ToString ());
196                         w.WriteAttributeString ("ThreadID", eventCache != null ? eventCache.ThreadId : Thread.CurrentThread.ManagedThreadId.ToString ());
197                         w.WriteEndElement ();
198                         w.WriteStartElement ("Channel", sys_ns);
199                         // FIXME: find out what should be written.
200                         w.WriteEndElement ();
201                         w.WriteStartElement ("Computer");
202                         w.WriteString (p.MachineName);
203                         w.WriteEndElement ();
204
205                         w.WriteEndElement ();
206
207                         // <ApplicationData>
208                         w.WriteStartElement ("ApplicationData", e2e_ns);
209                         foreach (object o in data) {
210                                 if (wrapData)
211                                         w.WriteStartElement ("TraceData", e2e_ns);
212                                 if (o != null)
213                                         w.WriteString (o.ToString ());
214                                 if (wrapData)
215                                         w.WriteEndElement ();
216                         }
217                         w.WriteEndElement ();
218
219                         w.WriteEndElement ();
220                 }
221         }
222 }
223
224 #endif