The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

		       Demonstration of Log Tail

This demonstration script illustrates Stem's ability to monitor log
files.  It showcases the Stem modules Stem::Log (which logs messages)
and Stem::LogTail (which checks files for changes/updates).  This
demonstration runs two hubs named archive and monitor.  The monitor
hub watches a particular log file for changes.  When a change occurs,
messages are sent to the archive hub to be logged.  The archive
hub records the contents of the monitored log file (sent by the
monitor hub) and also records status messages sent by the monitor
hub.  Log messages that are recorded by the archive hub can be
stored as either raw data or with custom formats.  This demonstrates
a single log file being monitored, in a real world case there could be
several log files being monitored.  It is easy to see in this example that
Stem can handle this with a small number of additions to its
configuration files.  This can be distributed securely across a network.
This demo script is described in detail below with sections on
running, using, configuring, and experimenting with it.

Running tail_demo

The log tail demonstration is called tail_demo and it uses monitor.stem
and archive.stem configuration files (found in conf/).  It is run with
the simple command:

tail_demo

To exit, just enter 'q' in the tail_demo script window itself. It will
kill all the other windows and then exit. This will also happen if you
interrupt the demo script with ^C.

If the -s option is used, then all the windows will use ssfe (split
screen front end) which provides a command line edit and history window
section and an output section.  Two hub windows named Archive and
Monitor will be created and a single shell window will be created with its
current directory set to tail/.  Stem will create two log files
in the tail/ directory, bar.log and bar_status.log.  bar.log is used
by the archive hub to record what ever is sent to that log file and
bar_status.log is used as a log file for status messages.
The hub windows can be used to interact with that hubs Stem environment
and the command line window can be used to put contents into a foo.log
file.  The two hub windows use the standard module Stem::TtyMsg which
allows you to interact with them.  In this demo they will be used to
modify the Stem environment which will affect the behavior of the
logical logs.

Using tail_demo

Initially, bar.log and bar_status.log will be empty files but in 10
seconds (the tailing interval set in the monitor.stem configuration)
the status log will have a message about foo.log not being found.  Run
ls -l several times in the shell (center) window to see when the status
has been logged and then read that file will

$ cat bar_status.log

Now type the following at the command line (in the shell window):

$ echo 'foobar' > foo.log

After 10 seconds (configured in the Stem configuration file)
you can look in bar.log and you will notice that there is a single line
that reads, "foobar", and in bar_status.log you will notice that there
is a status message saying that it is the first time that foo.log was
opened.  And, of course, we have the line "foobar" in the monitored log
file, foo.log.

Configuring tail_demo

Look at the file conf/monitor.stem. That is one of the configuration files
used by tail_demo. It is very simple and easy to understand. It is a Perl list
of lists structure with key/value pairs. Read the config_notes for more
on this.

The first Cell configured is Stem::Hub which names this hub as
'monitor'.

	[
		class	=>	'Stem::Hub',
		name	=>	'monitor',
		args	=>	[],
	],

Next comes the configuration for the Stem::Portal cell,

	[
		class	=>	'Stem::Portal',
		args	=>	[
		],
	],

It is important to note here that there are no args passed into the
portal.  This means that the portal is a client portal, its default
host is set to localhost, and its default port is set to 10,000.  For
more information on portals, read the portal design notes.

The next Cell configured is Stem::TtyMsg which supports typing in and
sending command messages. This is used in all the demo configurations.

	[
		class	=>	'Stem::TtyMsg',
		args	=>	[],
	],

The next cell is the application specific part in the monitor.stem
configuration, the Cell configuration for Stem::LogTail:

	[
		'class'	=>	'Stem::LogTail',
		'name'	=>	'foo',
		'args'	=>	[
			'path'		=> 'tail/foo.log',
			'repeat_interval' => 10,
			'data_log'	=> 'archive:bar',
			'status_log'	=> 'archive:bar_status',
		],
	],

This is the cell responsible for monitoring the indicated log file
(foo.log).  It has arguments for the path to the monitored file, what
the time interval is (in seconds) to check the file for changes, the
data log, and the status log.  Note that the address of the data and status
log indicates both the name of the hub that it is located at, as well as, the
name of the log cell.  For more information on these configuration options
please see the tail log design notes.

