Project Description
Sentinel is a log-viewer (implemented in WPF) with configurable filtering and highlighting (foreground/background colours).
A classification system allows messages to be parsed and recomposed prior to display.
Includes support for being a log4net UDP Appender target.

Sentinel

Log Sources

Sentinel is intended to be a viewer for log-files from multiple sources. These may be combined into a single view, but multiple views are also supported.

Source Status
Log4Net UdpAppender Supported since 0.8.0.0
nLog's nLogViewer Supported in 0.8.1.0
Trace Listener Planned
Log-File Watcher 0.9.0.0 (experimental)
Custom, via plug-in Planned

Command-Line usage

Until saving session information is implemented correctly, it can be a pain to constantly be greeted by the configuration wizard every time you start up. To overcome this, command-line options have been created that will allow the most common configurations to be specified (and put into a short-cut):

    sentinel <nlog|log4net> <udp|tcp> <portNumber>


For example, an nLog UDP listener on port 9999:

    sentinel nlog udp 9999

nLog's NLogViewer target configuration

To allow a nLog based application transmit its log messages to Sentinel, use a configuration like the one shown below:
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <targets>
    <target xsi:type="NLogViewer"
            name="viewer"
            address="udp://127.0.0.1:9999"/>
  </targets>
  <rules>
    <logger name="*"
            minlevel="Debug"
            writeTo="viewer" />
  </rules>
</nlog>

Log4Net UdpAppender configuration

To allow a log4net application transmit its log messages to Sentinel, use a configuration like the one shown below:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="log4net"
             type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
  </configSections>

  <log4net>
    <appender name="udp"
              type="log4net.Appender.UdpAppender">

      <RemoteAddress value="127.0.0.2"/>
      <RemotePort value="9999"/>
      <layout type="log4net.Layout.XmlLayout"/>
    </appender>

    <root>
      <appender-ref ref="udp"/>
    </root>
  </log4net>
</configuration>

Log Entries

Log file entries map the the following interface. This is core record for a log-file entry and used to populate the columns within the live-log view. Note, by using Classifiers it is possible to rearrange and/or change the content of these fields upon receiving a new log-entry.

public interface ILogEntry
{
    string Classification { get; set; }
    DateTime DateTime { get; set; }
    string Description { get; set; }
    string Source { get; set; }
    string System { get; set; }
    string Thread { get; set; }
    string Type { get; set; }
}
Log entries may be classified, highlighted and filtered based upon special services:
  • Classifiers can change the properties of a log entry
  • Highlighters can change its appearance.
  • Filters can be used to suppress the displaying of matching entries.

Classifiers

Upon receiving a new log-entry it is processed through registered classifiers. Classifiers have the ability to rewrite the log-entry prior to passing it to the visualisation aspect of Sentinel. At the moment, the addition of new Classifiers is not possible without going into the code itself, this is a planned feature.

As an example, suppose the incoming message when starting with the phrase "Sleeping for another" is intended to be switched from its supplied type (e.g. DEBUG or INFO) to its own type Timing. The ClassifierViewModel registers this on construction. Note that the regular expression below also rewrites the Description to the named-capture description, effectively stripping off the prefix "Sleeping for another" - information no longer needed due to the reclassification.

items.Add(
	new DescriptionTypeClassifier("Timing", "Timing")
		{
			Enabled = true,
			Name = "Timing messages",
			RegexString = @"^Sleeping for another (?<description>[^$]+)$"
		});
In addition to reclassifying messages, the Classifier mechanism is currently used to make other changes to the message appearance. Continuing the example above, using a TypeImageClassifier it is possible to specify the image to be used for entries with a type of Timing.

items.Add(
	new TypeImageClassifier("Timing", "/Resources/Clock.png")
		{
			Enabled = true,
			Name = "Timing Image",
		});
The classifiers can be seen in the Preferences dialog-box (although Add/Edit/Remove currently do not have registered handlers).

Preferences - Classifiers

Highlighters

Customisable and extendible highlighters that may be toggled on and off during live preview. The current implementation limits pattern matching to the Type and System fields, although this will be extended to all fields. An example of why this is useful, in the classifiers section above, a new type of "Timing" was added, this type can get its own highlighting style.

Preferences - Highlighters

Highlighters can match the contents of the Type and System fields
  • Exact Strings
  • Substrings
  • Regular Expressions

Adding Regex Highlighter

If the matching field is set to Type an the match string specified as "Timing", a new highlighter for the timing can be added. User-defined highlighters are automatically added to the toolbar for ease of enabling and disabling of the highlighting.

Toolbar - User defined highlighters

The highlighters work on a first-come, wins principle. Therefore, the order of the entries in the highlighters section of the Preferences dialog-box are important. It is possible to hide the highlighting of FATAL messages if a highlighter is positioned before FATAL and gets a match.

Filters

Filters are very much like highlighters except their purpose is to remove log-entries from the displayed values (note, the values are not lost, just hidden). Filters may be toggled on and off during the session. Filters are evaluated in the order specified, but since filters works on an any-match = hide principle the evaluation stops on the first match, resulting on the entry being hidden. Note, this means that messages displayed have travelled through ALL of the filters without being matched, this isn't a cost free aspect, so be careful about how many enabled filters you have!

Last edited Jun 21 at 10:54 AM by yarseyah, version 15