3using System.Collections.Generic;
6using System.Xml.Schema;
9using System.Windows.Controls;
15using System.Threading.Tasks;
24 private readonly
string identifier;
57 if (!(this.sink is
null))
69 private Task AddItem(
object P)
71 this.LogListView.Items.Add(P);
72 this.LogListView.ScrollIntoView(P);
74 return Task.CompletedTask;
77 public void NewButton_Click(
object Sender, RoutedEventArgs e)
79 this.LogListView.Items.Clear();
82 public void SaveButton_Click(
object Sender, RoutedEventArgs e)
84 this.SaveAsButton_Click(Sender, e);
87 public void SaveAsButton_Click(
object Sender, RoutedEventArgs e)
89 SaveFileDialog Dialog =
new SaveFileDialog()
92 CheckPathExists =
true,
95 Filter =
"XML Files (*.xml)|*.xml|HTML Files (*.html,*.htm)|*.html,*.htm|All Files (*.*)|*.*",
96 Title =
"Save log file"
99 bool? Result = Dialog.ShowDialog(
MainWindow.FindWindow(
this));
101 if (Result.HasValue && Result.Value)
105 if (Dialog.FilterIndex == 2)
107 StringBuilder Xml =
new StringBuilder();
113 string Html =
XSL.
Transform(Xml.ToString(), eventsToHtml);
115 File.WriteAllText(Dialog.FileName, Html, System.Text.Encoding.UTF8);
119 using (FileStream f = File.Create(Dialog.FileName))
130 MessageBox.Show(
MainWindow.FindWindow(
this), ex.Message,
"Unable to save file.", MessageBoxButton.OK, MessageBoxImage.Error);
135 private static readonly XslCompiledTransform eventsToHtml =
XSL.
LoadTransform(
"Waher.Client.WPF.Transforms.EventXmlToHtml.xslt");
136 private static readonly XmlSchema schema =
XSL.
LoadSchema(
"Waher.Client.WPF.Schema.EventOutput.xsd");
137 private const string logNamespace =
"http://waher.se/Schema/EventOutput.xsd";
138 private const string logRoot =
"EventOutput";
140 private void SaveAsXml(XmlWriter w)
142 w.WriteStartElement(logRoot, logNamespace);
144 foreach (
LogItem Item
in this.LogListView.Items)
148 w.WriteStartElement(
Event.
Type.ToString());
150 w.WriteAttributeString(
"level",
Event.
Level.ToString());
168 w.WriteStartElement(
"Message");
171 w.WriteElementString(
"Row", Row);
177 foreach (KeyValuePair<string, object> Tag
in Event.
Tags)
179 w.WriteStartElement(
"Tag");
180 w.WriteAttributeString(
"key", Tag.Key);
182 if (!(Tag.Value is
null))
183 w.WriteAttributeString(
"value", Tag.Value.ToString());
191 w.WriteStartElement(
"StackTrace");
194 w.WriteElementString(
"Row", Row);
207 private static string[] GetRows(
string s)
209 return s.Replace(
"\r\n",
"\n").Replace(
"\r",
"\n").Split(
'\n');
212 internal static string Encode(DateTime DT)
214 StringBuilder sb =
new StringBuilder();
216 sb.Append(DT.Year.ToString(
"D4"));
218 sb.Append(DT.Month.ToString(
"D2"));
220 sb.Append(DT.Day.ToString(
"D2"));
222 sb.Append(DT.Hour.ToString(
"D2"));
224 sb.Append(DT.Minute.ToString(
"D2"));
226 sb.Append(DT.Second.ToString(
"D2"));
228 sb.Append(DT.Millisecond.ToString(
"D3"));
230 if (DT.Kind == DateTimeKind.Utc)
233 return sb.ToString();
236 public void OpenButton_Click(
object Sender, RoutedEventArgs e)
240 OpenFileDialog Dialog =
new OpenFileDialog()
243 CheckFileExists =
true,
244 CheckPathExists =
true,
246 Filter =
"XML Files (*.xml)|*.xml|All Files (*.*)|*.*",
249 Title =
"Open log file"
252 bool? Result = Dialog.ShowDialog(
MainWindow.FindWindow(
this));
254 if (Result.HasValue && Result.Value)
256 XmlDocument Xml =
new XmlDocument()
258 PreserveWhitespace =
true
260 Xml.Load(Dialog.FileName);
262 this.Load(Xml, Dialog.FileName);
268 MessageBox.Show(ex.Message,
"Unable to load file.", MessageBoxButton.OK, MessageBoxImage.Error);
272 public void Load(XmlDocument Xml,
string FileName)
274 XmlElement E, E2, E3;
276 XSL.
Validate(FileName, Xml, logRoot, logNamespace, schema);
278 this.LogListView.Items.Clear();
280 foreach (XmlNode N
in Xml.DocumentElement.ChildNodes)
286 if (!Enum.TryParse(E.LocalName, out
EventType Type))
289 DateTime Timestamp =
XML.
Attribute(E,
"timestamp", DateTime.MinValue);
296 StringBuilder Message =
new StringBuilder();
297 StringBuilder StackTrace =
null;
298 List<KeyValuePair<string, object>> Tags =
new List<KeyValuePair<string, object>>();
300 foreach (XmlNode N2
in E.ChildNodes)
302 E2 = N2 as XmlElement;
306 switch (E2.LocalName)
309 foreach (XmlNode N3
in E2.ChildNodes)
311 E3 = N3 as XmlElement;
315 if (E3.LocalName ==
"Row")
316 Message.AppendLine(E3.InnerText);
324 Tags.Add(
new KeyValuePair<string, object>(Key, Value));
328 if (StackTrace is
null)
329 StackTrace =
new StringBuilder();
331 foreach (XmlNode N3
in E2.ChildNodes)
333 E3 = N3 as XmlElement;
337 if (E3.LocalName ==
"Row")
338 StackTrace.AppendLine(E3.InnerText);
344 Event Event =
new Event(Timestamp, Type, Message.ToString(), Object, Actor, EventId, Level, Facility, Module,
345 StackTrace?.ToString() ??
string.Empty, Tags.ToArray());
351 private void UserControl_SizeChanged(
object Sender, SizeChangedEventArgs e)
353 if (this.LogListView.View is GridView GridView)
355 double w = this.ActualWidth;
358 for (i = 0; i < 6; i++)
359 w -= (GridView.Columns[i].ActualWidth + SystemParameters.VerticalScrollBarWidth + 8);
361 GridView.Columns[6].Width = Math.Max(w, 10);
Interaction logic for LogView.xaml
void InitializeComponent()
InitializeComponent
string Identifier
Identifier of log view.
LogView(string Identifier, bool Register)
Interaction logic for LogView.xaml
LogSink Sink
Log sink registered with Log, if registered, null otherwise.
Represents one item in an event log output.
Interaction logic for xaml
Helps with common XML-related tasks.
static string Attribute(XmlElement E, string Name)
Gets the value of an XML attribute.
static XmlWriterSettings WriterSettings(bool Indent, bool OmitXmlDeclaration)
Gets an XML writer settings object.
Static class managing loading of XSL resources stored as embedded resources or in content files.
static XmlSchema LoadSchema(string ResourceName)
Loads an XML schema from an embedded resource.
static XslCompiledTransform LoadTransform(string ResourceName)
Loads an XSL transformation from an embedded resource.
static string Transform(string XML, XslCompiledTransform Transform)
Transforms an XML document using an XSL transform.
static void Validate(string ObjectID, XmlDocument Xml, params XmlSchema[] Schemas)
Validates an XML document given a set of XML schemas.
Class representing an event.
string Message
Free-text event message.
EventType Type
Type of event.
string Object
Object related to the event.
EventLevel Level
Event Level.
string Actor
Actor responsible for the action causing the event.
string Module
Module where the event is reported.
DateTime Timestamp
Timestamp of event.
KeyValuePair< string, object >[] Tags
Variable set of tags providing event-specific information.
string EventId
Computer-readable Event ID identifying type of even.
string Facility
Facility can be either a facility in the network sense or in the system sense.
string StackTrace
Stack Trace of event.
Static class managing the application event log. Applications and services log events on this static ...
static void Register(IEventSink EventSink)
Registers an event sink with the event log. Call Unregister(IEventSink) to unregister it,...
static Exception UnnestException(Exception Exception)
Unnests an exception, to extract the relevant inner exception.
static bool Unregister(IEventSink EventSink)
Unregisters an event sink from the event log.
Interface for tab view user controls in the client.