commit
This commit is contained in:
913
debian/smokeping/usr/lib/BER.pm
vendored
Normal file
913
debian/smokeping/usr/lib/BER.pm
vendored
Normal file
@@ -0,0 +1,913 @@
|
||||
### -*- mode: Perl -*-
|
||||
######################################################################
|
||||
### BER (Basic Encoding Rules) encoding and decoding.
|
||||
######################################################################
|
||||
### Copyright (c) 1995-2008, Simon Leinen.
|
||||
###
|
||||
### This program is free software; you can redistribute it under the
|
||||
### "Artistic License 2.0" included in this distribution
|
||||
### (file "Artistic").
|
||||
######################################################################
|
||||
### This module implements encoding and decoding of ASN.1-based data
|
||||
### structures using the Basic Encoding Rules (BER). Only the subset
|
||||
### necessary for SNMP is implemented.
|
||||
######################################################################
|
||||
### Created by: Simon Leinen <simon@switch.ch>
|
||||
###
|
||||
### Contributions and fixes by:
|
||||
###
|
||||
### Andrzej Tobola <san@iem.pw.edu.pl>: Added long String decode
|
||||
### Tobias Oetiker <tobi@oetiker.ch>: Added 5 Byte Integer decode ...
|
||||
### Dave Rand <dlr@Bungi.com>: Added SysUpTime decode
|
||||
### Philippe Simonet <sip00@vg.swissptt.ch>: Support larger subids
|
||||
### Yufang HU <yhu@casc.com>: Support even larger subids
|
||||
### Mike Mitchell <Mike.Mitchell@sas.com>: New generalized encode_int()
|
||||
### Mike Diehn <mdiehn@mindspring.net>: encode_ip_address()
|
||||
### Rik Hoorelbeke <rik.hoorelbeke@pandora.be>: encode_oid() fix
|
||||
### Brett T Warden <wardenb@eluminant.com>: pretty UInteger32
|
||||
### Bert Driehuis <driehuis@playbeing.org>: Handle SNMPv2 exception codes
|
||||
### Jakob Ilves (/IlvJa) <jakob.ilves@oracle.com>: PDU decoding
|
||||
### Jan Kasprzak <kas@informatics.muni.cz>: Fix for PDU syntax check
|
||||
### Milen Pavlov <milen@batmbg.com>: Recognize variant length for ints
|
||||
######################################################################
|
||||
|
||||
package BER;
|
||||
|
||||
require 5.002;
|
||||
|
||||
use strict;
|
||||
use vars qw(@ISA @EXPORT $VERSION $pretty_print_timeticks
|
||||
%pretty_printer %default_printer $errmsg);
|
||||
use Exporter;
|
||||
|
||||
$VERSION = '1.05';
|
||||
|
||||
@ISA = qw(Exporter);
|
||||
|
||||
@EXPORT = qw(context_flag constructor_flag
|
||||
encode_int encode_int_0 encode_null encode_oid
|
||||
encode_sequence encode_tagged_sequence
|
||||
encode_string encode_ip_address encode_timeticks
|
||||
encode_uinteger32 encode_counter32 encode_counter64
|
||||
encode_gauge32
|
||||
decode_sequence decode_by_template
|
||||
pretty_print pretty_print_timeticks
|
||||
hex_string hex_string_of_type
|
||||
encoded_oid_prefix_p errmsg
|
||||
register_pretty_printer unregister_pretty_printer);
|
||||
|
||||
### Variables
|
||||
|
||||
## Bind this to zero if you want to avoid that TimeTicks are converted
|
||||
## into "human readable" strings containing days, hours, minutes and
|
||||
## seconds.
|
||||
##
|
||||
## If the variable is zero, pretty_print will simply return an
|
||||
## unsigned integer representing hundredths of seconds.
|
||||
##
|
||||
$pretty_print_timeticks = 1;
|
||||
|
||||
### Prototypes
|
||||
sub encode_header ($$);
|
||||
sub encode_int_0 ();
|
||||
sub encode_int ($);
|
||||
sub encode_oid (@);
|
||||
sub encode_null ();
|
||||
sub encode_sequence (@);
|
||||
sub encode_tagged_sequence ($@);
|
||||
sub encode_string ($);
|
||||
sub encode_ip_address ($);
|
||||
sub encode_timeticks ($);
|
||||
sub pretty_print ($);
|
||||
sub pretty_using_decoder ($$);
|
||||
sub pretty_string ($);
|
||||
sub pretty_intlike ($);
|
||||
sub pretty_unsignedlike ($);
|
||||
sub pretty_oid ($);
|
||||
sub pretty_uptime ($);
|
||||
sub pretty_uptime_value ($);
|
||||
sub pretty_ip_address ($);
|
||||
sub pretty_generic_sequence ($);
|
||||
sub register_pretty_printer ($);
|
||||
sub unregister_pretty_printer ($);
|
||||
sub hex_string ($);
|
||||
sub hex_string_of_type ($$);
|
||||
sub decode_oid ($);
|
||||
sub decode_by_template;
|
||||
sub decode_by_template_2;
|
||||
sub decode_sequence ($);
|
||||
sub decode_int ($);
|
||||
sub decode_intlike ($);
|
||||
sub decode_unsignedlike ($);
|
||||
sub decode_intlike_s ($$);
|
||||
sub decode_string ($);
|
||||
sub decode_length ($@);
|
||||
sub encoded_oid_prefix_p ($$);
|
||||
sub decode_subid ($$$);
|
||||
sub decode_generic_tlv ($);
|
||||
sub error (@);
|
||||
sub template_error ($$$);
|
||||
|
||||
sub version () { $VERSION; }
|
||||
|
||||
### Flags for different types of tags
|
||||
|
||||
sub universal_flag { 0x00 }
|
||||
sub application_flag { 0x40 }
|
||||
sub context_flag { 0x80 }
|
||||
sub private_flag { 0xc0 }
|
||||
|
||||
sub primitive_flag { 0x00 }
|
||||
sub constructor_flag { 0x20 }
|
||||
|
||||
### Universal tags
|
||||
|
||||
sub boolean_tag { 0x01 }
|
||||
sub int_tag { 0x02 }
|
||||
sub bit_string_tag { 0x03 }
|
||||
sub octet_string_tag { 0x04 }
|
||||
sub null_tag { 0x05 }
|
||||
sub object_id_tag { 0x06 }
|
||||
sub sequence_tag { 0x10 }
|
||||
sub set_tag { 0x11 }
|
||||
sub uptime_tag { 0x43 }
|
||||
|
||||
### Flag for length octet announcing multi-byte length field
|
||||
|
||||
sub long_length { 0x80 }
|
||||
|
||||
### SNMP specific tags
|
||||
|
||||
sub snmp_ip_address_tag { 0x00 | application_flag () }
|
||||
sub snmp_counter32_tag { 0x01 | application_flag () }
|
||||
sub snmp_gauge32_tag { 0x02 | application_flag () }
|
||||
sub snmp_timeticks_tag { 0x03 | application_flag () }
|
||||
sub snmp_opaque_tag { 0x04 | application_flag () }
|
||||
sub snmp_nsap_address_tag { 0x05 | application_flag () }
|
||||
sub snmp_counter64_tag { 0x06 | application_flag () }
|
||||
sub snmp_uinteger32_tag { 0x07 | application_flag () }
|
||||
|
||||
## Error codes (SNMPv2 and later)
|
||||
##
|
||||
sub snmp_nosuchobject { context_flag () | 0x00 }
|
||||
sub snmp_nosuchinstance { context_flag () | 0x01 }
|
||||
sub snmp_endofmibview { context_flag () | 0x02 }
|
||||
|
||||
### pretty-printer initialization code. Create a hash with
|
||||
### the most common types of pretty-printer routines.
|
||||
|
||||
BEGIN {
|
||||
$default_printer{int_tag()} = \&pretty_intlike;
|
||||
$default_printer{snmp_counter32_tag()} = \&pretty_unsignedlike;
|
||||
$default_printer{snmp_gauge32_tag()} = \&pretty_unsignedlike;
|
||||
$default_printer{snmp_counter64_tag()} = \&pretty_unsignedlike;
|
||||
$default_printer{snmp_uinteger32_tag()} = \&pretty_unsignedlike;
|
||||
$default_printer{octet_string_tag()} = \&pretty_string;
|
||||
$default_printer{object_id_tag()} = \&pretty_oid;
|
||||
$default_printer{snmp_ip_address_tag()} = \&pretty_ip_address;
|
||||
|
||||
%pretty_printer = %default_printer;
|
||||
}
|
||||
|
||||
#### Encoding
|
||||
|
||||
sub encode_header ($$) {
|
||||
my ($type,$length) = @_;
|
||||
return pack ("C C", $type, $length) if $length < 128;
|
||||
return pack ("C C C", $type, long_length | 1, $length) if $length < 256;
|
||||
return pack ("C C n", $type, long_length | 2, $length) if $length < 65536;
|
||||
return error ("Cannot encode length $length yet");
|
||||
}
|
||||
|
||||
sub encode_int_0 () {
|
||||
return pack ("C C C", 2, 1, 0);
|
||||
}
|
||||
|
||||
sub encode_int ($) {
|
||||
return encode_intlike ($_[0], int_tag);
|
||||
}
|
||||
|
||||
sub encode_uinteger32 ($) {
|
||||
return encode_intlike ($_[0], snmp_uinteger32_tag);
|
||||
}
|
||||
|
||||
sub encode_counter32 ($) {
|
||||
return encode_intlike ($_[0], snmp_counter32_tag);
|
||||
}
|
||||
|
||||
sub encode_counter64 ($) {
|
||||
return encode_intlike ($_[0], snmp_counter64_tag);
|
||||
}
|
||||
|
||||
sub encode_gauge32 ($) {
|
||||
return encode_intlike ($_[0], snmp_gauge32_tag);
|
||||
}
|
||||
|
||||
sub encode_intlike ($$) {
|
||||
my ($int, $tag)=@_;
|
||||
my ($sign, $val, @vals);
|
||||
$sign = ($int >= 0) ? 0 : 0xff;
|
||||
if (ref $int && $int->isa ("Math::BigInt")) {
|
||||
for(;;) {
|
||||
$val = $int->copy()->bmod (256);
|
||||
unshift(@vals, $val);
|
||||
return encode_header ($tag, $#vals + 1).pack ("C*", @vals)
|
||||
if ($int >= -128 && $int < 128);
|
||||
$int->bsub ($sign)->bdiv (256);
|
||||
}
|
||||
} else {
|
||||
for(;;) {
|
||||
$val = $int & 0xff;
|
||||
unshift(@vals, $val);
|
||||
return encode_header ($tag, $#vals + 1).pack ("C*", @vals)
|
||||
if ($int >= -128 && $int < 128);
|
||||
$int -= $sign, $int = int($int / 256);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub encode_oid (@) {
|
||||
my @oid = @_;
|
||||
my ($result,$subid);
|
||||
|
||||
$result = '';
|
||||
## Ignore leading empty sub-ID. The favourite reason for
|
||||
## those to occur is that people cut&paste numeric OIDs from
|
||||
## CMU/UCD SNMP including the leading dot.
|
||||
shift @oid if $oid[0] eq '';
|
||||
|
||||
return error ("Object ID too short: ", join('.',@oid))
|
||||
if $#oid < 1;
|
||||
## The first two subids in an Object ID are encoded as a single
|
||||
## byte in BER, according to a funny convention. This poses
|
||||
## restrictions on the ranges of those subids. In the past, I
|
||||
## didn't check for those. But since so many people try to use
|
||||
## OIDs in CMU/UCD SNMP's format and leave out the mib-2 or
|
||||
## enterprises prefix, I introduced this check to catch those
|
||||
## errors.
|
||||
##
|
||||
return error ("first subid too big in Object ID ", join('.',@oid))
|
||||
if $oid[0] > 2;
|
||||
$result = shift (@oid) * 40;
|
||||
$result += shift @oid;
|
||||
return error ("second subid too big in Object ID ", join('.',@oid))
|
||||
if $result > 255;
|
||||
$result = pack ("C", $result);
|
||||
foreach $subid (@oid) {
|
||||
if ( ($subid>=0) && ($subid<128) ){ #7 bits long subid
|
||||
$result .= pack ("C", $subid);
|
||||
} elsif ( ($subid>=128) && ($subid<16384) ){ #14 bits long subid
|
||||
$result .= pack ("CC", 0x80 | $subid >> 7, $subid & 0x7f);
|
||||
}
|
||||
elsif ( ($subid>=16384) && ($subid<2097152) ) {#21 bits long subid
|
||||
$result .= pack ("CCC",
|
||||
0x80 | (($subid>>14) & 0x7f),
|
||||
0x80 | (($subid>>7) & 0x7f),
|
||||
$subid & 0x7f);
|
||||
} elsif ( ($subid>=2097152) && ($subid<268435456) ){ #28 bits long subid
|
||||
$result .= pack ("CCCC",
|
||||
0x80 | (($subid>>21) & 0x7f),
|
||||
0x80 | (($subid>>14) & 0x7f),
|
||||
0x80 | (($subid>>7) & 0x7f),
|
||||
$subid & 0x7f);
|
||||
} elsif ( ($subid>=268435456) && ($subid<4294967296) ){ #32 bits long subid
|
||||
$result .= pack ("CCCCC",
|
||||
0x80 | (($subid>>28) & 0x0f), #mask the bits beyond 32
|
||||
0x80 | (($subid>>21) & 0x7f),
|
||||
0x80 | (($subid>>14) & 0x7f),
|
||||
0x80 | (($subid>>7) & 0x7f),
|
||||
$subid & 0x7f);
|
||||
} else {
|
||||
return error ("Cannot encode subid $subid");
|
||||
}
|
||||
}
|
||||
encode_header (object_id_tag, length $result).$result;
|
||||
}
|
||||
|
||||
sub encode_null () { encode_header (null_tag, 0); }
|
||||
sub encode_sequence (@) { encode_tagged_sequence (sequence_tag, @_); }
|
||||
|
||||
sub encode_tagged_sequence ($@) {
|
||||
my ($tag,$result);
|
||||
|
||||
$tag = shift @_;
|
||||
$result = join '',@_;
|
||||
return encode_header ($tag | constructor_flag, length $result).$result;
|
||||
}
|
||||
|
||||
sub encode_string ($) {
|
||||
my ($string)=@_;
|
||||
return encode_header (octet_string_tag, length $string).$string;
|
||||
}
|
||||
|
||||
sub encode_ip_address ($) {
|
||||
my ($addr)=@_;
|
||||
my @octets;
|
||||
|
||||
if (length $addr == 4) {
|
||||
## Four bytes... let's suppose that this is a binary IP address
|
||||
## in network byte order.
|
||||
return encode_header (snmp_ip_address_tag, length $addr).$addr;
|
||||
} elsif (@octets = ($addr =~ /^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)$/)) {
|
||||
return encode_ip_address (pack ("CCCC", @octets));
|
||||
} else {
|
||||
return error ("IP address must be four bytes long or a dotted-quad");
|
||||
}
|
||||
}
|
||||
|
||||
sub encode_timeticks ($) {
|
||||
my ($tt) = @_;
|
||||
return encode_intlike ($tt, snmp_timeticks_tag);
|
||||
}
|
||||
|
||||
#### Decoding
|
||||
|
||||
sub pretty_print ($) {
|
||||
my ($packet) = @_;
|
||||
return undef unless defined $packet;
|
||||
my $result = ord (substr ($packet, 0, 1));
|
||||
if (exists ($pretty_printer{$result})) {
|
||||
my $c_ref = $pretty_printer{$result};
|
||||
return &$c_ref ($packet);
|
||||
}
|
||||
return ($pretty_print_timeticks
|
||||
? pretty_uptime ($packet)
|
||||
: pretty_unsignedlike ($packet))
|
||||
if $result == uptime_tag;
|
||||
return "(null)" if $result == null_tag;
|
||||
return error ("Exception code: noSuchObject") if $result == snmp_nosuchobject;
|
||||
return error ("Exception code: noSuchInstance") if $result == snmp_nosuchinstance;
|
||||
return error ("Exception code: endOfMibView") if $result == snmp_endofmibview;
|
||||
|
||||
# IlvJa
|
||||
# pretty print sequences and their contents.
|
||||
|
||||
my $ctx_cons_flags = context_flag | constructor_flag;
|
||||
|
||||
if($result == (&constructor_flag | &sequence_tag) # sequence
|
||||
|| $result == (0 | $ctx_cons_flags) #get_request
|
||||
|| $result == (1 | $ctx_cons_flags) #getnext_request
|
||||
|| $result == (2 | $ctx_cons_flags) #response
|
||||
|| $result == (3 | $ctx_cons_flags) #set_request
|
||||
|| $result == (4 | $ctx_cons_flags) #trap_request
|
||||
|| $result == (5 | $ctx_cons_flags) #getbulk_request
|
||||
|| $result == (6 | $ctx_cons_flags) #inform_request
|
||||
|| $result == (7 | $ctx_cons_flags) #trap2_request
|
||||
)
|
||||
{
|
||||
my $pretty_result = pretty_generic_sequence($packet);
|
||||
$pretty_result =~ s/^/ /gm; #Indent.
|
||||
|
||||
my $seq_type_desc =
|
||||
{
|
||||
(constructor_flag | sequence_tag) => "Sequence",
|
||||
(0 | $ctx_cons_flags) => "GetRequest",
|
||||
(1 | $ctx_cons_flags) => "GetNextRequest",
|
||||
(2 | $ctx_cons_flags) => "Response",
|
||||
(3 | $ctx_cons_flags) => "SetRequest",
|
||||
(4 | $ctx_cons_flags) => "Trap",
|
||||
(5 | $ctx_cons_flags) => "GetBulkRequest",
|
||||
(6 | $ctx_cons_flags) => "InformRequest",
|
||||
(7 | $ctx_cons_flags) => "SNMPv2-Trap",
|
||||
(8 | $ctx_cons_flags) => "Report",
|
||||
}->{($result)};
|
||||
|
||||
return $seq_type_desc . "{\n" . $pretty_result . "\n}";
|
||||
}
|
||||
|
||||
return sprintf ("#<unprintable BER type 0x%x>", $result);
|
||||
}
|
||||
|
||||
sub pretty_using_decoder ($$) {
|
||||
my ($decoder, $packet) = @_;
|
||||
my ($decoded,$rest);
|
||||
($decoded,$rest) = &$decoder ($packet);
|
||||
return error ("Junk after object") unless $rest eq '';
|
||||
return $decoded;
|
||||
}
|
||||
|
||||
sub pretty_string ($) {
|
||||
pretty_using_decoder (\&decode_string, $_[0]);
|
||||
}
|
||||
|
||||
sub pretty_intlike ($) {
|
||||
my $decoded = pretty_using_decoder (\&decode_intlike, $_[0]);
|
||||
$decoded;
|
||||
}
|
||||
|
||||
sub pretty_unsignedlike ($) {
|
||||
return pretty_using_decoder (\&decode_unsignedlike, $_[0]);
|
||||
}
|
||||
|
||||
sub pretty_oid ($) {
|
||||
my ($oid) = shift;
|
||||
my ($result,$subid,$next);
|
||||
my (@oid);
|
||||
$result = ord (substr ($oid, 0, 1));
|
||||
return error ("Object ID expected") unless $result == object_id_tag;
|
||||
($result, $oid) = decode_length ($oid, 1);
|
||||
return error ("inconsistent length in OID") unless $result == length $oid;
|
||||
@oid = ();
|
||||
$subid = ord (substr ($oid, 0, 1));
|
||||
push @oid, int ($subid / 40);
|
||||
push @oid, $subid % 40;
|
||||
$oid = substr ($oid, 1);
|
||||
while ($oid ne '') {
|
||||
$subid = ord (substr ($oid, 0, 1));
|
||||
if ($subid < 128) {
|
||||
$oid = substr ($oid, 1);
|
||||
push @oid, $subid;
|
||||
} else {
|
||||
$next = $subid;
|
||||
$subid = 0;
|
||||
while ($next >= 128) {
|
||||
$subid = ($subid << 7) + ($next & 0x7f);
|
||||
$oid = substr ($oid, 1);
|
||||
$next = ord (substr ($oid, 0, 1));
|
||||
}
|
||||
$subid = ($subid << 7) + $next;
|
||||
$oid = substr ($oid, 1);
|
||||
push @oid, $subid;
|
||||
}
|
||||
}
|
||||
join ('.', @oid);
|
||||
}
|
||||
|
||||
sub pretty_uptime ($) {
|
||||
my ($packet,$uptime);
|
||||
|
||||
($uptime,$packet) = &decode_unsignedlike (@_);
|
||||
pretty_uptime_value ($uptime);
|
||||
}
|
||||
|
||||
sub pretty_uptime_value ($) {
|
||||
my ($uptime) = @_;
|
||||
my ($seconds,$minutes,$hours,$days,$result);
|
||||
## We divide the uptime by hundred since we're not interested in
|
||||
## sub-second precision.
|
||||
$uptime = int ($uptime / 100);
|
||||
|
||||
$days = int ($uptime / (60 * 60 * 24));
|
||||
$uptime %= (60 * 60 * 24);
|
||||
|
||||
$hours = int ($uptime / (60 * 60));
|
||||
$uptime %= (60 * 60);
|
||||
|
||||
$minutes = int ($uptime / 60);
|
||||
$seconds = $uptime % 60;
|
||||
|
||||
if ($days == 0){
|
||||
$result = sprintf ("%d:%02d:%02d", $hours, $minutes, $seconds);
|
||||
} elsif ($days == 1) {
|
||||
$result = sprintf ("%d day, %d:%02d:%02d",
|
||||
$days, $hours, $minutes, $seconds);
|
||||
} else {
|
||||
$result = sprintf ("%d days, %d:%02d:%02d",
|
||||
$days, $hours, $minutes, $seconds);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
sub pretty_ip_address ($) {
|
||||
my $pdu = shift;
|
||||
my ($length, $rest);
|
||||
return error ("IP Address tag (".snmp_ip_address_tag.") expected")
|
||||
unless ord (substr ($pdu, 0, 1)) == snmp_ip_address_tag;
|
||||
($length,$pdu) = decode_length ($pdu, 1);
|
||||
return error ("Length of IP address should be four")
|
||||
unless $length == 4;
|
||||
sprintf "%d.%d.%d.%d", unpack ("CCCC", $pdu);
|
||||
}
|
||||
|
||||
# IlvJa
|
||||
# Returns a string with the pretty prints of all
|
||||
# the elements in the sequence.
|
||||
sub pretty_generic_sequence ($) {
|
||||
my ($pdu) = shift;
|
||||
|
||||
my $rest;
|
||||
|
||||
my $type = ord substr ($pdu, 0 ,1);
|
||||
my $flags = context_flag | constructor_flag;
|
||||
|
||||
return error (sprintf ("Tag 0x%x is not a valid sequence tag",$type))
|
||||
unless ($type == (&constructor_flag | &sequence_tag) # sequence
|
||||
|| $type == (0 | $flags) #get_request
|
||||
|| $type == (1 | $flags) #getnext_request
|
||||
|| $type == (2 | $flags) #response
|
||||
|| $type == (3 | $flags) #set_request
|
||||
|| $type == (4 | $flags) #trap_request
|
||||
|| $type == (5 | $flags) #getbulk_request
|
||||
|| $type == (6 | $flags) #inform_request
|
||||
|| $type == (7 | $flags) #trap2_request
|
||||
);
|
||||
|
||||
my $curelem;
|
||||
my $pretty_result; # Holds the pretty printed sequence.
|
||||
my $pretty_elem; # Holds the pretty printed current elem.
|
||||
my $first_elem = 'true';
|
||||
|
||||
# Cut away the first Tag and Length from $packet and then
|
||||
# init $rest with that.
|
||||
(undef, $rest) = decode_length ($pdu, 1);
|
||||
while($rest)
|
||||
{
|
||||
($curelem,$rest) = decode_generic_tlv($rest);
|
||||
$pretty_elem = pretty_print($curelem);
|
||||
|
||||
$pretty_result .= "\n" if not $first_elem;
|
||||
$pretty_result .= $pretty_elem;
|
||||
|
||||
# The rest of the iterations are not related to the
|
||||
# first element of the sequence so..
|
||||
$first_elem = '' if $first_elem;
|
||||
}
|
||||
return $pretty_result;
|
||||
}
|
||||
|
||||
sub hex_string ($) {
|
||||
&hex_string_of_type ($_[0], octet_string_tag);
|
||||
}
|
||||
|
||||
sub hex_string_of_type ($$) {
|
||||
my ($pdu, $wanted_type) = @_;
|
||||
my ($length);
|
||||
return error ("BER tag ".$wanted_type." expected")
|
||||
unless ord (substr ($pdu, 0, 1)) == $wanted_type;
|
||||
($length,$pdu) = decode_length ($pdu, 1);
|
||||
hex_string_aux ($pdu);
|
||||
}
|
||||
|
||||
sub hex_string_aux ($) {
|
||||
my ($binary_string) = @_;
|
||||
my ($c, $result);
|
||||
$result = '';
|
||||
for $c (unpack "C*", $binary_string) {
|
||||
$result .= sprintf "%02x", $c;
|
||||
}
|
||||
$result;
|
||||
}
|
||||
|
||||
sub decode_oid ($) {
|
||||
my ($pdu) = @_;
|
||||
my ($result,$pdu_rest);
|
||||
my (@result);
|
||||
$result = ord (substr ($pdu, 0, 1));
|
||||
return error ("Object ID expected") unless $result == object_id_tag;
|
||||
($result, $pdu_rest) = decode_length ($pdu, 1);
|
||||
return error ("Short PDU")
|
||||
if $result > length $pdu_rest;
|
||||
@result = (substr ($pdu, 0, $result + (length ($pdu) - length ($pdu_rest))),
|
||||
substr ($pdu_rest, $result));
|
||||
@result;
|
||||
}
|
||||
|
||||
# IlvJa
|
||||
# This takes a PDU and returns a two element list consisting of
|
||||
# the first element found in the PDU (whatever it is) and the
|
||||
# rest of the PDU
|
||||
sub decode_generic_tlv ($) {
|
||||
my ($pdu) = @_;
|
||||
my (@result);
|
||||
my ($elemlength,$pdu_rest) = decode_length ($pdu, 1);
|
||||
@result = (# Extract the first element.
|
||||
substr ($pdu, 0, $elemlength + (length ($pdu)
|
||||
- length ($pdu_rest)
|
||||
)
|
||||
),
|
||||
#Extract the rest of the PDU.
|
||||
substr ($pdu_rest, $elemlength)
|
||||
);
|
||||
@result;
|
||||
}
|
||||
|
||||
sub decode_by_template {
|
||||
my ($pdu) = shift;
|
||||
local ($_) = shift;
|
||||
return decode_by_template_2 ($pdu, $_, 0, 0, @_);
|
||||
}
|
||||
|
||||
my $template_debug = 0;
|
||||
|
||||
sub decode_by_template_2 {
|
||||
my ($pdu, $template, $pdu_index, $template_index);
|
||||
local ($_);
|
||||
$pdu = shift;
|
||||
$template = $_ = shift;
|
||||
$pdu_index = shift;
|
||||
$template_index = shift;
|
||||
my (@results);
|
||||
my ($length,$expected,$read,$rest);
|
||||
return undef unless defined $pdu;
|
||||
while (0 < length ($_)) {
|
||||
if (substr ($_, 0, 1) eq '%') {
|
||||
print STDERR "template $_ ", length $pdu," bytes remaining\n"
|
||||
if $template_debug;
|
||||
$_ = substr ($_,1);
|
||||
++$template_index;
|
||||
if (($expected) = /^(\d*|\*)\{(.*)/) {
|
||||
## %{
|
||||
$template_index += length ($expected) + 1;
|
||||
print STDERR "%{\n" if $template_debug;
|
||||
$_ = $2;
|
||||
$expected = shift | constructor_flag if ($expected eq '*');
|
||||
$expected = sequence_tag | constructor_flag
|
||||
if $expected eq '';
|
||||
return template_error ("Unexpected end of PDU",
|
||||
$template, $template_index)
|
||||
if !defined $pdu or $pdu eq '';
|
||||
return template_error ("Expected sequence tag $expected, got ".
|
||||
ord (substr ($pdu, 0, 1)),
|
||||
$template,
|
||||
$template_index)
|
||||
unless (ord (substr ($pdu, 0, 1)) == $expected);
|
||||
(($length,$pdu) = decode_length ($pdu, 1))
|
||||
|| return template_error ("cannot read length",
|
||||
$template, $template_index);
|
||||
return template_error ("Expected length $length, got ".length $pdu ,
|
||||
$template, $template_index)
|
||||
unless length $pdu == $length;
|
||||
} elsif (($expected,$rest) = /^(\*|)s(.*)/) {
|
||||
## %s
|
||||
$template_index += length ($expected) + 1;
|
||||
($expected = shift) if $expected eq '*';
|
||||
(($read,$pdu) = decode_string ($pdu))
|
||||
|| return template_error ("cannot read string",
|
||||
$template, $template_index);
|
||||
print STDERR "%s => $read\n" if $template_debug;
|
||||
if ($expected eq '') {
|
||||
push @results, $read;
|
||||
} else {
|
||||
return template_error ("Expected $expected, read $read",
|
||||
$template, $template_index)
|
||||
unless $expected eq $read;
|
||||
}
|
||||
$_ = $rest;
|
||||
} elsif (($rest) = /^A(.*)/) {
|
||||
## %A
|
||||
$template_index += 1;
|
||||
{
|
||||
my ($tag, $length, $value);
|
||||
$tag = ord (substr ($pdu, 0, 1));
|
||||
return error ("Expected IP address, got tag ".$tag)
|
||||
unless $tag == snmp_ip_address_tag;
|
||||
($length, $pdu) = decode_length ($pdu, 1);
|
||||
return error ("Inconsistent length of InetAddress encoding")
|
||||
if $length > length $pdu;
|
||||
return template_error ("IP address must be four bytes long",
|
||||
$template, $template_index)
|
||||
unless $length == 4;
|
||||
$read = substr ($pdu, 0, $length);
|
||||
$pdu = substr ($pdu, $length);
|
||||
}
|
||||
print STDERR "%A => $read\n" if $template_debug;
|
||||
push @results, $read;
|
||||
$_ = $rest;
|
||||
} elsif (/^O(.*)/) {
|
||||
## %O
|
||||
$template_index += 1;
|
||||
$_ = $1;
|
||||
(($read,$pdu) = decode_oid ($pdu))
|
||||
|| return template_error ("cannot read OID",
|
||||
$template, $template_index);
|
||||
print STDERR "%O => ".pretty_oid ($read)."\n"
|
||||
if $template_debug;
|
||||
push @results, $read;
|
||||
} elsif (($expected,$rest) = /^(\d*|\*|)i(.*)/) {
|
||||
## %i
|
||||
$template_index += length ($expected) + 1;
|
||||
print STDERR "%i\n" if $template_debug;
|
||||
$_ = $rest;
|
||||
(($read,$pdu) = decode_int ($pdu))
|
||||
|| return template_error ("cannot read int",
|
||||
$template, $template_index);
|
||||
if ($expected eq '') {
|
||||
push @results, $read;
|
||||
} else {
|
||||
$expected = int (shift) if $expected eq '*';
|
||||
return template_error (sprintf ("Expected %d (0x%x), got %d (0x%x)",
|
||||
$expected, $expected, $read, $read),
|
||||
$template, $template_index)
|
||||
unless ($expected == $read)
|
||||
}
|
||||
} elsif (($rest) = /^u(.*)/) {
|
||||
## %u
|
||||
$template_index += 1;
|
||||
print STDERR "%u\n" if $template_debug;
|
||||
$_ = $rest;
|
||||
(($read,$pdu) = decode_unsignedlike ($pdu))
|
||||
|| return template_error ("cannot read uptime",
|
||||
$template, $template_index);
|
||||
push @results, $read;
|
||||
} elsif (/^\@(.*)/) {
|
||||
## %@
|
||||
$template_index += 1;
|
||||
print STDERR "%@\n" if $template_debug;
|
||||
$_ = $1;
|
||||
push @results, $pdu;
|
||||
$pdu = '';
|
||||
} else {
|
||||
return template_error ("Unknown decoding directive in template: $_",
|
||||
$template, $template_index);
|
||||
}
|
||||
} else {
|
||||
if (substr ($_, 0, 1) ne substr ($pdu, 0, 1)) {
|
||||
return template_error ("Expected ".substr ($_, 0, 1).", got ".substr ($pdu, 0, 1),
|
||||
$template, $template_index);
|
||||
}
|
||||
$_ = substr ($_,1);
|
||||
$pdu = substr ($pdu,1);
|
||||
}
|
||||
}
|
||||
return template_error ("PDU too long", $template, $template_index)
|
||||
if length ($pdu) > 0;
|
||||
return template_error ("PDU too short", $template, $template_index)
|
||||
if length ($_) > 0;
|
||||
@results;
|
||||
}
|
||||
|
||||
sub decode_sequence ($) {
|
||||
my ($pdu) = @_;
|
||||
my ($result);
|
||||
my (@result);
|
||||
$result = ord (substr ($pdu, 0, 1));
|
||||
return error ("Sequence expected")
|
||||
unless $result == (sequence_tag | constructor_flag);
|
||||
($result, $pdu) = decode_length ($pdu, 1);
|
||||
return error ("Short PDU")
|
||||
if $result > length $pdu;
|
||||
@result = (substr ($pdu, 0, $result), substr ($pdu, $result));
|
||||
@result;
|
||||
}
|
||||
|
||||
sub decode_int ($) {
|
||||
my ($pdu) = @_;
|
||||
my $tag = ord (substr ($pdu, 0, 1));
|
||||
return error ("Integer expected, found tag ".$tag)
|
||||
unless $tag == int_tag;
|
||||
decode_intlike ($pdu);
|
||||
}
|
||||
|
||||
sub decode_intlike ($) {
|
||||
decode_intlike_s ($_[0], 1);
|
||||
}
|
||||
|
||||
sub decode_unsignedlike ($) {
|
||||
decode_intlike_s ($_[0], 0);
|
||||
}
|
||||
|
||||
my $have_math_bigint_p = 0;
|
||||
|
||||
sub decode_intlike_s ($$) {
|
||||
my ($pdu, $signedp) = @_;
|
||||
my ($length,$result);
|
||||
($length,$pdu) = decode_length ($pdu, 1);
|
||||
my $ptr = 0;
|
||||
$result = unpack ($signedp ? "c" : "C", substr ($pdu, $ptr++, 1));
|
||||
if ($length > 5 || ($length == 5 && $result > 0)) {
|
||||
require 'Math/BigInt.pm' unless $have_math_bigint_p++;
|
||||
$result = new Math::BigInt ($result);
|
||||
}
|
||||
while (--$length > 0) {
|
||||
$result *= 256;
|
||||
$result += unpack ("C", substr ($pdu, $ptr++, 1));
|
||||
}
|
||||
($result, substr ($pdu, $ptr));
|
||||
}
|
||||
|
||||
sub decode_string ($) {
|
||||
my ($pdu) = shift;
|
||||
my ($result);
|
||||
$result = ord (substr ($pdu, 0, 1));
|
||||
return error ("Expected octet string, got tag ".$result)
|
||||
unless $result == octet_string_tag;
|
||||
($result, $pdu) = decode_length ($pdu, 1);
|
||||
return error ("Short PDU")
|
||||
if $result > length $pdu;
|
||||
return (substr ($pdu, 0, $result), substr ($pdu, $result));
|
||||
}
|
||||
|
||||
sub decode_length ($@) {
|
||||
my ($pdu) = shift;
|
||||
my $index = shift || 0;
|
||||
my ($result);
|
||||
my (@result);
|
||||
$result = ord (substr ($pdu, $index, 1));
|
||||
if ($result & long_length) {
|
||||
if ($result == (long_length | 1)) {
|
||||
@result = (ord (substr ($pdu, $index+1, 1)), substr ($pdu, $index+2));
|
||||
} elsif ($result == (long_length | 2)) {
|
||||
@result = ((ord (substr ($pdu, $index+1, 1)) << 8)
|
||||
+ ord (substr ($pdu, $index+2, 1)), substr ($pdu, $index+3));
|
||||
} else {
|
||||
return error ("Unsupported length");
|
||||
}
|
||||
} else {
|
||||
@result = ($result, substr ($pdu, $index+1));
|
||||
}
|
||||
@result;
|
||||
}
|
||||
|
||||
# This takes a hashref that specifies functions to call when
|
||||
# the specified value type is being printed. It returns the
|
||||
# number of functions that were registered.
|
||||
sub register_pretty_printer($)
|
||||
{
|
||||
my ($h_ref) = shift;
|
||||
my ($type, $val, $cnt);
|
||||
|
||||
$cnt = 0;
|
||||
while(($type, $val) = each %$h_ref) {
|
||||
if (ref $val eq "CODE") {
|
||||
$pretty_printer{$type} = $val;
|
||||
$cnt++;
|
||||
}
|
||||
}
|
||||
return($cnt);
|
||||
}
|
||||
|
||||
# This takes a hashref that specifies functions to call when
|
||||
# the specified value type is being printed. It removes the
|
||||
# functions from the list for the types specified.
|
||||
# It returns the number of functions that were unregistered.
|
||||
sub unregister_pretty_printer($)
|
||||
{
|
||||
my ($h_ref) = shift;
|
||||
my ($type, $val, $cnt);
|
||||
|
||||
$cnt = 0;
|
||||
while(($type, $val) = each %$h_ref) {
|
||||
if ((exists ($pretty_printer{$type}))
|
||||
&& ($pretty_printer{$type} == $val)) {
|
||||
if (exists($default_printer{$type})) {
|
||||
$pretty_printer{$type} = $default_printer{$type};
|
||||
} else {
|
||||
delete $pretty_printer{$type};
|
||||
}
|
||||
$cnt++;
|
||||
}
|
||||
}
|
||||
return($cnt);
|
||||
}
|
||||
|
||||
#### OID prefix check
|
||||
|
||||
### encoded_oid_prefix_p OID1 OID2
|
||||
###
|
||||
### OID1 and OID2 should be BER-encoded OIDs.
|
||||
### The function returns non-zero iff OID1 is a prefix of OID2.
|
||||
### This can be used in the termination condition of a loop that walks
|
||||
### a table using GetNext or GetBulk.
|
||||
###
|
||||
sub encoded_oid_prefix_p ($$) {
|
||||
my ($oid1, $oid2) = @_;
|
||||
my ($i1, $i2);
|
||||
my ($l1, $l2);
|
||||
my ($subid1, $subid2);
|
||||
return error ("OID tag expected") unless ord (substr ($oid1, 0, 1)) == object_id_tag;
|
||||
return error ("OID tag expected") unless ord (substr ($oid2, 0, 1)) == object_id_tag;
|
||||
($l1,$oid1) = decode_length ($oid1, 1);
|
||||
($l2,$oid2) = decode_length ($oid2, 1);
|
||||
for ($i1 = 0, $i2 = 0;
|
||||
$i1 < $l1 && $i2 < $l2;
|
||||
++$i1, ++$i2) {
|
||||
($subid1,$i1) = &decode_subid ($oid1, $i1, $l1);
|
||||
($subid2,$i2) = &decode_subid ($oid2, $i2, $l2);
|
||||
return 0 unless $subid1 == $subid2;
|
||||
}
|
||||
return $i2 if $i1 == $l1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
### decode_subid OID INDEX
|
||||
###
|
||||
### Decodes a subid field from a BER-encoded object ID.
|
||||
### Returns two values: the field, and the index of the last byte that
|
||||
### was actually decoded.
|
||||
###
|
||||
sub decode_subid ($$$) {
|
||||
my ($oid, $i, $l) = @_;
|
||||
my $subid = 0;
|
||||
my $next;
|
||||
|
||||
while (($next = ord (substr ($oid, $i, 1))) >= 128) {
|
||||
$subid = ($subid << 7) + ($next & 0x7f);
|
||||
++$i;
|
||||
return error ("decoding object ID: short field")
|
||||
unless $i < $l;
|
||||
}
|
||||
return (($subid << 7) + $next, $i);
|
||||
}
|
||||
|
||||
sub error (@) {
|
||||
$errmsg = join ("",@_);
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub template_error ($$$) {
|
||||
my ($errmsg, $template, $index) = @_;
|
||||
return error ($errmsg."\n ".$template."\n ".(' ' x $index)."^");
|
||||
}
|
||||
|
||||
1;
|
||||
1123
debian/smokeping/usr/lib/SNMP_Session.pm
vendored
Normal file
1123
debian/smokeping/usr/lib/SNMP_Session.pm
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1321
debian/smokeping/usr/lib/SNMP_util.pm
vendored
Normal file
1321
debian/smokeping/usr/lib/SNMP_util.pm
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3
debian/smokeping/usr/lib/cgi-bin/smokeping.cgi
vendored
Executable file
3
debian/smokeping/usr/lib/cgi-bin/smokeping.cgi
vendored
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec /usr/share/smokeping/smokeping.cgi /etc/smokeping/config
|
||||
24
debian/smokeping/usr/lib/systemd/system/smokeping.service
vendored
Normal file
24
debian/smokeping/usr/lib/systemd/system/smokeping.service
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
[Unit]
|
||||
Description=Latency Logging and Graphing System
|
||||
Documentation=man:smokeping(1) file:/usr/share/doc/smokeping/examples/systemd/slave_mode.conf
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
# It would in theory be simpler to run smokeping with the --nodaemon option and
|
||||
# Type=simple, but smokeping does not work properly when in "slave" mode with
|
||||
# --nodaemon set.
|
||||
Type=forking
|
||||
RuntimeDirectory=smokeping
|
||||
PIDFile=/run/smokeping/smokeping.pid
|
||||
User=smokeping
|
||||
Group=smokeping
|
||||
|
||||
# If you need to run smokeping in slave/master mode, see the example unit
|
||||
# override in /usr/share/doc/smokeping/examples/systemd/slave_mode.conf
|
||||
#ExecStart=/usr/sbin/smokeping --pid-dir=/run/smokeping
|
||||
ExecStart=/usr/sbin/smokeping --config=/etc/smokeping/config --nodaemon
|
||||
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
143
debian/smokeping/usr/sbin/smokeinfo
vendored
Executable file
143
debian/smokeping/usr/sbin/smokeinfo
vendored
Executable file
@@ -0,0 +1,143 @@
|
||||
#!/usr/bin/perl
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use lib (split /:/, q{}); # PERL5LIB
|
||||
use lib qw(/usr/share/perl5); # LIBDIR
|
||||
|
||||
use Smokeping::Info;
|
||||
use Getopt::Long 2.25 qw(:config no_ignore_case);
|
||||
use Pod::Usage 1.14;
|
||||
|
||||
'$Revision: 3879 $ ' =~ /Revision: (\S*)/;
|
||||
my $Revision = $1;
|
||||
|
||||
sub main()
|
||||
{
|
||||
# parse options
|
||||
my %opt = (mode=>'plain',separator=>';',format=>'%le',start=>'end-24h',end=>'now');
|
||||
|
||||
GetOptions(\%opt, 'help|h', 'man', 'version', 'noaction|no-action|n','no-head',
|
||||
'start=s','end=s','filter=s','mode=s','separator=s','format=s') or exit(1);
|
||||
if($opt{help}) { pod2usage(1) }
|
||||
if($opt{man}) { pod2usage(-exitstatus => 0, -verbose => 2) }
|
||||
if($opt{version}) { print "smokeinfo $Revision\n"; exit(0) }
|
||||
if($opt{noaction}) { die "ERROR: don't know how to \"no-action\".\n" }
|
||||
my $config = shift @ARGV;
|
||||
|
||||
my $si = Smokeping::Info->new($config);
|
||||
my $nodes = $si->fetch_nodes(pattern=>$opt{filter},mode=>$opt{mode});
|
||||
my @rows = qw(med_avg med_min med_max med_now loss_avg loss_max loss_now);
|
||||
print '# ',join $opt{separator}, 'node_path',@rows if not $opt{'no-head'};
|
||||
print "\n";
|
||||
for my $node (@$nodes) {
|
||||
my $data = $si->stat_node($node,$opt{start},$opt{end});
|
||||
print join $opt{separator},$node->{path},map {defined $data->{$_} ? sprintf($opt{format},$data->{$_}) : '?'} @rows;
|
||||
print "\n";
|
||||
}
|
||||
}
|
||||
|
||||
main;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
smokeinfo - poll smokeping site for numeric information
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<smokeinfo> path/to/config.cfg [I<options>]
|
||||
|
||||
--start x rrd graph start time. (default now-24h)
|
||||
|
||||
--end y rrd graph end time. (default now)
|
||||
|
||||
--filter pattern search pattern for node selection
|
||||
|
||||
--mode plain (default) how to use the pattern
|
||||
- plain
|
||||
- recursive
|
||||
- regexp
|
||||
|
||||
--separator ; (default)
|
||||
|
||||
--format %le (default)
|
||||
|
||||
--no-head do not print a header
|
||||
|
||||
--man show man-page and exit
|
||||
-h, --help display this help and exit
|
||||
--version output version information and exit
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
SmokeInfo is a simple frontend to the L<Smokeping::Info> module. It provides
|
||||
access to numeric data stored in the rrd files.
|
||||
|
||||
Note that --start and --end are passed directly to rrd graph. This means
|
||||
they work on the same syntax.
|
||||
|
||||
=head2 Examples
|
||||
|
||||
Get all data all nodes
|
||||
|
||||
smokeinfo etc/config
|
||||
|
||||
Only show nodes directly under /Customers
|
||||
|
||||
smokeinfo --filter=/Customers/ etc/config
|
||||
|
||||
Show all nodes under /Customers
|
||||
|
||||
smokeinfo --mode=recursive --filter=/Customers/ etc/config
|
||||
|
||||
Show all nodes with '_wlan_' in the name
|
||||
|
||||
smokeinfo --mode=regexp --filter=_wlan_ etc/config
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<smokeping(1)>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (c) 2009 by OETIKER+PARTNER AG. All rights reserved.
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
S<Tobi Oetiker E<lt>tobi@oetiker.chE<gt>>
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
2009-01-05 to Initial Version
|
||||
|
||||
=cut
|
||||
|
||||
# Emacs Configuration
|
||||
#
|
||||
# Local Variables:
|
||||
# mode: cperl
|
||||
# eval: (cperl-set-style "PerlStyle")
|
||||
# mode: flyspell
|
||||
# mode: flyspell-prog
|
||||
# End:
|
||||
#
|
||||
# vi: sw=4 et
|
||||
|
||||
184
debian/smokeping/usr/sbin/smokeping
vendored
Executable file
184
debian/smokeping/usr/sbin/smokeping
vendored
Executable file
@@ -0,0 +1,184 @@
|
||||
#!/usr/bin/perl
|
||||
# -*-perl-*-
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use FindBin;
|
||||
use lib (split /:/, q{}); # PERL5LIB
|
||||
use lib qw(/usr/share/perl5); # LIBDIR
|
||||
|
||||
use Smokeping;
|
||||
|
||||
Smokeping::main("$FindBin::RealBin/../etc/config");
|
||||
|
||||
=head1 NAME
|
||||
|
||||
smokeping - Commandline tool for SmokePing
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<smokeping> [ B<--email> | B<--makepod> | B<--version> | B<--restart> ]
|
||||
|
||||
Options:
|
||||
|
||||
--man[=x] Show the manpage for the program (or for probe x, if specified)
|
||||
|
||||
--help Help :-)
|
||||
|
||||
--email Send SmokePing Agents to all Targets marked DYNAMIC
|
||||
|
||||
--config=x Use a config file different from the default
|
||||
|
||||
--check Just check the config file syntax, don't start the daemon
|
||||
|
||||
--makepod[=x] Create POD documentation on Config file (or for probe x, if specified)
|
||||
|
||||
--version Show SmokePing Version
|
||||
|
||||
--debug Run Only once and do not Fork
|
||||
|
||||
--debug-daemon Start the daemon with debugging enabled
|
||||
|
||||
--restart Restart SmokePing
|
||||
|
||||
--reload Reload configuration in the running process without interrupting
|
||||
any probes
|
||||
|
||||
--nodaemon Do no daemonize the process (no fork)
|
||||
|
||||
--filter=x Only measure entries which pass the filter x
|
||||
|
||||
--logfile=x Append warnings to logfile x.
|
||||
|
||||
--static[=x] Generates a static website in directory x. If x is left out,
|
||||
pagedir from the config is used.
|
||||
|
||||
--nosleep For debugging you may want to run SmokePing without sleep interval
|
||||
|
||||
--gen-examples Generate the smokeping_examples document and example config files
|
||||
(to be used while building inside the smokeping distribution)
|
||||
With --check : check the syntax of the generated examples.
|
||||
|
||||
--master-url=s Run smokeping in slave mode. Attach to master for config.
|
||||
|
||||
--slave-name=s By default the slave will use whatever it thinks its name
|
||||
is, when talking to its master. In some cases you may
|
||||
probably want to override this.
|
||||
|
||||
|
||||
--shared-secret=s File containing the shared secret for talking to the server.
|
||||
|
||||
--cache-dir=s Directory for temporary data storage when running in slave mode.
|
||||
|
||||
--pid-dir=s Directory for the PID file when running in slave mode.
|
||||
(optional, defaults to --cache-dir)
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The B<smokeping> tool is the commandline part of the SmokePing system. Its
|
||||
main function is to run as a daemon and send Pings to all the Targets you
|
||||
have specified in the Config file. When you call B<smokeping> without
|
||||
arguments it will start as a daemon and do its work.
|
||||
|
||||
If called with an argument, then further functions can be activated, as seen
|
||||
in the Synopsis above. The B<--email> function is explained in the
|
||||
documentation on the config file.
|
||||
|
||||
The B<--filter> option allows you to run the daemon on a big config file,
|
||||
but have the config file filtered and only measure the entries that pass the
|
||||
filter. This is useful for remote measurement. Run Smokeping with two
|
||||
exclusive filters in two locations and rsync the rrds back to the webserver
|
||||
host where you run the cgi. Filters act on the section names in the config
|
||||
file. Multiple section names are concatenated with B</> like path names:
|
||||
|
||||
*** targets ***
|
||||
+ A
|
||||
....
|
||||
+ B
|
||||
...
|
||||
++ C
|
||||
|
||||
This gives
|
||||
|
||||
/A
|
||||
|
||||
and
|
||||
|
||||
/B, /B/C
|
||||
|
||||
If I want to monitor /A my filter would look like this:
|
||||
|
||||
--filter=/A
|
||||
|
||||
Filters follow regular expression syntax. The are always anchored at the tip of the string.
|
||||
by adding a B<!> to the front of the filter string you negate it. Matching entries will be excluded from monitoring.
|
||||
Multiple B<--filter> arguments can be used to assemble complex filters:
|
||||
|
||||
--filter=/A --filter=/B
|
||||
|
||||
would include all the targets
|
||||
|
||||
--filter=/A --filter=/B --filter=!/B/C
|
||||
|
||||
would include all but /B/C.
|
||||
|
||||
The B<--makepod> does get used internally to produce the
|
||||
L<documentation on the SmokePing configuration file|smokeping_config>.
|
||||
|
||||
Please refer to L<the installation document|smokeping_install> for detailed setup instructions.
|
||||
|
||||
=head1 SETUP
|
||||
|
||||
When installing SmokePing, this file has to be adjusted to fit your
|
||||
local system. Three paths have to be entered.
|
||||
|
||||
One pointing to your B<rrdtool> installation
|
||||
|
||||
use lib qw(/usr/pack/rrdtool-1.0.33-to/lib/perl);
|
||||
|
||||
One pointing to the place where you have installed the SmokePing libraries
|
||||
|
||||
use lib qw(/home/oetiker/public_html/smokeping/lib);
|
||||
|
||||
The third path is the argument to the Smokeping::main command. It points to
|
||||
the SmokePing configuration file.
|
||||
|
||||
use Smokeping;
|
||||
Smokeping::main("/home/oetiker/.smokeping/config");
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<smokeping_config(5)>, L<smokeping_examples(5)>, L<smokeping_cgi(1)>,
|
||||
L<tSmoke(1)>, L<smokeping_master_slave(7)>, L<smokeping_extend(7)>,
|
||||
L<smokeping_install(7)>, L<smokeping_upgrade(7)>,
|
||||
How to read the graphs https://oss.oetiker.ch/smokeping/doc/reading.en.html
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (c) 2002 by Tobias Oetiker. All right reserved.
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
This program is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public
|
||||
License along with this program; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
|
||||
02139, USA.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Tobias Oetiker E<lt>tobi@oetiker.chE<gt>
|
||||
|
||||
=cut
|
||||
570
debian/smokeping/usr/sbin/tSmoke
vendored
Executable file
570
debian/smokeping/usr/sbin/tSmoke
vendored
Executable file
@@ -0,0 +1,570 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
#-----------------------------------------------
|
||||
# tSmoke.pl
|
||||
# Dan McGinn-Combs, Sep 2003
|
||||
# tSmoke.v 0.4 2004/03 McGinn-Combs
|
||||
#-----------------------------------------------
|
||||
#
|
||||
# Modified for Smokeping official distribution since 20050526
|
||||
# Original README follows
|
||||
#
|
||||
# tSmoke.v04.README
|
||||
# - added downtime report (--downtime)
|
||||
# - a few tweaks to the calculations to ensure it's consistent
|
||||
#
|
||||
# tSmoke.v03.README
|
||||
# - Initial Release
|
||||
# - The script, started through cron, will cull through a config file and
|
||||
# determine which hosts are down at a point in time (Morning report) and
|
||||
# send out an smtp message to a mobile phone (for example).
|
||||
#
|
||||
# - It will also cull through the same config file and, using an included html
|
||||
# file (small change to General section of the config file), send an html
|
||||
# message which shows the availability over the past day, week, month
|
||||
# and quarter.
|
||||
#
|
||||
# - It can also show detail data depending on the setting of
|
||||
# command line option "detail".
|
||||
#
|
||||
# tSmoke.v02.README
|
||||
# - Local testing version
|
||||
#-----------------------------------------------
|
||||
#
|
||||
# 1) This program is run via CRON or the command line
|
||||
# 2) It extracts RRD information from a smokeping config file
|
||||
# 3) It pulls data from RRD files to determine if anything is offline, that is returning 0 PINGs
|
||||
# 4) tSmoke reports status via an SMTP alert
|
||||
# 5) tSmoke also generates an SMTP mail showing historical view of availability
|
||||
#
|
||||
# Many thanks to the following people for their help and guidance:
|
||||
# Jim Horwath of Agere Systems Inc. for his examples and pointers to Spreadsheet::WriteExcel
|
||||
# Frank Harper the author of SLAMon, a tool for tracking Service Level Agreements
|
||||
# Tobias Oetiker, or course, the author of Smokeping, RRDTool and MRTG
|
||||
#
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
# We need to use
|
||||
# -- Smokeping libraries
|
||||
# -- RRDTool
|
||||
# -- Getopt::Long
|
||||
#
|
||||
# Point the lib variables to your implementation
|
||||
|
||||
use lib (split /:/, q{}); # PERL5LIB
|
||||
use FindBin;
|
||||
use lib qw(/usr/share/perl5); # LIBDIR
|
||||
|
||||
|
||||
use Smokeping;
|
||||
use Net::SMTP;
|
||||
use Getopt::Long;
|
||||
use Pod::Usage;
|
||||
use RRDs;
|
||||
|
||||
# Point to your Smokeping config file
|
||||
my $cfgfile = (shift @ARGV) || "$FindBin::Bin/../etc/config";
|
||||
|
||||
# global variables
|
||||
my $cfg;
|
||||
|
||||
#this is designed to work on IPv4 only
|
||||
my $havegetaddrinfo = 0;
|
||||
|
||||
# we want opts everywhere
|
||||
my %opt;
|
||||
|
||||
#Hashes for the data
|
||||
my (%Daily,%Weekly,%Monthly,%Quarterly); # the entries
|
||||
my (%DailyC,%WeeklyC,%MonthlyC,%QuarterlyC); # a count of the entries
|
||||
|
||||
######################
|
||||
### Moving Average ###
|
||||
######################
|
||||
# Just a reminder of how to do a moving average if you ever want to
|
||||
# PREV,UN,<DS>,UN,1,<DS>,IF,PREV,IF,<DS>,UN,1,<DS>,IF,-,<WEIGHT>,*,A,UN,1,A,IF,+
|
||||
|
||||
# Change Log:
|
||||
# DMC - Added Quarterly Status
|
||||
# DMC - Added HTML mail reporting and consolidated functions
|
||||
# DMC = Added an external HTML mail template, tMail
|
||||
my $RCS_VERSION = '$id: tSmoke.v 0.4 2004/03 McGinn-Combs';
|
||||
|
||||
sub test_mail($) {
|
||||
my $cfg = shift;
|
||||
my $mail = <<"EOF";
|
||||
Subject: tSmoke test
|
||||
To: $cfg->{Alerts}{to}
|
||||
|
||||
This is a test mail with 'tSmoke --testmail'.
|
||||
EOF
|
||||
print "Sending a test mail to $cfg->{Alerts}{to} from $cfg->{Alerts}{from}...";
|
||||
Smokeping::sendmail($cfg->{Alerts}{from}, $cfg->{Alerts}{to}, $mail);
|
||||
print "done.\n";
|
||||
};
|
||||
|
||||
sub morning_update($) {
|
||||
# Send out a morning summary of devices that are down
|
||||
my $cfg = shift;
|
||||
my $Body = "";
|
||||
my $TmpBody = "";
|
||||
my $To = "";
|
||||
if ( $opt{to} ) { $To = $opt{to}; } else { $To = $cfg->{Alerts}{to}; }
|
||||
|
||||
# Get a list of the existing RRD Files
|
||||
my @rrds = split ( /\n/,list_rrds($cfg->{Targets},"","") );
|
||||
my $Count = $#rrds + 1;
|
||||
my $Down = 0;
|
||||
|
||||
foreach my $target (@rrds) {
|
||||
my $Loss = 0;
|
||||
my ($start,$step,$names,$data) = RRDs::fetch "$target","AVERAGE","--start","-300";
|
||||
my $ERR=RRDs::error;
|
||||
die "ERROR while reading $_: $ERR\n" if $ERR;
|
||||
foreach my $line (@$data) {
|
||||
$Loss += ( defined($$line[3]) ? $$line[3] : 0 );
|
||||
}
|
||||
$Down += 1 if $Loss == 0;
|
||||
$target =~ s/^([a-zA-Z0-9]*\/)*//;
|
||||
$target =~ s/.rrd//;
|
||||
$target =~ s/\~(.*)/ from $1/ if $target =~ m/\~/;
|
||||
$TmpBody .= "$target\n" if $Loss == 0;
|
||||
}
|
||||
$Body = <<MAIL_END;
|
||||
Subject: Of $Count Hosts, $Down Down
|
||||
To: $To
|
||||
Content-Type: text/plain; charset=iso-8859-15
|
||||
Content-Transfer-encoding: 8bit
|
||||
MIME-Version: 1.0
|
||||
|
||||
Of $Count Hosts, $Down Down:
|
||||
|
||||
$TmpBody
|
||||
MAIL_END
|
||||
Smokeping::sendmail($cfg->{Alerts}{from},$To,$Body);
|
||||
}
|
||||
|
||||
sub weekly_update($) {
|
||||
# Send out a formatted HTML Table of the
|
||||
# Previous Day, Week, Month and Quarter Availability
|
||||
# Get a list of the existing RRD Files
|
||||
my @rrds = split ( /\n/,list_rrds($cfg->{Targets},"","") );
|
||||
|
||||
my $To = "";
|
||||
if ( $opt{to} ) { $To = $opt{to}; } else { $To = $cfg->{Alerts}{to}; }
|
||||
|
||||
my $Body ='';
|
||||
|
||||
# Calculations Based on the following:
|
||||
# RRDs::graph "fake.png",
|
||||
# '--start','-86400',
|
||||
# '-end','-300',
|
||||
# "DEF:loss=${rrd}:loss:AVERAGE",
|
||||
# "CDEF:avail=loss,0,100,IF", or more precisely "CDEF:avail=loss,2,GE,0,100,IF"
|
||||
# and adding in the check for unknown for systems just coming on line
|
||||
# "CDEF:avail=loss,UN,0,loss,IF,$pings,GE,0,100,IF"
|
||||
# Arbitrarily a loss of 10% of Pings means the system was down
|
||||
my $pings = $cfg->{Database}{pings} * .1;
|
||||
|
||||
foreach my $target (@rrds) {
|
||||
# Get an average Availability for each RRD file
|
||||
my $ERR;
|
||||
|
||||
my ($DAverage,$Dxsize,$Dysize) = RRDs::graph "fake.png",
|
||||
"--start","-86400",
|
||||
"--end","-600",
|
||||
"--step","1008",
|
||||
"DEF:loss=$target:loss:AVERAGE",
|
||||
"CDEF:avail=loss,UN,0,loss,IF,$pings,GE,0,100,IF",
|
||||
"PRINT:avail:AVERAGE:%.2lf";
|
||||
$ERR=RRDs::error;
|
||||
die "ERROR while reading $_: $ERR\n" if $ERR;
|
||||
|
||||
my ($WAverage,$Wxsize,$Wysize) = RRDs::graph "fake.png",
|
||||
"--start","-604800",
|
||||
"--end","-600",
|
||||
"--step","4320",
|
||||
"DEF:loss=$target:loss:AVERAGE",
|
||||
"CDEF:avail=loss,UN,0,loss,IF,$pings,GE,0,100,IF",
|
||||
"PRINT:avail:AVERAGE:%.2lf";
|
||||
$ERR=RRDs::error;
|
||||
die "ERROR while reading $_: $ERR\n" if $ERR;
|
||||
|
||||
my ($MAverage,$Mxsize,$Mysize) = RRDs::graph "fake.png",
|
||||
"--start","-2592000",
|
||||
"--end","-600",
|
||||
"--step","4320",
|
||||
"DEF:loss=$target:loss:AVERAGE",
|
||||
"CDEF:avail=loss,UN,0,loss,IF,$pings,GE,0,100,IF",
|
||||
"PRINT:avail:AVERAGE:%.2lf";
|
||||
$ERR=RRDs::error;
|
||||
die "ERROR while reading $_: $ERR\n" if $ERR;
|
||||
|
||||
my ($QAverage,$Qxsize,$Qysize) = RRDs::graph "fake.png",
|
||||
"--start","-7776000",
|
||||
"--end","-600",
|
||||
"--step","4320",
|
||||
"DEF:loss=$target:loss:AVERAGE",
|
||||
"CDEF:avail=loss,UN,0,loss,IF,$pings,GE,0,100,IF",
|
||||
"PRINT:avail:AVERAGE:%.2lf";
|
||||
$ERR=RRDs::error;
|
||||
die "ERROR while reading $_: $ERR\n" if $ERR;
|
||||
|
||||
$target =~ s/$cfg->{General}{datadir}\///;
|
||||
$target =~ s/.rrd//;
|
||||
my @Path;
|
||||
push @Path,split/\//,$target;
|
||||
update_stats ( \@Path, @$DAverage[0], @$WAverage[0], @$MAverage[0], @$QAverage[0]);
|
||||
}
|
||||
|
||||
# Prepare the e-mail message
|
||||
$Body = <<MAIL_END;
|
||||
Subject: IT System Availability
|
||||
To: $To
|
||||
Content-Type: text/html; charset=iso-8859-15
|
||||
Content-Transfer-encoding: 8bit
|
||||
MIME-Version: 1.0
|
||||
|
||||
MAIL_END
|
||||
open tSMOKE, $cfg->{General}{tmail} or die "ERROR: can't read $cfg->{General}{tmail}\n";
|
||||
while (<tSMOKE>){
|
||||
my $Summary = Summary_Sheet();
|
||||
s/<##SUMMARY##>/$Summary/ig;
|
||||
my $Daily = DetailSheet(86400);
|
||||
s/<##DAYDETAIL##>/$Daily/ig;
|
||||
my $Weekly = DetailSheet(604800);
|
||||
s/<##WEEKDETAIL##>/$Weekly/ig;
|
||||
my $Monthly = DetailSheet(2592000);
|
||||
s/<##MONTHDETAIL##>/$Monthly/ig;
|
||||
my $Quarterly = DetailSheet(7776000);
|
||||
s/<##QUARTERDETAIL##>/$Quarterly/ig;
|
||||
$Body .= $_;
|
||||
}
|
||||
close tSMOKE;
|
||||
Smokeping::sendmail($cfg->{Alerts}{from}, $To, $Body);
|
||||
}
|
||||
|
||||
sub update_stats($$$$$);
|
||||
sub update_stats($$$$$) {
|
||||
# Update the uptime percentages in the Hash Arrays
|
||||
my $Path = shift;
|
||||
my $DAverage = shift;
|
||||
my $WAverage = shift;
|
||||
my $MAverage = shift;
|
||||
my $QAverage = shift;
|
||||
|
||||
#Enter everything once as it exists
|
||||
#Trim off the rightmost component (hostname) and reenter the code
|
||||
#If there is only one component, this is the final level
|
||||
#This is an average of averages
|
||||
|
||||
my $Ticket = join ( ".",@$Path);
|
||||
$Daily { $Ticket } += $DAverage;
|
||||
$Weekly { $Ticket } += $WAverage;
|
||||
$Monthly { $Ticket } += $MAverage;
|
||||
$Quarterly {$Ticket } += $QAverage;
|
||||
$DailyC { $Ticket }++;
|
||||
$WeeklyC { $Ticket }++;
|
||||
$MonthlyC { $Ticket }++;
|
||||
$QuarterlyC { $Ticket }++;
|
||||
my $Length = @$Path;
|
||||
@$Path = @$Path [ 0 .. $Length - 2 ];
|
||||
update_stats(\@$Path,$DAverage,$WAverage,$MAverage,$QAverage) if $Length > 1;
|
||||
}
|
||||
|
||||
sub Summary_Sheet() {
|
||||
my $Body = '';
|
||||
|
||||
$Body .= "<table border='1' bordercolor=#111111>\n";
|
||||
$Body .= "<tr>\n";
|
||||
$Body .= "<td class ='appHeader' colspan='5'>IT Network Systems Availability Summary</td></tr>\n";
|
||||
$Body .= "<tr>\n";
|
||||
$Body .= "<td class ='appHeader' colspan='5'>Compiled: ". scalar(localtime) . "</td></tr>\n";
|
||||
$Body .= "<tr>\n";
|
||||
$Body .= "<td class = 'subhead' width='20%'>Service</td>
|
||||
<td class = 'subhead' width='20%'>Past Quarter</td>
|
||||
<td class = 'subhead' width='20%'>Past Month</td>
|
||||
<td class = 'subhead' width='20%'>Past Week</td>
|
||||
<td class = 'subhead' width='20%'>Past Day</td></tr>\n";
|
||||
foreach (sort { $a cmp $b } keys %Monthly) {
|
||||
next if ( $_ =~ /\./ );
|
||||
# this is a major section heading
|
||||
$Body .= "<tr>\n";
|
||||
$Body .= "<td class = 'SubHead'>$_</td>";
|
||||
$Body .= "<td class = 'Up99'>" . sprintf('%.2f',$Quarterly{$_}/$QuarterlyC{$_}) . "%</td>"
|
||||
if $Quarterly{$_}/$QuarterlyC{$_} >= 99 ;
|
||||
$Body .= "<td class = 'Up95'>" . sprintf('%.2f',$Quarterly{$_}/$QuarterlyC{$_}) . "%</td>"
|
||||
if $Quarterly{$_}/$QuarterlyC{$_} > 95 and $Quarterly{$_}/$QuarterlyC{$_} < 99 ;
|
||||
$Body .= "<td class = 'Up90'>" . sprintf('%.2f',$Quarterly{$_}/$QuarterlyC{$_}) . "%</td>"
|
||||
if $Quarterly{$_}/$QuarterlyC{$_} > 90 and $Quarterly{$_}/$QuarterlyC{$_} < 95 ;
|
||||
$Body .= "<td class = 'UpNo'>" . sprintf('%.2f',$Quarterly{$_}/$QuarterlyC{$_}) . "%</td>"
|
||||
if $Quarterly{$_}/$QuarterlyC{$_} < 90 ;
|
||||
$Body .= "<td class = 'Up99'>" . sprintf('%.2f',$Monthly{$_}/$MonthlyC{$_}) . "%</td>"
|
||||
if $Monthly{$_}/$MonthlyC{$_} >= 99 ;
|
||||
$Body .= "<td class = 'Up95'>" . sprintf('%.2f',$Monthly{$_}/$MonthlyC{$_}) . "%</td>"
|
||||
if $Monthly{$_}/$MonthlyC{$_} > 95 and $Monthly{$_}/$MonthlyC{$_} < 99 ;
|
||||
$Body .= "<td class = 'Up90'>" . sprintf('%.2f',$Monthly{$_}/$MonthlyC{$_}) . "%</td>"
|
||||
if $Monthly{$_}/$MonthlyC{$_} > 90 and $Monthly{$_}/$MonthlyC{$_} < 95 ;
|
||||
$Body .= "<td class = 'UpNo'>" . sprintf('%.2f',$Monthly{$_}/$MonthlyC{$_}) . "%</td>"
|
||||
if $Monthly{$_}/$MonthlyC{$_} < 90 ;
|
||||
$Body .= "<td class = 'Up99'>" . sprintf('%.2f',$Weekly{$_}/$WeeklyC{$_}) . "%</td>"
|
||||
if $Weekly{$_}/$WeeklyC{$_} >= 99;
|
||||
$Body .= "<td class = 'Up95'>" . sprintf('%.2f',$Weekly{$_}/$WeeklyC{$_}) . "%</td>"
|
||||
if $Weekly{$_}/$WeeklyC{$_} > 95 and $Weekly{$_}/$WeeklyC{$_} < 99 ;
|
||||
$Body .= "<td class = 'Up90'>" . sprintf('%.2f',$Weekly{$_}/$WeeklyC{$_}) . "%</td>"
|
||||
if $Weekly{$_}/$WeeklyC{$_} > 90 and $Weekly{$_}/$WeeklyC{$_} < 95 ;
|
||||
$Body .= "<td class = 'UpNo'>" . sprintf('%.2f',$Weekly{$_}/$WeeklyC{$_}) . "%</td>"
|
||||
if $Weekly{$_}/$WeeklyC{$_} < 90 ;
|
||||
$Body .= "<td class = 'Up99'>" . sprintf('%.2f',$Daily{$_}/$DailyC{$_}) . "%</td>"
|
||||
if $Daily{$_}/$DailyC{$_} >= 99;
|
||||
$Body .= "<td class = 'Up95'>" . sprintf('%.2f',$Daily{$_}/$DailyC{$_}) . "%</td>"
|
||||
if $Daily{$_}/$DailyC{$_} > 95 and $Daily{$_}/$DailyC{$_} < 99 ;
|
||||
$Body .= "<td class = 'Up90'>" . sprintf('%.2f',$Daily{$_}/$DailyC{$_}) . "%</td>"
|
||||
if $Daily{$_}/$DailyC{$_} > 90 and $Daily{$_}/$DailyC{$_} < 95 ;
|
||||
$Body .= "<td class = 'UpNo'>" . sprintf('%.2f',$Daily{$_}/$DailyC{$_}) . "%</td>"
|
||||
if $Daily{$_}/$DailyC{$_} < 90 ;
|
||||
$Body .= "</tr>\n";
|
||||
}
|
||||
$Body .= "</table>";
|
||||
$Body .= "<P><P><P>\n";
|
||||
$Body .= "<table border='1' bordercolor=#111111><tr><td class ='appHeader'>Legend:</td>\n";
|
||||
$Body .= "<tr><td class = 'Up99'>if uptime > 99% then GREEN</td></tr>\n";
|
||||
$Body .= "<tr><td class = 'Up95'>if uptime > 95% but < 99% then BLUE</td></tr>\n";
|
||||
$Body .= "<tr><td class = 'Up90'>if uptime > 90% but < 95% then YELLOW</td></tr>\n";
|
||||
$Body .= "<tr><td class = 'UpNo'>if uptime < 90% then RED</td></tr>\n";
|
||||
$Body .= "</table>\n";
|
||||
return $Body;
|
||||
}
|
||||
|
||||
sub NumDots($) {
|
||||
# Count the number of dots in a string
|
||||
# There's probably a better way to do this
|
||||
my $DNA = shift;
|
||||
my $a = 0;
|
||||
while($DNA =~ /\./ig){$a++}
|
||||
return $a
|
||||
}
|
||||
|
||||
sub DetailSheet($) {
|
||||
# Populate the table with details depending on the value of %opts{detail}
|
||||
my $Seconds = shift;
|
||||
my $Body = '';
|
||||
|
||||
return '' unless $opt{detail};
|
||||
|
||||
# Monthly/Weekly/Daily
|
||||
$Body .= "<table border='1' bordercolor=#111111>\n";
|
||||
$Body .= "<tr>\n";
|
||||
$Body .= "<td class ='appHeader' colspan='3'>IT Network Systems Availability Previous " . $Seconds/86400 . " Day(s)</td></tr>\n";
|
||||
$Body .= "<tr>\n";
|
||||
$Body .= "<td class ='appHeader' colspan='3'>Compiled: ". scalar(localtime) . "</td></tr>\n";
|
||||
$Body .= "<tr>\n";
|
||||
$Body .= "<td class = 'SubHead' width='40%'>Service</td>
|
||||
<td class = 'SubHead' width='30%'>Seconds</td>
|
||||
<td class = 'SubHead' width='30%'>Percent</td></tr>\n";
|
||||
|
||||
my %CornBeef;
|
||||
my %CornBeefC;
|
||||
|
||||
CASE: {
|
||||
%CornBeef = %Daily, %CornBeefC = %DailyC, print "Doing Daily\n", last CASE if $Seconds == 86400;
|
||||
%CornBeef = %Weekly, %CornBeefC = %WeeklyC, print "Doing Weekly\n", last CASE if $Seconds == 604800;
|
||||
%CornBeef = %Monthly, %CornBeefC = %MonthlyC, print "Doing Monthly\n", last CASE if $Seconds == 2592000;
|
||||
%CornBeef = %Quarterly, %CornBeefC = %QuarterlyC, print "Doing Quarterly\n", last CASE if $Seconds == 7776000;
|
||||
} # end of CASE block
|
||||
|
||||
foreach (sort { $a cmp $b } keys %CornBeef ) {
|
||||
next if NumDots ($_) > $opt{detail};
|
||||
if ( $_ =~ /\./ ) {
|
||||
#this is a sub section
|
||||
$Body .= "<tr>\n";
|
||||
$Body .= "<td class = 'SubSubHead'>$_</td>\n";
|
||||
$Body .= "<td class = 'SubDetail'>" . sprintf('%.0f',(100 - $CornBeef{$_} / $CornBeefC{$_}) * ($Seconds/100)) . "</td>\n";
|
||||
$Body .= "<td class = 'SubDetail'>" . sprintf('%.2f',$CornBeef{$_} / $CornBeefC{$_}) . "%</td>\n";
|
||||
$Body .= "</tr>\n";
|
||||
} else {
|
||||
# this is a non-sub section
|
||||
$Body .= "<tr>\n";
|
||||
$Body .= "<td class = 'SubHead'>" . $_ . "</td>\n";
|
||||
$Body .= "<td class = 'SubDetail'>" . sprintf('%.0f',(100 - $CornBeef{$_} / $CornBeefC{$_}) * ($Seconds/100)) . "</td>\n";
|
||||
$Body .= "<td class = 'SubDetail'>" . sprintf('%.2f',$CornBeef{$_} / $CornBeefC{$_}) . "%</td>\n";
|
||||
$Body .= "</tr>";
|
||||
}
|
||||
}
|
||||
$Body .= "</table>\n";
|
||||
return $Body;
|
||||
}
|
||||
|
||||
sub list_rrds($$$$$);
|
||||
sub list_rrds($$$$$) {
|
||||
# List the RRD's used by this configuration
|
||||
my $tree = shift;
|
||||
my $path = shift;
|
||||
my $print = shift;
|
||||
my $slaves = shift;
|
||||
my $nomasterpoll = shift;
|
||||
my $prline = '';
|
||||
if ( $opt{slaves} ) {
|
||||
$slaves = $tree->{slaves} if exists( $tree->{slaves} );
|
||||
} else {
|
||||
$slaves = '';
|
||||
}
|
||||
$nomasterpoll = $tree->{nomasterpoll} if exists ( $tree->{nomasterpoll} );
|
||||
foreach my $rrds (keys %{$tree}) {
|
||||
if (ref $tree->{$rrds} eq 'HASH'){
|
||||
$prline .= list_rrds( $tree->{$rrds}, $path."/$rrds", $print, $slaves, $nomasterpoll );
|
||||
}
|
||||
if ($rrds eq 'host' and $tree->{$rrds} !~ m|/| ) {
|
||||
if ( exists( $opt{slaves} ) && $slaves ) {
|
||||
foreach( split( /\s+/, $slaves ) ) {
|
||||
my $tslave = $_;
|
||||
$prline .= "$cfg->{General}{datadir}$path~$tslave".".rrd\n"
|
||||
if $opt{slaves} eq '' || grep( $tslave, split( ',', $opt{slaves} ) );
|
||||
}
|
||||
$prline .= "$cfg->{General}{datadir}$path".".rrd\n" unless $nomasterpoll;
|
||||
} else {
|
||||
$prline .= "$cfg->{General}{datadir}$path".".rrd\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
return $prline;
|
||||
}
|
||||
|
||||
sub load_cfg ($) {
|
||||
my $cfgfile = shift;
|
||||
# my $parser = get_parser;
|
||||
my $parser = Smokeping::get_parser;
|
||||
$cfg = Smokeping::get_config $parser, $cfgfile;
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# The Main Program
|
||||
###########################################################################
|
||||
|
||||
sub main($);
|
||||
main($cfgfile);
|
||||
|
||||
sub main ($) {
|
||||
umask 022;
|
||||
my $cfgfile = shift;
|
||||
my $sendto;
|
||||
GetOptions(\%opt, 'quiet','version','testmail','listrrds','to=s','detail=n','morning','weekly','help','man','slaves:s') or pod2usage(2);
|
||||
if($opt{version}) { print "$RCS_VERSION\n"; exit(0) };
|
||||
if($opt{help}) { pod2usage(-verbose => 1); exit 0 };
|
||||
if($opt{man}) { pod2usage(-verbose => 2); exit 0 };
|
||||
load_cfg $cfgfile;
|
||||
print "tSmoke for network managed by $cfg->{General}{owner}\nat $cfg->{General}{contact}\n(c) 2003 Dan McGinn-Combs\n" unless $opt{quiet};
|
||||
if($opt{testmail}) { test_mail($cfg) };
|
||||
if($opt{listrrds}) { print "List of Round Robin Databases used by this implementation\n";
|
||||
my @rrds = split ( /\n/,list_rrds($cfg->{Targets},"","","","") );
|
||||
foreach (@rrds) {
|
||||
print "RRD: $_\n"; };
|
||||
}
|
||||
if($opt{morning}) { morning_update($cfg) };
|
||||
if($opt{weekly}) { weekly_update($cfg) };
|
||||
exit 0;
|
||||
}
|
||||
|
||||
=head1 NAME
|
||||
|
||||
tSmoke - Commandline tool for sending SmokePing information
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<tSmoke> [ B<--testmail> | B<--morning> | B<--weekly> | B<--version> | B<--help> | B<--man> | B<--slaves> ]
|
||||
|
||||
Options:
|
||||
|
||||
--man Show the manpage
|
||||
--help Help :-)
|
||||
--version Show SmokePing Version
|
||||
--testmail Send a test message
|
||||
--listrrds List the RRDs used by this Smokeping
|
||||
--morning Send a morning synopsis
|
||||
--weekly Send a weekly status report
|
||||
--to E-mail address to send message (i.e. '--to=xyz@company.com.invalid'
|
||||
--detail How much detail to send in weekly report (i.e. '--detail=1')
|
||||
--quiet Do not print welcome
|
||||
--slaves Enable slave support assumes all slaves unless csv list of slaves
|
||||
is added (i.e. '--slaves' or '--slaves=slave1[,slave2...]')
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The B<tSmoke> tool is a commandline tool which interfaces with the SmokePing system.
|
||||
Its main function is to send a message indicating the current status of the systems
|
||||
being monitored by Smokeping or an HTML mail file containing the status over the past day,
|
||||
past week and past month including an overview.
|
||||
|
||||
Typical crontab used to invoke this are
|
||||
|
||||
# Quick morning alert to see what's down
|
||||
0 6 * * * /usr/local/smokeping/bin/tSmoke.pl --q --to=mobilephone@att.net.invalid --morning
|
||||
# Weekly report on the percent availability of network systems with no detail
|
||||
0 8 * * * /usr/local/smokeping/bin/tSmoke.pl --q --to=mailbox@company.com.invalid --weekly --detail=0
|
||||
|
||||
=head1 SETUP
|
||||
|
||||
When installing tSmoke, some variables must be adjusted to fit your local system.
|
||||
|
||||
We need to use the following B<libraries>:
|
||||
|
||||
=over
|
||||
|
||||
=item Smokeping
|
||||
|
||||
=item RRDTool Perl bindings
|
||||
|
||||
=item Getopt::Long
|
||||
|
||||
=back
|
||||
|
||||
Set up your libraries:
|
||||
|
||||
use lib "/usr/local/smokeping/lib";
|
||||
use lib "/usr/local/rrdtool-1.0.39/lib/perl";
|
||||
|
||||
Point to your Smokeping B<config> file
|
||||
|
||||
my $cfgfile = "/usr/local/smokeping/etc/config";
|
||||
|
||||
Modify the Smokeping config file to include a path for tmail in the
|
||||
General section:
|
||||
|
||||
tmail = /usr/local/smokeping/etc/tmail
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<smokeping(1)>, L<smokeping_config(5)>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (c) 2003 by Dan McGinn-Combs. All right reserved.
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
This program is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public
|
||||
License along with this program; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
|
||||
02139, USA.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Dan McGinn-Combs E<lt>d.mcginn-combs@mindspring.comE<gt>
|
||||
|
||||
Modified for Smokeping official distribution by Niko Tyni E<lt>ntyni@iki.fiE<gt>
|
||||
|
||||
=cut
|
||||
|
||||
22
debian/smokeping/usr/share/doc/smokeping/README.Debian
vendored
Normal file
22
debian/smokeping/usr/share/doc/smokeping/README.Debian
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
After installing the package you have to edit the files in
|
||||
/etc/smokeping/config.d to set your preferences.
|
||||
|
||||
Note that the domain names are bogus to avoid all the people who
|
||||
install the package DoSing the same servers, but at the same time an
|
||||
fping probe in localhost is enabled, so you can check if smokeping
|
||||
works for you.
|
||||
|
||||
You can also edit the file /etc/smokeping/basepage.html to suit your
|
||||
needs.
|
||||
|
||||
A FastCGI configuration might be desirable for large sites. Simply add
|
||||
this to the Apache configuration, in /etc/apache2/conf-available/smokeping.conf:
|
||||
|
||||
<Location /smokeping/smokeping.cgi>
|
||||
SetHandler fcgid-script
|
||||
</Location>
|
||||
|
||||
Please refer to the smokeping_config man page to see all the available
|
||||
options.
|
||||
|
||||
-- Antoine Beaupré <anarcat@debian.org>, Sat, 12 May 2018 16:02:25 -0400
|
||||
36
debian/smokeping/usr/share/doc/smokeping/README.md
vendored
Normal file
36
debian/smokeping/usr/share/doc/smokeping/README.md
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
```
|
||||
____ _ ____ _
|
||||
/ ___| _ __ ___ ___ | | _____| _ \(_)_ __ __ _
|
||||
\___ \| '_ ` _ \ / _ \| |/ / _ \ |_) | | '_ \ / _` |
|
||||
___) | | | | | | (_) | < __/ __/| | | | | (_| |
|
||||
|____/|_| |_| |_|\___/|_|\_\___|_| |_|_| |_|\__, |
|
||||
|___/
|
||||
```
|
||||
|
||||
Original Authors: Tobias Oetiker <tobi of oetiker.ch> and Niko Tyni <ntyni with iki.fi>
|
||||
|
||||
[](https://github.com/oetiker/SmokePing/actions/workflows/build-test.yaml)
|
||||
|
||||
SmokePing is a latency logging and graphing and
|
||||
alerting system. It consists of a daemon process which
|
||||
organizes the latency measurements and a CGI which
|
||||
presents the graphs.
|
||||
|
||||
SmokePing is ...
|
||||
================
|
||||
|
||||
* extensible through plug-in modules
|
||||
|
||||
* easy to customize through a webtemplate and an extensive
|
||||
configuration file.
|
||||
|
||||
* written in perl and should readily port to any unix system
|
||||
|
||||
* an RRDtool frontend
|
||||
|
||||
* able to deal with DYNAMIC IP addresses as used with
|
||||
Cable and ADSL internet.
|
||||
|
||||
|
||||
cheers
|
||||
tobi
|
||||
12
debian/smokeping/usr/share/doc/smokeping/TODO.Debian
vendored
Normal file
12
debian/smokeping/usr/share/doc/smokeping/TODO.Debian
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
The following issues need to be fixed:
|
||||
|
||||
* fast-cgi should be default
|
||||
* review upstream changes since last release, esp. config changes
|
||||
* do not prompt for modifications on the files:
|
||||
- Slaves
|
||||
- General
|
||||
- basepage.html
|
||||
- this is very hard. we would need to fix the checksum in
|
||||
/var/lib/dpkg/status, which doesn't seem to be doable
|
||||
programmatically. See dpkg/src/configure.c:336 to see how this
|
||||
works better.
|
||||
BIN
debian/smokeping/usr/share/doc/smokeping/changelog.Debian.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/doc/smokeping/changelog.Debian.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/doc/smokeping/changelog.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/doc/smokeping/changelog.gz
vendored
Normal file
Binary file not shown.
156
debian/smokeping/usr/share/doc/smokeping/copyright
vendored
Normal file
156
debian/smokeping/usr/share/doc/smokeping/copyright
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: SmokePing
|
||||
Source: https://github.com/oetiker/SmokePing
|
||||
Comment:
|
||||
The upstream source tarball is repacked to drop vendored javascript libraries.
|
||||
Files-Excluded:
|
||||
htdocs/js/cropper/*
|
||||
htdocs/js/prototype.js
|
||||
htdocs/js/scriptaculous/*
|
||||
|
||||
Files: *
|
||||
Copyright: 2001-2005 Tobias Oetiker <tobi@oetiker.ch>
|
||||
License: GPL-2+
|
||||
|
||||
Files: bin/tSmoke
|
||||
Copyright: 2003 by Dan McGinn-Combs. All right reserved.
|
||||
License: GPL-2+
|
||||
|
||||
Files: lib/Smokeping/Examples.pm lib/Smokeping/RRDtools.pm
|
||||
Copyright: 2005 by Niko Tyni.
|
||||
License: GPL-2+
|
||||
|
||||
Files: lib/Smokeping/matchers/Avgratio.pm lib/Smokeping/matchers/Median.pm lib/Smokeping/matchers/base.pm
|
||||
Copyright: 2004 by OETIKER+PARTNER AG. All rights reserved.
|
||||
License: GPL-2+
|
||||
|
||||
Files: lib/Smokeping/matchers/CheckLatency.pm lib/Smokeping/matchers/CheckLoss.pm
|
||||
Copyright: 2006 Dylan C Vanderhoof, Semaphore Corporation
|
||||
License: GPL-2+
|
||||
|
||||
Files: lib/BER.pm lib/SNMP_Session.pm
|
||||
Copyright: 1995-2008, Simon Leinen.
|
||||
.
|
||||
This program is free software; you can redistribute it under the
|
||||
"Artistic License 2.0" included in this distribution
|
||||
(file "Artistic").
|
||||
License: Artistic-2.0
|
||||
Comment: These files are not used in the Debian version. The mentioned
|
||||
"Artistic" license file is not present in the source repository.
|
||||
|
||||
Files: debian/*
|
||||
Copyright: Wed, 13 Feb 2002 23:11:07 +0100 Jose Carlos Garcia Sogo <jsogo@debian.org>
|
||||
2018-2020 Gabriel Filion <gabster@lelutin.ca>
|
||||
License: GPL-2+
|
||||
Comment: The copyright mention was not updated throughout the years and there
|
||||
are more authors and contributors that donated their time to maintaining those
|
||||
files.
|
||||
|
||||
License: GPL-2+
|
||||
On Debian systems, the full text of the GNU General Public
|
||||
License version 2 can be found in the file
|
||||
`/usr/share/common-licenses/GPL-2'.
|
||||
|
||||
License: Artistic-2.0
|
||||
Copyright (c) 2000-2006, The Perl Foundation.
|
||||
.
|
||||
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
|
||||
Preamble
|
||||
.
|
||||
This license establishes the terms under which a given free software Package may be copied, modified, distributed, and/or redistributed. The intent is that the Copyright Holder maintains some artistic control over the development of that Package while still keeping the Package available as open source and free software.
|
||||
.
|
||||
You are always permitted to make arrangements wholly outside of this license directly with the Copyright Holder of a given Package. If the terms of this license do not permit the full use that you propose to make of the Package, you should contact the Copyright Holder and seek a different licensing arrangement.
|
||||
Definitions
|
||||
.
|
||||
"Copyright Holder" means the individual(s) or organization(s) named in the copyright notice for the entire Package.
|
||||
.
|
||||
"Contributor" means any party that has contributed code or other material to the Package, in accordance with the Copyright Holder's procedures.
|
||||
.
|
||||
"You" and "your" means any person who would like to copy, distribute, or modify the Package.
|
||||
.
|
||||
"Package" means the collection of files distributed by the Copyright Holder, and derivatives of that collection and/or of those files. A given Package may consist of either the Standard Version, or a Modified Version.
|
||||
.
|
||||
"Distribute" means providing a copy of the Package or making it accessible to anyone else, or in the case of a company or organization, to others outside of your company or organization.
|
||||
.
|
||||
"Distributor Fee" means any fee that you charge for Distributing this Package or providing support for this Package to another party. It does not mean licensing fees.
|
||||
.
|
||||
"Standard Version" refers to the Package if it has not been modified, or has been modified only in ways explicitly requested by the Copyright Holder.
|
||||
.
|
||||
"Modified Version" means the Package, if it has been changed, and such changes were not explicitly requested by the Copyright Holder.
|
||||
.
|
||||
"Original License" means this Artistic License as Distributed with the Standard Version of the Package, in its current version or as it may be modified by The Perl Foundation in the future.
|
||||
.
|
||||
"Source" form means the source code, documentation source, and configuration files for the Package.
|
||||
.
|
||||
"Compiled" form means the compiled bytecode, object code, binary, or any other form resulting from mechanical transformation or translation of the Source form.
|
||||
Permission for Use and Modification Without Distribution
|
||||
.
|
||||
(1) You are permitted to use the Standard Version and create and use Modified Versions for any purpose without restriction, provided that you do not Distribute the Modified Version.
|
||||
Permissions for Redistribution of the Standard Version
|
||||
.
|
||||
(2) You may Distribute verbatim copies of the Source form of the Standard Version of this Package in any medium without restriction, either gratis or for a Distributor Fee, provided that you duplicate all of the original copyright notices and associated disclaimers. At your discretion, such verbatim copies may or may not include a Compiled form of the Package.
|
||||
.
|
||||
(3) You may apply any bug fixes, portability changes, and other modifications made available from the Copyright Holder. The resulting Package will still be considered the Standard Version, and as such will be subject to the Original License.
|
||||
Distribution of Modified Versions of the Package as Source
|
||||
.
|
||||
(4) You may Distribute your Modified Version as Source (either gratis or for a Distributor Fee, and with or without a Compiled form of the Modified Version) provided that you clearly document how it differs from the Standard Version, including, but not limited to, documenting any non-standard features, executables, or modules, and provided that you do at least ONE of the following:
|
||||
.
|
||||
(a) make the Modified Version available to the Copyright Holder of the Standard Version, under the Original License, so that the Copyright Holder may include your modifications in the Standard Version.
|
||||
(b) ensure that installation of your Modified Version does not prevent the user installing or running the Standard Version. In addition, the Modified Version must bear a name that is different from the name of the Standard Version.
|
||||
(c) allow anyone who receives a copy of the Modified Version to make the Source form of the Modified Version available to others under
|
||||
(i) the Original License or
|
||||
(ii) a license that permits the licensee to freely copy, modify and redistribute the Modified Version using the same licensing terms that apply to the copy that the licensee received, and requires that the Source form of the Modified Version, and of any works derived from it, be made freely available in that license fees are prohibited but Distributor Fees are allowed.
|
||||
Distribution of Compiled Forms of the Standard Version or Modified Versions without the Source
|
||||
.
|
||||
(5) You may Distribute Compiled forms of the Standard Version without the Source, provided that you include complete instructions on how to get the Source of the Standard Version. Such instructions must be valid at the time of your distribution. If these instructions, at any time while you are carrying out such distribution, become invalid, you must provide new instructions on demand or cease further distribution. If you provide valid instructions or cease distribution within thirty days after you become aware that the instructions are invalid, then you do not forfeit any of your rights under this license.
|
||||
.
|
||||
(6) You may Distribute a Modified Version in Compiled form without the Source, provided that you comply with Section 4 with respect to the Source of the Modified Version.
|
||||
Aggregating or Linking the Package
|
||||
.
|
||||
(7) You may aggregate the Package (either the Standard Version or Modified Version) with other packages and Distribute the resulting aggregation provided that you do not charge a licensing fee for the Package. Distributor Fees are permitted, and licensing fees for other components in the aggregation are permitted. The terms of this license apply to the use and Distribution of the Standard or Modified Versions as included in the aggregation.
|
||||
.
|
||||
(8) You are permitted to link Modified and Standard Versions with other works, to embed the Package in a larger work of your own, or to build stand-alone binary or bytecode versions of applications that include the Package, and Distribute the result without restriction, provided the result does not expose a direct interface to the Package.
|
||||
Items That are Not Considered Part of a Modified Version
|
||||
.
|
||||
(9) Works (including, but not limited to, modules and scripts) that merely extend or make use of the Package, do not, by themselves, cause the Package to be a Modified Version. In addition, such works are not considered parts of the Package itself, and are not subject to the terms of this license.
|
||||
General Provisions
|
||||
.
|
||||
(10) Any use, modification, and distribution of the Standard or Modified Versions is governed by this Artistic License. By using, modifying or distributing the Package, you accept this license. Do not use, modify, or distribute the Package, if you do not accept this license.
|
||||
.
|
||||
(11) If your Modified Version has been derived from a Modified Version made by someone other than you, you are nevertheless required to ensure that your Modified Version complies with the requirements of this license.
|
||||
.
|
||||
(12) This license does not grant you the right to use any trademark, service mark, tradename, or logo of the Copyright Holder.
|
||||
.
|
||||
(13) This license includes the non-exclusive, worldwide, free-of-charge patent license to make, have made, use, offer to sell, sell, import and otherwise transfer the Package with respect to any patent claims licensable by the Copyright Holder that are necessarily infringed by the Package. If you institute patent litigation (including a cross-claim or counterclaim) against any party alleging that the Package constitutes direct or contributory patent infringement, then this Artistic License to you shall terminate on the date that such litigation is filed.
|
||||
.
|
||||
(14) Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
License: BSD-3-clause
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
.
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the David Spurr nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.
|
||||
http://www.opensource.org/licenses/bsd-license.php
|
||||
|
||||
License: Expat
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
.
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
241
debian/smokeping/usr/share/doc/smokeping/examples/config.echoping
vendored
Normal file
241
debian/smokeping/usr/share/doc/smokeping/examples/config.echoping
vendored
Normal file
@@ -0,0 +1,241 @@
|
||||
# This Smokeping example configuration file was automatically generated.
|
||||
#
|
||||
# Everything up to the Probes section is derived from a common template file.
|
||||
# See the Probes and Targets sections for the actual example.
|
||||
#
|
||||
# This example is included in the smokeping_examples document.
|
||||
|
||||
*** General ***
|
||||
|
||||
owner = Peter Random
|
||||
contact = some@address.nowhere
|
||||
mailhost = my.mail.host
|
||||
sendmail = /usr/sbin/sendmail
|
||||
# NOTE: do not put the Image Cache below cgi-bin
|
||||
# since all files under cgi-bin will be executed ... this is not
|
||||
# good for images.
|
||||
imgcache = /usr/cache
|
||||
imgurl = cache
|
||||
datadir = /usr/data
|
||||
piddir = /usr/var
|
||||
cgiurl = http://some.url/smokeping.cgi
|
||||
smokemail = /usr/etc/smokemail.dist
|
||||
tmail = /usr/etc/tmail.dist
|
||||
# specify this to get syslog logging
|
||||
syslogfacility = local0
|
||||
# each probe is now run in its own process
|
||||
# disable this to revert to the old behaviour
|
||||
# concurrentprobes = no
|
||||
|
||||
*** Alerts ***
|
||||
to = alertee@address.somewhere
|
||||
from = smokealert@company.xy
|
||||
|
||||
+someloss
|
||||
type = loss
|
||||
# in percent
|
||||
pattern = >0%,*12*,>0%,*12*,>0%
|
||||
comment = loss 3 times in a row
|
||||
|
||||
*** Database ***
|
||||
|
||||
step = 300
|
||||
pings = 20
|
||||
|
||||
# consfn mrhb steps total
|
||||
|
||||
AVERAGE 0.5 1 28800
|
||||
AVERAGE 0.5 12 9600
|
||||
MIN 0.5 12 9600
|
||||
MAX 0.5 12 9600
|
||||
AVERAGE 0.5 144 2400
|
||||
MAX 0.5 144 2400
|
||||
MIN 0.5 144 2400
|
||||
|
||||
*** Presentation ***
|
||||
|
||||
template = /usr/etc/basepage.html.dist
|
||||
htmltitle = yes
|
||||
graphborders = no
|
||||
# If enabled, treat all filter menu queries as literal strings instead of regex
|
||||
literalsearch = no
|
||||
|
||||
+ charts
|
||||
|
||||
menu = Charts
|
||||
title = The most interesting destinations
|
||||
|
||||
++ stddev
|
||||
sorter = StdDev(entries=>4)
|
||||
title = Top Standard Deviation
|
||||
menu = Std Deviation
|
||||
format = Standard Deviation %f
|
||||
|
||||
++ max
|
||||
sorter = Max(entries=>5)
|
||||
title = Top Max Roundtrip Time
|
||||
menu = by Max
|
||||
format = Max Roundtrip Time %f seconds
|
||||
|
||||
++ loss
|
||||
sorter = Loss(entries=>5)
|
||||
title = Top Packet Loss
|
||||
menu = Loss
|
||||
format = Packets Lost %f
|
||||
|
||||
++ median
|
||||
sorter = Median(entries=>5)
|
||||
title = Top Median Roundtrip Time
|
||||
menu = by Median
|
||||
format = Median RTT %f seconds
|
||||
|
||||
+ overview
|
||||
|
||||
width = 600
|
||||
height = 50
|
||||
range = 10h
|
||||
|
||||
+ detail
|
||||
|
||||
width = 600
|
||||
height = 200
|
||||
unison_tolerance = 2
|
||||
|
||||
"Last 3 Hours" 3h
|
||||
"Last 30 Hours" 30h
|
||||
"Last 10 Days" 10d
|
||||
"Last 360 Days" 360d
|
||||
|
||||
#+ hierarchies
|
||||
#++ owner
|
||||
#title = Host Owner
|
||||
#++ location
|
||||
#title = Location
|
||||
|
||||
# (The actual example starts here.)
|
||||
|
||||
*** Probes ***
|
||||
|
||||
# This example shows most of the echoping-derived probes in action.
|
||||
|
||||
+ FPing
|
||||
binary = /usr/bin/fping
|
||||
|
||||
# these expect to find echoping in /usr/bin
|
||||
# if not, you'll have to specify the location separately for each probe
|
||||
# + EchoPing # uses TCP or UDP echo (port 7)
|
||||
# + EchoPingDiscard # uses TCP or UDP discard (port 9)
|
||||
# + EchoPingChargen # uses TCP chargen (port 19)
|
||||
+ EchoPingSmtp # SMTP (25/tcp) for mail servers
|
||||
+ EchoPingHttps # HTTPS (443/tcp) for web servers
|
||||
+ EchoPingHttp # HTTP (80/tcp) for web servers and caches
|
||||
+ EchoPingIcp # ICP (3130/udp) for caches
|
||||
# these need at least echoping 6 with the corresponding plugins
|
||||
+ EchoPingDNS # DNS (53/udp or tcp) servers
|
||||
+ EchoPingLDAP # LDAP (389/tcp) servers
|
||||
+ EchoPingWhois # Whois (43/tcp) servers
|
||||
|
||||
*** Targets ***
|
||||
|
||||
# All the servers are pinged both with ICMP (the FPing probe)
|
||||
# and their respective echoping probe. The proxy server, www-cache,
|
||||
# is probed with both HTTP requests and ICP requests for the same
|
||||
# URL.
|
||||
|
||||
# default probe
|
||||
probe = FPing
|
||||
|
||||
menu = Top
|
||||
title = Network Latency Grapher
|
||||
remark = Welcome to this SmokePing website.
|
||||
|
||||
+ MyServers
|
||||
|
||||
menu = My Servers
|
||||
title = My Servers
|
||||
|
||||
++ www-server
|
||||
menu = www-server
|
||||
title = Web Server (www-server) / ICMP
|
||||
# probe = FPing propagated from top
|
||||
host = www-server.example
|
||||
|
||||
+++ http
|
||||
menu = http
|
||||
title = Web Server (www-server) / HTTP
|
||||
probe = EchoPingHttp
|
||||
host = www-server.example
|
||||
# default url is /
|
||||
|
||||
+++ https
|
||||
menu = https
|
||||
title = Web Server (www-server) / HTTPS
|
||||
probe = EchoPingHttps
|
||||
host = www-server.example
|
||||
|
||||
++ cache
|
||||
menu = www-cache
|
||||
title = Web Cache (www-cache) / ICMP
|
||||
host = www-cache.example
|
||||
|
||||
+++ http
|
||||
menu = http
|
||||
title = www-cache / HTTP
|
||||
probe = EchoPingHttp
|
||||
host = www-cache.example
|
||||
port = 8080 # use the squid port
|
||||
url = http://www.somehost.example/
|
||||
|
||||
+++ icp
|
||||
menu = icp
|
||||
title = www-cache / ICP
|
||||
probe = EchoPingIcp
|
||||
host = www-cache.example
|
||||
url = http://www.somehost.example/
|
||||
|
||||
++ mail
|
||||
menu = mail-server
|
||||
title = Mail Server (mail-server) / ICMP
|
||||
host = mail-server.example
|
||||
|
||||
+++ smtp
|
||||
menu = mail-server / SMTP
|
||||
title = Mail Server (mail-server) / SMTP
|
||||
probe = EchoPingSmtp
|
||||
host = mail-server.example
|
||||
|
||||
++ ldap-server
|
||||
menu = ldap-server
|
||||
title = ldap-server / ICMP
|
||||
host = ldap-server.example
|
||||
|
||||
+++ ldap
|
||||
menu = ldap-server / LDAP
|
||||
title = LDAP Server (ldap-server) / LDAP
|
||||
probe = EchoPingLDAP
|
||||
ldap_request = (objectclass=*)
|
||||
host = ldap-server.example
|
||||
|
||||
++ name-server
|
||||
menu = name-server
|
||||
title = name-server / ICMP
|
||||
host = name-server.example
|
||||
|
||||
+++ DNS
|
||||
menu = name-server / DNS
|
||||
title = DNS Server (name-server) / DNS
|
||||
probe = EchoPingDNS
|
||||
dns_request = name.example
|
||||
host = name-server.example
|
||||
|
||||
++ whois-server
|
||||
menu = whois-server
|
||||
title = whois-server / ICMP
|
||||
host = whois-server.example
|
||||
|
||||
+++ Whois
|
||||
menu = whois-server / Whois
|
||||
title = Whois Server (whois-server) / Whois
|
||||
probe = EchoPingWhois
|
||||
whois_request = domain.example
|
||||
host = whois-server.example
|
||||
185
debian/smokeping/usr/share/doc/smokeping/examples/config.fping-instances
vendored
Normal file
185
debian/smokeping/usr/share/doc/smokeping/examples/config.fping-instances
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
# This Smokeping example configuration file was automatically generated.
|
||||
#
|
||||
# Everything up to the Probes section is derived from a common template file.
|
||||
# See the Probes and Targets sections for the actual example.
|
||||
#
|
||||
# This example is included in the smokeping_examples document.
|
||||
|
||||
*** General ***
|
||||
|
||||
owner = Peter Random
|
||||
contact = some@address.nowhere
|
||||
mailhost = my.mail.host
|
||||
sendmail = /usr/sbin/sendmail
|
||||
# NOTE: do not put the Image Cache below cgi-bin
|
||||
# since all files under cgi-bin will be executed ... this is not
|
||||
# good for images.
|
||||
imgcache = /usr/cache
|
||||
imgurl = cache
|
||||
datadir = /usr/data
|
||||
piddir = /usr/var
|
||||
cgiurl = http://some.url/smokeping.cgi
|
||||
smokemail = /usr/etc/smokemail.dist
|
||||
tmail = /usr/etc/tmail.dist
|
||||
# specify this to get syslog logging
|
||||
syslogfacility = local0
|
||||
# each probe is now run in its own process
|
||||
# disable this to revert to the old behaviour
|
||||
# concurrentprobes = no
|
||||
|
||||
*** Alerts ***
|
||||
to = alertee@address.somewhere
|
||||
from = smokealert@company.xy
|
||||
|
||||
+someloss
|
||||
type = loss
|
||||
# in percent
|
||||
pattern = >0%,*12*,>0%,*12*,>0%
|
||||
comment = loss 3 times in a row
|
||||
|
||||
*** Database ***
|
||||
|
||||
step = 300
|
||||
pings = 20
|
||||
|
||||
# consfn mrhb steps total
|
||||
|
||||
AVERAGE 0.5 1 28800
|
||||
AVERAGE 0.5 12 9600
|
||||
MIN 0.5 12 9600
|
||||
MAX 0.5 12 9600
|
||||
AVERAGE 0.5 144 2400
|
||||
MAX 0.5 144 2400
|
||||
MIN 0.5 144 2400
|
||||
|
||||
*** Presentation ***
|
||||
|
||||
template = /usr/etc/basepage.html.dist
|
||||
htmltitle = yes
|
||||
graphborders = no
|
||||
# If enabled, treat all filter menu queries as literal strings instead of regex
|
||||
literalsearch = no
|
||||
|
||||
+ charts
|
||||
|
||||
menu = Charts
|
||||
title = The most interesting destinations
|
||||
|
||||
++ stddev
|
||||
sorter = StdDev(entries=>4)
|
||||
title = Top Standard Deviation
|
||||
menu = Std Deviation
|
||||
format = Standard Deviation %f
|
||||
|
||||
++ max
|
||||
sorter = Max(entries=>5)
|
||||
title = Top Max Roundtrip Time
|
||||
menu = by Max
|
||||
format = Max Roundtrip Time %f seconds
|
||||
|
||||
++ loss
|
||||
sorter = Loss(entries=>5)
|
||||
title = Top Packet Loss
|
||||
menu = Loss
|
||||
format = Packets Lost %f
|
||||
|
||||
++ median
|
||||
sorter = Median(entries=>5)
|
||||
title = Top Median Roundtrip Time
|
||||
menu = by Median
|
||||
format = Median RTT %f seconds
|
||||
|
||||
+ overview
|
||||
|
||||
width = 600
|
||||
height = 50
|
||||
range = 10h
|
||||
|
||||
+ detail
|
||||
|
||||
width = 600
|
||||
height = 200
|
||||
unison_tolerance = 2
|
||||
|
||||
"Last 3 Hours" 3h
|
||||
"Last 30 Hours" 30h
|
||||
"Last 10 Days" 10d
|
||||
"Last 360 Days" 360d
|
||||
|
||||
#+ hierarchies
|
||||
#++ owner
|
||||
#title = Host Owner
|
||||
#++ location
|
||||
#title = Location
|
||||
|
||||
# (The actual example starts here.)
|
||||
|
||||
*** Probes ***
|
||||
|
||||
# This example demonstrates the concept of probe instances. The FPingLarge
|
||||
# and FPingNormal probes are independent of each other, they just use
|
||||
# the same module, FPing. FPingNormal uses the default parameters, and
|
||||
# so does FPingLarge except for the 5 kilobyte packetsize. Both use the
|
||||
# same fping binary, and its path is configured FPing top section.
|
||||
#
|
||||
# The 'offset' parameters make sure the probes don't run at the same time -
|
||||
# FPingNormal is run every 'full' 5 minutes (eg. 8:00, 8:05, 8:10 and so on,
|
||||
# in wallclock time) while FPingLarge is run halfway through these intervals
|
||||
# (eg. 8:02:30, 8:07:30 etc.)
|
||||
#
|
||||
# The top FPing section does not define a probe in itself because it
|
||||
# has subsections. If we really wanted to have one probe named "FPing",
|
||||
# we could do so by making a subsection by that name.
|
||||
|
||||
+ FPing
|
||||
binary = /usr/bin/fping
|
||||
|
||||
++ FPingNormal
|
||||
offset = 0%
|
||||
|
||||
++ FPingLarge
|
||||
packetsize = 5000
|
||||
offset = 50%
|
||||
|
||||
*** Targets ***
|
||||
|
||||
# The target section shows two host, myhost1.example and myhost2.example,
|
||||
# being pinged with two differently sized ICMP packets. This time the tree
|
||||
# is divided by the target host rather than the probe.
|
||||
|
||||
probe = FPingNormal
|
||||
menu = Top
|
||||
title = Network Latency Grapher
|
||||
remark = Welcome to this SmokePing website.
|
||||
|
||||
+ network
|
||||
menu = Net latency
|
||||
title = Network latency (ICMP pings)
|
||||
|
||||
++ myhost1
|
||||
menu = myhost1
|
||||
title = ICMP latency for myhost1
|
||||
|
||||
+++ normal
|
||||
title = Normal packetsize (56 bytes)
|
||||
probe = FPingNormal
|
||||
host = myhost1.example
|
||||
|
||||
+++ large
|
||||
title = Large packetsize (5000 bytes)
|
||||
probe = FPingLarge
|
||||
host = myhost1.example
|
||||
|
||||
++ myhost2
|
||||
menu = myhost2
|
||||
title = ICMP latency for myhost2
|
||||
|
||||
+++ normal
|
||||
title = Normal packetsize (56 bytes)
|
||||
probe = FPingNormal
|
||||
host = myhost2.example
|
||||
|
||||
+++ large
|
||||
title = Large packetsize (5000 bytes)
|
||||
probe = FPingLarge
|
||||
host = myhost2.example
|
||||
189
debian/smokeping/usr/share/doc/smokeping/examples/config.multiple-probes
vendored
Normal file
189
debian/smokeping/usr/share/doc/smokeping/examples/config.multiple-probes
vendored
Normal file
@@ -0,0 +1,189 @@
|
||||
# This Smokeping example configuration file was automatically generated.
|
||||
#
|
||||
# Everything up to the Probes section is derived from a common template file.
|
||||
# See the Probes and Targets sections for the actual example.
|
||||
#
|
||||
# This example is included in the smokeping_examples document.
|
||||
|
||||
*** General ***
|
||||
|
||||
owner = Peter Random
|
||||
contact = some@address.nowhere
|
||||
mailhost = my.mail.host
|
||||
sendmail = /usr/sbin/sendmail
|
||||
# NOTE: do not put the Image Cache below cgi-bin
|
||||
# since all files under cgi-bin will be executed ... this is not
|
||||
# good for images.
|
||||
imgcache = /usr/cache
|
||||
imgurl = cache
|
||||
datadir = /usr/data
|
||||
piddir = /usr/var
|
||||
cgiurl = http://some.url/smokeping.cgi
|
||||
smokemail = /usr/etc/smokemail.dist
|
||||
tmail = /usr/etc/tmail.dist
|
||||
# specify this to get syslog logging
|
||||
syslogfacility = local0
|
||||
# each probe is now run in its own process
|
||||
# disable this to revert to the old behaviour
|
||||
# concurrentprobes = no
|
||||
|
||||
*** Alerts ***
|
||||
to = alertee@address.somewhere
|
||||
from = smokealert@company.xy
|
||||
|
||||
+someloss
|
||||
type = loss
|
||||
# in percent
|
||||
pattern = >0%,*12*,>0%,*12*,>0%
|
||||
comment = loss 3 times in a row
|
||||
|
||||
*** Database ***
|
||||
|
||||
step = 300
|
||||
pings = 20
|
||||
|
||||
# consfn mrhb steps total
|
||||
|
||||
AVERAGE 0.5 1 28800
|
||||
AVERAGE 0.5 12 9600
|
||||
MIN 0.5 12 9600
|
||||
MAX 0.5 12 9600
|
||||
AVERAGE 0.5 144 2400
|
||||
MAX 0.5 144 2400
|
||||
MIN 0.5 144 2400
|
||||
|
||||
*** Presentation ***
|
||||
|
||||
template = /usr/etc/basepage.html.dist
|
||||
htmltitle = yes
|
||||
graphborders = no
|
||||
# If enabled, treat all filter menu queries as literal strings instead of regex
|
||||
literalsearch = no
|
||||
|
||||
+ charts
|
||||
|
||||
menu = Charts
|
||||
title = The most interesting destinations
|
||||
|
||||
++ stddev
|
||||
sorter = StdDev(entries=>4)
|
||||
title = Top Standard Deviation
|
||||
menu = Std Deviation
|
||||
format = Standard Deviation %f
|
||||
|
||||
++ max
|
||||
sorter = Max(entries=>5)
|
||||
title = Top Max Roundtrip Time
|
||||
menu = by Max
|
||||
format = Max Roundtrip Time %f seconds
|
||||
|
||||
++ loss
|
||||
sorter = Loss(entries=>5)
|
||||
title = Top Packet Loss
|
||||
menu = Loss
|
||||
format = Packets Lost %f
|
||||
|
||||
++ median
|
||||
sorter = Median(entries=>5)
|
||||
title = Top Median Roundtrip Time
|
||||
menu = by Median
|
||||
format = Median RTT %f seconds
|
||||
|
||||
+ overview
|
||||
|
||||
width = 600
|
||||
height = 50
|
||||
range = 10h
|
||||
|
||||
+ detail
|
||||
|
||||
width = 600
|
||||
height = 200
|
||||
unison_tolerance = 2
|
||||
|
||||
"Last 3 Hours" 3h
|
||||
"Last 30 Hours" 30h
|
||||
"Last 10 Days" 10d
|
||||
"Last 360 Days" 360d
|
||||
|
||||
#+ hierarchies
|
||||
#++ owner
|
||||
#title = Host Owner
|
||||
#++ location
|
||||
#title = Location
|
||||
|
||||
# (The actual example starts here.)
|
||||
|
||||
*** Probes ***
|
||||
|
||||
# Here we have three probes: FPing for the regular ICMP pings,
|
||||
# DNS for name server latency measurement and EchoPingHttp
|
||||
# for web servers.
|
||||
#
|
||||
# The FPing probe runs with the default parameters, except that the ICMP
|
||||
# packet size is 1000 bytes instead of the default 56 bytes.
|
||||
#
|
||||
# The DNS and EchoPingHttp probes have been configured to be a bit more
|
||||
# gentle with the servers, as they only do 5 queries (pings) instead of the
|
||||
# default 20 (or whatever is specified in the Database section). However,
|
||||
# DNS queries are made more often: 5 queries every 3 minutes instead of
|
||||
# every 5 minutes.
|
||||
|
||||
+ FPing
|
||||
binary = /usr/bin/fping
|
||||
packetsize = 1000
|
||||
|
||||
+ DNS
|
||||
binary = /usr/bin/dig
|
||||
lookup = name.example
|
||||
pings = 5
|
||||
step = 180
|
||||
|
||||
+ EchoPingHttp
|
||||
pings = 5
|
||||
url = /test-url
|
||||
|
||||
*** Targets ***
|
||||
|
||||
# The target tree has been divided by the probe used. This does not have
|
||||
# to be the case: every target (sub)section can use a different probe,
|
||||
# and the same probe can be used in different parts of the config tree.
|
||||
|
||||
probe = FPing
|
||||
menu = Top
|
||||
title = Network Latency Grapher
|
||||
remark = Welcome to this SmokePing website.
|
||||
|
||||
+ network
|
||||
menu = Net latency
|
||||
title = Network latency (ICMP pings)
|
||||
|
||||
++ myhost1
|
||||
host = myhost1.example
|
||||
++ myhost2
|
||||
host = myhost2.example
|
||||
|
||||
+ services
|
||||
menu = Service latency
|
||||
title = Service latency (DNS, HTTP)
|
||||
|
||||
++ DNS
|
||||
probe = DNS
|
||||
menu = DNS latency
|
||||
title = Service latency (DNS)
|
||||
|
||||
+++ dns1
|
||||
host = dns1.example
|
||||
|
||||
+++ dns2
|
||||
host = dns2.example
|
||||
|
||||
++ HTTP
|
||||
menu = HTTP latency
|
||||
title = Service latency (HTTP)
|
||||
|
||||
+++ www1
|
||||
host = www1.example
|
||||
|
||||
+++ www2
|
||||
host = www2.example
|
||||
156
debian/smokeping/usr/share/doc/smokeping/examples/config.simple
vendored
Normal file
156
debian/smokeping/usr/share/doc/smokeping/examples/config.simple
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
# This Smokeping example configuration file was automatically generated.
|
||||
#
|
||||
# Everything up to the Probes section is derived from a common template file.
|
||||
# See the Probes and Targets sections for the actual example.
|
||||
#
|
||||
# This example is included in the smokeping_examples document.
|
||||
|
||||
*** General ***
|
||||
|
||||
owner = Peter Random
|
||||
contact = some@address.nowhere
|
||||
mailhost = my.mail.host
|
||||
sendmail = /usr/sbin/sendmail
|
||||
# NOTE: do not put the Image Cache below cgi-bin
|
||||
# since all files under cgi-bin will be executed ... this is not
|
||||
# good for images.
|
||||
imgcache = /usr/cache
|
||||
imgurl = cache
|
||||
datadir = /usr/data
|
||||
piddir = /usr/var
|
||||
cgiurl = http://some.url/smokeping.cgi
|
||||
smokemail = /usr/etc/smokemail.dist
|
||||
tmail = /usr/etc/tmail.dist
|
||||
# specify this to get syslog logging
|
||||
syslogfacility = local0
|
||||
# each probe is now run in its own process
|
||||
# disable this to revert to the old behaviour
|
||||
# concurrentprobes = no
|
||||
|
||||
*** Alerts ***
|
||||
to = alertee@address.somewhere
|
||||
from = smokealert@company.xy
|
||||
|
||||
+someloss
|
||||
type = loss
|
||||
# in percent
|
||||
pattern = >0%,*12*,>0%,*12*,>0%
|
||||
comment = loss 3 times in a row
|
||||
|
||||
*** Database ***
|
||||
|
||||
step = 300
|
||||
pings = 20
|
||||
|
||||
# consfn mrhb steps total
|
||||
|
||||
AVERAGE 0.5 1 28800
|
||||
AVERAGE 0.5 12 9600
|
||||
MIN 0.5 12 9600
|
||||
MAX 0.5 12 9600
|
||||
AVERAGE 0.5 144 2400
|
||||
MAX 0.5 144 2400
|
||||
MIN 0.5 144 2400
|
||||
|
||||
*** Presentation ***
|
||||
|
||||
template = /usr/etc/basepage.html.dist
|
||||
htmltitle = yes
|
||||
graphborders = no
|
||||
# If enabled, treat all filter menu queries as literal strings instead of regex
|
||||
literalsearch = no
|
||||
|
||||
+ charts
|
||||
|
||||
menu = Charts
|
||||
title = The most interesting destinations
|
||||
|
||||
++ stddev
|
||||
sorter = StdDev(entries=>4)
|
||||
title = Top Standard Deviation
|
||||
menu = Std Deviation
|
||||
format = Standard Deviation %f
|
||||
|
||||
++ max
|
||||
sorter = Max(entries=>5)
|
||||
title = Top Max Roundtrip Time
|
||||
menu = by Max
|
||||
format = Max Roundtrip Time %f seconds
|
||||
|
||||
++ loss
|
||||
sorter = Loss(entries=>5)
|
||||
title = Top Packet Loss
|
||||
menu = Loss
|
||||
format = Packets Lost %f
|
||||
|
||||
++ median
|
||||
sorter = Median(entries=>5)
|
||||
title = Top Median Roundtrip Time
|
||||
menu = by Median
|
||||
format = Median RTT %f seconds
|
||||
|
||||
+ overview
|
||||
|
||||
width = 600
|
||||
height = 50
|
||||
range = 10h
|
||||
|
||||
+ detail
|
||||
|
||||
width = 600
|
||||
height = 200
|
||||
unison_tolerance = 2
|
||||
|
||||
"Last 3 Hours" 3h
|
||||
"Last 30 Hours" 30h
|
||||
"Last 10 Days" 10d
|
||||
"Last 360 Days" 360d
|
||||
|
||||
#+ hierarchies
|
||||
#++ owner
|
||||
#title = Host Owner
|
||||
#++ location
|
||||
#title = Location
|
||||
|
||||
# (The actual example starts here.)
|
||||
|
||||
*** Probes ***
|
||||
|
||||
# Here we have just one probe, fping, pinging four hosts.
|
||||
#
|
||||
# The fping probe is using the default parameters, some of them supplied
|
||||
# from the Database section ("step" and "pings"), and some of them by
|
||||
# the probe module.
|
||||
|
||||
+FPing
|
||||
binary = /usr/bin/fping
|
||||
|
||||
*** Targets ***
|
||||
|
||||
# The hosts are located in two sites of two hosts each, and the
|
||||
# configuration has been divided to site sections ('+') and host subsections
|
||||
# ('++') accordingly.
|
||||
|
||||
probe = FPing
|
||||
|
||||
menu = Top
|
||||
title = Network Latency Grapher
|
||||
remark = Welcome to this SmokePing website.
|
||||
|
||||
+ mysite1
|
||||
menu = Site 1
|
||||
title = Hosts in Site 1
|
||||
|
||||
++ myhost1
|
||||
host = myhost1.mysite1.example
|
||||
++ myhost2
|
||||
host = myhost2.mysite1.example
|
||||
|
||||
+ mysite2
|
||||
menu = Site 2
|
||||
title = Hosts in Site 2
|
||||
|
||||
++ myhost3
|
||||
host = myhost3.mysite2.example
|
||||
++ myhost4
|
||||
host = myhost4.mysite2.example
|
||||
210
debian/smokeping/usr/share/doc/smokeping/examples/config.targetvars-with-Curl
vendored
Normal file
210
debian/smokeping/usr/share/doc/smokeping/examples/config.targetvars-with-Curl
vendored
Normal file
@@ -0,0 +1,210 @@
|
||||
# This Smokeping example configuration file was automatically generated.
|
||||
#
|
||||
# Everything up to the Probes section is derived from a common template file.
|
||||
# See the Probes and Targets sections for the actual example.
|
||||
#
|
||||
# This example is included in the smokeping_examples document.
|
||||
|
||||
*** General ***
|
||||
|
||||
owner = Peter Random
|
||||
contact = some@address.nowhere
|
||||
mailhost = my.mail.host
|
||||
sendmail = /usr/sbin/sendmail
|
||||
# NOTE: do not put the Image Cache below cgi-bin
|
||||
# since all files under cgi-bin will be executed ... this is not
|
||||
# good for images.
|
||||
imgcache = /usr/cache
|
||||
imgurl = cache
|
||||
datadir = /usr/data
|
||||
piddir = /usr/var
|
||||
cgiurl = http://some.url/smokeping.cgi
|
||||
smokemail = /usr/etc/smokemail.dist
|
||||
tmail = /usr/etc/tmail.dist
|
||||
# specify this to get syslog logging
|
||||
syslogfacility = local0
|
||||
# each probe is now run in its own process
|
||||
# disable this to revert to the old behaviour
|
||||
# concurrentprobes = no
|
||||
|
||||
*** Alerts ***
|
||||
to = alertee@address.somewhere
|
||||
from = smokealert@company.xy
|
||||
|
||||
+someloss
|
||||
type = loss
|
||||
# in percent
|
||||
pattern = >0%,*12*,>0%,*12*,>0%
|
||||
comment = loss 3 times in a row
|
||||
|
||||
*** Database ***
|
||||
|
||||
step = 300
|
||||
pings = 20
|
||||
|
||||
# consfn mrhb steps total
|
||||
|
||||
AVERAGE 0.5 1 28800
|
||||
AVERAGE 0.5 12 9600
|
||||
MIN 0.5 12 9600
|
||||
MAX 0.5 12 9600
|
||||
AVERAGE 0.5 144 2400
|
||||
MAX 0.5 144 2400
|
||||
MIN 0.5 144 2400
|
||||
|
||||
*** Presentation ***
|
||||
|
||||
template = /usr/etc/basepage.html.dist
|
||||
htmltitle = yes
|
||||
graphborders = no
|
||||
# If enabled, treat all filter menu queries as literal strings instead of regex
|
||||
literalsearch = no
|
||||
|
||||
+ charts
|
||||
|
||||
menu = Charts
|
||||
title = The most interesting destinations
|
||||
|
||||
++ stddev
|
||||
sorter = StdDev(entries=>4)
|
||||
title = Top Standard Deviation
|
||||
menu = Std Deviation
|
||||
format = Standard Deviation %f
|
||||
|
||||
++ max
|
||||
sorter = Max(entries=>5)
|
||||
title = Top Max Roundtrip Time
|
||||
menu = by Max
|
||||
format = Max Roundtrip Time %f seconds
|
||||
|
||||
++ loss
|
||||
sorter = Loss(entries=>5)
|
||||
title = Top Packet Loss
|
||||
menu = Loss
|
||||
format = Packets Lost %f
|
||||
|
||||
++ median
|
||||
sorter = Median(entries=>5)
|
||||
title = Top Median Roundtrip Time
|
||||
menu = by Median
|
||||
format = Median RTT %f seconds
|
||||
|
||||
+ overview
|
||||
|
||||
width = 600
|
||||
height = 50
|
||||
range = 10h
|
||||
|
||||
+ detail
|
||||
|
||||
width = 600
|
||||
height = 200
|
||||
unison_tolerance = 2
|
||||
|
||||
"Last 3 Hours" 3h
|
||||
"Last 30 Hours" 30h
|
||||
"Last 10 Days" 10d
|
||||
"Last 360 Days" 360d
|
||||
|
||||
#+ hierarchies
|
||||
#++ owner
|
||||
#title = Host Owner
|
||||
#++ location
|
||||
#title = Location
|
||||
|
||||
# (The actual example starts here.)
|
||||
|
||||
*** Probes ***
|
||||
|
||||
# This example explains the difference between probe- and target-specific
|
||||
# variables. We use the Curl probe for this.
|
||||
#
|
||||
# Every probe supports at least some probe-specific variables. The values
|
||||
# of these variables are common to all the targets of the probe, and
|
||||
# they can only be configured in the Probes section. In this case,
|
||||
# the probe-specific variables are "binary" and "step".
|
||||
#
|
||||
# Target-specific variables are supported by most probes, the most notable
|
||||
# exception being the FPing probe and its derivatives. Target-specific
|
||||
# variables can have different values for different targets. They can be
|
||||
# configured in both Probes and Targets sections. The values assigned in the
|
||||
# Probes section function become default values that can be overridden
|
||||
# in the Targets section.
|
||||
#
|
||||
# The documentation of each probe states which of its variables are
|
||||
# probe-specific and which are target-specific.
|
||||
#
|
||||
# In this case the "urlformat" variable is a target-specific one. It is
|
||||
# also quite uncommon, because it can contain a placeholder for the "host"
|
||||
# variable in the Targets section. This is not a general feature, its
|
||||
# usage is only limited to the "urlformat" variable and the "%host%" escape.
|
||||
#
|
||||
# (The reason why the FPing probe does not support target-specific variables
|
||||
# is simply the fact that the fping program measures all its targets in one
|
||||
# go, so they all have the same parameters. The other probes ping their targets
|
||||
# one at a time.)
|
||||
|
||||
+ Curl
|
||||
# probe-specific variables
|
||||
binary = /usr/bin/curl
|
||||
step = 60
|
||||
|
||||
# a default for this target-specific variable
|
||||
urlformat = http://%host%/
|
||||
|
||||
*** Targets ***
|
||||
|
||||
# The target tree is divided into an HTTP branch and an FTP one.
|
||||
# The servers "myhost1.example" and "myhost2.example" are probed
|
||||
# in both. The third server, "myhost3.example", only has an HTTP
|
||||
# server, and it's in a non-standard port (8080).
|
||||
#
|
||||
# The "urlformat" variable is specified for the whole FTP branch
|
||||
# as "ftp://%host%/". For the HTTP branch, the default from the
|
||||
# Probes section is used, except for myhost3, which overrides
|
||||
# it to tag the port number into the URL.
|
||||
#
|
||||
# The myhost3 assignment could just as well have included the hostname
|
||||
# verbatim (ie. urlformat = http://myhost3.example:8080/) instead of
|
||||
# using the %host% placeholder, but the host variable would still have
|
||||
# been required (even though it wouldn't have been used for anything).
|
||||
|
||||
probe = Curl
|
||||
menu = Top
|
||||
title = Network Latency Grapher
|
||||
remark = Welcome to this SmokePing website.
|
||||
|
||||
+ HTTP
|
||||
menu = http
|
||||
title = HTTP latency
|
||||
|
||||
++ myhost1
|
||||
menu = myhost1
|
||||
title = HTTP latency for myhost1
|
||||
host = myhost1.example
|
||||
|
||||
++ myhost2
|
||||
menu = myhost2
|
||||
title = HTTP latency for myhost2
|
||||
host = myhost2.example
|
||||
|
||||
++ myhost3
|
||||
menu = myhost3
|
||||
title = HTTP latency for myhost3 (port 8080!)
|
||||
host = myhost3.example
|
||||
urlformat = http://%host%:8080/
|
||||
|
||||
+ FTP
|
||||
menu = ftp
|
||||
title = FTP latency
|
||||
urlformat = ftp://%host%/
|
||||
|
||||
++ myhost1
|
||||
menu = myhost1
|
||||
title = FTP latency for myhost1
|
||||
host = myhost1.example
|
||||
|
||||
++ myhost2
|
||||
menu = myhost2
|
||||
title = FTP latency for myhost2
|
||||
host = myhost2.example
|
||||
168
debian/smokeping/usr/share/doc/smokeping/examples/config.template
vendored
Normal file
168
debian/smokeping/usr/share/doc/smokeping/examples/config.template
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
# This Smokeping example configuration file was automatically generated.
|
||||
#
|
||||
# Everything up to the Probes section is derived from a common template file.
|
||||
# See the Probes and Targets sections for the actual example.
|
||||
#
|
||||
# This example is included in the smokeping_examples document.
|
||||
|
||||
*** General ***
|
||||
|
||||
owner = Peter Random
|
||||
contact = some@address.nowhere
|
||||
mailhost = my.mail.host
|
||||
sendmail = /usr/sbin/sendmail
|
||||
# NOTE: do not put the Image Cache below cgi-bin
|
||||
# since all files under cgi-bin will be executed ... this is not
|
||||
# good for images.
|
||||
imgcache = /usr/cache
|
||||
imgurl = cache
|
||||
datadir = /usr/data
|
||||
piddir = /usr/var
|
||||
cgiurl = http://some.url/smokeping.cgi
|
||||
smokemail = /usr/etc/smokemail.dist
|
||||
tmail = /usr/etc/tmail.dist
|
||||
# specify this to get syslog logging
|
||||
syslogfacility = local0
|
||||
# each probe is now run in its own process
|
||||
# disable this to revert to the old behaviour
|
||||
# concurrentprobes = no
|
||||
|
||||
*** Alerts ***
|
||||
to = alertee@address.somewhere
|
||||
from = smokealert@company.xy
|
||||
|
||||
+someloss
|
||||
type = loss
|
||||
# in percent
|
||||
pattern = >0%,*12*,>0%,*12*,>0%
|
||||
comment = loss 3 times in a row
|
||||
|
||||
*** Database ***
|
||||
|
||||
step = 300
|
||||
pings = 20
|
||||
|
||||
# consfn mrhb steps total
|
||||
|
||||
AVERAGE 0.5 1 28800
|
||||
AVERAGE 0.5 12 9600
|
||||
MIN 0.5 12 9600
|
||||
MAX 0.5 12 9600
|
||||
AVERAGE 0.5 144 2400
|
||||
MAX 0.5 144 2400
|
||||
MIN 0.5 144 2400
|
||||
|
||||
*** Presentation ***
|
||||
|
||||
template = /usr/etc/basepage.html.dist
|
||||
htmltitle = yes
|
||||
graphborders = no
|
||||
# If enabled, treat all filter menu queries as literal strings instead of regex
|
||||
literalsearch = no
|
||||
|
||||
+ charts
|
||||
|
||||
menu = Charts
|
||||
title = The most interesting destinations
|
||||
|
||||
++ stddev
|
||||
sorter = StdDev(entries=>4)
|
||||
title = Top Standard Deviation
|
||||
menu = Std Deviation
|
||||
format = Standard Deviation %f
|
||||
|
||||
++ max
|
||||
sorter = Max(entries=>5)
|
||||
title = Top Max Roundtrip Time
|
||||
menu = by Max
|
||||
format = Max Roundtrip Time %f seconds
|
||||
|
||||
++ loss
|
||||
sorter = Loss(entries=>5)
|
||||
title = Top Packet Loss
|
||||
menu = Loss
|
||||
format = Packets Lost %f
|
||||
|
||||
++ median
|
||||
sorter = Median(entries=>5)
|
||||
title = Top Median Roundtrip Time
|
||||
menu = by Median
|
||||
format = Median RTT %f seconds
|
||||
|
||||
+ overview
|
||||
|
||||
width = 600
|
||||
height = 50
|
||||
range = 10h
|
||||
|
||||
+ detail
|
||||
|
||||
width = 600
|
||||
height = 200
|
||||
unison_tolerance = 2
|
||||
|
||||
"Last 3 Hours" 3h
|
||||
"Last 30 Hours" 30h
|
||||
"Last 10 Days" 10d
|
||||
"Last 360 Days" 360d
|
||||
|
||||
#+ hierarchies
|
||||
#++ owner
|
||||
#title = Host Owner
|
||||
#++ location
|
||||
#title = Location
|
||||
|
||||
# (The actual example starts here.)
|
||||
|
||||
*** Probes ***
|
||||
|
||||
# This is the template configuration file distributed with Smokeping.
|
||||
# It is included in the examples as well for the sake of completeness.
|
||||
|
||||
|
||||
+ FPing
|
||||
|
||||
binary = /usr/sbin/fping
|
||||
|
||||
*** Slaves ***
|
||||
secrets=/usr/etc/smokeping_secrets.dist
|
||||
+boomer
|
||||
display_name=boomer
|
||||
color=0000ff
|
||||
|
||||
+slave2
|
||||
display_name=another
|
||||
color=00ff00
|
||||
|
||||
|
||||
*** Targets ***
|
||||
|
||||
# This is the template configuration file distributed with Smokeping.
|
||||
# It is included in the examples as well for the sake of completeness.
|
||||
|
||||
|
||||
probe = FPing
|
||||
|
||||
menu = Top
|
||||
title = Network Latency Grapher
|
||||
remark = Welcome to the SmokePing website of xxx Company. \
|
||||
Here you will learn all about the latency of our network.
|
||||
|
||||
+ Test
|
||||
menu= Targets
|
||||
#parents = owner:/Test/James location:/
|
||||
|
||||
++ James
|
||||
|
||||
menu = James
|
||||
title =James
|
||||
alerts = someloss
|
||||
slaves = boomer slave2
|
||||
host = james.address
|
||||
|
||||
++ MultiHost
|
||||
|
||||
menu = Multihost
|
||||
title = James and James as seen from Boomer
|
||||
host = /Test/James /Test/James~boomer
|
||||
|
||||
22
debian/smokeping/usr/share/doc/smokeping/examples/lighttpd_45-smokeping.conf
vendored
Normal file
22
debian/smokeping/usr/share/doc/smokeping/examples/lighttpd_45-smokeping.conf
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
# /etc/lighttpd/conf-available/45-smokeping.conf
|
||||
# Configuration for smokeping CGI program
|
||||
|
||||
server.modules += ( "mod_fastcgi", "mod_rewrite" )
|
||||
|
||||
$HTTP["url"] =~ "^/smokeping/" {
|
||||
server.document-root = "/usr/share/"
|
||||
url.rewrite-once = (
|
||||
"^/smokeping/($|\?)" => "/smokeping/smokeping.cgi?${qsa}",
|
||||
"^/smokeping/(.*)" => "/smokeping/www/$1",
|
||||
)
|
||||
fastcgi.server = (
|
||||
"/smokeping/smokeping.cgi" => (
|
||||
"localhost" => (
|
||||
"bin-path" => "/usr/lib/cgi-bin/smokeping.cgi",
|
||||
"socket" => "/run/lighttpd/smokeping-fcgi.socket",
|
||||
)
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
# vim: set ts=4 sw=4 et:
|
||||
3
debian/smokeping/usr/share/doc/smokeping/examples/smokeping_secrets.dist
vendored
Normal file
3
debian/smokeping/usr/share/doc/smokeping/examples/smokeping_secrets.dist
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
host1:mysecret
|
||||
host2:yoursecret
|
||||
boomer:lkasdf93uhhfdfddf
|
||||
11
debian/smokeping/usr/share/doc/smokeping/examples/systemd/slave_mode.conf
vendored
Normal file
11
debian/smokeping/usr/share/doc/smokeping/examples/systemd/slave_mode.conf
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
# If you need to run smokeping in a master/slave setup, you can create a
|
||||
# drop-in override to add the required parameters to the daemon like shown
|
||||
# below.
|
||||
#
|
||||
# To enable this, you'd need to create a directory
|
||||
# /etc/systemd/system/smokeping.service.d/ and copy this file in that
|
||||
# directory. Then, modify it according to your requirements.
|
||||
#
|
||||
[Service]
|
||||
ExecStart=
|
||||
ExecStart=/usr/sbin/smokeping --master-url=http://127.0.0.1/smokeping.fcgi --cache-dir=/var/lib/smokeping --shared-secret=/etc/smokeping/smokeping_secrets --pid-dir=/run/smokeping
|
||||
BIN
debian/smokeping/usr/share/man/man1/smokeinfo.1.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man1/smokeinfo.1.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man1/smokeping.1.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man1/smokeping.1.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man1/smokeping_cgi.1.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man1/smokeping_cgi.1.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man1/tSmoke.1.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man1/tSmoke.1.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_matchers_Avgratio.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_matchers_Avgratio.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_matchers_CheckLatency.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_matchers_CheckLatency.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_matchers_CheckLoss.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_matchers_CheckLoss.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_matchers_ConsecutiveLoss.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_matchers_ConsecutiveLoss.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_matchers_ExpLoss.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_matchers_ExpLoss.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_matchers_Median.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_matchers_Median.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_matchers_Medratio.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_matchers_Medratio.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_matchers_base.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_matchers_base.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_AnotherCurl.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_AnotherCurl.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_AnotherDNS.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_AnotherDNS.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_AnotherSSH.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_AnotherSSH.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_CiscoRTTMonDNS.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_CiscoRTTMonDNS.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_CiscoRTTMonEchoICMP.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_CiscoRTTMonEchoICMP.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_CiscoRTTMonTcpConnect.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_CiscoRTTMonTcpConnect.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_Curl.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_Curl.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_DNS.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_DNS.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_DismanPing.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_DismanPing.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_EchoPing.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_EchoPing.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_EchoPingChargen.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_EchoPingChargen.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_EchoPingDNS.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_EchoPingDNS.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_EchoPingDiscard.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_EchoPingDiscard.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_EchoPingHttp.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_EchoPingHttp.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_EchoPingHttps.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_EchoPingHttps.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_EchoPingIcp.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_EchoPingIcp.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_EchoPingLDAP.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_EchoPingLDAP.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_EchoPingPlugin.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_EchoPingPlugin.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_EchoPingSmtp.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_EchoPingSmtp.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_EchoPingWhois.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_EchoPingWhois.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_FPing.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_FPing.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_FPing6.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_FPing6.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_FPingContinuous.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_FPingContinuous.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_FTPtransfer.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_FTPtransfer.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_IOSPing.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_IOSPing.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_IRTT.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_IRTT.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_LDAP.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_LDAP.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_NFSping.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_NFSping.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_OpenSSHEOSPing.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_OpenSSHEOSPing.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_OpenSSHJunOSPing.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_OpenSSHJunOSPing.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_Qstat.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_Qstat.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_Radius.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_Radius.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_RemoteFPing.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_RemoteFPing.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_SSH.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_SSH.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_SendEmail.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_SendEmail.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_SipSak.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_SipSak.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_TCPPing.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_TCPPing.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_TacacsPlus.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_TacacsPlus.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_TelnetIOSPing.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_TelnetIOSPing.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_TelnetJunOSPing.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_TelnetJunOSPing.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_TraceroutePing.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_TraceroutePing.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_WebProxyFilter.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_WebProxyFilter.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_base.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_base.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_basefork.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_basefork.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_basevars.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_basevars.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_passwordchecker.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_passwordchecker.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_skel.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_probes_skel.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_sorters_Loss.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_sorters_Loss.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_sorters_Max.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_sorters_Max.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_sorters_Median.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_sorters_Median.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_sorters_StdDev.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_sorters_StdDev.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man3/Smokeping_sorters_base.3.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man3/Smokeping_sorters_base.3.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man5/smokeping_config.5.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man5/smokeping_config.5.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man5/smokeping_examples.5.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man5/smokeping_examples.5.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man7/smokeping_extend.7.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man7/smokeping_extend.7.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man7/smokeping_install.7.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man7/smokeping_install.7.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man7/smokeping_master_slave.7.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man7/smokeping_master_slave.7.gz
vendored
Normal file
Binary file not shown.
BIN
debian/smokeping/usr/share/man/man7/smokeping_upgrade.7.gz
vendored
Normal file
BIN
debian/smokeping/usr/share/man/man7/smokeping_upgrade.7.gz
vendored
Normal file
Binary file not shown.
5169
debian/smokeping/usr/share/perl5/Smokeping.pm
vendored
Normal file
5169
debian/smokeping/usr/share/perl5/Smokeping.pm
vendored
Normal file
File diff suppressed because it is too large
Load Diff
152
debian/smokeping/usr/share/perl5/Smokeping/Colorspace.pm
vendored
Normal file
152
debian/smokeping/usr/share/perl5/Smokeping/Colorspace.pm
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
# -*- perl -*-
|
||||
|
||||
package Smokeping::Colorspace;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Smokeping::Colorspace - Simple Colorspace Conversion methods
|
||||
|
||||
=head1 OVERVIEW
|
||||
|
||||
This module provides simple colorspace conversion methods, primarily allowing
|
||||
conversion from RGB (red, green, blue) to and from HSL (hue, saturation, luminosity).
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2006 by Grahame Bowland.
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
This program is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public
|
||||
License along with this program; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
|
||||
02139, USA.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Grahame Bowland <grahame.bowland@uwa.edu.au>
|
||||
|
||||
=cut
|
||||
|
||||
sub web_to_rgb {
|
||||
my $web = shift;
|
||||
$web =~ s/^#//;
|
||||
my @rgb = (hex(substr($web, 0, 2)) / 255,
|
||||
hex(substr($web, 2, 2)) / 255,
|
||||
hex(substr($web, 4, 2)) / 255) ;
|
||||
return @rgb;
|
||||
}
|
||||
|
||||
sub rgb_to_web {
|
||||
my @rgb = @_;
|
||||
return sprintf("#%.2x%.2x%.2x", 255 * $rgb[0], 255 * $rgb[1], 255 * $rgb[2]);
|
||||
}
|
||||
|
||||
sub min_max_indexes {
|
||||
my $idx = 0;
|
||||
my ($min_idx, $min, $max_idx, $max);
|
||||
my @l = @_;
|
||||
|
||||
foreach my $i (@l) {
|
||||
if (not defined($min) or ($i < $min)) {
|
||||
$min = $i;
|
||||
$min_idx = $idx;
|
||||
}
|
||||
if (not defined($max) or ($i > $max)) {
|
||||
$max = $i;
|
||||
$max_idx = $idx;
|
||||
}
|
||||
$idx++;
|
||||
}
|
||||
return ($min_idx, $min, $max_idx, $max);
|
||||
}
|
||||
|
||||
# source for conversion algorithm is:
|
||||
# http://www.easyrgb.com/math.php?MATH=M18#text18
|
||||
sub rgb_to_hsl {
|
||||
my @rgb = @_;
|
||||
my ($h, $l, $s);
|
||||
|
||||
my ($min_idx, $min, $max_idx, $max) = min_max_indexes(@rgb);
|
||||
my $delta_max = $max - $min;
|
||||
$l = ($max + $min) / 2;
|
||||
if ($delta_max == 0) {
|
||||
my $h = 0;
|
||||
my $s = 0;
|
||||
} else {
|
||||
if ($l < 0.5) {
|
||||
$s = $delta_max / ($max + $min);
|
||||
} else {
|
||||
$s = $delta_max / (2 - $max - $min);
|
||||
}
|
||||
my $delta_r = ((($max - $rgb[0]) / 6) + ($max / 2)) / $delta_max;
|
||||
my $delta_g = ((($max - $rgb[1]) / 6) + ($max / 2)) / $delta_max;
|
||||
my $delta_b = ((($max - $rgb[2]) / 6) + ($max / 2)) / $delta_max;
|
||||
if ($max_idx == 0) {
|
||||
$h = $delta_b - $delta_g;
|
||||
} elsif ($max_idx == 1) {
|
||||
$h = (1/3) + $delta_r - $delta_b;
|
||||
} else {
|
||||
$h = (2/3) + $delta_g - $delta_r;
|
||||
}
|
||||
if ($h < 0) {
|
||||
$h += 1;
|
||||
} elsif ($h > 1) {
|
||||
$h -= 1;
|
||||
}
|
||||
}
|
||||
return ($h, $s, $l);
|
||||
}
|
||||
|
||||
sub hue_to_rgb {
|
||||
my ($v1, $v2, $vh) = @_;
|
||||
if ($vh < 0) {
|
||||
$vh += 1;
|
||||
} elsif ($vh > 1) {
|
||||
$vh -= 1;
|
||||
}
|
||||
if ($vh * 6 < 1) {
|
||||
return $v1 + ($v2 - $v1) * 6 * $vh;
|
||||
} elsif ($vh * 2 < 1) {
|
||||
return $v2;
|
||||
} elsif ($vh * 3 < 2) {
|
||||
return $v1 + ($v2 - $v1) * ((2/3) - $vh) * 6;
|
||||
} else {
|
||||
return $v1;
|
||||
}
|
||||
}
|
||||
|
||||
sub hsl_to_rgb {
|
||||
my ($h, $s, $l) = @_;
|
||||
my ($r, $g, $b);
|
||||
if ($s == 0) {
|
||||
$r = $g = $b = $l;
|
||||
} else {
|
||||
my $ls;
|
||||
if ($l < 0.5) {
|
||||
$ls = $l * (1 + $s);
|
||||
} else {
|
||||
$ls = ($l + $s) - ($s * $l);
|
||||
}
|
||||
$l = 2 * $l - $ls;
|
||||
$r = hue_to_rgb($l, $ls, $h + 1/3);
|
||||
$g = hue_to_rgb($l, $ls, $h);
|
||||
$b = hue_to_rgb($l, $ls, $h - (1/3));
|
||||
}
|
||||
return ($r, $g, $b);
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
15
debian/smokeping/usr/share/perl5/Smokeping/Config.pm
vendored
Normal file
15
debian/smokeping/usr/share/perl5/Smokeping/Config.pm
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
# provide backward compatibility for Config::Grammar
|
||||
package Smokeping::Config;
|
||||
|
||||
BEGIN {
|
||||
require Config::Grammar;
|
||||
if($Config::Grammar::VERSION ge '1.10') {
|
||||
require Config::Grammar::Dynamic;
|
||||
@ISA = qw(Config::Grammar::Dynamic);
|
||||
}
|
||||
else {
|
||||
@ISA = qw(Config::Grammar);
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
678
debian/smokeping/usr/share/perl5/Smokeping/Examples.pm
vendored
Normal file
678
debian/smokeping/usr/share/perl5/Smokeping/Examples.pm
vendored
Normal file
@@ -0,0 +1,678 @@
|
||||
# -*- perl -*-
|
||||
package Smokeping::Examples;
|
||||
use strict;
|
||||
use Smokeping;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Smokeping::Examples - A module for generating the smokeping_examples document
|
||||
|
||||
=head1 OVERVIEW
|
||||
|
||||
This module generates L<smokeping_examples> and the example
|
||||
configuration files distributed with Smokeping. It is supposed to be
|
||||
invoked from the smokeping distribution top directory, as it will need
|
||||
the C<etc/config.dist> template configuration file and will create files
|
||||
in the directories C<doc> and C<doc/examples>.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The entry point to the module is the C<make> subroutine. It takes one optional
|
||||
parameter, C<check>, that makes the module run a syntax check for all the
|
||||
created example configuration files.
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
This module uses more or less internal functions from L<Smokeping.pm|Smokeping>. It's a
|
||||
separate module only because the latter is much too big already.
|
||||
|
||||
It should be possible to include POD markup in the configuration explanations
|
||||
and have this module filter them away for the config files.
|
||||
|
||||
It might be nice for the probe module authors to be able to provide an
|
||||
example configuration as part of the probe module instead of having to
|
||||
modify Smokeping::Examples too.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2005 by Niko Tyni.
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
This program is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public
|
||||
License along with this program; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
|
||||
02139, USA.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Niko Tyni <ntyni@iki.fi>
|
||||
|
||||
=cut
|
||||
|
||||
use strict;
|
||||
|
||||
sub read_config_template {
|
||||
my $file = "../etc/config.dist";
|
||||
my $h = {
|
||||
common => "", # everything up to the Probes section
|
||||
probes => "", # the Probes section, without the *** Probes *** line
|
||||
targets => "", # the Targets section, without the *** Targets *** line
|
||||
};
|
||||
open(F, "<$file") or die("open template configuration file $file for reading: $!");
|
||||
my %found;
|
||||
while (<F>) {
|
||||
/\*\*\*\s*(Probes|Targets)\s*\*\*\*/ and $found{$1} = 1, next;
|
||||
$h->{common} .= $_ and next unless $found{Probes};
|
||||
$h->{probes} .= $_ and next unless $found{Targets};
|
||||
$h->{targets} .= $_;
|
||||
}
|
||||
close F;
|
||||
return $h;
|
||||
}
|
||||
|
||||
sub prologue {
|
||||
my $e = "=";
|
||||
return <<DOC;
|
||||
${e}head1 NAME
|
||||
|
||||
smokeping_examples - Examples of Smokeping configuration
|
||||
|
||||
${e}head1 OVERVIEW
|
||||
|
||||
This document provides some examples of Smokeping configuration files.
|
||||
All the examples can be found in the C<examples> directory in the
|
||||
Smokeping documentation. Note that the DNS names in the examples are
|
||||
non-functional.
|
||||
|
||||
Details of the syntax and all the variables are found in
|
||||
L<smokeping_config> and in the documentation of the
|
||||
corresponding probe, if applicable.
|
||||
|
||||
This manual is automatically generated from the Smokeping source code,
|
||||
specifically the L<Smokeping::Examples|Smokeping::Examples> module.
|
||||
|
||||
${e}head1 DESCRIPTION
|
||||
|
||||
Currently the examples differ only in the C<Probes> and C<Targets>
|
||||
sections. The other sections are taken from the C<etc/config.dist>
|
||||
configuration template in the Smokeping distribution so that the example
|
||||
files are complete.
|
||||
|
||||
If you would like to provide more examples, document the other sections
|
||||
or enhance the existing examples, please do so, preferably by sending
|
||||
the proposed changes to the smokeping-users mailing list.
|
||||
|
||||
DOC
|
||||
}
|
||||
|
||||
sub epilogue {
|
||||
my $e = "=";
|
||||
return <<DOC;
|
||||
|
||||
${e}head1 COPYRIGHT
|
||||
|
||||
Copyright 2005 by Niko Tyni.
|
||||
|
||||
${e}head1 LICENSE
|
||||
|
||||
This program is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public
|
||||
License along with this program; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
|
||||
02139, USA.
|
||||
|
||||
${e}head1 AUTHOR
|
||||
|
||||
Niko Tyni <ntyni\@iki.fi>
|
||||
|
||||
${e}head1 SEE ALSO
|
||||
|
||||
The other Smokeping documents, especially L<smokeping_config>.
|
||||
DOC
|
||||
}
|
||||
|
||||
sub make {
|
||||
print "Generating example files...\n";
|
||||
my $check = shift; # check the syntax of the generated config files
|
||||
my $template = read_config_template();
|
||||
my $examples = examples($template);
|
||||
my $manual = prologue();
|
||||
for my $ex (sort { $examples->{$a}{order} <=> $examples->{$b}{order} } keys %$examples) {
|
||||
my $h = $examples->{$ex};
|
||||
$manual .= "\n=head2 Example $h->{order}: config.$ex\n\n"
|
||||
. genpod($h);
|
||||
my $cfgfile = "examples/config.$ex";
|
||||
print "\t$cfgfile ...\n";
|
||||
writecfg($cfgfile, $template, $h);
|
||||
if ($check) {
|
||||
local $Smokeping::cfg = undef;
|
||||
eval {
|
||||
Smokeping::verify_cfg($cfgfile);
|
||||
};
|
||||
die("Syntax check for $cfgfile failed: $@") if $@;
|
||||
}
|
||||
}
|
||||
$manual .= epilogue();
|
||||
writemanual($manual);
|
||||
print "done.\n";
|
||||
}
|
||||
|
||||
sub writemanual {
|
||||
my $text = shift;
|
||||
my $filename = "smokeping_examples.pod";
|
||||
print "\t$filename ...\n";
|
||||
open(F, ">$filename") or die("open $filename for writing: $!");
|
||||
print F $text;
|
||||
close F;
|
||||
}
|
||||
|
||||
sub genpod {
|
||||
my $h = shift;
|
||||
my $text = "";
|
||||
$text .= "=over\n\n";
|
||||
$text .= "=item Probe configuration\n\n";
|
||||
$text .= " *** Probes ***\n";
|
||||
$text .= join("\n", map { " $_" } split(/\n/, $h->{probes}));
|
||||
$text .= "\n\n=item Probe explanation\n\n";
|
||||
$text .= $h->{probedoc} || "No probedoc found !";
|
||||
$text .= "\n\n=item Target configuration\n\n";
|
||||
$text .= " *** Targets ***\n";
|
||||
$text .= join("\n", map { " $_" } split(/\n/, $h->{targets}));
|
||||
$text .= "\n\n=item Target explanation\n\n";
|
||||
$text .= $h->{targetdoc} || "No targetdoc found !";
|
||||
$text .= "\n\n=back\n\n";
|
||||
return $text;
|
||||
}
|
||||
|
||||
sub writecfg {
|
||||
my $file = shift;
|
||||
my $template = shift;
|
||||
my $h = shift;
|
||||
open(F, ">$file") or die("open $file for writing: $!");
|
||||
print F <<DOC;
|
||||
# This Smokeping example configuration file was automatically generated.
|
||||
#
|
||||
# Everything up to the Probes section is derived from a common template file.
|
||||
# See the Probes and Targets sections for the actual example.
|
||||
#
|
||||
# This example is included in the smokeping_examples document.
|
||||
|
||||
DOC
|
||||
print F $template->{common};
|
||||
print F "# (The actual example starts here.)\n";
|
||||
print F "\n*** Probes ***\n\n";
|
||||
print F join("\n", map { "# $_" } split(/\n/, $h->{probedoc} || 'No probedoc found!'));
|
||||
print F "\n\n";
|
||||
print F $h->{probes};
|
||||
print F "\n*** Targets ***\n\n";
|
||||
print F join("\n", map { "# $_" } split(/\n/, $h->{targetdoc} || 'No targetdoc found'));
|
||||
print F "\n\n";
|
||||
print F $h->{targets};
|
||||
close F;
|
||||
}
|
||||
|
||||
sub examples {
|
||||
my $template = shift;
|
||||
return {
|
||||
simple => {
|
||||
order => 1,
|
||||
probes => <<DOC,
|
||||
+FPing
|
||||
binary = /usr/bin/fping
|
||||
DOC
|
||||
targets => <<DOC,
|
||||
probe = FPing
|
||||
|
||||
menu = Top
|
||||
title = Network Latency Grapher
|
||||
remark = Welcome to this SmokePing website.
|
||||
|
||||
+ mysite1
|
||||
menu = Site 1
|
||||
title = Hosts in Site 1
|
||||
|
||||
++ myhost1
|
||||
host = myhost1.mysite1.example
|
||||
++ myhost2
|
||||
host = myhost2.mysite1.example
|
||||
|
||||
+ mysite2
|
||||
menu = Site 2
|
||||
title = Hosts in Site 2
|
||||
|
||||
++ myhost3
|
||||
host = myhost3.mysite2.example
|
||||
++ myhost4
|
||||
host = myhost4.mysite2.example
|
||||
DOC
|
||||
probedoc => <<DOC,
|
||||
Here we have just one probe, fping, pinging four hosts.
|
||||
|
||||
The fping probe is using the default parameters, some of them supplied
|
||||
from the Database section ("step" and "pings"), and some of them by
|
||||
the probe module.
|
||||
DOC
|
||||
targetdoc => <<DOC,
|
||||
The hosts are located in two sites of two hosts each, and the
|
||||
configuration has been divided to site sections ('+') and host subsections
|
||||
('++') accordingly.
|
||||
DOC
|
||||
}, # simple
|
||||
"multiple-probes" => {
|
||||
order => 2,
|
||||
probes => <<DOC,
|
||||
+ FPing
|
||||
binary = /usr/bin/fping
|
||||
packetsize = 1000
|
||||
|
||||
+ DNS
|
||||
binary = /usr/bin/dig
|
||||
lookup = name.example
|
||||
pings = 5
|
||||
step = 180
|
||||
|
||||
+ EchoPingHttp
|
||||
pings = 5
|
||||
url = /test-url
|
||||
DOC
|
||||
targets => <<DOC,
|
||||
probe = FPing
|
||||
menu = Top
|
||||
title = Network Latency Grapher
|
||||
remark = Welcome to this SmokePing website.
|
||||
|
||||
+ network
|
||||
menu = Net latency
|
||||
title = Network latency (ICMP pings)
|
||||
|
||||
++ myhost1
|
||||
host = myhost1.example
|
||||
++ myhost2
|
||||
host = myhost2.example
|
||||
|
||||
+ services
|
||||
menu = Service latency
|
||||
title = Service latency (DNS, HTTP)
|
||||
|
||||
++ DNS
|
||||
probe = DNS
|
||||
menu = DNS latency
|
||||
title = Service latency (DNS)
|
||||
|
||||
+++ dns1
|
||||
host = dns1.example
|
||||
|
||||
+++ dns2
|
||||
host = dns2.example
|
||||
|
||||
++ HTTP
|
||||
menu = HTTP latency
|
||||
title = Service latency (HTTP)
|
||||
|
||||
+++ www1
|
||||
host = www1.example
|
||||
|
||||
+++ www2
|
||||
host = www2.example
|
||||
DOC
|
||||
probedoc => <<DOC,
|
||||
Here we have three probes: FPing for the regular ICMP pings,
|
||||
DNS for name server latency measurement and EchoPingHttp
|
||||
for web servers.
|
||||
|
||||
The FPing probe runs with the default parameters, except that the ICMP
|
||||
packet size is 1000 bytes instead of the default 56 bytes.
|
||||
|
||||
The DNS and EchoPingHttp probes have been configured to be a bit more
|
||||
gentle with the servers, as they only do 5 queries (pings) instead of the
|
||||
default 20 (or whatever is specified in the Database section). However,
|
||||
DNS queries are made more often: 5 queries every 3 minutes instead of
|
||||
every 5 minutes.
|
||||
DOC
|
||||
targetdoc => <<DOC,
|
||||
The target tree has been divided by the probe used. This does not have
|
||||
to be the case: every target (sub)section can use a different probe,
|
||||
and the same probe can be used in different parts of the config tree.
|
||||
DOC
|
||||
}, # multiple-probes
|
||||
"fping-instances" => {
|
||||
order => 3,
|
||||
probes => <<DOC,
|
||||
+ FPing
|
||||
binary = /usr/bin/fping
|
||||
|
||||
++ FPingNormal
|
||||
offset = 0%
|
||||
|
||||
++ FPingLarge
|
||||
packetsize = 5000
|
||||
offset = 50%
|
||||
DOC
|
||||
probedoc => <<DOC,
|
||||
This example demonstrates the concept of probe instances. The FPingLarge
|
||||
and FPingNormal probes are independent of each other, they just use
|
||||
the same module, FPing. FPingNormal uses the default parameters, and
|
||||
so does FPingLarge except for the 5 kilobyte packetsize. Both use the
|
||||
same fping binary, and its path is configured FPing top section.
|
||||
|
||||
The 'offset' parameters make sure the probes don't run at the same time -
|
||||
FPingNormal is run every 'full' 5 minutes (eg. 8:00, 8:05, 8:10 and so on,
|
||||
in wallclock time) while FPingLarge is run halfway through these intervals
|
||||
(eg. 8:02:30, 8:07:30 etc.)
|
||||
|
||||
The top FPing section does not define a probe in itself because it
|
||||
has subsections. If we really wanted to have one probe named "FPing",
|
||||
we could do so by making a subsection by that name.
|
||||
DOC
|
||||
targets => <<DOC,
|
||||
probe = FPingNormal
|
||||
menu = Top
|
||||
title = Network Latency Grapher
|
||||
remark = Welcome to this SmokePing website.
|
||||
|
||||
+ network
|
||||
menu = Net latency
|
||||
title = Network latency (ICMP pings)
|
||||
|
||||
++ myhost1
|
||||
menu = myhost1
|
||||
title = ICMP latency for myhost1
|
||||
|
||||
+++ normal
|
||||
title = Normal packetsize (56 bytes)
|
||||
probe = FPingNormal
|
||||
host = myhost1.example
|
||||
|
||||
+++ large
|
||||
title = Large packetsize (5000 bytes)
|
||||
probe = FPingLarge
|
||||
host = myhost1.example
|
||||
|
||||
++ myhost2
|
||||
menu = myhost2
|
||||
title = ICMP latency for myhost2
|
||||
|
||||
+++ normal
|
||||
title = Normal packetsize (56 bytes)
|
||||
probe = FPingNormal
|
||||
host = myhost2.example
|
||||
|
||||
+++ large
|
||||
title = Large packetsize (5000 bytes)
|
||||
probe = FPingLarge
|
||||
host = myhost2.example
|
||||
DOC
|
||||
targetdoc => <<DOC,
|
||||
The target section shows two host, myhost1.example and myhost2.example,
|
||||
being pinged with two differently sized ICMP packets. This time the tree
|
||||
is divided by the target host rather than the probe.
|
||||
DOC
|
||||
}, # fping-instances
|
||||
"targetvars-with-Curl" => {
|
||||
order => 4,
|
||||
probes => <<DOC,
|
||||
+ Curl
|
||||
# probe-specific variables
|
||||
binary = /usr/bin/curl
|
||||
step = 60
|
||||
|
||||
# a default for this target-specific variable
|
||||
urlformat = http://%host%/
|
||||
DOC
|
||||
probedoc => <<DOC,
|
||||
This example explains the difference between probe- and target-specific
|
||||
variables. We use the Curl probe for this.
|
||||
|
||||
Every probe supports at least some probe-specific variables. The values
|
||||
of these variables are common to all the targets of the probe, and
|
||||
they can only be configured in the Probes section. In this case,
|
||||
the probe-specific variables are "binary" and "step".
|
||||
|
||||
Target-specific variables are supported by most probes, the most notable
|
||||
exception being the FPing probe and its derivatives. Target-specific
|
||||
variables can have different values for different targets. They can be
|
||||
configured in both Probes and Targets sections. The values assigned in the
|
||||
Probes section function become default values that can be overridden
|
||||
in the Targets section.
|
||||
|
||||
The documentation of each probe states which of its variables are
|
||||
probe-specific and which are target-specific.
|
||||
|
||||
In this case the "urlformat" variable is a target-specific one. It is
|
||||
also quite uncommon, because it can contain a placeholder for the "host"
|
||||
variable in the Targets section. This is not a general feature, its
|
||||
usage is only limited to the "urlformat" variable and the "%host%" escape.
|
||||
|
||||
(The reason why the FPing probe does not support target-specific variables
|
||||
is simply the fact that the fping program measures all its targets in one
|
||||
go, so they all have the same parameters. The other probes ping their targets
|
||||
one at a time.)
|
||||
DOC
|
||||
targets => <<DOC,
|
||||
probe = Curl
|
||||
menu = Top
|
||||
title = Network Latency Grapher
|
||||
remark = Welcome to this SmokePing website.
|
||||
|
||||
+ HTTP
|
||||
menu = http
|
||||
title = HTTP latency
|
||||
|
||||
++ myhost1
|
||||
menu = myhost1
|
||||
title = HTTP latency for myhost1
|
||||
host = myhost1.example
|
||||
|
||||
++ myhost2
|
||||
menu = myhost2
|
||||
title = HTTP latency for myhost2
|
||||
host = myhost2.example
|
||||
|
||||
++ myhost3
|
||||
menu = myhost3
|
||||
title = HTTP latency for myhost3 (port 8080!)
|
||||
host = myhost3.example
|
||||
urlformat = http://%host%:8080/
|
||||
|
||||
+ FTP
|
||||
menu = ftp
|
||||
title = FTP latency
|
||||
urlformat = ftp://%host%/
|
||||
|
||||
++ myhost1
|
||||
menu = myhost1
|
||||
title = FTP latency for myhost1
|
||||
host = myhost1.example
|
||||
|
||||
++ myhost2
|
||||
menu = myhost2
|
||||
title = FTP latency for myhost2
|
||||
host = myhost2.example
|
||||
DOC
|
||||
targetdoc => <<DOC,
|
||||
The target tree is divided into an HTTP branch and an FTP one.
|
||||
The servers "myhost1.example" and "myhost2.example" are probed
|
||||
in both. The third server, "myhost3.example", only has an HTTP
|
||||
server, and it's in a non-standard port (8080).
|
||||
|
||||
The "urlformat" variable is specified for the whole FTP branch
|
||||
as "ftp://%host%/". For the HTTP branch, the default from the
|
||||
Probes section is used, except for myhost3, which overrides
|
||||
it to tag the port number into the URL.
|
||||
|
||||
The myhost3 assignment could just as well have included the hostname
|
||||
verbatim (ie. urlformat = http://myhost3.example:8080/) instead of
|
||||
using the %host% placeholder, but the host variable would still have
|
||||
been required (even though it wouldn't have been used for anything).
|
||||
DOC
|
||||
}, # targetvars-with-Curl
|
||||
echoping => {
|
||||
order => 5,
|
||||
probes => <<DOC,
|
||||
+ FPing
|
||||
binary = /usr/bin/fping
|
||||
|
||||
# these expect to find echoping in /usr/bin
|
||||
# if not, you'll have to specify the location separately for each probe
|
||||
# + EchoPing # uses TCP or UDP echo (port 7)
|
||||
# + EchoPingDiscard # uses TCP or UDP discard (port 9)
|
||||
# + EchoPingChargen # uses TCP chargen (port 19)
|
||||
+ EchoPingSmtp # SMTP (25/tcp) for mail servers
|
||||
+ EchoPingHttps # HTTPS (443/tcp) for web servers
|
||||
+ EchoPingHttp # HTTP (80/tcp) for web servers and caches
|
||||
+ EchoPingIcp # ICP (3130/udp) for caches
|
||||
# these need at least echoping 6 with the corresponding plugins
|
||||
+ EchoPingDNS # DNS (53/udp or tcp) servers
|
||||
+ EchoPingLDAP # LDAP (389/tcp) servers
|
||||
+ EchoPingWhois # Whois (43/tcp) servers
|
||||
DOC
|
||||
probedoc => <<DOC,
|
||||
This example shows most of the echoping-derived probes in action.
|
||||
DOC
|
||||
targets => <<DOC,
|
||||
# default probe
|
||||
probe = FPing
|
||||
|
||||
menu = Top
|
||||
title = Network Latency Grapher
|
||||
remark = Welcome to this SmokePing website.
|
||||
|
||||
+ MyServers
|
||||
|
||||
menu = My Servers
|
||||
title = My Servers
|
||||
|
||||
++ www-server
|
||||
menu = www-server
|
||||
title = Web Server (www-server) / ICMP
|
||||
# probe = FPing propagated from top
|
||||
host = www-server.example
|
||||
|
||||
+++ http
|
||||
menu = http
|
||||
title = Web Server (www-server) / HTTP
|
||||
probe = EchoPingHttp
|
||||
host = www-server.example
|
||||
# default url is /
|
||||
|
||||
+++ https
|
||||
menu = https
|
||||
title = Web Server (www-server) / HTTPS
|
||||
probe = EchoPingHttps
|
||||
host = www-server.example
|
||||
|
||||
++ cache
|
||||
menu = www-cache
|
||||
title = Web Cache (www-cache) / ICMP
|
||||
host = www-cache.example
|
||||
|
||||
+++ http
|
||||
menu = http
|
||||
title = www-cache / HTTP
|
||||
probe = EchoPingHttp
|
||||
host = www-cache.example
|
||||
port = 8080 # use the squid port
|
||||
url = http://www.somehost.example/
|
||||
|
||||
+++ icp
|
||||
menu = icp
|
||||
title = www-cache / ICP
|
||||
probe = EchoPingIcp
|
||||
host = www-cache.example
|
||||
url = http://www.somehost.example/
|
||||
|
||||
++ mail
|
||||
menu = mail-server
|
||||
title = Mail Server (mail-server) / ICMP
|
||||
host = mail-server.example
|
||||
|
||||
+++ smtp
|
||||
menu = mail-server / SMTP
|
||||
title = Mail Server (mail-server) / SMTP
|
||||
probe = EchoPingSmtp
|
||||
host = mail-server.example
|
||||
|
||||
++ ldap-server
|
||||
menu = ldap-server
|
||||
title = ldap-server / ICMP
|
||||
host = ldap-server.example
|
||||
|
||||
+++ ldap
|
||||
menu = ldap-server / LDAP
|
||||
title = LDAP Server (ldap-server) / LDAP
|
||||
probe = EchoPingLDAP
|
||||
ldap_request = (objectclass=*)
|
||||
host = ldap-server.example
|
||||
|
||||
++ name-server
|
||||
menu = name-server
|
||||
title = name-server / ICMP
|
||||
host = name-server.example
|
||||
|
||||
+++ DNS
|
||||
menu = name-server / DNS
|
||||
title = DNS Server (name-server) / DNS
|
||||
probe = EchoPingDNS
|
||||
dns_request = name.example
|
||||
host = name-server.example
|
||||
|
||||
++ whois-server
|
||||
menu = whois-server
|
||||
title = whois-server / ICMP
|
||||
host = whois-server.example
|
||||
|
||||
+++ Whois
|
||||
menu = whois-server / Whois
|
||||
title = Whois Server (whois-server) / Whois
|
||||
probe = EchoPingWhois
|
||||
whois_request = domain.example
|
||||
host = whois-server.example
|
||||
DOC
|
||||
targetdoc => <<DOC,
|
||||
All the servers are pinged both with ICMP (the FPing probe)
|
||||
and their respective echoping probe. The proxy server, www-cache,
|
||||
is probed with both HTTP requests and ICP requests for the same
|
||||
URL.
|
||||
DOC
|
||||
}, # echoping
|
||||
template => {
|
||||
order => 6, # last
|
||||
probes => $template->{probes},
|
||||
targets => $template->{targets},
|
||||
probedoc => <<DOC,
|
||||
This is the template configuration file distributed with Smokeping.
|
||||
It is included in the examples as well for the sake of completeness.
|
||||
DOC
|
||||
targetdoc => <<DOC,
|
||||
This is the template configuration file distributed with Smokeping.
|
||||
It is included in the examples as well for the sake of completeness.
|
||||
DOC
|
||||
},
|
||||
}; # return
|
||||
} # sub examples
|
||||
|
||||
1;
|
||||
403
debian/smokeping/usr/share/perl5/Smokeping/Graphs.pm
vendored
Normal file
403
debian/smokeping/usr/share/perl5/Smokeping/Graphs.pm
vendored
Normal file
@@ -0,0 +1,403 @@
|
||||
# -*- perl -*-
|
||||
package Smokeping::Graphs;
|
||||
use strict;
|
||||
use Smokeping;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Smokeping::Graphs - Functions used in Smokeping for creating graphs
|
||||
|
||||
=head1 OVERVIEW
|
||||
|
||||
This module currently only contains the code for generating the 'multi target' graphs.
|
||||
Code for the other graphs will be moved here too in time.
|
||||
|
||||
=head2 IMPLEMENTATION
|
||||
|
||||
=head3 get_multi_detail
|
||||
|
||||
A version of get_detail for multi host graphs where there is data from
|
||||
multiple targets shown in one graph. The look of the graph is modeld after
|
||||
the graphs shown in the overview page, except for the size.
|
||||
|
||||
=cut
|
||||
|
||||
sub get_colors ($){
|
||||
my $cfg = shift;
|
||||
my @colorList = ();
|
||||
my $colorText = $cfg->{Presentation}{colortext};
|
||||
my $colorBorder = $cfg->{Presentation}{colorborder};
|
||||
my $colorBackground = $cfg->{Presentation}{colorbackground};
|
||||
|
||||
# If graphborders set to no, and no color override, then return default colors as before
|
||||
if (($cfg->{Presentation}{graphborders} eq 'no') && !($colorText||$colorBorder||$colorBackground)) {
|
||||
return '--border', '0',
|
||||
'--color', 'BACK#ffffff00',
|
||||
'--color', 'CANVAS#ffffff00';
|
||||
};
|
||||
|
||||
# If there are any overrides, use them
|
||||
if ($cfg->{Presentation}{graphborders} eq 'no') {
|
||||
push(@colorList, '--border', '0');
|
||||
};
|
||||
if ($colorText) {
|
||||
push(@colorList, '--color', "FONT#${colorText}");
|
||||
};
|
||||
if ($colorBorder) {
|
||||
push(@colorList, '--color', "FRAME#${colorBorder}");
|
||||
};
|
||||
if ($colorBackground) {
|
||||
push(@colorList, '--color', "SHADEA#${colorBackground}");
|
||||
push(@colorList, '--color', "SHADEB#${colorBackground}");
|
||||
push(@colorList, '--color', "BACK#${colorBackground}");
|
||||
push(@colorList, '--color', "CANVAS#${colorBackground}");
|
||||
};
|
||||
|
||||
if (@colorList) { return @colorList[0..$#colorList] };
|
||||
|
||||
# Otherwise use rrdtool defaults
|
||||
return
|
||||
}
|
||||
|
||||
sub get_multi_detail ($$$$;$){
|
||||
# a) 's' classic with several static graphs on the page
|
||||
# b) 'n' navigator mode with one graph. below the graph one can specify the end time
|
||||
# and the length of the graph.
|
||||
# c) 'a' ajax mode, generate image based on given url and dump in on stdout
|
||||
#
|
||||
my $cfg = shift;
|
||||
my $q = shift;
|
||||
my $tree = shift;
|
||||
my $open = shift;
|
||||
my $mode = shift || $q->param('displaymode') || 's';
|
||||
my $phys_open = $open;
|
||||
if ($tree->{__tree_link}){
|
||||
$tree=$tree->{__tree_link};
|
||||
$phys_open = $tree->{__real_path};
|
||||
}
|
||||
|
||||
my @dirs = @{$phys_open};
|
||||
|
||||
return "<div>ERROR: ".(join ".", @dirs)." has no probe defined</div>"
|
||||
unless $tree->{probe};
|
||||
|
||||
return "<div>ERROR: ".(join ".", @dirs)." $tree->{probe} is not known</div>"
|
||||
unless $cfg->{__probes}{$tree->{probe}};
|
||||
|
||||
return "<div>ERROR: ".(join ".", @dirs)." ist no multi host</div>"
|
||||
unless $tree->{host} =~ m|^/|;
|
||||
|
||||
return "<div>ERROR: unknown displaymode $mode</div>"
|
||||
unless $mode =~ /^[snca]$/;
|
||||
|
||||
my $dir = "";
|
||||
|
||||
for (@dirs) {
|
||||
$dir .= "/$_";
|
||||
mkdir $cfg->{General}{imgcache}.$dir, 0755
|
||||
unless -d $cfg->{General}{imgcache}.$dir;
|
||||
die "ERROR: creating $cfg->{General}{imgcache}$dir: $!\n"
|
||||
unless -d $cfg->{General}{imgcache}.$dir;
|
||||
|
||||
}
|
||||
|
||||
my $page;
|
||||
my $file = pop @dirs;
|
||||
|
||||
my @hosts = split /\s+/, $tree->{host};
|
||||
|
||||
|
||||
|
||||
my $ProbeDesc;
|
||||
my $ProbeUnit;
|
||||
|
||||
|
||||
my $imgbase;
|
||||
my $imghref;
|
||||
my @tasks;
|
||||
my %lastheight;
|
||||
my $max = {};
|
||||
|
||||
if ($mode eq 's'){
|
||||
# in nav mode there is only one graph, so the height calculation
|
||||
# is not necessary.
|
||||
$imgbase = $cfg->{General}{imgcache}."/".(join "/", @dirs)."/${file}";
|
||||
$imghref = $cfg->{General}{imgurl}."/".(join "/", @dirs)."/${file}";
|
||||
@tasks = @{$cfg->{Presentation}{detail}{_table}};
|
||||
if (open (HG,"<${imgbase}.maxheight")){
|
||||
while (<HG>){
|
||||
chomp;
|
||||
my @l = split / /;
|
||||
$lastheight{$l[0]} = $l[1];
|
||||
}
|
||||
close HG;
|
||||
}
|
||||
for my $rrd (@hosts){
|
||||
my $newmax = Smokeping::findmax($cfg, $cfg->{General}{datadir}.$rrd.".rrd");
|
||||
map {$max->{$_} = $newmax->{$_} if not $max->{$_} or $newmax->{$_} > $max->{$_} } keys %{$newmax};
|
||||
}
|
||||
if (open (HG,">${imgbase}.maxheight")){
|
||||
foreach my $size (keys %{$max}){
|
||||
print HG "$size $max->{$size}\n";
|
||||
}
|
||||
close HG;
|
||||
}
|
||||
}
|
||||
elsif ($mode eq 'n' or $mode eq 'a') {
|
||||
|
||||
if ($mode eq 'n') {
|
||||
$imgbase =$cfg->{General}{imgcache}."/__navcache/".time()."$$";
|
||||
$imghref =$cfg->{General}{imgurl}."/__navcache/".time()."$$";
|
||||
} else {
|
||||
my $serial = int(rand(2000));
|
||||
$imgbase =$cfg->{General}{imgcache}."/__navcache/".$serial;
|
||||
$imghref =$cfg->{General}{imgurl}."/__navcache/".$serial;
|
||||
}
|
||||
mkdir $cfg->{General}{imgcache}."/__navcache",0755 unless -d $cfg->{General}{imgcache}."/__navcache";
|
||||
# remove old images after one hour
|
||||
my $pattern = $cfg->{General}{imgcache}."/__navcache/*.png";
|
||||
for (glob $pattern){
|
||||
unlink $_ if time - (stat $_)[9] > 3600;
|
||||
}
|
||||
|
||||
@tasks = (["Navigator Graph", Smokeping::parse_datetime($q->param('start')),Smokeping::parse_datetime($q->param('end'))]);
|
||||
} else {
|
||||
# chart mode
|
||||
mkdir $cfg->{General}{imgcache}."/__chartscache",0755 unless -d $cfg->{General}{imgcache}."/__chartscache";
|
||||
# remove old images after one hour
|
||||
my $pattern = $cfg->{General}{imgcache}."/__chartscache/*.png";
|
||||
for (glob $pattern){
|
||||
unlink $_ if time - (stat $_)[9] > 3600;
|
||||
}
|
||||
my $desc = join "/",@{$open};
|
||||
@tasks = ([$desc , time()-3600, time()]);
|
||||
$imgbase = $cfg->{General}{imgcache}."/__chartscache/".(join ".", @dirs).".${file}";
|
||||
$imghref = $cfg->{General}{imgurl}."/__chartscache/".(join ".", @dirs).".${file}";
|
||||
}
|
||||
if ($mode =~ /[anc]/){
|
||||
my $val = 0;
|
||||
for my $host (@hosts){
|
||||
my ($graphret,$xs,$ys) = RRDs::graph
|
||||
("dummy",
|
||||
'--start', $tasks[0][1],
|
||||
'--end', $tasks[0][2],
|
||||
"DEF:maxping=$cfg->{General}{datadir}${host}.rrd:median:AVERAGE",
|
||||
'PRINT:maxping:MAX:%le' );
|
||||
my $ERROR = RRDs::error();
|
||||
return "<div>RRDtool did not understand your input: $ERROR.</div>" if $ERROR;
|
||||
$val = $graphret->[0] if $val < $graphret->[0];
|
||||
}
|
||||
$val = 1e-6 if $val =~ /nan/i;
|
||||
$max = { $tasks[0][1] => $val * 1.5 };
|
||||
}
|
||||
|
||||
for (@tasks) {
|
||||
my ($desc,$start,$end) = @{$_};
|
||||
my $xs;
|
||||
my $ys;
|
||||
my $sigtime = ($end and $end =~ /^\d+$/) ? $end : time;
|
||||
my $date = $cfg->{Presentation}{detail}{strftime} ?
|
||||
POSIX::strftime($cfg->{Presentation}{detail}{strftime}, localtime($sigtime)) : scalar localtime($sigtime);
|
||||
if ( $RRDs::VERSION >= 1.199908 ){
|
||||
$date =~ s|:|\\:|g;
|
||||
}
|
||||
$end ||= 'last';
|
||||
$start = Smokeping::exp2seconds($start) if $mode =~ /[s]/;
|
||||
|
||||
my $startstr = $start =~ /^\d+$/ ? POSIX::strftime("%Y-%m-%d %H:%M",localtime($mode eq 'n' ? $start : time-$start)) : $start;
|
||||
my $endstr = $end =~ /^\d+$/ ? POSIX::strftime("%Y-%m-%d %H:%M",localtime($mode eq 'n' ? $end : time)) : $end;
|
||||
|
||||
my $realstart = ( $mode =~ /[sc]/ ? '-'.$start : $start);
|
||||
|
||||
my @G;
|
||||
my @colors = split /\s+/, $cfg->{Presentation}{multihost}{colors};
|
||||
my $i = 0;
|
||||
for my $host (@hosts){
|
||||
$i++;
|
||||
my $swidth = $max->{$start} / $cfg->{Presentation}{detail}{height};
|
||||
my $rrd = $cfg->{General}{datadir}.$host.".rrd";
|
||||
next unless -r $rrd; # skip things that do not exist;
|
||||
my $medc = shift @colors;
|
||||
my @tree_path = split /\//,$host;
|
||||
shift @tree_path;
|
||||
my ($host,$real_slave) = split /~/, $tree_path[-1]; #/
|
||||
$tree_path[-1] = $host;
|
||||
my $tree = Smokeping::get_tree($cfg,\@tree_path);
|
||||
my $label = $tree->{menu};
|
||||
if ($real_slave){
|
||||
$label .= "<". $cfg->{Slaves}{$real_slave}{display_name};
|
||||
}
|
||||
|
||||
my $probe = $cfg->{__probes}{$tree->{probe}};
|
||||
my $XProbeDesc = $probe->ProbeDesc();
|
||||
if (not $ProbeDesc or $ProbeDesc eq $XProbeDesc){
|
||||
$ProbeDesc = $XProbeDesc;
|
||||
}
|
||||
else {
|
||||
$ProbeDesc = "various probes";
|
||||
}
|
||||
my $XProbeUnit = $probe->ProbeUnit();
|
||||
if (not $ProbeUnit or $ProbeUnit eq $XProbeUnit){
|
||||
$ProbeUnit = $XProbeUnit;
|
||||
}
|
||||
else {
|
||||
$ProbeUnit = "various units";
|
||||
}
|
||||
|
||||
my $pings = $probe->_pings($tree);
|
||||
|
||||
$label = sprintf("%-20s",$label);
|
||||
$label =~ s/:/\\:/g;
|
||||
|
||||
push @colors, $medc;
|
||||
my $sdc = $medc;
|
||||
my $stddev = Smokeping::RRDhelpers::get_stddev($rrd,'median','AVERAGE',$realstart,$sigtime) || 0;
|
||||
$sdc =~ s/^(......).*/${1}30/;
|
||||
push @G,
|
||||
"DEF:median$i=${rrd}:median:AVERAGE",
|
||||
"DEF:loss$i=${rrd}:loss:AVERAGE",
|
||||
"CDEF:ploss$i=loss$i,$pings,/,100,*",
|
||||
"CDEF:dm$i=median$i,0,".$max->{$start}.",LIMIT",
|
||||
Smokeping::calc_stddev($rrd,$i,$pings),
|
||||
"CDEF:dmlow$i=dm$i,sdev$i,2,/,-",
|
||||
"CDEF:s2d$i=sdev$i",
|
||||
# "CDEF:dm2=median,1.5,*,0,$max,LIMIT",
|
||||
# "LINE1:dm2", # this is for kicking things down a bit
|
||||
"AREA:dmlow$i",
|
||||
"AREA:s2d${i}#${sdc}::STACK",
|
||||
"LINE1:dm$i#${medc}:${label}",
|
||||
"VDEF:avmed$i=median$i,AVERAGE",
|
||||
"VDEF:avsd$i=sdev$i,AVERAGE",
|
||||
"CDEF:msr$i=median$i,POP,avmed$i,avsd$i,/",
|
||||
"VDEF:avmsr$i=msr$i,AVERAGE",
|
||||
"GPRINT:avmed$i:%5.1lf %ss av md ",
|
||||
"GPRINT:ploss$i:AVERAGE:%5.1lf %% av ls",
|
||||
sprintf('COMMENT:%5.1lf ms sd',$stddev*1000.0),
|
||||
"GPRINT:avmsr$i:%5.1lf %s am/as\\l";
|
||||
|
||||
};
|
||||
my @task;
|
||||
push @task, "--logarithmic" if $cfg->{Presentation}{detail}{logarithmic} and
|
||||
$cfg->{Presentation}{detail}{logarithmic} eq 'yes';
|
||||
push @task, '--lazy' if $mode eq 's' and $lastheight{$start} == $max->{$start};
|
||||
|
||||
push @task,
|
||||
"${imgbase}_${end}_${start}.png",
|
||||
'--start',$realstart,
|
||||
($end ne 'last' ? ('--end',$end) : ()),
|
||||
'--height',$cfg->{Presentation}{detail}{height},
|
||||
'--width',$cfg->{Presentation}{detail}{width},
|
||||
'--title',$cfg->{Presentation}{htmltitle} ne 'yes' ? $desc : '',
|
||||
'--rigid','--upper-limit', $max->{$start},
|
||||
'--lower-limit',($cfg->{Presentation}{detail}{logarithmic} ? ($max->{$start} > 0.01) ? '0.001' : '0.0001' : '0'),
|
||||
'--vertical-label',$ProbeUnit,
|
||||
'--imgformat','PNG',
|
||||
Smokeping::Graphs::get_colors($cfg),
|
||||
@G,
|
||||
"COMMENT:$ProbeDesc",
|
||||
"COMMENT:$date\\j";
|
||||
|
||||
my $graphret;
|
||||
($graphret,$xs,$ys) = RRDs::graph @task;
|
||||
# print "<div>INFO:".join("<br/>",@task)."</div>";
|
||||
my $ERROR = RRDs::error();
|
||||
if ($ERROR) {
|
||||
return "<div>ERROR: $ERROR</div><div>".join("<br/>",@task)."</div>";
|
||||
};
|
||||
|
||||
|
||||
if ($mode eq 'a'){ # ajax mode
|
||||
open my $img, "${imgbase}_${end}_${start}.png";
|
||||
binmode $img;
|
||||
print "Content-Type: image/png\n";
|
||||
my $data;
|
||||
read($img,$data,(stat($img))[7]);
|
||||
close $img;
|
||||
print "Content-Length: ".length($data)."\n\n";
|
||||
print $data;
|
||||
unlink "${imgbase}_${end}_${start}.png";
|
||||
return undef;
|
||||
}
|
||||
|
||||
elsif ($mode eq 'n'){ # navigator mode
|
||||
$page .= "<div class=\"panel\">";
|
||||
$page .= "<div class=\"panel-heading\"><h2>$desc</h2></div>"
|
||||
if $cfg->{Presentation}{htmltitle} eq 'yes';
|
||||
$page .= "<div class=\"panel-body\">";
|
||||
|
||||
$page .= qq|<IMG id="zoom" alt="" width="$xs" height="$ys" SRC="${imghref}_${end}_${start}.png">| ;
|
||||
|
||||
$page .= $q->start_form(-method=>'GET', -id=>'range_form')
|
||||
. "<p>Time range: "
|
||||
. $q->textfield(-name=>'start',-default=>$startstr)
|
||||
. " to ".$q->textfield(-name=>'end',-default=>$endstr)
|
||||
. $q->hidden(-name=>'epoch_start',-id=>'epoch_start',-default=>$start)
|
||||
. $q->hidden(-name=>'epoch_end',-id=>'epoch_end',-default=>time())
|
||||
. $q->hidden(-name=>'target',-id=>'target' )
|
||||
. $q->hidden(-name=>'hierarchy',-id=>'hierarchy' )
|
||||
. $q->hidden(-name=>'displaymode',-default=>$mode )
|
||||
. " "
|
||||
. $q->submit(-name=>'Generate!')
|
||||
. "</p>"
|
||||
. $q->end_form();
|
||||
|
||||
$page .= "</div></div>\n";
|
||||
} elsif ($mode eq 's') { # classic mode
|
||||
$startstr =~ s/\s/%20/g;
|
||||
$endstr =~ s/\s/%20/g;
|
||||
$page .= "<div class=\"panel\">";
|
||||
# $page .= (time-$timer_start)."<br/>";
|
||||
# $page .= join " ",map {"'$_'"} @task;
|
||||
$page .= "<div class=\"panel-heading\"><h2>$desc</h2></div>"
|
||||
if $cfg->{Presentation}{htmltitle} eq 'yes';
|
||||
$page .= "<div class=\"panel-body\">";
|
||||
$page .= ( qq{<a href="?displaymode=n;start=$startstr;end=now;}."target=".$q->param('target').'">'
|
||||
. qq{<IMG ALT="" SRC="${imghref}_${end}_${start}.png" class="img-responsive">}."</a>" ); #"
|
||||
$page .= "</div></div>\n";
|
||||
} else { # chart mode
|
||||
$page .= "<div class=\"panel\">";
|
||||
$page .= "<div class=\"panel-heading\"><h2>$desc</h2></div>"
|
||||
if $cfg->{Presentation}{htmltitle} eq 'yes';
|
||||
$page .= "<div class=\"panel-body\">";
|
||||
$page .= ( qq{<a href="}.lnk($q, (join ".", @$open)).qq{">}
|
||||
. qq{<IMG ALT="" SRC="${imghref}_${end}_${start}.png" class="img-responsive">}."</a>" ); #"
|
||||
$page .= "</div></div>\n";
|
||||
}
|
||||
|
||||
}
|
||||
return $page;
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2007 by Tobias Oetiker
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
This program is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public
|
||||
License along with this program; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
|
||||
02139, USA.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Tobias Oetiker E<lt>tobi@oetiker.chE<gt>
|
||||
|
||||
=cut
|
||||
204
debian/smokeping/usr/share/perl5/Smokeping/Info.pm
vendored
Normal file
204
debian/smokeping/usr/share/perl5/Smokeping/Info.pm
vendored
Normal file
@@ -0,0 +1,204 @@
|
||||
# -*- perl -*-
|
||||
package Smokeping::Info;
|
||||
use warnings;
|
||||
use strict;
|
||||
use RRDs;
|
||||
use Smokeping;
|
||||
use Carp;
|
||||
use Data::Dumper;
|
||||
|
||||
sub new {
|
||||
my $this = shift;
|
||||
my $class = ref($this) || $this;
|
||||
my $self = { cfg_file => shift };
|
||||
bless $self, $class;
|
||||
my $parser = Smokeping::get_parser();
|
||||
$self->{cfg_hash} = $parser->parse( $self->{cfg_file} )
|
||||
or croak "ERROR reading config file $parser->{err}";
|
||||
$self->{probe_hash} = Smokeping::load_probes $self->{cfg_hash};
|
||||
return $self;
|
||||
}
|
||||
|
||||
# get a list of all rrd files in the config file
|
||||
|
||||
sub __flatten_targets;
|
||||
sub __flatten_targets {
|
||||
my $probes = shift;
|
||||
my $root = shift;
|
||||
my $prefix = shift;
|
||||
my @paths;
|
||||
for my $target ( sort {$root->{$a}{_order} <=> $root->{$b}{_order}}
|
||||
grep { ref $root->{$_} eq 'HASH' } keys %$root ) {
|
||||
push @paths, __flatten_targets($probes,$root->{$target},$prefix.'/'.$target);
|
||||
};
|
||||
if (exists $root->{host} and not $root->{host} =~ m|/|){
|
||||
my $probe = $probes->{$root->{probe}};
|
||||
my $pings = $probe->_pings($root);
|
||||
if (not $root->{nomasterpoll} or $root->{nomasterpoll} eq 'no') {
|
||||
push @paths, { path => $prefix, pings=>$pings };
|
||||
};
|
||||
if ($root->{slaves}) {
|
||||
for my $slave (split /\s+/,$root->{slaves}){
|
||||
push @paths, { path => $prefix.'~'.$slave, pings=>$pings };
|
||||
}
|
||||
}
|
||||
};
|
||||
return @paths;
|
||||
}
|
||||
|
||||
sub fetch_nodes {
|
||||
my $self = shift;
|
||||
my %args = ( 'mode' => 'plain', @_); # no mode is default
|
||||
my %valid = ( pattern=>1, mode => 1 );
|
||||
my %valid_modes = ( plain=>1, recursive=>1, regexp=>1);
|
||||
map {
|
||||
croak "Invalid fetch nodes argument '$_'"
|
||||
if not $valid{$_};
|
||||
} keys %args;
|
||||
|
||||
croak "Invalid fetch mode $args{mode}"
|
||||
if not $valid_modes{$args{mode}};
|
||||
|
||||
my $cfg = $self->{cfg_hash};
|
||||
my @flat = __flatten_targets($self->{probe_hash},$cfg->{Targets},'');
|
||||
my $rx = qr{.*};
|
||||
if ( defined $args{pattern} ) {
|
||||
if ( $args{mode} eq 'recursive' ) {
|
||||
$rx = qr{^\Q$args{pattern}\E};
|
||||
}
|
||||
elsif ( $args{mode} eq 'regexp' ) {
|
||||
$rx = qr{$args{pattern}};
|
||||
}
|
||||
else {
|
||||
$rx = qr{^\Q$args{pattern}\E[^/]*$};
|
||||
}
|
||||
}
|
||||
return [ grep { $_->{path} =~ /${rx}/ } @flat ];
|
||||
}
|
||||
|
||||
|
||||
sub stat_node {
|
||||
my $self = shift;
|
||||
my $path = shift;
|
||||
my $start = shift;
|
||||
my $end = shift;
|
||||
my $cfg = $self->{cfg_hash};
|
||||
my ($graphret,$xs,$ys) = RRDs::graph (
|
||||
'/tmp/dummy',
|
||||
'--start'=>$start,
|
||||
'--end'=>$end,
|
||||
'DEF:loss_avg_r='.$cfg->{General}{datadir}.$path->{path}.'.rrd:loss:AVERAGE',
|
||||
'CDEF:loss_avg=loss_avg_r,'.$path->{pings}.',/',
|
||||
'VDEF:loss_avg_tot=loss_avg,AVERAGE',
|
||||
'PRINT:loss_avg_tot:%.8le',
|
||||
'DEF:loss_max_r='.$cfg->{General}{datadir}.$path->{path}.'.rrd:loss:MAX',
|
||||
'CDEF:loss_max=loss_max_r,'.$path->{pings}.',/',
|
||||
'VDEF:loss_max_tot=loss_max,MAXIMUM',
|
||||
'PRINT:loss_max_tot:%.8le',
|
||||
'VDEF:loss_now=loss_avg,LAST',
|
||||
'PRINT:loss_now:%.8le',
|
||||
'DEF:median_avg='.$cfg->{General}{datadir}.$path->{path}.'.rrd:median:AVERAGE',
|
||||
'VDEF:median_avg_tot=median_avg,AVERAGE',
|
||||
'PRINT:median_avg_tot:%.8le',
|
||||
'DEF:median_min='.$cfg->{General}{datadir}.$path->{path}.'.rrd:median:MIN',
|
||||
'VDEF:median_min_tot=median_min,MINIMUM',
|
||||
'PRINT:median_min_tot:%.8le',
|
||||
'DEF:median_max='.$cfg->{General}{datadir}.$path->{path}.'.rrd:median:MAX',
|
||||
'VDEF:median_max_tot=median_max,MAXIMUM',
|
||||
'PRINT:median_max_tot:%.8le',
|
||||
'VDEF:median_now=median_avg,LAST',
|
||||
'PRINT:median_now:%.8le'
|
||||
);
|
||||
my %data;
|
||||
if (my $ERROR = RRDs::error()){
|
||||
carp "$path->{path}: $ERROR";
|
||||
} else {
|
||||
@data{qw(loss_avg loss_max loss_now med_avg med_min med_max med_now)} = @$graphret;
|
||||
}
|
||||
return \%data;
|
||||
};
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Smokeping::Info - Pull numerical info out of the rrd databases
|
||||
|
||||
=head1 OVERVIEW
|
||||
|
||||
This module provides methods to further process information contained in
|
||||
smokeping rrd files. The smokeinfo tool is a simple wrapper around the
|
||||
functionality contained in here.
|
||||
|
||||
my $si = Smokeping::Info->new("config/file/path");
|
||||
|
||||
my $array_ref = $si->fetch_nodes(pattern=>'/node/path',
|
||||
mode=>'recursive');
|
||||
|
||||
my $hash_ref = $si->stat_node(path,start,end);
|
||||
|
||||
=head1 IMPLEMENTATION
|
||||
|
||||
=head2 new(path)
|
||||
|
||||
Create a new Smokeping::Info instance. Instantiating Smokeping::Info entails
|
||||
reading the configuration file. This is a compute heavy procedure. So you may
|
||||
want to use a single info object to handle multiple requests.
|
||||
|
||||
=head2 fetch_nodes(pattern=>'/...',mode=>{recursive|regexp})
|
||||
|
||||
The fetch_nodes method will find all nodes sitting in the given pattern
|
||||
(absolute path) including the path itself. By setting the recursive mode,
|
||||
all rrd files in paths below will be returned as well. In regexp mode, all
|
||||
rrd paths matching the given expression will be returned.
|
||||
|
||||
=head2 stat_node(node,start,end)
|
||||
|
||||
Return a hash pointer to statistics based on the data stored in the given
|
||||
rrd path.
|
||||
|
||||
med_avg - average median
|
||||
med_min - minimal median
|
||||
med_max - maximal median
|
||||
med_now - current median
|
||||
loss_avg - average loss
|
||||
loss_max - maximum loss
|
||||
loss_now - current loss
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2009 by OETIKER+PARTNER AG
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 675 Mass
|
||||
Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Tobias Oetiker E<lt>tobi@oetiker.chE<gt>, development sponsored by Swisscom Hospitality
|
||||
|
||||
=cut
|
||||
|
||||
# Emacs Configuration
|
||||
#
|
||||
# Local Variables:
|
||||
# mode: cperl
|
||||
# eval: (cperl-set-style "PerlStyle")
|
||||
# mode: flyspell
|
||||
# mode: flyspell-prog
|
||||
# End:
|
||||
#
|
||||
# vi: sw=4
|
||||
339
debian/smokeping/usr/share/perl5/Smokeping/Master.pm
vendored
Normal file
339
debian/smokeping/usr/share/perl5/Smokeping/Master.pm
vendored
Normal file
@@ -0,0 +1,339 @@
|
||||
# -*- perl -*-
|
||||
package Smokeping::Master;
|
||||
use Data::Dumper;
|
||||
use Storable qw(nstore dclone fd_retrieve);
|
||||
use strict;
|
||||
use warnings;
|
||||
use Fcntl qw(:flock);
|
||||
use Digest::HMAC_MD5 qw(hmac_md5_hex);
|
||||
use File::Basename qw(dirname);
|
||||
use File::Path qw(make_path);
|
||||
# keep this in sync with the Slave.pm part
|
||||
# only update if you have to force a parallel upgrade
|
||||
my $PROTOCOL = "2";
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Smokeping::Master - Master Functionality for Smokeping
|
||||
|
||||
=head1 OVERVIEW
|
||||
|
||||
This module handles all special functionality required by smokeping running
|
||||
in master mode.
|
||||
|
||||
=head2 IMPLEMENTATION
|
||||
|
||||
=head3 slave_cfg=extract_config(cfg,slave)
|
||||
|
||||
Extract the relevant configuration information for the selected slave. The
|
||||
configuration will only contain the information that is relevant for the
|
||||
slave. Any parameters overwritten in the B<Slaves> section of the configuration
|
||||
file will be patched for the slave.
|
||||
|
||||
=cut
|
||||
|
||||
sub get_targets;
|
||||
sub get_targets {
|
||||
my $trg = shift;
|
||||
my $slave = shift;
|
||||
my %return;
|
||||
my $ok;
|
||||
foreach my $key (keys %{$trg}){
|
||||
# dynamic hosts can only be queried from the
|
||||
# master
|
||||
next if $key eq 'host' and $trg->{$key} eq 'DYNAMIC';
|
||||
next if $key eq 'host' and $trg->{$key} =~ m|^/|; # skip multi targets
|
||||
next if $key eq 'host' and not ( defined $trg->{slaves} and $trg->{slaves} =~ /\b${slave}\b/);
|
||||
if (ref $trg->{$key} eq 'HASH'){
|
||||
$return{$key} = get_targets ($trg->{$key},$slave);
|
||||
$ok = 1 if defined $return{$key};
|
||||
} else {
|
||||
$ok = 1 if $key eq 'host';
|
||||
$return{$key} = $trg->{$key};
|
||||
}
|
||||
}
|
||||
$return{nomasterpoll} = 'no'; # slaves poll always
|
||||
return ($ok ? \%return : undef);
|
||||
}
|
||||
|
||||
sub extract_config {
|
||||
my $cfg = shift;
|
||||
my $slave = shift;
|
||||
# get relevant Targets
|
||||
my %slave_config;
|
||||
$slave_config{Database} = dclone $cfg->{Database};
|
||||
$slave_config{General} = dclone $cfg->{General};
|
||||
$slave_config{Probes} = dclone $cfg->{Probes};
|
||||
$slave_config{Targets} = get_targets($cfg->{Targets},$slave);
|
||||
$slave_config{__last} = $cfg->{__last};
|
||||
if ($cfg->{Slaves} and $cfg->{Slaves}{$slave} and $cfg->{Slaves}{$slave}{override}){
|
||||
for my $override (keys %{$cfg->{Slaves}{$slave}{override}}){
|
||||
my $node = \%slave_config;
|
||||
my @keys = split /\./, $override;
|
||||
my $last_key = pop @keys;
|
||||
for my $key (@keys){
|
||||
$node->{$key} = {}
|
||||
unless $node->{$key} and ref $node->{$key} eq 'HASH';
|
||||
$node = $node->{$key};
|
||||
}
|
||||
$node->{$last_key} = $cfg->{Slaves}{$slave}{override}{$override};
|
||||
}
|
||||
}
|
||||
if ($slave_config{Targets}){
|
||||
return Dumper \%slave_config;
|
||||
} else {
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
|
||||
=head3 save_updates (updates)
|
||||
|
||||
When the cgi gets updates from a client, these updates are saved away, for
|
||||
each 'target' so that the updates can be integrated into the relevant rrd
|
||||
database by the rrd daemon as the next round of updates is processed. This
|
||||
two stage process is chosen so that all results flow through the same code
|
||||
path in the daemon.
|
||||
|
||||
The updates are stored in the directory configured as 'dyndir' in the 'General'
|
||||
configuration section, defaulting to the value of 'datadir' from the same section
|
||||
if 'dyndir' is not present.
|
||||
|
||||
=cut
|
||||
|
||||
sub slavedatadir ($) {
|
||||
my $cfg = shift;
|
||||
my $dir = $cfg->{General}{dyndir} ||
|
||||
$cfg->{General}{datadir};
|
||||
$dir =~ s{/*$}{};
|
||||
return $dir;
|
||||
}
|
||||
|
||||
sub make_slavedatadir ($) {
|
||||
my $file = shift;
|
||||
my $dir = dirname($file);
|
||||
|
||||
if (! -d $dir) {
|
||||
make_path($dir, {'error' => \my $err});
|
||||
|
||||
if ($err && @$err) {
|
||||
for my $diag (@$err) {
|
||||
my ($f,$m) = %$diag;
|
||||
warn "Failed to create slave cache directory [$f]: $m";
|
||||
}
|
||||
} else {
|
||||
warn "Slave cache directory $dir created\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub save_updates {
|
||||
my $cfg = shift;
|
||||
my $slave = shift;
|
||||
my $updates = shift;
|
||||
# name\ttime\tupdatestring
|
||||
# name\ttime\tupdatestring
|
||||
my %u;
|
||||
for my $update (split /\n/, $updates){
|
||||
my ($name, $time, $updatestring) = split /\t/, $update;
|
||||
if ( ${name} =~ m{(^|/)\.\.($|/)} ){
|
||||
warn "Skipping update for ${name}.${slave}.slave_cache since ".
|
||||
"you seem to try todo some directory magic here. Don't!";
|
||||
} else {
|
||||
push @{$u{$name}}, [$time,$updatestring];
|
||||
}
|
||||
}
|
||||
for my $name (sort keys %u){
|
||||
my $file = slavedatadir($cfg) ."/${name}.${slave}.slave_cache";
|
||||
for (my $i = 2; $i >= 0; $i--){
|
||||
my $fh;
|
||||
make_slavedatadir($file);
|
||||
if ( open ($fh, '+>>' , $file) and flock($fh, LOCK_EX) ){
|
||||
my $existing = [];
|
||||
if (! -e $file) { # the reader unlinked it from under us
|
||||
flock($fh, LOCK_UN);
|
||||
close $fh;
|
||||
next;
|
||||
}
|
||||
seek $fh, 0, 0;
|
||||
if ( -s _ ){
|
||||
my $in = eval { fd_retrieve $fh };
|
||||
if ($@) { #error
|
||||
warn "Loading $file: $@";
|
||||
} else {
|
||||
$existing = $in;
|
||||
};
|
||||
};
|
||||
map {
|
||||
push @{$existing}, [ $slave, $_->[0], $_->[1] ];
|
||||
} @{$u{$name}};
|
||||
nstore($existing, $file.$$);
|
||||
rename $file.$$,$file;
|
||||
flock($fh, LOCK_UN);
|
||||
close $fh;
|
||||
last;
|
||||
} elsif ($i > 0) {
|
||||
warn "Could not lock $file ($!). Trying again $i more times.\n";
|
||||
sleep rand(2);
|
||||
next;
|
||||
}
|
||||
warn "Could not update $file, giving up for now.";
|
||||
close $fh;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
=head3 get_slaveupdates
|
||||
|
||||
Read in all updates provided by the selected slave and return an array reference.
|
||||
|
||||
=cut
|
||||
|
||||
sub get_slaveupdates {
|
||||
my $cfg = shift;
|
||||
my $name = shift;
|
||||
my $slave = shift;
|
||||
my $file = $name . "." . $slave. ".slave_cache";
|
||||
my $empty = [];
|
||||
my $data;
|
||||
|
||||
my $datadir = $cfg->{General}{datadir};
|
||||
my $dir = slavedatadir($cfg);
|
||||
$file =~ s/^\Q$datadir\E/$dir/;
|
||||
|
||||
my $fh;
|
||||
if ( open ($fh, '<', $file) ) {
|
||||
if ( flock $fh, LOCK_SH ){
|
||||
eval { $data = fd_retrieve $fh };
|
||||
unlink $file;
|
||||
flock $fh, LOCK_UN;
|
||||
if ($@) { #error
|
||||
warn "Loading $file: $@";
|
||||
close $fh;
|
||||
return $empty;
|
||||
}
|
||||
} else {
|
||||
warn "Could not lock $file. Will skip and try again in the next round. No harm done!\n";
|
||||
}
|
||||
close $fh;
|
||||
return $data;
|
||||
}
|
||||
return $empty;
|
||||
}
|
||||
|
||||
|
||||
=head3 get_secret
|
||||
|
||||
Read the secrets file and figure the secret for the slave which is talking to us.
|
||||
|
||||
=cut
|
||||
|
||||
sub get_secret {
|
||||
my $cfg = shift;
|
||||
my $slave = shift;
|
||||
if (open my $hand, "<", $cfg->{Slaves}{secrets}){
|
||||
while (<$hand>){
|
||||
next unless /^${slave}:(\S+)/;
|
||||
close $hand;
|
||||
return $1;
|
||||
}
|
||||
} else {
|
||||
print "Content-Type: text/plain\n\n";
|
||||
print "WARNING: Opening secrets file $cfg->{Slaves}{secrets}: $!\n";
|
||||
return '__HORRIBLE_INLINE_SIGNALING__';
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
=head3 answer_slave
|
||||
|
||||
Answer the requests from the slave by accepting the data, verifying the secrets
|
||||
and providing updated config information if necessary.
|
||||
|
||||
=cut
|
||||
|
||||
sub answer_slave {
|
||||
my $cfg = shift;
|
||||
my $q = shift;
|
||||
my $slave = $q->param('slave');
|
||||
my $secret = get_secret($cfg,$slave);
|
||||
return if $secret eq '__HORRIBLE_INLINE_SIGNALING__';
|
||||
if (not $secret){
|
||||
print "Content-Type: text/plain\n\n";
|
||||
print "WARNING: No secret found for slave ${slave}\n";
|
||||
return;
|
||||
}
|
||||
my $protocol = $q->param('protocol') || '?';
|
||||
if (not $protocol eq $PROTOCOL){
|
||||
print "Content-Type: text/plain\n\n";
|
||||
print "WARNING: I expected protocol $PROTOCOL and got $protocol from slave ${slave}. I will skip this.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
my $key = $q->param('key');
|
||||
my $data = $q->param('data');
|
||||
my $config_time = $q->param('config_time');
|
||||
if (not ref $cfg->{Slaves}{$slave} eq 'HASH'){
|
||||
print "Content-Type: text/plain\n\n";
|
||||
print "WARNING: I don't know the slave ${slave} ignoring it";
|
||||
return;
|
||||
}
|
||||
# lets make sure the we share a secret
|
||||
if (hmac_md5_hex($data,$secret) eq $key){
|
||||
save_updates $cfg, $slave, $data;
|
||||
} else {
|
||||
print "Content-Type: text/plain\n\n";
|
||||
print "WARNING: Data from $slave was signed with $key which does not match our expectation\n";
|
||||
return;
|
||||
}
|
||||
# does the client need new config ?
|
||||
if ($config_time < $cfg->{__last}){
|
||||
my $config = extract_config $cfg, $slave;
|
||||
if ($config){
|
||||
print "Content-Type: application/smokeping-config\n";
|
||||
print "Protocol: $PROTOCOL\n";
|
||||
print "Key: ".hmac_md5_hex($config,$secret)."\n\n";
|
||||
print $config;
|
||||
} else {
|
||||
print "Content-Type: text/plain\n\n";
|
||||
print "WARNING: No targets found for slave '$slave'\n";
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
print "Content-Type: text/plain\n\nOK\n";
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2007 by Tobias Oetiker
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
This program is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public
|
||||
License along with this program; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
|
||||
02139, USA.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Tobias Oetiker E<lt>tobi@oetiker.chE<gt>
|
||||
|
||||
=cut
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user