Now, lets take a look at the conf/archive.stem configuration file.  This
file defines logical log files  (bar and bar_status) that are used by the
monitor.stem configuration file to log the changes to foo.log.  

The first three cells that are configured are the same as the monitor
configuration, Stem::Hub, Stem::Portal, and Stem::TtyMsg.  They are
for the most part identical.  It is worth mentioning here that the
configuration for the Portal has its server boolean flag set to true,
indicating that this portal will be awaiting connection requests from
remote Portals anywhere on a network.

The next three are the configurations for Stem::Log logical logs.  The
first one is a typical logical log file configuration,

	[
		'class'	=>	'Stem::Log',
		'args'	=>	[
			'name'		=> 'bar',
			'path'		=> 'tail/bar.log',
			'filters'	=> [
				file	=> 1,
				forward	=> [ 'bar_stdout' ],
			],
		],
	],

This is defining a logical log named "bar" that is associated with
a real log file indicated by the path, "tail/bar.log".  It also
has a filters argument that allows Stem::Log::Entries to be filtered
before they are placed in the log file.  The first of the filter
operations in the above configuration, 'file', indicates that the 
incoming log entry should be placed in the file indicated by the 'path'
argument.  Another one of these filter rules, 'forward, indicates that
the log entry is always forwarded to the log 'bar_stdout'.


The next Stem::Log configuration defines a logical log that conditionally
outputs its entries to STDOUT.  It will write log file entries to STDOUT
if the 'bar_stdout' Stem environment variable is set to be greater than
the severity level of the log entry.

	[
		'class'	=>	'Stem::Log',
		'args'	=>	[

			'name'		=> 'bar_stdout',
			'format'	=> '%f [%L][%l] %T',
			'strftime'	=> '%D %T',
			'filters'	=> [
				'env_gt_level'	=> 'bar_stdout',
				stdout	=> 1,
			],
		],
	],

This configuration specifies a format (overriding the default raw format 
like bar.log) that displays the entry with timestamps, label, and level.
This allows you to customize your log entries to your liking.
To demonstrate the severity level detection, do the following at the
Stem prompt in the archive hub window (upper left),

bar_stdout=8

This will ensure that if the severity level of the incoming log entry
is less than 8, it will be displayed to standard output.  now, append a
line to the foo.log file in the command line window,

echo 'hello log' >> foo.log

You will see in the archive hub window a log message appear in stdout
in 10 seconds (according to this configuration),

02/11/02 14:27:15 [tail][5] hello log

This log entry is in raw format, the other Stem::Log configurations add
formats (as mentioned above).  For more information on the format of the
log entries and filters please take a look at the log design notes.

The final cell configuration is for filtering the status messages from the
LogTail Cell,

	[
		'class'	=>	'Stem::Log',
		'args'	=>	[

			'name'		=> 'bar_status',
			'path'		=> 'tail/bar_status.log',
			'format'	=> '[%f]%h:%H:%P - %T',
			'strftime'	=> '%T',
			'filters'	=> [
				file	=> 1,
				'env_gt_level'	=> 'bar_status',
				tty_msg	=> 1,
			],
		],
	],

As you can see, it has the same format as the previous Stem::Log
configurations.  This configuration has both a logfile (tail/bar_status.log)
and the ability to display the status message if the severity level is less
than the Stem environment variable 'bar_status' to the tty message
console (indicated by the tty_msg filter operation, which is set to true).
Note that tty_msg is different than stdout, the message is being sent to
the TtyMsg module for output to the console versus just using stdout
directly.  There are also other actions including custom ones.

Let's see this in action, close the three widows created from the tail_demo
script and re-run tail_demo.  do the following at the
Stem prompt in the archive hub window,

bar_status=8

This will ensure that if the severity level of the incoming log entry
is less than 8, it will be displayed to standard output.  now, append a
line to the foo.log file in the command line window,

echo 'hello again log' >> foo.log

You will see in the archive hub window a log message appear in stdout
in 10 seconds (according to this configuration),

[21:58:04]trichards-linux.alias.net:monitor:/opt/bin/run_stem - LogTail: first open of /opt/bin/tail/foo.log