DFSR Debug Analysis with Message Analyzer – Part 5, Parsing Multi-line Messages
This post continues the series that started here.
Today I want to continue to demonstrate the development of my DFSR debug log parser for Message Analyzer by extending the message handling to multi-line messages. Multi-line messages appear as follows –
20120522 11:01:19.265 1824 VDSN 649 [WARN] VdsAdviseSink::InitializeCache (Ignored) Unable to retrieve volume's GUID. Volume will not be added to the cache. This could be a CD ROM. Error:
+ [Error:9225(0x2409) VolumeIdTable::GetVolumeIdFromVolumeNotification context.cpp:1440 1824 C The volume was not found]
+ [Error:9225(0x2409) VolumeIdTable::GetVolumeIdFromVolumeNotification context.cpp:1437 1824 C The volume was not found]
In other words, the message starts just the same as a single-line message (Date stamp, time stamp, etc.) but for long messages, they’re continued by prefixing the following line(s) with a + and then some whitespace.
Let’s go back to the message definition I had earlier (RegEx removed for clarity) but add generic handling for multi-line messages –
message DfsrMessage with
EntryInfo { Regex = @"REGEX_REMOVED_FOR_CLARITY", Multiline = parseMultiLine},
DisplayInfo { ToText = GetSimpleSummaryText } : DfsrTimeStamp
{
uint Thread;
string ModuleID;
uint SourceCodeLine;
string Namespace;
string Class;
string Method;
string Level;
string MessageText;static string GetSimpleSummaryText(any d)
{
var e = d as DfsrMessage;
return e.MessageText;
}
bool parseMultiLine(string line, LineContext context)
{
if (context.IsInitialLine)
{
// initial line is already matched by the
// regular expression and captured into MessageText
// Here we return true to indicate we want
// to see more lines
return true;
}
else
{
// line starting with "+" is considered continuation
// of the current message
if (line.Count > 0 && line[0] == '+')
{
MessageText = MessageText + " " + (line.Segment(1)).Trim();
return true;
}
else
{
return false;
}
}
}
}
In this example, REGEX_REMOVED_FOR_CLARITY would be replaced with the RegEx statement that I ended on in Part 2 of this series.
You’ll see I’ve added Multiline = parseMultiLine to the EntryInfo in the message definition, telling Message Analyzer to treat every message as a possible multi-line message and to call into parseMultiline() .
parseMultiline() first checks whether the line is already handled by the EntryInfo RegEx –
if (context.IsInitialLine)
{
return true;
}
If it’s not the initial line, parseMultiline() checks for a + indicating a multi-line continuation and then strips away the + and any whitespace, appending it to the MessageText field. If the line doesn’t begin with + , return false so that the line is re-evaluated against all message definitions –
else
{
if (line.Count > 0 && line[0] == '+')
{
MessageText = MessageText + " " + (line.Segment(1)).Trim();
return true;
}
else
{
return false;
}
}
The Result
With the parser updated, loading a DFSR debug log that includes multi-line messages results in the following –
Limitations
This is a good start but it doesn’t account for multi-line messages which contain field data in the message continuation. For example –
20120522 11:01:55.858 2600 JOIN 1201 Join::SubmitUpdate LDB Updating ID Record:
+ fid 0x200000000F503
+ usn 0x600d5e48
+ uidVisible 1
+ filtered 0
+ journalWrapped 0
+ slowRecoverCheck 0
+ pendingTombstone 0
+ internalUpdate 0
+ dirtyShutdownMismatch 0
+ meetInstallUpdate 0
+ meetReanimated 0
+ recUpdateTime 20120522 00:31:11.500 GMT
+ present 1
+ nameConflict 0
+ attributes 0x20
+ ghostedHeader 0
+ data 0
+ gvsn {5442ADD7-04C7-486B-B665-2CB036997A67}-v899394
+ uid {5442ADD7-04C7-486B-B665-2CB036997A67}-v598754
+ parent {8A6CF487-2D5A-456C-A235-09F312D631C8}-v1
+ fence Default (3)
+ clockDecrementedInDirtyShutdown 0
+ clock 20120522 00:31:11.500 GMT (0x1cd37b230245303)
+ createTime 20120516 00:30:40.306 GMT
+ csId {8A6CF487-2D5A-456C-A235-09F312D631C8}
+ hash 3C379B81-28E4F2A8-52F091A5-0D4CFAB8
+ similarity 2E233A14-253F363F-3E110515-22120C04
+ name file0000004161.txt
+
Next Up