Custom Parsers

When learning to create custom parsers for LogViewPlus it is helpful to begin with the sample code projects.  This tutorial will assume that you have downloaded and run the sample projects successfully. Please see running the samples for more information.

Custom parsers are helpful when your log files are stored as text data, but the text data cannot be parsed easily by one of the installed LogViewPlus parsers. For example, if your log files used a proprietary text-based data format.

Our custom parser implementation will be responsible for parsing a very simple log file which should be written in the format %d{yyyy-MM-dd HH:mm:ss,fff} - %m%n.  Note that LogViewPlus is already capable of parsing log files in this format. Therefore our custom parser will provide no functional benefit. However, it would likely have a performance benefit - although this is not been tested.

If we look at the code included in the CustomParser project and remove of the comments, we can see the custom parser implementation is straightforward.

public class MyParser : ILogParser
{
     public string Arguments { get; private set; }

     public bool AcceptsConfiguration()
     {
          return true;
     }

     public void Initialize(string arguments)
     {
          Arguments = arguments;
     }

     public List<string> GetWarnings()
     {
          return new List<string>();
     }

     public bool IsLogEntry(string logLine)
     {
          if (string.IsNullOrEmpty(logLine))
               return false;

          return logLine.IndexOf(" - ", StringComparison.Ordinal) >= 0;
     }

     public ParseResult Parse(string logLine, LogEntry newEntry)
     {
          int pos = logLine.IndexOf(" - ", StringComparison.Ordinal);
          if(pos <= 0)
               return ParseResult.Fail;

          var date = logLine.Substring(0, pos);
          var msg = logLine.Substring(pos + 3);

          newEntry.Date = DateTime.ParseExact(date, "yyyy-MM-dd HH:mm:ss,fff", CultureInfo.CurrentCulture);
          newEntry.Message = msg;
          return ParseResult.Success;
     }
}

Note that MyParser is a sample implementation of the ILogParser interface:

public interface ILogParser
{
     string Arguments { get; }
     bool AcceptsConfiguration();
     void Initialize(string arguments);
     List<string> GetWarnings();
     bool IsLogEntry(string logLine);
     ParseResult Parse(string logLine, LogEntry newEntry);
}

public enum ParseResult
{
     Success,
     Fail,
     ContinueRead,
     EndRead
}

This interface has four parts:

GetDescription - This method will return a description for our parser. This description will be displayed to the user in the tooltip that is displayed when the user hovers over a log file.

Initialize - A custom parser is initialized with a string that is provided by the user when creating the parser. Providing a initialization string to a custom filter is optional as some parsers may not need initialization.  Initialization arguments can use Argument Templates

If your parser implements ICustomConfiguration, the Parser Arguments will be shown with a configuration command which calls back into your code to display a configuration dialog.  Please see Custom Configuration for more information.

IsLogEntry - Given a line of text, this method is responsible for determining whether or not the line is the beginning of a new log entry.  Our (overly simplistic) example simply checks whether the line has the text " - " in it.  While this is fine for our example it probably wouldn't work in a production system because a long line may have the text " - " unexpectedly as part of its log message.  It would be better to check both the date and the static text.

Parse - This method is responsible for parsing the given log line and saving the result into the provided log entry. Note the log entry may span multiple lines.  You can control the way the log entry is parsed by managing your parse result.  A parse result could have one of four values:

Parse Result
Description
Success
Success is a signal to the parser controller that you have been able to identify the start of a new log entry.  The next few lines in the log file may be part of the same entry. In order to determine whether the next line in the log file is part of the same log entry, LogViewPlus will call the IsLogEntry method previously discussed.  If the IsLogEntry method returns false, the line will be appended to the message field of this log entry.  If IsLogEntry returns true, the parse method will be called again for the same log line.
 
This is the basic processing loop for parsing a log file.
 
Fail
Fail is a signal to the parser controller that the given log file line does not represent the beginning of a log entry. This may be the case, for example, if you are partially opening a log file and have started reading from the middle of the file.  LogViewPlus may try to recover by ignoring the failure for a period of time and attempting to continue processing the file.
 
ContinueRead
ContinueRead is a signal to the parser controller that we do not yet have enough information to process this log entry and will need (at a minimum) the next log line.  This field is used, for example, by the XML parser because XML log entries may span multiple lines before the entry can be parsed.
 
EndRead
EndRead is a signal to the parser controller to terminate processing of this log entry and start over with the next entry.  It is helpful when reading from the middle of a log file when you know where your log entry begins and ends.  This field is used, for example, by the Log4XmlParser to signal that the current entry should be discarded and we should start fresh on the next line.
 
An exception is thrown
The result of throwing an exception from within the Parse method is dependent on what LogViewPlus is trying to do.  If LogViewPlus is trying to do something complicated like a partial read - exceptions may be expected.  In this case parsing may continue.
 
However, generally speaking, the exception will be raised and the application will crash.  You should therefore try to catch and handle exceptions internally.

As you can see, creating a custom parser for LogViewPlus is relatively simple. If you have any questions or comments please feel free to contact us.


< >