Agent-TCLI
view release on metacpan or search on metacpan
lib/Agent/TCLI/Package/Tail.pm view on Meta::CPAN
use Agent::TCLI::Package::Tail::Line;
use Agent::TCLI::Package::Tail::Test;
use Getopt::Lucid qw(:all);
our $VERSION = '0.030.'.sprintf "%04d", (qw($Id: Tail.pm 59 2007-04-30 11:24:24Z hacker $))[2];
=head2 ATTRIBUTES
These attrbiutes are generally internal and are probably only useful to
someone trying to enhance the functionality of this Package module.
It would be unusual to set any of these attributes on creation of the
package for an Agent. That doesn't mean you can't.
=over
=item files
A hash of the 'files' being tailed.
B<files> will only contain hash values.
=cut
my @files :Field
:Type('hash')
:All('files');
=item line_cache
An array for holding the last few lines to enable lookbacks
B<line_cache> will only contain Array values.
=cut
my @line_cache :Field
:Type('Array')
:Arg('name'=>'line_cache', 'default' => [ ] )
:Acc('line_cache');
=item test_queue
A queue of all the tests waiting to be activated by triggers
B<test_queue> will only contain Array values.
=cut
my @test_queue :Field
:Type('Array')
:All('test_queue');
=item active
A hash keyed on num of all the tests currently active.
B<active> will only contain hash values.
=cut
my @active :Field
:Type('hash')
:Arg('name'=>'active', 'default'=> { '0' => 1 } )
:Acc('active');
=item ordered
The default setting for ordered test processing.
B<ordered> should only contain boolean values.
=cut
my @ordered :Field
# :Type('boolean')
:Arg('name'=>'ordered','default'=>0)
:Acc('ordered');
=item interval
The default interval setting
B<interval> should only contain integer values.
=cut
my @interval :Field
:Type('numeric')
:Arg('name'=>'interval', 'default'=> 0.05 )
:Acc('interval');
=item line_max_cache
Maximum size of the line cache, in lines.
B<line_max_cache> will only contain numeric values.
=cut
my @line_max_cache :Field
:Type('numeric')
:Arg('name'=>'line_max_cache','default'=>10)
:Acc('line_max_cache');
=item line_hold_time
Time to hold lines in the cache, in seconds.
B<line_hold_time> will only contain numeric values.
=cut
my @line_hold_time :Field
:Type('numeric')
:Arg('name'=>'line_hold_time','default'=>30)
:Acc('line_hold_time');
=item test_max_lines
Default setting for how many lines a test will observe before failing. Defaults to zero (unlimited).
B<test_max_lines> will only contain numeric values.
=cut
my @test_max_lines :Field
:Type('numeric')
:Arg('name'=>'test_max_lines','default'=>10)
:Acc('test_max_lines');
=item test_match_times
Default setting for how many times a test should match. Default is 1.
B<test_match_times> will only contain numeric values.
=cut
my @test_match_times :Field
:Type('numeric')
lib/Agent/TCLI/Package/Tail.pm view on Meta::CPAN
=item Append <input>, <wheel_id>
This POE Event handler receives the tail events and creates the
line objects to insert into the line_cache. It typically
accepts events from POE::Wheel::FollowTail. It may also be
called directly from another POE Session, in which case only
the input to be logged should be provided. It will insert the
sending POE Session as the line->source if no wheel_id is provided.
=cut
sub Append {
my ($kernel, $self, $sender, $input, $wheel_id) =
@_[KERNEL, OBJECT, SENDER, ARG0, ARG1];
# This and Log are virtually identical. Maybe merge someday?
return unless defined $input;
# assign source to either a wheel or another POE session
my $source = defined($wheel_id)
? $self->GetWheelKey($wheel_id, 'source')
: $sender ;
$self->Verbose("append: input(".$input.") from ".$source, 2 );
$line_count[$$self]++;
my $type = ref($input);
$type = "line" if ($type eq '');
# push line onto cache
$self->push_line_cache( Agent::TCLI::Package::Tail::Line->new(
'input' => $input,
'count' => $line_count[$$self],
'birth_time' => time(),
'ttl' => time()+ $self->line_hold_time,
'source' => $source,
'type' => $type,
));
# remove first-in line if total line count exceeded.
if ( $self->depth_line_cache > $self->line_max_cache )
{
$self->Verbose('Too many lines, removing...');
shift ( @{$self->line_cache} );
}
# post new event to active states
foreach my $state ( sort keys %{$self->active} )
{
$kernel->yield( $state => 'Append', $self->line_count );
}
}
=item Activate
This POE event handler activates tests in the queue by registering an
event with SimpleLog and creating an event handler.
This whole process is currently ineffecient and will hopefully get
redone sometime.
=cut
sub Activate {
my ($kernel, $self, ) =
@_[KERNEL, OBJECT, ];
my $counter = $self->activated_count;
$self->Verbose('Activate: counter('.$counter.') ',2);
# remember that counter is an array index and is one less than the size...
if ($self->depth_test_queue == 0 || $counter >= $self->depth_test_queue )
{
$kernel->delay('Activate',$self->interval );
return('nothing activated');
}
my $test = $self->test_queue->[$counter];
$self->Verbose('Activate: counter('.$counter.') dump ',4,$self->test_queue);
$self->Verbose('Activate: test_num('.$test->num.') dump '.$test->dump(1),4);
$self->increment_activated_count;
$kernel->delay('Activate',$self->interval );
my $num = $test->num;
#put into active list
$self->active->{$num} = $test;
# set up test TTL. We add the time so that we now know the exact
# expiration of this event.
# Note that a sufficiently large number for TTL could get a test to last
# for years...
$test->increment_ttl( time() ) if ( $test->ttl != 0 );
$self->Verbose('Activate: counter('.$counter.') time('.time().') test dump ',3,$test );
# Set up state to receive an event for this test
$kernel->state( $num => $self => $test->handler );
$self->Verbose('Activate: state('.$num.') handler('.$test->handler.')',1);
# kick off state to process cache
$kernel->yield( $num );
return('activated '.$num );
}
=item Check
The POE event handler is what does the actual test/watch on the line
objects.
=cut
sub Check {
my ($kernel, $self, $sender, $session, $state ) =
@_[KERNEL, OBJECT, SENDER, SESSION, STATE ];
# Note the right now we're ignoring the ARGS which has the
# Line number, since we keep track of that in each test.
# The line number is not supplied if we're processing the cache
# This might be used for optimization in the future
$self->Verbose('Check: state('.$state.') lines('.$self->depth_line_cache.
') completed('.$self->tests_complete.') ',1);
$self->Verbose('Check: state('.$state.') test queue dump ',5,$self->test_queue );
# OK, so I actually had a bug where I created a Check event with no event name.
return unless defined ($state);
my $test = $self->test_queue->[$state -1];
$self->Verbose('Check: state('.$state.') test dump ',4,$test );
# Catch any events posted after this test completed
return if ( $test->complete );
# if ordered, make sure previous test has completed
# BUG This only works if all previous tests are ordered.
# Though it mostly does it right.
$self->Verbose('Check: ordered('.$test->ordered.') state('.$state.
') previous complete('.$self->test_queue->[$state - 2]->complete.
') complete('.$self->tests_complete.')',1);
if ( $test->ordered && ( $state > 1 ) &&
!$self->test_queue->[$state - 2]->complete
)
{
$self->Verbose('Check: state('.$state.') ordered is on, previous not complete.');
return;
}
# Get time here so that all checking uses same time
my $time = time();
my ($because, $comment, $code, $input, $matchline);
my $ok;
#loop over line of input (in order)
my $line_index = 0;
LINE: while ( $line_index < @{$line_cache[$$self]} )
{
my $line = $self->line_cache->[$line_index];
$ok = 0;
$self->Verbose('Check: state('.$state.') LINE dump ',4,$line );
# if line.index_counter > test.index_counter
# this is a line we haven't checked out
$self->Verbose('Check: num('.$test->num.') $line->count('.$line->count.
') $test->last_line('.$test->last_line.')', 1 - $test->verbose );
if ($line->count > $test->last_line )
{
$input = $line->input;
# get test
$code = $test->code;
$self->Verbose('Check: state('.$state.') input('.$input.
') $code->($input) = ('.$code->( $input ).')',2);
$self->Verbose('Check: num('.$test->num.') input('.$input.
') $code->($input) = ('.$code->( $input ).')',0)
if ($test->verbose);
# remove line if match, increment count
lib/Agent/TCLI/Package/Tail.pm view on Meta::CPAN
the end of the file.
Seek and SeekBack are mutually exclusive. If Seek and SeekBack are not
specified, Tail seeks 4096 bytes back from the end of the file
and discards everything until the end of the file. This helps ensure
that Tail returns only complete records.
type: Param
---
Agent::TCLI::Parameter:
name: seekback
help: Seek backwards byte count.
manual: >
The SeekBack parameter tells Tail how far back from the end of the file
to start reading. Its value is specified in bytes, and values greater
than the file's current size will quietly cause Tail to start from
the file's beginning.
A SeekBack parameter of 0 starts Tail at the end of the file.
It's recommended to omit Seek and SeekBack to start from the end of a file.
A negative SeekBack parameter emulates Seek: it seeks forwards from
the start of the file.
type: Param
---
Agent::TCLI::Parameter:
name: name
help: The name of the test.
manual: >
The name is purely cosmetic and will be returned with the test results
simliarly to the way Test::Simple operates. This might be useful
when reporting results to a group chat or log.
type: Param
---
Agent::TCLI::Parameter:
name: like
help: A regex to match.
manual: >
Like sets a regular expression for the test to match within a line.
The regex should be either a string
type: Param
---
Agent::TCLI::Parameter:
name: line_max_cache
alaises: max_cache
constraints:
- UINT
help: The maximum number of lines to keep in the line_cache.
manual: >
The line_max_cache parameter sets how many lines to keep in the line cache.
Since actions are asynchronous, it is a good idea to have at least some
line cache so that a tail test will work when the action to generate the
log ocurred before the test was in place.
type: Param
---
Agent::TCLI::Parameter:
name: line_hold_time
alaises: hold_time
constraints:
- UINT
help: The time, in seconds, to keep lines in the cache.
manual: >
The line_hold_time parameter sets how many seconds to keep lines in
the line_cache. This is not an exact amount but rather the minimum,
The purge_line_cache process does not run every second, but lines that
exceeed the hold_time will be purged when it does run.
type: Param
---
Agent::TCLI::Parameter:
name: test_max_lines
alaises: max_lines
help: The maximum number of lines to check before failing.
manual: >
The max_lines parameter sets how many lines to check before giving up
and failing. For tests, the default is ten, which is the default size
of the line cache. This means that by default, a test will only check the
most recent lines of what is being tailed.
For watches, the default is zero, which means it does not ever give up.
type: Param
---
Agent::TCLI::Parameter:
name: test_match_times
aliases: match_times
help: The numer of times the a match must be found.
manual: >
The match_times parameter sets how many times a line must match
in order to pass. For tests, the default is one. For watches, the default is
zero, which means it ignores match_times and stays active.
type: Param
---
Agent::TCLI::Parameter:
name: test_ttl
aliases: ttl
help: The time-to-live in seconds.
manual: >
The ttl parameter sets how many seconds to wait before giving up
and failing. For tests, the default is 30. For watches, the default is
zero, which means it does not ever expire.
type: Param
---
Agent::TCLI::Parameter:
name: ordered
help: Set the order for processing tests.
manual: >
Ordered is a boolean switch indicating how to process the tests. If set
a test will not be checked against a line until the previous test has
passed. If ordered is off then multiple tests are running, and tests
are always processed in the order that they were created. The default
ordered setting is off for both tests and watches.
type: Switch
---
Agent::TCLI::Parameter:
name: feedback
help: Sets the feedback level for what is seen.
manual: >
Feedback sets the level of additional information about the line that is
returned. Currently it is either zero, which is nothing,
or one, which returns the whole line. Feedback occurs when a line is
matched or if a test is set for verbose. Feedback is set per test, so
if multiple tests are active and verbose is one, there is the possibility
of seeing the same line more than once. This is useful for debugging
a particular test/watch.
type: Switch
---
Agent::TCLI::Parameter:
name: test_verbose
aliases: verbose|v
help: Sets the verbosity level for a test.
manual: >
Verbose sets the level of additional information about the test that is
returned. Currently it is either zero, which is nothing,
or one, which enables feedback (if set) on every line that is seen.
type: Switch
---
Agent::TCLI::Parameter:
name: cache
help: Determines whether the line cache is used.
manual: >
The line cache will hold the most recent lines seen. This option determines
whether to use the line cache or only examine new lines when a test is set.
The default for tests is on, and for watches is off. To turn off use
no-cache as a test/watch option.
type: Switch
---
Agent::TCLI::Parameter:
name: line_cache
help: The lines in the cache currently.
manual: >
The line cache will hold the most recent lines seen. This will show the
contents of the line cache.
type: Switch
---
Agent::TCLI::Parameter:
name: test_queue
help: The tests and watches that have been requested.
manual: >
The test_queue holds all the tests that have been requested.
This could be a very long list.
type: Switch
---
Agent::TCLI::Parameter:
name: active
help: The tests and watches that are currently active.
type: Switch
---
Agent::TCLI::Command:
name: tail
call_style: session
( run in 0.877 second using v1.01-cache-2.11-cpan-39bf76dae61 )