Custom Readers

When learning to create custom readers 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 readers are the most advanced LogViewPlus extension type. Custom readers can be used when you need to import data into LogViewPlus from a data source that is not a text file. A custom reader might be used to access the database, read information off the network, or decode the data stored in a custom binary format (for example, a Protobuf log file).

Most custom readers will be environment specific. In an effort to simplify the deployment of our custom reader, we have decided to simply create a new log entry on a timer tick. This example is not very helpful in a real-world scenario but it does effectively show how to create a custom reader while simplifying the deployment and learning curve.

If we look at the code included in the CustomReader project and remove all of the comments, we can see the custom reader implementation is divided into three parts. First, there is the code which generates the log entries. This code is relatively straight forward.

Our class has three private variables:

_entriesProcessed - This integer will keep track of the number of log entries which have been created. This number may be useful in certain debugging scenarios.

_timer - The timer is used to simulate new log entries coming into the system. Note that in the above example our timer has not yet been started.

_cache - Our cache is a list of log entries that have been created. We will need to manage our cache as part of our ILogReader implementation. Some aspects of our ILogReader implementation may be called on a separate thread. Therefore we need to control access to the cache with a lock.

The main method in our custom log reader implementation is the OnTimerTick event. This is the event that will generate our new log entries. We can see from the example above that our log entries should have the columns date, priority, logger, and message. Our custom log reader implementation is creating a simple log entry which echoes the reader configuration back to the user.

The next method in our custom log reader implementation is the GetSupportedTypes method.

The GetSupportedTypes method is required when we are implementing the IColumnManagement interface. This method is responsible for returning the column definitions for our data set. Implementation of this interface is not strictly required, however if we do not implement this interface we will not be able to see any columns for our parsed log entries. Therefore, most real-world examples will require an implementation.

The remaining methods in our CustomReader implement the ILogReader interface. It is important to note that the ILogReader interface is optimized for the scenario where we are reading log files in batches to allow for improved performance.

There are four features that the ILogReader interface will allow us to control.

Progress bars
LogViewPlus can use either a normal progress bar or a marquee progress bar when loading a new log file. Use a marquee progress bar when the total number of log entries is unknown. To use a marquee progress bar set the AllowProgressTracking field to false.
The LogViewPlus progress bar will only be shown when opening our log file.
Argument initialization
If our custom reader needs to be configured (AcceptsConfiguration), we can call Initialize with a list of arguments followed by GetWarnings to get a list of messages to be displayed to the user. Initialization arguments can use Argument Templates.
Batch processing
When a tail file event occurs in LogViewPlus we will check if we are at the end of the log file. If not we will get the next batch of log entries and immediately check if further entries are pending with HasNextBatch. If HasNextBatch returns false we will wait for the next tail file event in LogViewPlus.
Reader Initialization
The InitializeRead method is responsible for initializing our log reader based on the given file. In our case, the given file contains configuration that we need to execute our log reader. Note that this configuration file will be the file selected by the end user when trying to run our log reader. Using a configuration file as the target "log file" when opening a non-file based log reader is the recommended approach. Using this approach our log file access history will be managed automatically.

Once we have built our custom log reader and copied the resulting binaries into the LogViewPlus Plugins directory, we are ready to test. To do this start LogViewPlus, open Application Settings -> Reader Mappings and add the configuration shown.

After you have saved your settings, open the MyReaderConfig.log file which is included in the sample code distribution. Assuming tail is enabled you should see a new log entry appear approximately every second.

If you were to temporarily disable tail and then re-enable it, all of the log entries missed during the time interval will be shown.

< >