private syntax_info parse_relative_syntax(string syntax) { syntax_info si = new syntax_info(); si.relative_syntax_ = true; si.relative_idx_in_line_.Clear(); // Example: "$time[0,12] $ctx1['[','-'] $func[' ',']'] $ctx2['[[',' ] ]'] $msg" syntax = syntax.Trim(); while (syntax.Length > 0) { if (syntax[0] != '$') { // invalid syntax break; } syntax = syntax.Substring(1); string type_str = syntax.Split('[')[0]; info_type type = info_type_io.from_str(type_str); if (type == info_type.max) { // invalid syntax break; } int bracket = syntax.IndexOf("["); syntax = bracket >= 0 ? syntax.Substring(bracket + 1).Trim() : ""; if (syntax == "") { // this was the last item (the remainder of the string) si.relative_idx_in_line_.Add(new syntax_info.relative_pos { type = type, start = -1, start_str = null, len = -1, end_str = null }); break; } var start = parse_sub_relative_syntax(ref syntax); var end = parse_sub_relative_syntax(ref syntax); si.relative_idx_in_line_.Add(new syntax_info.relative_pos { type = type, start = start.Item1, start_str = start.Item2, len = end.Item1, end_str = end.Item2 }); syntax = syntax.Trim(); } return(si); }
private syntax_info parse_single_syntax(string syntax) { try { if (syntax.Contains("'")) { return(parse_relative_syntax(syntax)); } syntax_info si = new syntax_info(); si.idx_in_line_[(int)info_type.time] = parse_syntax_pos(syntax, "time["); si.idx_in_line_[(int)info_type.date] = parse_syntax_pos(syntax, "date["); si.idx_in_line_[(int)info_type.level] = parse_syntax_pos(syntax, "level["); si.idx_in_line_[(int)info_type.msg] = parse_syntax_pos(syntax, "msg["); si.idx_in_line_[(int)info_type.class_] = parse_syntax_pos(syntax, "class["); si.idx_in_line_[(int)info_type.file] = parse_syntax_pos(syntax, "file["); si.idx_in_line_[(int)info_type.func] = parse_syntax_pos(syntax, "func["); si.idx_in_line_[(int)info_type.ctx1] = parse_syntax_pos(syntax, "ctx1["); si.idx_in_line_[(int)info_type.ctx2] = parse_syntax_pos(syntax, "ctx2["); si.idx_in_line_[(int)info_type.ctx3] = parse_syntax_pos(syntax, "ctx3["); si.idx_in_line_[(int)info_type.ctx4] = parse_syntax_pos(syntax, "ctx4["); si.idx_in_line_[(int)info_type.ctx5] = parse_syntax_pos(syntax, "ctx5["); si.idx_in_line_[(int)info_type.ctx6] = parse_syntax_pos(syntax, "ctx6["); si.idx_in_line_[(int)info_type.ctx7] = parse_syntax_pos(syntax, "ctx7["); si.idx_in_line_[(int)info_type.ctx8] = parse_syntax_pos(syntax, "ctx8["); si.idx_in_line_[(int)info_type.ctx9] = parse_syntax_pos(syntax, "ctx9["); si.idx_in_line_[(int)info_type.ctx10] = parse_syntax_pos(syntax, "ctx10["); si.idx_in_line_[(int)info_type.ctx11] = parse_syntax_pos(syntax, "ctx11["); si.idx_in_line_[(int)info_type.ctx12] = parse_syntax_pos(syntax, "ctx12["); si.idx_in_line_[(int)info_type.ctx13] = parse_syntax_pos(syntax, "ctx13["); si.idx_in_line_[(int)info_type.ctx14] = parse_syntax_pos(syntax, "ctx14["); si.idx_in_line_[(int)info_type.ctx15] = parse_syntax_pos(syntax, "ctx15["); si.idx_in_line_[(int)info_type.thread] = parse_syntax_pos(syntax, "thread["); Debug.Assert(si.idx_in_line_.Length == syntax_info.line_contains_msg_only_.Length); return(si); } catch { // invalid syntax return(null); } }
// returns null if it can't parse private line parse_line_with_syntax(sub_string l, syntax_info si) { if (si.relative_syntax_) { return(parse_relative_line(l, si)); } try { string sub = l.msg; bool normal_line = parse_time(sub, si.idx_in_line_[(int)info_type.time]) && parse_date(sub, si.idx_in_line_[(int)info_type.date]); if (si.idx_in_line_[(int)info_type.time].Item1 < 0 && si.idx_in_line_[(int)info_type.date].Item1 < 0) { // in this case, we don't have time & date - see that the level matches // note: we can't rely on level too much, since the user might have additional levels that our defaults - so we could get false negatives normal_line = parse_level(sub, si.idx_in_line_[(int)info_type.level]); } return(normal_line ? new line(l, si.idx_in_line_) : null); } catch (Exception e) { logger.Error("invalid line: " + l + " : " + e.Message); //return new line(pos_in_log, l, line_contains_msg_only_); return(null); } }
private line parse_relative_line(sub_string l, syntax_info si) { List <Tuple <int, int> > indexes = new List <Tuple <int, int> >(); for (int i = 0; i < (int)info_type.max; ++i) { indexes.Add(new Tuple <int, int>(-1, -1)); } string sub = l.msg; int cur_idx = 0; int correct_count = 0; foreach (var rel in si.relative_idx_in_line_) { if (cur_idx < 0) { break; } var index = parse_relative_part(sub, rel, ref cur_idx); if (index == null) { return(null); } if (index.Item1 >= 0) { indexes[(int)rel.type] = index; ++correct_count; } } // if we could parse time or date, we consider it an OK line bool normal_line = correct_count == si.relative_idx_in_line_.Count; return(normal_line ? new line(l, indexes.ToArray()) : null); }
// returns null if it can't parse private line parse_line_with_syntax(sub_string l, syntax_info si) { if (si.relative_syntax_) return parse_relative_line(l, si); try { string sub = l.msg; bool normal_line = parse_time(sub, si.idx_in_line_[(int) info_type.time]) && parse_date(sub, si.idx_in_line_[(int) info_type.date]); if (si.idx_in_line_[(int) info_type.time].Item1 < 0 && si.idx_in_line_[(int) info_type.date].Item1 < 0) // in this case, we don't have time & date - see that the level matches // note: we can't rely on level too much, since the user might have additional levels that our defaults - so we could get false negatives normal_line = parse_level(sub, si.idx_in_line_[(int) info_type.level]); return normal_line ? new line(l, si.idx_in_line_) : null; } catch(Exception e) { logger.Error("invalid line: " + l + " : " + e.Message); //return new line(pos_in_log, l, line_contains_msg_only_); return null; } }
private line parse_relative_line(sub_string l, syntax_info si) { List< Tuple<int,int> > indexes = new List<Tuple<int, int>>(); for ( int i = 0; i < (int)info_type.max; ++i) indexes.Add(new Tuple<int,int>(-1,-1)); string sub = l.msg; int cur_idx = 0; int correct_count = 0; foreach (var rel in si.relative_idx_in_line_) { if (cur_idx < 0) break; var index = parse_relative_part(sub, rel, ref cur_idx); if (index == null) return null; if (index.Item1 >= 0 && index.Item2 >= 0) { indexes[(int) rel.type] = index; ++correct_count; } } // if we could parse time or date, we consider it an OK line bool normal_line = correct_count == si.relative_idx_in_line_.Count; return normal_line ? new line(l, indexes.ToArray()) : null ; }
// if at exit of function, idx < 0, the line could not be parsed private Tuple<int, int> parse_relative_part(string l, syntax_info.relative_pos part, ref int idx) { if (part.is_end_of_string) { // return remainder of the string int at = idx; idx = l.Length; return new Tuple<int, int>(at, l.Length - at); } int start = -1, end = -1; if (part.start >= 0) start = part.start; else { if ( idx >= l.Length) // passed the end of string return null; start = l.IndexOf(part.start_str, idx); idx = start >= 0 ? start + part.start_str.Length : -1; if (start >= 0) start += part.start_str.Length; } if ( idx >= 0) if (part.len >= 0) { end = start + part.len; idx = end; } else { if (part.end_str != null) end = l.IndexOf(part.end_str, idx); else { end = l.Length; if ( part.start_str != null) start -= part.start_str.Length; } idx = end >= 0 ? end + (part.end_str != null ? part.end_str.Length : 0) : -1; } return ( start < l.Length && end <= l.Length) ? new Tuple<int, int>(start, end - start) : null; }
private syntax_info parse_single_syntax(string syntax) { try { if (syntax.Contains("'")) return parse_relative_syntax(syntax); syntax_info si = new syntax_info(); si.idx_in_line_[(int) info_type.time] = parse_syntax_pos(syntax, "time["); si.idx_in_line_[(int) info_type.date] = parse_syntax_pos(syntax, "date["); si.idx_in_line_[(int) info_type.level] = parse_syntax_pos(syntax, "level["); si.idx_in_line_[(int) info_type.msg] = parse_syntax_pos(syntax, "msg["); si.idx_in_line_[(int) info_type.class_] = parse_syntax_pos(syntax, "class["); si.idx_in_line_[(int) info_type.file] = parse_syntax_pos(syntax, "file["); si.idx_in_line_[(int) info_type.func] = parse_syntax_pos(syntax, "func["); si.idx_in_line_[(int) info_type.ctx1] = parse_syntax_pos(syntax, "ctx1["); si.idx_in_line_[(int) info_type.ctx2] = parse_syntax_pos(syntax, "ctx2["); si.idx_in_line_[(int) info_type.ctx3] = parse_syntax_pos(syntax, "ctx3["); si.idx_in_line_[(int) info_type.ctx4] = parse_syntax_pos(syntax, "ctx4["); si.idx_in_line_[(int) info_type.ctx5] = parse_syntax_pos(syntax, "ctx5["); si.idx_in_line_[(int) info_type.ctx6] = parse_syntax_pos(syntax, "ctx6["); si.idx_in_line_[(int) info_type.ctx7] = parse_syntax_pos(syntax, "ctx7["); si.idx_in_line_[(int) info_type.ctx8] = parse_syntax_pos(syntax, "ctx8["); si.idx_in_line_[(int) info_type.ctx9] = parse_syntax_pos(syntax, "ctx9["); si.idx_in_line_[(int) info_type.ctx10] = parse_syntax_pos(syntax, "ctx10["); si.idx_in_line_[(int) info_type.ctx11] = parse_syntax_pos(syntax, "ctx11["); si.idx_in_line_[(int) info_type.ctx12] = parse_syntax_pos(syntax, "ctx12["); si.idx_in_line_[(int) info_type.ctx13] = parse_syntax_pos(syntax, "ctx13["); si.idx_in_line_[(int) info_type.ctx14] = parse_syntax_pos(syntax, "ctx14["); si.idx_in_line_[(int) info_type.ctx15] = parse_syntax_pos(syntax, "ctx15["); si.idx_in_line_[(int) info_type.thread] = parse_syntax_pos(syntax, "thread["); Debug.Assert(si.idx_in_line_.Length == syntax_info.line_contains_msg_only_.Length); return si; } catch { // invalid syntax return null; } }
private syntax_info parse_relative_syntax(string syntax) { syntax_info si = new syntax_info(); si.relative_syntax_ = true; si.relative_idx_in_line_.Clear(); // Example: "$time[0,12] $ctx1['[','-'] $func[' ',']'] $ctx2['[[',' ] ]'] $msg" syntax = syntax.Trim(); while (syntax.Length > 0) { if (syntax[0] != '$') // invalid syntax break; syntax = syntax.Substring(1); string type_str = syntax.Split('[')[0]; info_type type = info_type_io.from_str(type_str); if (type == info_type.max) // invalid syntax break; int bracket = syntax.IndexOf("["); syntax = bracket >= 0 ? syntax.Substring(bracket + 1).Trim() : ""; if (syntax == "") { // this was the last item (the remainder of the string) si.relative_idx_in_line_.Add( new syntax_info.relative_pos { type = type, start = -1, start_str = null, len = -1, end_str = null }); break; } var start = parse_sub_relative_syntax(ref syntax); var end = parse_sub_relative_syntax(ref syntax); si.relative_idx_in_line_.Add( new syntax_info.relative_pos { type = type, start = start.Item1, start_str = start.Item2, len = end.Item1, end_str = end.Item2 }); syntax = syntax.Trim(); } return si; }
private syntax_info parse_relative_syntax(string syntax) { syntax_info si = new syntax_info(); si.relative_syntax_ = true; si.relative_idx_in_line_.Clear(); // Example: "$time[0,12] $ctx1['[','-'] $func[' ',']'] $ctx2['[[',' ] ]'] $msg" syntax = syntax.Trim(); while (syntax.Length > 0) { if (syntax[0] != '$') { // invalid syntax break; } syntax = syntax.Substring(1); string type_str = syntax.Split('[')[0]; string column_alias = ""; if (type_str.Contains("{")) { column_alias = type_str.Substring(type_str.IndexOf("{") + 1).Trim(); column_alias = column_alias.Substring(0, column_alias.Length - 1); // ignore ending } // note: we can't have an alias match a logwizard existing column type - like, "line". That would interfere with how we process the columns if (info_type_io.from_str(column_alias) != info_type.max) { column_alias = "_" + column_alias; } type_str = type_str.Substring(0, type_str.IndexOf("{")).Trim(); } info_type type = info_type_io.from_str(type_str); if (type == info_type.max) { // invalid syntax break; } int bracket = syntax.IndexOf("["); syntax = bracket >= 0 ? syntax.Substring(bracket + 1).Trim() : ""; if (syntax == "") { // this was the last item (the remainder of the string) si.relative_idx_in_line_.Add(new syntax_info.relative_pos { type = type, start = -1, start_str = null, len = -1, end_str = null, column_alias = column_alias }); break; } var start = parse_sub_relative_syntax(ref syntax); syntax = syntax.Length > 0 ? syntax.Substring(1) : syntax; // ignore the delimeter after the number var end = parse_sub_relative_syntax(ref syntax); bool has_min_chars = syntax.StartsWith(";"); syntax = syntax.Length > 0 ? syntax.Substring(1) : syntax; // ignore the delimeter after the number int min_chars = 0; if (has_min_chars) { int idx_next = syntax.IndexOf("]"); if (idx_next >= 0) { int.TryParse(syntax.Substring(0, idx_next), out min_chars); syntax = syntax.Substring(idx_next + 1); } } si.relative_idx_in_line_.Add(new syntax_info.relative_pos { type = type, start = start.Item1, start_str = start.Item2, len = end.Item1, end_str = end.Item2, column_alias = column_alias, min_chars = min_chars }); syntax = syntax.Trim(); } return(si); }
// if at exit of function, idx < 0, the line could not be parsed private Tuple<int, int> parse_relative_part(string l, syntax_info.relative_pos part, ref int idx) { if (part.is_end_of_string) { // return remainder of the string int at = idx; idx = l.Length; //return new Tuple<int, int>(at, l.Length - at); // 1.8.4+ - this way, I can merge a consecutive line into this one return new Tuple<int, int>(at, -1); } int start = -1, end = -1; if (part.start >= 0) start = part.start; else { if ( idx >= l.Length) // passed the end of string return null; start = l.IndexOf(part.start_str, idx); idx = start >= 0 ? start + part.start_str.Length : -1; if (start >= 0) start += part.start_str.Length; } if ( idx >= 0) if (part.len >= 0) { end = start + part.len; idx = end; } else { if (part.end_str != null) // 1.8.12 - care about min chars end = l.IndexOf(part.end_str, idx + part.min_chars); else { end = l.Length; if ( part.start_str != null) start -= part.start_str.Length; } idx = end >= 0 ? end + (part.end_str != null ? part.end_str.Length : 0) : -1; } return ( start < l.Length && end <= l.Length) ? new Tuple<int, int>(start, end - start) : null; }
private syntax_info parse_relative_syntax(string syntax) { syntax_info si = new syntax_info(); si.relative_syntax_ = true; si.relative_idx_in_line_.Clear(); // Example: "$time[0,12] $ctx1['[','-'] $func[' ',']'] $ctx2['[[',' ] ]'] $msg" syntax = syntax.Trim(); while (syntax.Length > 0) { if (syntax[0] != '$') // invalid syntax break; syntax = syntax.Substring(1); string type_str = syntax.Split('[')[0]; string column_alias = ""; if (type_str.Contains("{")) { column_alias = type_str.Substring(type_str.IndexOf("{") + 1).Trim(); column_alias = column_alias.Substring(0, column_alias.Length - 1); // ignore ending } // note: we can't have an alias match a logwizard existing column type - like, "line". That would interfere with how we process the columns if (info_type_io.from_str(column_alias) != info_type.max) column_alias = "_" + column_alias; type_str = type_str.Substring(0, type_str.IndexOf("{")).Trim(); } info_type type = info_type_io.from_str(type_str); if (type == info_type.max) // invalid syntax break; int bracket = syntax.IndexOf("["); syntax = bracket >= 0 ? syntax.Substring(bracket + 1).Trim() : ""; if (syntax == "") { // this was the last item (the remainder of the string) si.relative_idx_in_line_.Add( new syntax_info.relative_pos { type = type, start = -1, start_str = null, len = -1, end_str = null, column_alias = column_alias }); break; } var start = parse_sub_relative_syntax(ref syntax); syntax = syntax.Length > 0 ? syntax.Substring(1) : syntax; // ignore the delimeter after the number var end = parse_sub_relative_syntax(ref syntax); bool has_min_chars = syntax.StartsWith(";"); syntax = syntax.Length > 0 ? syntax.Substring(1) : syntax; // ignore the delimeter after the number int min_chars = 0; if (has_min_chars) { int idx_next = syntax.IndexOf("]"); if (idx_next >= 0) { int.TryParse(syntax.Substring(0, idx_next), out min_chars); syntax = syntax.Substring(idx_next + 1); } } si.relative_idx_in_line_.Add( new syntax_info.relative_pos { type = type, start = start.Item1, start_str = start.Item2, len = end.Item1, end_str = end.Item2, column_alias = column_alias, min_chars = min_chars }); syntax = syntax.Trim(); } return si; }