LogWatcher

Version 0.0.3.2
by Daniel Wesslén

Frequently Asked Questions

Q What does this program do?
A LogWatcher monitors log files and other file activity in the system and notifies the user when certain events occur using the PopUp and NotifyAnything plugins.

Requirements

Writing Your Own Watcher

First of all, in order to write a useful watcher you must be able to write regular expressions, this Perl regular expression tutorial is a good starting point. LogWatcher uses the boost::regex library for pattern matching so the best reference to the expression syntax used in LogWatcher is the boost::regex syntax reference, the extended syntax with Win32 localization is used.

A watcher is the combination of an event generator and one or more pattern matching scripts, called handlers. When something interesting happens, the event generator sets a few variables describing the event and starts the associated handler. The handler will process the event and perform the specified actions.

The easiest way to get an understanding of how watchers work is probably to take a look at the provided ones. Setting the log level to "debug" will allow you to see what is going on by reading the logfile.

Variables

Every event has a number of variables associated with it, describing what actually happened. Variables set by the user are persistent across invocations of the handler but local to the object associated with the event (file or event log), automatically set variables will be overwritten each time an event is generated. Variables with "number names", e.g. 0, 1, 2 ... are automatically assigned when matching regular expressions.

Variable Substitution

Some attributes are subject to variable substitution. When the value of such an attribute is required, all occurences of %varname% will be replaced by the contents of the variable varname. If varname has not been set, the empty string is substituted.

In order to produce the '%' character in the attribute value, use %%.

When a variable is substituted inside a regular expression, the inserted value is considered to be an atomic string, i.e. %varname%{2} will match the value of varname twice.

Miscellaneous

Target

Defines a name for a target computer and port number, or an alias for previously defined targets. Messages are aimed at one or more targets. If not overridden by the user, the target named 'default' is used.

<target name='string' [host='name' port='number' [protocol='tcp|udp'] [password='string']] [alias='targets'] />

Import

Not an actual event generator, but it may be used to import one from a separate file. Any attributes except file will override attributes in the root element in the imported file.

<import file='filename' />

Property

May be used to change the default values of attributes. Parameter nodes are processed at load time. All instances of the specified handler without an explicit attribute value will be given the new default value.

<property id='handler:attribute' value='default' />

Event generators

Event generator nodes may be placed at top level within the <settings> node in the main configuration file or as a root element in a file to be <import>ed to the main configuration file.

Eventlog

Will monitor Windows NT event logs. The system has three builtin logs, Application, Security and System. Custom logfiles can also be used.

<eventlog [delay_start='number'] [discard_time='number']>
    <log name='event log name'>
    <!-- handlers -->
    </log>
<!-- more <log> nodes -->
</eventlog>
Attributes
Option Default Description
delay_start 0 When the computer is started, a large amount of event log records are generated, if LogWatcher is set to start automatically it may recieve notification of these, resulting in an equally large number of popups being generated. To avoid this problem, the delay_start attribute specifies the number of seconds to wait before starting to generate events.
discard_time Event log records are sometimes left behind due to insufficient flushing and may then appear together with the next event. If discard_time is set, events older than the given number of seconds are ignored.
Events

Events are generated each time a new record is appended to the monitored event log.

Variable Value Description
source string Name of the service or application that generated the event.
message string The message.
type error|warning|information|audit success|audit failure The type of event.
time hh:mm:ss The time the event was generated.
date yyyy:mm:dd The day the event was generated.
computer string Name of the computer on which the event was generated.

Time

Generates one event every minute.

Variable Value Description
hour hh
minute mm
weekday d 0-6, Sunday = 0.
monthday dd
month mm
year yyyy
yearday ddd

Filewatch

Monitors file events.

<filewatch directory='path' [subtree='yes|no'] [files='regex']
[idle_time='number'] [watch_lines='yes|no']>

    <!-- handlers -->
