NAME
Nagios::Report - Perl class to filter and munge Nagios availability data
SYNOPSIS
use
Nagios::Report ;
my
$x
= Nagios::Report->new(
q<local_cgi nagios_web_server nagios_user>
, [
'24x7'
],
'thismonth'
)
or
die
"Can't construct Nagios::Report object."
;
my
@these_fields
=
qw(
HOST_NAME
PERCENT_TOTAL_TIME_UP
TOTAL_TIME_DOWN
TIME_DOWN_HHMMSS
TOTAL_TIME_UNREACHABLE
TIME_UNREACH_HHMMSS
AVAIL_URL
TREND_URL
)
;
$x
->mkreport(
# Field selector; display these fields only (in the listed order)
# [] means display all the fields.
\
@these_fields
,
# Record selector
# Called with @_ loaded # with a list of field names and
# their vals for this record. Usually copied to a hash
# so it can be used as one.
# All records
# sub { 1 },
# All records whose HOST_NAME starts with 'Alb'
# sub { my %F = @_; my $h = $F{HOST_NAME}; $h =~ /^Alb/ },
# Regrettably, this is _NOT_ the same since
# @_ can't be used as a hash.
# sub { $_{HOST_NAME} =~ /^Alb/ }
# All records with an up time percent < 98%
sub
{
my
%F
=
@_
;
my
$u
=
$F
{PERCENT_TOTAL_TIME_UP};
$u
=~ s/%//;
$u
< 98 },
# Sort order
&comp
(
alpha
=> 0,
ascend
=> 0,
fields
=> [
qw(TOTAL_TIME_DOWN TOTAL_TIME_UNREACHABLE)
]),
# Sorts descending by max of TOTAL_TIME_DOWN and TOTAL_TIME_UNREACHABLE
# DIY sorters remember that $a and $b _must_ be in Nagios::Report package.
# eg by TOTAL_DOWN_TIME descending.
# sub { my %f = @_ ;
# package Nagios::Report;
# $b->[$f{TOTAL_TIME_DOWN}] <=> $a->[$f{TOTAL_TIME_DOWN}]
# },
# Same as
# &comp(alpha => 0, ascend => 0, fields => ['TOTAL_TIME_DOWN'])
# Same but harder,
# sub { package Nagios::Report; $b->[16] <=> $a->[16] },
# Optional callback to add or mangle fields.
# Add 2 fields for downtime vals in hours minutes and secs.
sub
{
$F
=
shift
@_
;
$F
->{TIME_DOWN_HHMMSS} = t2hms(
$F
->{TOTAL_TIME_DOWN} ),
$F
->{TIME_UNREACH_HHMMSS}= t2hms(
$F
->{TOTAL_TIME_UNREACHABLE} ) ;
qw(TIME_DOWN_HHMMSS TIME_UNREACH_HHMMSS)
}
) ;
$x
->debug_dump ;
# $x->csv_dump ;
DESCRIPTION
Gets the Nagios (http://wwww.Nagios.ORG/) All Hosts or Services availability report (getting the results in CSV format) and applies grep like filters, map like munging, and slice like field masks to produce a report which can be output in various ways.
This class provides extra control over the content and disposition of the data produced by the Nagios availability CGI, by writing for example a spreadsheet containing the selected data.
Since the data originates from standard Nagios availability CGI, its results are no more accurate - and should be exactly the same - as that CGI.
METHODS
new (DATA_SOURCE, REPORT_PERIODS, TIME_PERIOD, HOST_OR_SERVICE, PRE_FILTER)
This is the constructor of the Nagios::Report object.
DATA_SOURCE
is one of1 local_cgi - get the data by running the availability report CGI on the
local
host.
Space separated
values
of the Nagios web server name/address and a Nagios user should follow.
2 web_page - get the data
with
LYNX or WGET from the named web server
with
the credential.
Space separated
values
of the Nagios web server name/address, a Nagios user and that users password
should follow.
3 dev_debug - get __development__ data by running a client supplied callback.
The _name_ of the callback should follow the tag, separated by spaces.
NB the callback is assumed to be in the __main__
package
.
The callback is expected to
return
a string consisting of a schema
(of CSV fieldnames) followed by lines of CSV data.
REPORT_PERIODS
is an optional reference to a list of names of Nagios time periods (conventionally defined in timeperiods.cfg) for which the availability data will be computed (by the CGI).TIME_PERIOD
is an optional specification of the interval containing eligible availability records. It is scalar whose value is one of the Nagios interval names such asthisday
,thismonth
, or some of the time forms used by the at command. (These forms include HHMM, HH:MM, DD.MM.YYYY MM/DD/YYYY and 24hour-time date). It can also be a month abbreviation followed by any amount of white space and an optional 4 digit year. This form, like Mar 2006, selects all the days in that month. If the year is missing, the month refers to this year.Usually the timeperiod specifies an interval from some time in the past to now from which availability data will be selected.
However, if the argument is of the form start_24hour-time_date - end_24hour-time_date, the availability data will be extracted from the corresponding interval.
If this argument is omitted, the report is compiled for the thismonth time period (ie any host availability record from the first of the current month to the current time).
HOST_OR_SERVICE
is an optional scalar specifying the service report instead of the host report. If not set, the host report is produced.PRE_FILTER
is a callback that is called with the %F hash (vi) set to the values of the field names for this availability record. The constructor saves the availability report for all the hosts and therefore if mkreport() then requests the down records (vi), the availability CGI will be run for every host, whether or not the filter in mkreport() actually selects them. To eliminate this waste and speed up the report, supply a callback like sub { my %F = @_; $u = $F{PERCENT_TOTAL_TIME_UP}; $u =~ s/%//; $u < 99 } or sub { my %F = @_; $F{TOTAL_TIME_DOWN} >= 600 }The constructor gets the Nagios availability data by running the all hosts or all services report (in CSV format) and storing it in the object.
mkreport (FIELD_LIST, SELECTOR_CALLBACK, ORDER_CALLBACK, MUNGE_CALLBACK, DOWNS)
FIELD_LIST
is a reference to an array containing the field names that will appear in the report (a logical slice of the reports fields). The fields appear in the report in the same order they have in this list. Fields added byMUNGE_CALLBACK
must be specified byFIELD_LIST
or they will not be shown in the report unless this parameter is omitted. If theFIELD_LIST
is omitted, all the fields appear in the report, no matter where they come from (ie if fields are added by theMUNGE_CALLBACK
, the new fields will appear in the report). If a field inFIELD_LIST
does not exist in the schema, it will not appear in the report; the caller must spell the field names correctly.SELECTOR_CALLBACK
is a reference to a user supplied subroutine that will return true if the record is to be included in the report. The subroutine is called with an argument list of field names and their values for this record. This argument list can be copied to a hash in the callback, conventionally named %F, so that the field names can be used in expressions like$F{HOST_NAME} =~ /^foo/
to select eligible records.
ORDER_CALLBACK
is a reference to a user supplied sort subroutine that determines the order of the records in the report. The subroutine is called with an argument list of field names and their offsets in the records (eg (HOST_NAME, 0)). This argument list can be copied to a hash in the callback, conventionally named %f, so that the field names can be used in expressions like$a->[$f{TOTAL_TIME_DOWN}] <=> $b->[$f{TOTAL_TIME_DOWN}]
to sort the records based on the field values.
MUNGE_CALLBACK
is a reference to a user supplied subroutine that is used to munge (transform input to output) the records. The subroutine is called with a pointer to a hash of field names and their values for this record. The callback is expected to modify the record by setting the values of this hash, munging fields with expressions like$F
->{TOTAL_TIME_DOWN} = 0
If the callback adds fields to the record, it should add the new field value in the same way (by setting a value for a new key in the hash, like for example,
$F
->{TOTAL_TIME_DOWN_HMS} = t2hms(
$F
->{TOTAL_TIME_DOWN})
).
If the callback adds no fields (modifies values only), it must return an empty list.
A complete callback to set TOTAL_TIME_DOWN to zero is therefore
sub
{
my
$F
=
shift
@_
;
$F
->{TOTAL_TIME_DOWN} = 0;
()
}
mkreport() takes the availability data for each time period, adds outage data (which involves duplicating the
original
availability record as many times as there are outages), does any specified munging, applies the filter discarding records not rated asinteresting
by the selector callback, before sorting and slicing the results - dropping fields unwanted fields - and storing them as areport
for each time period.mkreport() must be run before any of the output methods.
DOWNS
is an optional scalar flag. If the flag is set the availability report - the detailed report with the outage log - for each host is fetched and the outage records extracted.Then, for each of the outage records, the availability record is duplicated followed by the outage data: when the host went down, when it came back up, and the hours minutes seconds formatted value of the outage. These fields are named DOWN, UP, and OUTAGE.
Since the availability data is repeated for each outage record,
DOWNS
can make the report look messy. It is best used with a small number of report fields (eg HOST_NAME, PERCENT_TOTAL_UP_TIME). Also, since the outage records are added before filtering by the selector callback, you should set a pre-filter in the constructor.The callbacks are run in this order
to_dbh
If the DBD::AnyData module is installed, returns an array of DBI data handles connected to the pseudo-databases containing one table populated with the availability data corresponding to each of the REPORT_PERIODS specified in the constructor call.
Each table is named
tab_REPORT_PERIOD
. For example, after constructing the Nagios::Report object with the default report period, the table is named tab_24x7.This method allows the use of SQL statements as an alternative means of filtering and modifying the data. For example,
$SQL
=
<<SQL;
SELECT host_name,
total_time_down,
time_down_scheduled,
time_down_unscheduled,
FROM tab_24x7
WHERE total_time_down >= 300
SQL
$x
= Nagios::Report->new(local_cgi Nagios-server Nagios-contact) ;
(
$d
) =
$x
->to_dbh ;
$s
=
$d
->prepare(
$SQL
) ;
$s
->execute ;
$s
->dump_results ;
Unfortunately, the use of DBD::AnyData does not invalidate this module because the SQL grammar implemented by SQL::Statement (and used by DBD::AnyData) is not as extensive as the SQL grammar provided by an RDBMS, or as useful as the record selector mechanism provided by this.
If one is determined to process with SELECT, load the data into an RDBMS of choice ( MySQL comes to mind) and use the corresponding Perl DBD module on that. There is an example of a script to do so included in the distribution.
Also, as of version 0.002, there were noisy complaints from DBI when DBD::AnyData processes SQL.
excel_dump (EXCEL_FILENAME, CHART_DETAIL)
excel_dump writes a Workbook in the specified filename. The workbook contains a worksheet for each report (ie one for each time period specified by the constructor). excel_dump() requires the John McNamara's excellent CPAN module, Spreadsheet::WriteExcel.
EXCEL_FILENAME
is the path of the file in which the Excel workbook will be written.CHART_DETAIL
is an optional reference to a hash that specifies the details of an Excel Chart that will be linked to the data from the report.The keys of his hash are
template - the path to a binary file, produced by the Spreadsheet::WriteExcel chartex utility, containing the chart to be linked to the data.
link - an optional scalar that specifies the data to be linked to the chart. Defaults to "q<'24x7'!A1>". You almost certainly will need to change this.
title - an optional scalar that specifies the name of the chart to be added to the workbook. Defaults to '24x7 Chart'.
Note that only one chart can be added to a workbook (by this module).
csv_dump
CSV formatted output on STDOUT. Note that this mainly useful for debugging since the cell data is not formatted should it be imported by Excel
dev_debug (FIELD_WIDTH, FIELDS_PER_LINE)
report formatted output on STDOUT.
ACCESSORS/MUTATORS
Acessors and mutators are provided for most of the attributes in the object. The module makes no use of them and, except for those below, are probably of little interest. Unless noted, the caller is responsible for processing the attribute type correctly; the acessor does nothing more than hand back a ref.
report (REPORT_PERIOD)
Accessor that returns, in scalar context, an iterator that when kicked returns each of the records produced by mkreport() for that report period; in array context, returns the list of those records.
Note that the 'records' are refs to anonymous lists containing only those fields specified by the field list parameter of mkreport().
avail (REPORT_PERIOD)
Accessor that returns, in scalar context, an iterator that when kicked returns each of the records returned by the constructor; in array context, returns the list of those records. Note that the 'records' are refs to anonymous lists containing all of the Nagios availability report fields augmented by the two extra fields AVAIL_URL and TREND_URL (vi).
The iterator is a code ref that, when called, will return a ref to the next availability record. Without a REPORT_PERIOD, returns an iterator to the 24x7 data, otherwise the availability data corresponding to that report period (if it exists). If the methods of this class are not useful, then the iterator allows the caller transform the availability data with imap and filter it with igrep.
FIELDNAMES
Ref to a list of field names eg @fields = @{$me->FIELDNAMES}
FIELDS
Ref to a hash of field indices keyed by field name eg %f = %{$me->FIELDS}}
SERVER
Hostname of the server on which the Nagios CGIs can be found.
SOURCE_TAG
How the availability data will be fetched.
REPORT_TYPE
host | service report
DATA_SOURCE
Reference to a subroutine that will fetch the availability data.
REPORTS
Ref to a hash keyed by report period containing a hash keyed by FIELDNAMES and RECORDS. The latter key refers to a list containing the records selected and munged by mkreport(). Note that each record contains only those fields specified by the field list parm of mkreport().
See report (REPORT_PERIOD).
AVAIL_REPORTS
Ref to a hash keyed by report period containing a ref to a list containing all those records returned by the Nagios availability report that are accepted by the pre-filter.
Unlike REPORTS, each record contains all the Nagios reporting fields including the fields AVAIL_URL and TREND_URL whose values are hyperlinks to the Nagios trend and availability reports for the host named HOST_NAME.
See avail (REPORT_PERIOD).
SUBROUTINES
max_l ( LIST_OF_NUMERIC_VALS)
Returns the maximum value in the list. Does not handle non-numeric values.
comp ( OPTION_HASH )
Returns a ref to a comparator function that determines the order of the records and can be used as the ORDER_CALLBACK argument of mkreport().
OPTION_HASH
is an optional hash with keysalpha
Sort by the HOST_NAME field if set, otherwise by the maximum of the fields value.ascend
Sort in ascending order if set.fields
The comparator function orders the records based on the maximum of the numeric field values. Only applies if alpha is not set.fields
is a reference to an array of numeric field names.eg
&comp
(
alpha
=> 1,
ascend
=> 1 )
Returns a
ref
to function that orders the records by the HOST_NAME field.
eg
&comp
()
Same as calling comp
with
(
alpha
=> 1,
ascend
=> 1 )
eg
&comp
(
alpha
=> 0,
ascend
=> 1,
fields
=> [TOTAL_TIME_DOWN, TOTAL_TIME_UNREACHABLE] )
Returns a
ref
to a function that orders the records by the maximum of the
values
of the
TOTAL_TIME_DOWN and TOTAL_TIME_UNREACHABLE fields.
t2hms (TIME_T)
Returns the argument formatted by weeks, days, hours, minutes and seconds eg &t2hms(300) -> 5m.
d2t (time_string)
Returns the time_t value of the string formatted as either a localtime, US (MM-DD-YYYY) or EURO date (DD-MM-YYY).
i2t (interval)
Returns the time_t value of the string formatted as an interval of time ie one that matches (?:\d+[wdhms]\s*)+ eg 3h 5m 30s (3 hours 5 minutes and 30 seconds).
$st_et{TAG}->(TAG, [ STRUCT TM ] )
A hash of code refs indexed by an interval selecting tag. The second optinal argument is a ref to a STRUCT TM. If this arg is missing, [localtime] is used.
Returns the pair of time_ts bounding the interval named by the tag. The upper boundary of the interval is usually the time_t value corresponding to the second argument. The lower boundary is this less the tags value.
Tags include last_n_days, last_n_hours, last_n_mins, thisweek, lastweek, thismonth, lastmonth, thisyear, lastyear and variable strings like the 'at' style time stamps such as 'MMM YYYY' (eg Mar 2006) or HHMM DD.MM.YYYY. When the tag represents a fixed date or time, the interval returned is from 'then' to 'now'.
When called by this module, the second argument is always 'now' (ie [localtime]). eg join('-', map { scalar(localtime($_)) } $st_et{today}->('today') eq 'Fri Aug 18 00:00:00 2006-Fri Aug 18 10:13:00 2006' eg join('-', map { scalar(localtime($_)) } $st_et{today}->('today', [ 0, 0, 0, 18, 7, 106])) eq 'Fri Aug 18 00:00:00 2006-Fri Aug 18 10:13:00 2006'
BUGS
Does not do much more than the standard availability CGI. The reports has the same bugs as those produced by the CGI.
The comp() subroutine does not behave well if called with fields whose values are non numeric.
The hand done date and time functions are poor.
Anything good in this module comes from Higher Order Perl; the rest comes from the author.
The module does not buy much more than rolling ones own with DBD::AnyData. Had I been more aware of the fundamental utility and importance of RDBMS data, this module would probably not exist. OTOH, this module now provides some sort of programmatic access to Nagios availability data that Nagios has not had (AFAIK) hitherto.
SEE ALSO
perl(1).
Nagios (http://www.Nagios.ORG/)
AUTHOR
Stanley Hopcroft <HopcroftS@CPAN.Org>
COPYRIGHT
Copyright (c) 2006 Stanley Hopcroft. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
1 POD Error
The following errors were encountered while parsing the POD:
- Around line 1443:
You forgot a '=back' before '=head1'