public bool TryParse(string line, RegexPattern regex, out AnalogyLogMessage message) { try { Match match = Regex.Match(line, regex.Pattern, RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace); if (match.Success) { var m = new AnalogyLogMessage(); foreach (var regexMember in regexMapper) { string value = match.Groups[regexMember.Key].Success ? match.Groups[regexMember.Key].Value : string.Empty; switch (regexMember.Value) { case AnalogyLogMessagePropertyName.Date: if (!string.IsNullOrEmpty(value) && DateTime.TryParseExact(value, regex.DateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out var date)) { m.Date = date; } continue; case AnalogyLogMessagePropertyName.Id: if (!string.IsNullOrEmpty(value) && Guid.TryParseExact(value, regex.GuidFormat, out var guidValue)) { m.Id = guidValue; } continue; case AnalogyLogMessagePropertyName.Text: m.Text = value; continue; case AnalogyLogMessagePropertyName.Category: m.Category = value; continue; case AnalogyLogMessagePropertyName.Source: m.Source = value; continue; case AnalogyLogMessagePropertyName.Module: m.Module = value; continue; case AnalogyLogMessagePropertyName.MethodName: m.MethodName = value; continue; case AnalogyLogMessagePropertyName.FileName: m.FileName = value; continue; case AnalogyLogMessagePropertyName.User: m.User = value; continue; case AnalogyLogMessagePropertyName.LineNumber: if (!string.IsNullOrEmpty(value) && int.TryParse(value, out var lineNum)) { m.LineNumber = lineNum; } continue; case AnalogyLogMessagePropertyName.ProcessId: if (!string.IsNullOrEmpty(value) && int.TryParse(value, out var processNum)) { m.ProcessId = processNum; } continue; case AnalogyLogMessagePropertyName.ThreadId: if (!string.IsNullOrEmpty(value) && int.TryParse(value, out var threadNum)) { m.ThreadId = threadNum; } continue; case AnalogyLogMessagePropertyName.Level: switch (value) { case "OFF": m.Level = AnalogyLogLevel.None; break; case "TRACE": m.Level = AnalogyLogLevel.Trace; break; case "DEBUG": m.Level = AnalogyLogLevel.Debug; break; case "INFO": m.Level = AnalogyLogLevel.Information; break; case "WARN": m.Level = AnalogyLogLevel.Warning; break; case "ERROR": m.Level = AnalogyLogLevel.Error; break; case "FATAL": m.Level = AnalogyLogLevel.Critical; break; default: m.Level = AnalogyLogLevel.Unknown; break; } continue; case AnalogyLogMessagePropertyName.Class: if (string.IsNullOrEmpty(value)) { m.Class = AnalogyLogClass.General; } else { m.Class = Enum.TryParse(value, true, out AnalogyLogClass cls) && Enum.IsDefined(typeof(AnalogyLogClass), cls) ? cls : AnalogyLogClass.General; } continue; case AnalogyLogMessagePropertyName.MachineName: m.MachineName = value; break; case AnalogyLogMessagePropertyName.RawText: m.RawText = value; break; case AnalogyLogMessagePropertyName.RawTextType: m.RawTextType = AnalogyRowTextType.PlainText; break; default: throw new ArgumentOutOfRangeException(); } } message = m; return(true); } message = null; return(false); } catch (Exception e) { string error = $"Error parsing line: {e.Message}"; Logger?.LogException(error, e, nameof(RegexParser)); message = new AnalogyLogMessage(error, AnalogyLogLevel.Error, AnalogyLogClass.General, nameof(RegexParser)); return(false); } }