// Public methods. /// <summary> /// Shows the form as a dialog and the specified event. /// </summary> /// <param name="owner">The owner window.</param> /// <param name="evt">The event.</param> /// <returns>The dialog result.</returns> public DialogResult ShowDialog(IWin32Window owner, LogEvent evt) { // If the event is null, do nothing. if (null == evt) return DialogResult.Abort; // Set the event. this.logEvent.Event = evt; // Set the title. this.Text = "{0} Event at {1} Properties".FormatWith(LogEvent.GetDescription(evt.Type), evt.Timestamp.ToString()); // Open the dialog. return base.ShowDialog(owner); }
/// <summary> /// Opens an event in a new dialog. /// </summary> /// <param name="evt"></param> private void OnOpenEvent(LogEvent evt) { if (null == evt) return; // Create a new dialog if one does not exist. if (null == this.formLogEvent) { this.formLogEvent = new FormEventProperties(); } // Open the dialog. this.formLogEvent.ShowDialog(this, evt); }
// Protected methods. /// <summary> /// An event handler called when a new log event has been set. /// </summary> /// <param name="oldEvent">The old event.</param> /// <param name="newEvent">The new event.</param> protected virtual void OnEventSet(LogEvent oldEvent, LogEvent newEvent) { // If the event has not been changed, do nothing. if (oldEvent == newEvent) return; if (null == newEvent) { this.pictureBox.Image = Resources.EventMagenta_32; this.labelType.Text = "No event selected"; this.tabControl.Visible = false; return; } this.pictureBox.Image = ControlLogEventProperties.eventImage[(int)newEvent.Type]; this.labelType.Text = LogEvent.GetDescription(newEvent.Type); this.tabControl.Visible = true; this.textBoxLevel.Text = LogEvent.GetDescription(newEvent.Level); this.textBoxTimestamp.Text = newEvent.Timestamp.ToString(); this.textBoxSource.Text = newEvent.Source; this.textBoxMessage.Text = newEvent.MessageRaw; this.labelError.Text = string.Empty; if (newEvent.Parent != null) { this.linkLabel.Text = "Event at {0}".FormatWith(newEvent.Parent.Timestamp.ToString()); this.linkLabel.ImageIndex = (int)newEvent.Parent.Type + 1; this.linkLabel.Enabled = true; } else { this.linkLabel.Text = "None"; this.linkLabel.ImageIndex = 0; this.linkLabel.Enabled = false; } this.linkLabel.Width = this.linkLabel.PreferredWidth + 20; this.linkLabel.Height = this.linkLabel.PreferredHeight > 16 ? this.linkLabel.PreferredHeight : 16; if (newEvent.Paremeters != null) { this.listViewParameters.Items.Clear(); int index = 0; foreach (object param in newEvent.Paremeters) this.listViewParameters.Items.Add(new ListViewItem(new string[] { (index++).ToString(), param.ToExtendedString() })); if (!this.tabControl.TabPages.Contains(this.tabPageParameters)) this.tabControl.TabPages.Add(this.tabPageParameters); } else if (this.tabControl.TabPages.Contains(this.tabPageParameters)) this.tabControl.TabPages.Remove(this.tabPageParameters); // Exception if (newEvent.Exception != null) { this.textBoxExceptionType.Text = newEvent.Exception.GetType().ToString(); this.textBoxExceptionMessage.Text = newEvent.Exception.Message; this.textBoxExceptionStack.Text = newEvent.Exception.StackTrace; if (!this.tabControl.TabPages.Contains(this.tabPageException)) this.tabControl.TabPages.Add(this.tabPageException); } else if (this.tabControl.TabPages.Contains(this.tabPageException)) this.tabControl.TabPages.Remove(this.tabPageException); // Exception serialization error if (newEvent.ExceptionSerializationExceptionType != null) { this.labelError.Text += "Could not serialize the event exception while saving to the log file. An exception of type \'{0}\' occurred. {1}{2}{3}".FormatWith( newEvent.ExceptionSerializationExceptionType, newEvent.ExceptionSerializationExceptionMessage, Environment.NewLine, Environment.NewLine); } // Exception deserialization error if (newEvent.ExceptionDeserializationException != null) { this.labelError.Text += "Could not deserialize the event exception while reading from the log file. An exception of type \'{0}\' occurred. {1}{2}{3}".FormatWith( newEvent.ExceptionDeserializationException.GetType().ToString(), newEvent.ExceptionDeserializationException.Message, Environment.NewLine, Environment.NewLine); } if (!string.IsNullOrEmpty(this.labelError.Text)) { if (!this.tabControl.TabPages.Contains(this.tabPageError)) this.tabControl.TabPages.Add(this.tabPageError); } else if (this.tabControl.TabPages.Contains(this.tabPageError)) this.tabControl.TabPages.Remove(this.tabPageError); // Subevents if (newEvent.Subevents != null) { this.listViewSubevents.Items.Clear(); foreach (LogEvent evt in newEvent.Subevents) { ListViewItem item = new ListViewItem( new string[] { evt.Timestamp.ToString(), evt.Message }, (int)evt.Type + 1 ); item.Tag = evt; this.listViewSubevents.Items.Add(item); } if (!this.tabControl.TabPages.Contains(this.tabPageSubevents)) this.tabControl.TabPages.Add(this.tabPageSubevents); } else if (this.tabControl.TabPages.Contains(this.tabPageSubevents)) this.tabControl.TabPages.Remove(this.tabPageSubevents); // Load XML data. if (this.OnLoadXml(newEvent.Exception)) { if (!this.tabControl.TabPages.Contains(this.tabPageXml)) this.tabControl.TabPages.Add(this.tabPageXml); } else if (this.tabControl.TabPages.Contains(this.tabPageXml)) this.tabControl.TabPages.Remove(this.tabPageXml); // Load the atom data. if (this.OnLoadCode(newEvent.Exception)) { if (!this.tabControl.TabPages.Contains(this.tabPageCode)) this.tabControl.TabPages.Add(this.tabPageCode); } else if (this.tabControl.TabPages.Contains(this.tabPageCode)) this.tabControl.TabPages.Remove(this.tabPageCode); this.tabControl.SelectedTab = this.tabPageGeneral; if (this.Focused) { this.textBoxLevel.Select(); this.textBoxLevel.SelectionStart = 0; this.textBoxLevel.SelectionLength = 0; } }
/// <summary> /// Creates a new log event from an XML element. /// </summary> /// <param name="element">The XML element.</param> /// <param name="parent">The parent event.</param> public LogEvent(XElement element, LogEvent parent = null) { // Check the element name. if (element.Name != "event") throw new LogException("Cannot parse the XML element to create a new log event, the element name is \"{0}\".".FormatWith(element.Name)); // Add the event data. try { this.level = (LogEventLevel) int.Parse(element.Attribute(XName.Get("level")).Value, CultureInfo.InvariantCulture); this.type = (LogEventType)int.Parse(element.Attribute(XName.Get("type")).Value, CultureInfo.InvariantCulture); this.timestamp = DateTime.Parse(element.Attribute(XName.Get("timestamp")).Value, CultureInfo.InvariantCulture); this.source = element.Element(XName.Get("source")).Value; this.message = element.Element(XName.Get("message")).Value; this.parent = parent; this.indent = (this.parent != null) ? this.parent.indent + 1 : 0; // Parameters. XElement parameters = element.Element(XName.Get("parameters")); if (null != parameters) { IEnumerable<XElement> parameter = parameters.Elements(XName.Get("parameter")); this.parameters = new object[parameter.Count()]; for (int index = 0; index < parameter.Count(); index++) this.parameters[index] = parameter.ElementAt(index).Value; } else this.parameters = null; // Exception. XElement exception = element.Element(XName.Get("exception")); if (null != exception) { // Check if there exists a serialization exception attribute. XAttribute attr; if(null != (attr = exception.Attribute(XName.Get("serializationExceptionType")))) this.exceptionSerializationExceptionType = attr.Value; if(null != (attr = exception.Attribute(XName.Get("serializationExceptionMessage")))) this.exceptionSerializationExceptionMessage = attr.Value; // If the serialization was successfull. if(null == this.exceptionSerializationExceptionType) { // Try to deserialize the exception. try { // Create a new binary formatter and a memory stream. BinaryFormatter formatter = new BinaryFormatter(); MemoryStream stream = new MemoryStream(); // Read the base-64 string. byte[] bytes = Convert.FromBase64String(exception.Value); stream.Write(bytes, 0, bytes.Length); stream.Seek(0, SeekOrigin.Begin); // Deserialize the object. this.exception = formatter.Deserialize(stream) as Exception; } catch(Exception ex) { this.exceptionDeserializationException = ex; } } } else this.exception = null; // Sub-events. XElement subevents = element.Element(XName.Get("subevents")); if (null != subevents) { // Create the subevents array. this.subevents = new List<LogEvent>(); // Add the sub-events. foreach (XElement child in subevents.Elements("event")) { this.subevents.Add(new LogEvent(child, this)); } } } catch (Exception exception) { throw new LogException("Cannot parse the XML element to create a new log event; some data is missing or is malformed.", exception); } }
/// <summary> /// Creates a new log event. /// </summary> /// <param name="level">The log event level.</param> /// <param name="type">The log event type.</param> /// <param name="timestamp">The event timestamp.</param> /// <param name="source">The even source.</param> /// <param name="message">The event message.</param> /// <param name="parameters">The event parameters.</param> /// <param name="exception">The event exception.</param> /// <param name="subevents">A list of subevents corresponding to this event.</param> public LogEvent( LogEventLevel level, LogEventType type, DateTime timestamp, string source, string message, object[] parameters = null, Exception exception = null, List<LogEvent> subevents = null ) { this.level = level; this.type = type; this.timestamp = timestamp; this.source = source; this.message = message; this.parameters = parameters; this.exception = exception; this.subevents = subevents; this.parent = null; this.indent = (null != this.parent) ? this.parent.indent + 1 : 0; // If there are subevents, set their timestamp, level, and parent to this event. if (null != this.subevents) { foreach (LogEvent evt in this.subevents) { if((int)this.level > (int)evt.level) this.level = evt.level; evt.timestamp = this.timestamp; evt.parent = this; } } }
/// <summary> /// Creates a new event arguments instance. /// </summary> /// <param name="server">The log event.</param> public LogEventArgs(LogEvent evt) { this.Event = evt; }
// Public methods. /// <summary> /// Adds a new event to the event log. The method is thread-safe. /// </summary> /// <param name="evt">The event.</param> public void Add(LogEvent evt) { // Execute the code on the UI thread. this.Invoke(() => { // Create a new list view menu item. ListViewItem item = new ListViewItem(new string[] { DateTime.Now.ToString(), evt.Message }, (int)evt.Type); item.Tag = evt; if (this.listView.Items.Count > this.MaximumItems) this.listView.Items.RemoveAt(0); this.listView.Items.Add(item); this.listView.EnsureVisible(this.listView.Items.Count - 1); // If the clear button is disabled, enable the button. if (!this.buttonClear.Enabled) this.buttonClear.Enabled = true; }); }
/// <summary> /// Adds a new event to the event log for the current date/time. /// </summary> /// <param name="level">The log event level.</param> /// <param name="type">The log event type.</param> /// <param name="source">The event source.</param> /// <param name="message">The event message.</param> /// <param name="parameters">The event parameters.</param> /// <param name="exception">The event exception.</param> /// <param name="subevents">The list of subevents.</param> /// <returns>The log event.</returns> public LogEvent Add( LogEventLevel level, LogEventType type, string source, string message, object[] parameters = null, Exception exception = null, List<LogEvent> subevents = null ) { LogEvent evt; // Create the event. evt = new LogEvent(level, type, DateTime.Now, source, message, parameters, exception, subevents); // Compute the file name. string fileName = string.Format(this.filePattern, evt.Timestamp.ToUniversalTime().Year, evt.Timestamp.ToUniversalTime().Month, evt.Timestamp.ToUniversalTime().Day); try { XDocument xml; // Check whether there exists a file for the event date. if (!this.logs.TryGetValue(evt.Timestamp.Date, out xml)) { // If the file exists. if (File.Exists(fileName)) { // Read the XML from the file. try { xml = XDocument.Load(fileName); } catch (Exception) { xml = new XDocument(new XElement("log", new XAttribute("date", evt.Timestamp.ToUniversalTime().Date.ToString(CultureInfo.InvariantCulture)))); } } else { // Create a new empty XML. xml = new XDocument(new XElement("log", new XAttribute("date", evt.Timestamp.ToUniversalTime().Date.ToString(CultureInfo.InvariantCulture)))); } // Add the XML to the logs list. this.logs.Add(evt.Timestamp.Date, xml); } // Add the event to the XML file. xml.Root.Add(evt.Xml); } catch (Exception ex) { evt.Logger = string.Format("Could not save the event {0} to the log \"{1}\" ({2}).", evt.Timestamp, fileName, ex.Message); } // Raise the event for this log event. if (this.EventLogged != null) this.EventLogged(this, new LogEventArgs(evt)); return evt; }