</filewatch>
Attributes
Attribute Default Description
directory The path to the directory in which file events will be tracked.
subtree no Whether or not events in subdirectories should be tracked as well.
files If provided, the handler will only be invoked for files matching this pattern. The pattern is case-insensitive and anchored in both ends.
idle_time The number of seconds that must pass for an idle event to be generated. If the argument is not provided, no idle or resumed events will be generated.
watch_lines no If enabled, line events are generated when files are modified. The files attribute is required if watch_lines is enabled.
Events

Events are generated each time a file is created, deleted, renamed, moved or, depending on attributes, modified.

Variable Value Description
what added|removed|renamed_old|
renamed_new|idle|resumed|line
The type of event.
file path The path name of the file for which the event was generated, relative to dirname.
dirname path The value of the directory attribute.
line string Only set if watch_lines=yes, the line that was appended to the file.

Handlers

Block

The simplest handler. It has no function but to execute the contained handlers and to provide an extra nesting level when needed.

<block>

<!-- handlers -->
</block>

Break

Execution will break out of the specified number of levels.The default is to break out of the current level.

<break levels='number|all' />
Argument Default Substitute Description
levels Yes The number of block levels to break out from.

Set

The variable with the specified name will be set to the given value.

<set var='name' value='string' />
Argument Default Substitute Description
var No The name of the variable to set.
value Yes The new value.

Send

Send a message describing a popup to NotifyAnything.

<send raw='message' />
<send text='message' [from='name'] [opt:option='string']... [fg='color'] [bg='color']
[beep='yes|no'] [icon='icon locator'] [type='notification|message|error']
[id='string' [replace='yes|no|append|prepend']] [target='name(s)'] />
Argument Default Substitute Description
raw Yes A message string to send. May not be combined with text, all other attributes are ignored.
text Yes Message text. (First line in popup.)
from Yes Contact name. (Second line in popup.)
opt:option Yes

Anything. The NotifyAnything message option named option will be set to the given value.

See the NotifyAnything documentation for a list of options. Future options will usually not be given a custom <send> attribute; they will instead be supported by this feature.

fg Yes Foreground color.
bg Yes Background color.
beep Yes Whether or not NotifyAnything should generate a beep. The user may override this setting.
icon Yes

Either of:
path\filename.ico
path\dll_or_exe,number
path\dll_or_exe,resource_name

type notification Yes Selects presets for the other attributes.
id Yes Identification string for the message popup.
replace Yes Edit a previous message.
target default No Comma-separated list of target names that will receive the message.

Match

If input matches the pattern, the contained handlers will be executed. The text matching parenthesized subexpressions will be assigned to variables 1, 2, 3 ... ordered from left to right. The entire matching section of input will be assigned to variable 0.

<match input='string' pattern='regex' [exact='yes']
[match_case='yes|no'] [anchor='no|left|right|both']>
<!-- handlers -->
</match>
Argument Default Substitute Description
input Yes Text to match against pattern.
pattern Yes A regular expression.
exact No Alias for match_case=yes and anchor=both.
match_case no No If yes, then matching is case-sensitive.
anchor no No Specifies if the pattern should be anchored to either side of the input.

Switch

Execute the case handler where input matches the value, if none matches and a default handler is defined, execute it instead.

<switch input='string' [match_case='yes|no']>
<case value='string'>
<!-- handlers -->
</case>
<!-- more cases -->
[<default>
<!-- handlers -->
</default>]
</match>
Argument Default Substitute Description
input Yes Text to match against the case values.
match_case no No If yes, then matching is case-sensitive.

Loop

Execute the contained handlers count times.

The loop spans two break levels. If it is reached at level 1 the next iteration will be handled. If it is reached at level 2 or above the loop will be terminated and the break level will be decremented by two.

<loop count='number'>
<!-- handlers -->
</loop>
Argument Default Substitute Description
count No The number of times the contained handlers should be executed.

Options

A few options are avaliable, these should be given as attributes of the root element in the main configuration file.

Option Value Default Description
log no|yes|debug no The amount of logging. no = none, yes = program status, debug = trace watchers
control_port number 12002 The port to listen for control messages on.

Remote Control

