Custom Analyzers

When learning to create custom analyzers 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.

Beginning in LogViewPlus 2.3.5, we introduced the ILogAnalyzer interface.  This interface is both really simple and incredibly powerful.  It takes an IWin32Window parent object as well as a list of all of the LogEntries found in the current view.  This lets you execute a custom analysis on a set of log entries and potentially display your analysis in a custom reporting window. 

public interface ILogAnalyzer
{
     void Analyze(object ownerWindow, IReadOnlyList<LogEntry> logEntries);
}

As discussed, the API has two parts:

OwnerWindow - An IWin32Window object which can be used to display a child form.  The type is set as object for simplicity, but the object can be safely cast if needed.

IReadOnlyList<LogEntry> - The full list of all log entries shown in the current view.  The data received by your implementation will be dependent on which view is used to execute the analyzer.

This interface will always be called from the UI thread.  This allows you freely create UI components and control the user experience by blocking if necessary.

Our sample projects contain several examples of using the ICustomConfiguration interface.  For our discussion, we will focus on the implementation contained in MyParser.cs.  This implementation simply calls into a new OpenFileDialog instance - this keeps the GUI aspects of this configuration simple.

MyParser implements the following ICustomConfiguration.Configure method:

public void Analyze(object ownerWindow, IReadOnlyList<LogEntry> logEntries)
{
     var owner = (IWin32Window)ownerWindow;
     if (logEntries == null || logEntries.Count == 0)
     {
          MessageBox.Show(owner, "No log entries found.", "No Entries",
                               MessageBoxButtons.OK, MessageBoxIcon.Information);
          return;
     }

     var first = logEntries.First();
     var last = logEntries.Last();

     LogEntry largest;
     var a1 = CalculateAverageElapsed(logEntries, out largest);
     var a2 = CalculateAverageElapsed(first, first.FindNext(LookupSource.CurrentFilter, null));
     var a3 = CalculateAverageElapsed(last, last.FindPrevious(LookupSource.CurrentFilter, null));

     var result = MessageBox.Show(owner, $"Average time between log entries:" +
                         "\r\n({a1})\r\n({a2})\r\n({a3})\r\n\r\n" +
                          "Would you like to show the largest value?",
                         "Average Elapsed", MessageBoxButtons.YesNo,
                          MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);

     if (result == DialogResult.Yes)
     {
          ((ILogViewer)owner).FindLogEntry(largest);
     }
}

Here we cast our ownerWindow to an IWin32Window and use this as the parent for a MessageBox which just displays some basic statistics. 

One interesting thing to note about the code sample above is that it uses the FindNext / FindPrevious methods to navigate the current view.  These methods could also be used to navigate the parent filter, or the source log file.  As this is just an example, all three calculation methods produce the same result.

Beginning with LogViewPlus 2.4.30, you can also cast the IWin32Window owner object into an ILogViewer for additional functionality.  For example, in the latest sample code, we use the ILogViewer interface to optionally find and select a given log entry.  This functionality is currently only available in ILogAnalyzer implementations.  Other custom extension types are not supported.

Implementing custom configuration in LogViewPlus is relatively simple. If you have any questions or comments please feel free to contact us.


< >