// match entry like // <186>: 2020 Mar 4 17:20:54.183 UTC: public static bool TryParseIfStartsWithColonThenYear(ParserContext ctx) { var year = DateTime.UtcNow.Year; var savePos = ctx.Position; if (ctx.Match(": ") && (ctx.Match($"{year}") || ctx.Match($"{year - 1}"))) //check prior year { // we already matched beyond year; move back: ctx.Position = savePos + ": ".Length; var UTC = "PST:"; // "UTC:"; var utcPos = ctx.Text.IndexOf(UTC, ctx.Position); if (utcPos > 0) { var dtStr = ctx.Text.Substring(ctx.Position, utcPos - ctx.Position); ctx.Position = utcPos + UTC.Length; if (DateTime.TryParse(dtStr, out var dt)) { ctx.Entry.Header.Timestamp = DateTime.SpecifyKind(dt, DateTimeKind.Utc); return(true); } } } ctx.Position = savePos; return(false); }
public bool TryParse(ParserContext ctx) { if (!ctx.Reset()) { return(false); } if (!ctx.Match("1 ")) { return(false); } // It is RFC-5424 entry var entry = ctx.Entry; entry.PayloadType = PayloadType.Rfc5424; try { entry.Header = this.ParseHeader(ctx); this.ParseStructuredData(ctx); entry.Message = this.ParseMessage(ctx); return(true); } catch (Exception ex) { ctx.AddError(ex.Message); return(false); } }
// match entry like // <134> 03/04/2020:17:20:58 GMT ams07.... public static bool TryParseIfStartsWithSpace(ParserContext ctx) { ctx.Reset(); if (ctx.Current != SyslogChars.Space) { return(false); } var prefix = ctx.Text.Substring(ctx.Position, 25); var year = DateTime.UtcNow.Year; if (prefix.Contains($"/{year}:") || prefix.Contains($"/{year - 1}:")) //(also check prior year) { ctx.Position++; var spPos = ctx.Text.IndexOf(" ", ctx.Position); if (spPos > 0) { var dtStr = ctx.Text.Substring(ctx.Position, spPos - ctx.Position); ctx.Position = spPos + 1; ctx.Match("GMT"); //skip also GMT if (DateTime.TryParse(dtStr, out var dt) || DateTime.TryParseExact(dtStr, "MM/dd/yyyy:HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out dt)) { ctx.Entry.Header.Timestamp = dt.ToUniversalTime(); } } return(true); } return(false); }
public bool TryParse(ParserContext ctx) { if (ctx.Current == SyslogChars.Space) { ctx.SkipSpaces(); } // typically entries start with 'device=' or 'date=' var match = ctx.Match("device=") || ctx.Match("date="); if (!match) { match = TryMatchAnyKey(ctx); } if (!match) { return(false); } // It is the format for this parser ctx.Reset(); // Match(...) moved the position, so return to the start ctx.Entry.PayloadType = PayloadType.KeyValuePairs; var kvList = ReadKeyValuePairs(ctx); ctx.Entry.ExtractedData.AddRange(kvList); // try some known values and put them in the header var hdr = ctx.Entry.Header; hdr.HostName = kvList.GetValue("device_id"); var date = kvList.GetValue("date"); var time = kvList.GetValue("time"); if (date != null) { var dateTimeStr = $"{date}T{time}"; if (DateTime.TryParse(dateTimeStr, out var dt)) { hdr.Timestamp = dt; } } return(true); } //method
// match entry like // <141>2020-03-04T17:20:54.412705+00:00 MWH.... public static bool TryParseIfStartsWithYear(ParserContext ctx) { var year = DateTime.UtcNow.Year; var savePos = ctx.Position; if (ctx.Match($"{year}-") || ctx.Match($"{year - 1}-")) //(also check prior year) { ctx.Position = savePos; var spPos = ctx.Text.IndexOf(" ", ctx.Position);// if (spPos > 0) { var dtStr = ctx.Text.Substring(ctx.Position, spPos - ctx.Position); ctx.Position = spPos; if (DateTime.TryParse(dtStr, out var dt)) { ctx.Entry.Header.Timestamp = dt.ToUniversalTime(); return(true); } } } ctx.Position = savePos; return(false); }
// let try to match any key, like <120> abc = def private bool TryMatchAnyKey(ParserContext ctx) { if (!char.IsLetter(ctx.Current)) { return(false); } var savePos = ctx.Position; var word = ctx.ReadWord(); ctx.SkipSpaces(); var result = ctx.Match("="); ctx.Position = savePos; return(result); }
public static bool TryParseTimestamp(ParserContext ctx) { // sometimes there's starting space if (ctx.Current == SyslogChars.Space) { ctx.SkipSpaces(); } // some messages start with some numeric Id: // <139>36177473: Mar 4 17:21:18 UTC: if (char.IsDigit(ctx.Current)) { // make sure it's not a year and at least 5 chars var fiveDigits = ctx.Text.Substring(ctx.Position, 5).All(ch => char.IsDigit(ch)); if (fiveDigits) { var savePos = ctx.Position; var digits = ctx.ReadDigits(20); if (ctx.Match(": ")) { // we swallowed this numeric prefix and ': ' after that, nothing to do } else { ctx.Position = savePos; // rollback, timestamp evaluation will go from string start } } } try { // quick guess - if it contains current month name if (TryParseIfStartsWithYear(ctx) || TryParseTimestampWithMonthName(ctx) || TryParseIfStartsWithColonThenYear(ctx) || TryParseIfStartsWithSpace(ctx)) { return(true); } } catch (Exception ex) { ctx.ErrorMessages.Add(ex.ToString()); } return(false); }