protected virtual void OnNewMessages(LogMessage[] e) { var handler = NewMessages; if (handler != null) { handler(this, e); } }
/// <summary> /// Here we expect the log event to use the log4j schema. /// Sample: /// <log4j:event logger="Statyk7.Another.Name.DummyManager" timestamp="1184286222308" level="ERROR" thread="1"> /// <log4j:message>This is an Message</log4j:message> /// <log4j:properties> /// <log4j:data name="log4jmachinename" value="remserver" /> /// <log4j:data name="log4net:HostName" value="remserver" /> /// <log4j:data name="log4net:UserName" value="REMSERVER\Statyk7" /> /// <log4j:data name="log4japp" value="Test.exe" /> /// </log4j:properties> /// </log4j:event> /// </summary> /// /// Implementation inspired from: http://geekswithblogs.net/kobush/archive/2006/04/20/75717.aspx /// public static LogMessage ParseLog4JXmlLogEvent(XmlReader reader, string defaultLogger) { var logMsg = new LogMessage(); reader.Read(); // try // { // // } // catch(Exception e) // { // logMsg.LoggerName = "Logazmic"; // logMsg.ThreadName = "Logazmic"; // logMsg.LogLevel = LogLevel.Fatal; // logMsg.Message = e.ToString(); // logMsg.TimeStamp = DateTime.Now; // return logMsg; // } if ((reader.MoveToContent() != XmlNodeType.Element) || (reader.Name != "log4j:event")) throw new Exception("The Log Event is not a valid log4j Xml block."); logMsg.LoggerName = reader.GetAttribute("logger"); logMsg.LogLevel = (LogLevel)Enum.Parse(typeof(LogLevel), reader.GetAttribute("level"), true); logMsg.ThreadName = reader.GetAttribute("thread"); long timeStamp; if (long.TryParse(reader.GetAttribute("timestamp"), out timeStamp)) logMsg.TimeStamp = s1970.AddMilliseconds(timeStamp).ToLocalTime(); int eventDepth = reader.Depth; reader.Read(); while (reader.Depth > eventDepth) { if (reader.MoveToContent() == XmlNodeType.Element) { switch (reader.Name) { case "log4j:message": logMsg.Message = reader.ReadString(); break; case "log4j:throwable": logMsg.Message += Environment.NewLine + reader.ReadString(); break; case "log4j:locationInfo": logMsg.CallSiteClass = reader.GetAttribute("class"); logMsg.CallSiteMethod = reader.GetAttribute("method"); logMsg.SourceFileName = reader.GetAttribute("file"); uint sourceFileLine; if (uint.TryParse(reader.GetAttribute("line"), out sourceFileLine)) logMsg.SourceFileLineNr = sourceFileLine; break; case "nlog:eventSequenceNumber": ulong sequenceNumber; if (ulong.TryParse(reader.ReadString(), out sequenceNumber)) logMsg.SequenceNr = sequenceNumber; break; case "nlog:locationInfo": break; case "log4j:properties": reader.Read(); while (reader.MoveToContent() == XmlNodeType.Element && reader.Name == "log4j:data") { string name = reader.GetAttribute("name"); string value = reader.GetAttribute("value"); if (name != null && name.ToLower().Equals("exceptions")) { logMsg.ExceptionString = value; } else { logMsg.Properties[name] = value; } reader.Read(); } break; } } reader.Read(); } return logMsg; }
private void ReadFile() { if ((fileReader == null) || (fileReader.BaseStream.Length == lastFileLength)) { return; } // Seek to the last file length fileReader.BaseStream.Seek(lastFileLength, SeekOrigin.Begin); // Get last added lines string line; var sb = new StringBuilder(); var logMsgs = new List<LogMessage>(); while ((line = fileReader.ReadLine()) != null) { if (fileFormat == FileFormatEnums.Flat) { var logMsg = new LogMessage { ThreadName = "NA", Message = line, TimeStamp = DateTime.Now, LogLevel = LogLevel.Info }; logMsgs.Add(logMsg); } else { sb.AppendLine(line); // This condition allows us to process events that spread over multiple lines if (line.Contains("</log4j:event>")) { LogMessage logMsg = ReceiverUtils.ParseLog4JXmlLogEvent(sb.ToString(), null); logMsgs.Add(logMsg); sb = new StringBuilder(); } } } // Notify the UI with the set of messages OnNewMessages(logMsgs.ToArray()); // Update the last file length lastFileLength = fileReader.BaseStream.Position; }