Esempio n. 1
0
        private Tuple <string, List <NameValuePair> > ParseElement(ParserContext ctx)
        {
            if (ctx.Current != SyslogChars.Lbr)
            {
                return(null);
            }
            ctx.Position++;
            var elemName = ctx.ReadWord();

            ctx.SkipSpaces();
            var paramList = new List <NameValuePair>();
            var elem      = new Tuple <string, List <NameValuePair> >(elemName, paramList);

            while (ctx.Current != SyslogChars.Rbr)
            {
                var paramName = ctx.ReadWord();
                ctx.ReadSymbol('=');
                var paramValue = ctx.ReadQuotedString();
                var prm        = new NameValuePair()
                {
                    Name = paramName, Value = paramValue
                };
                paramList.Add(prm);
                ctx.SkipSpaces();
            }

            ctx.ReadSymbol(SyslogChars.Rbr);
            return(elem);
        }
        } //method

        private List <NameValuePair> ReadKeyValuePairs(ParserContext ctx)
        {
            var           prmList = new List <NameValuePair>();
            NameValuePair lastPrm = null;

            /*
             * 2 troubles here:
             */
            while (!ctx.Eof())
            {
                ctx.SkipSpaces();
                var name = ctx.ReadWord();
                if (!ctx.ReadSymbol('=', throwIfMismatch: false))
                {
                    // Some entries are malformed: double quoted strings
                    // the result is that we do not find '=' after closing the quote. So we just add the rest to a separate param and exit
                    var text = ctx.Text.Substring(ctx.Position);
                    prmList.Add(new NameValuePair()
                    {
                        Name = "Message", Value = text
                    });
                    return(prmList);
                }
                ctx.SkipSpaces();
                string value;
                if (ctx.Current == SyslogChars.DQuote)
                {
                    // For double-quoted values, some values are malformed - they contain nested d-quoted strings that are not escaped.
                    value = ctx.ReadQuotedString();
                }
                else
                {
                    // Special case: non quoted empty values, ex: ' a= b=234 '; value of 'a' is Empty. We check the char after we read the value,
                    //      and if it is '=', we back off, set value to empty.
                    var saveP = ctx.Position;
                    value = ctx.ReadWord();
                    if (ctx.Current == '=')
                    {
                        ctx.Position = saveP;
                        value        = string.Empty;
                    }
                }
                lastPrm = new NameValuePair()
                {
                    Name = name, Value = value
                };
                prmList.Add(lastPrm);
            }
            return(prmList);
        }
Esempio n. 3
0
        private void ParseStructuredData(ParserContext ctx)
        {
            ctx.SkipSpaces();

            if (ctx.Current == SyslogChars.NilChar)
            {
                ctx.Position++;
                return;
            }

            var data = ctx.Entry.StructuredData;

            try
            {
                if (ctx.Current != SyslogChars.Lbr)
                {
                    // do not report it as an error, some messages out there are a bit malformed
                    // ctx.AddError("Expected [ for structured data.");
                    return;
                }
                // start parsing elements
                while (!ctx.Eof())
                {
                    var elem = ParseElement(ctx);
                    if (elem == null)
                    {
                        return;
                    }
                    data[elem.Item1] = elem.Item2;
                }
            } catch (Exception ex)
            {
                ctx.AddError(ex.Message);
            }
        }
Esempio n. 4
0
 public bool TryParse(ParserContext ctx)
 {
     ctx.SkipSpaces();
     ctx.Entry.PayloadType      = Model.PayloadType.PlainText;
     ctx.Entry.Message          = ctx.Text.Substring(ctx.Position);
     ctx.Entry.Header.Timestamp = DateTime.UtcNow;
     return(true);
 }
        // 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 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
Esempio n. 7
0
        public static string ReadWord(this ParserContext ctx)
        {
            if (ctx.Current == SyslogChars.Space)
            {
                ctx.SkipSpaces();
            }

            var separatorPos = ctx.Text.IndexOfAny(SyslogChars.WordSeparators, ctx.Position);

            if (separatorPos < 0)
            {
                separatorPos = ctx.Text.Length;
            }

            var word = ctx.Text.Substring(ctx.Position, separatorPos - ctx.Position);

            ctx.Position = separatorPos;
            return(word);
        }
Esempio n. 8
0
        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);
        }
Esempio n. 9
0
 public static bool ReadSymbol(this ParserContext ctx, char symbol, bool throwIfMismatch = true)
 {
     if (ctx.Current == SyslogChars.Space)
     {
         ctx.SkipSpaces();
     }
     if (ctx.Current == symbol)
     {
         ctx.Position++;
         return(true);
     }
     if (throwIfMismatch)
     {
         throw new Exception($"Invalid input, expected '{symbol}' ");
     }
     else
     {
         return(false);
     }
 }