LogWatcher may be controlled by sending UDP messages to the control port. The currently supported messages are "ping", "stop" and "restart". Stop and restart will cause LogWatcher to perform the action. Ping will send a "Pong" message to the default target, if an error dialogue is currently open the error message will be included in the pong message. Control messages are only accepted on 127.0.0.1, meaning that they must be sent from the same computer.

Version History

0.0.3.2
  • Can now send messages through TCP as well as UDP.
  • Support for NotifyAnything passwords.
0.0.3.1
  • Bugfix: Date in log file was one month behind.
  • Bugfix: The wrong message would be used when a very long eventlog message was generated.
0.0.3.0
  • Added ability to send messages to remote computers and to multiple targets.
  • Added "type" variable to event log events.
  • Minor changes in watchers.
  • More example watchers included.
  • Bugfix: Fixed a problem causing the contents of variables referenced in the msg attribute of <send> to be expanded twice.
0.0.2.9
  • Added <loop> handler.
  • The download watcher no longer removes DC++ name mangling from files in subdirectories.
  • Bugfix: Fixed a problem when the separator occured in the text attribute of <send>.
0.0.2.8
  • Added the <time> event generator, which can be used to schedule popups.
  • Improved the FTP client and Serv-U watchers.
  • Unicode support everywhere.
  • No longer misses the first line when the first thing written to a watched file is a batch of lines.
  • Added "ping" control message and enabled remote control during loading.
0.0.2.7
  • Added indirect support for all current and future NotifyAnything message options.
0.0.2.6
  • Added parsing of numerical XML character references.
  • Added support for the NotifyAnything options "id" and "replace".
  • The DC++ private message watcher now supports multiline messages.
  • Improved FTP watching.
  • Bugfix: Attribute overrides now work correcly when a file is imported multiple times.
  • Bugfix: match_case='no' now works.
0.0.2.5
  • Rewrote line tracking to avoid some problems with FlashFXP.
  • Replaced the SmartFTP watcher with a generic FTP client watcher.
  • Improved logging.
  • Added <property> tag for changing default attribute values.
  • Bugfix: Another file locking bugfix. Only noticeable if a watched log file was deleted.
  • Bugfix: Logging of matches.
0.0.2.4c
  • Bugfix: Fixed a file locking bug that was causing problems with FlashFXP.
0.0.2.4b
  • Bugfix: Another wrong error reported-fix.
0.0.2.4
  • Added logging.
  • Now controllable by UDP messages (use sendlog).
  • Now works with Winsock 2.0.
  • The NotifyAnything port number is configurable.
  • Included a Serv-U log file watcher.
  • Bugfix: More robust to interference by firewalls.
  • Bugfix: The wrong error message was reported in one case.
0.0.2.3
  • Fixed the bugs in the Kerio PF handler, which now gives more detailed reports as well.
  • Increased the value of delay_start in the provided event log watcher, it should now work for everybody without a really slow computer.
  • Can now handle unicode files.
  • Included SmartFTP log file watcher.
  • Fixed the spurious idle event bug.
0.0.2.2
  • Fixed the problem with a dialog box being displayed when a program for which an event log message was displayed cannot find a required dll (very rare).
  • Updated documentation.
0.0.2.1
  • The delay_start attribute now woks as expected.
  • Fixed the bug that would cause events to be generated for partially written lines.
  • Surplus newline characters are removed from the end of event log messages.
  • Time and date of event log records is provided.
  • Added option to ignore event log records that were left behind due to insufficient flushing.
0.0.2.0
  • Completely redesigned, custom event handlers may now be written using a small scripting language with regular expression matching capabilities.
  • Better documentation.
  • Fixed the file locking problem that made it impossible to rename a file within a watched folder.
  • Many minor changes.
0.0.1.3
  • Moved LogWatcher to a separate package.
0.0.1.1
  • Fixed a small bug that made the Kerio PF LogWatcher useless.

Known Bugs

There are problems when using some text encoding formats. The workaround is to either stick to ANSI characters or use Unicode files, UTF-8 with international characters will usually not work properly.