%PDF- %PDF-
| Direktori : /usr/share/perl5/vendor_perl/Munin/Master/ |
| Current File : //usr/share/perl5/vendor_perl/Munin/Master/HTMLOld.pm |
package Munin::Master::HTMLOld;
=encoding utf-8
=begin comment
-*- perl -*-
This is Munin::Master::HTMLOld, a minimal package shell to make
munin-html modular (so it can loaded persistently in
munin-fastcgi-graph for example) without making it object oriented
yet. The non-"old" module will feature propper object orientation
like munin-update and will have to wait until later.
Copyright (C) 2002-2009 Jimmy Olsen, Audun Ytterdal, Kjell Magne
Øierud, Nicolai Langfeldt, Linpro AS, Redpill Linpro AS and others.
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; version 2 dated June,
1991.
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., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
$Id$
This is the hierarchy of templates
* munin-overview.tmpl - Overview with all groups and hosts shown (2 levels down)
* munin-domainview.tmpl - all members of one domain, showing links down to each single service
and/or sub-group
* munin-nodeview.tmpl - two (=day, week) graphs from all plugins on the node
* munin-serviceview.tmpl - deepest level of view, shows all 4 graphs from one timeseries
* Zoom view - zoomable graph based on one of the other four graphs
OR
* munin-nodeview.tmpl - multigraph sub-level. When multigraph sublevels end ends
the next is a munin-serviceview.
* Comparison pages (x4) are at the service level. Not sure how to work multigraph into them so
avoid it all-together.
=end comment
=cut
use warnings;
use strict;
use Exporter;
our (@ISA, @EXPORT);
@ISA = qw(Exporter);
@EXPORT = qw(html_startup html_main get_config emit_main_index emit_comparison_template emit_group_template emit_graph_template emit_service_template emit_category_template emit_problem_template update_timestamp);
use HTML::Template;
use POSIX qw(strftime);
use Getopt::Long;
use Time::HiRes;
use File::Copy::Recursive qw(dircopy);
use IO::File;
use Munin::Master::Logger;
use Munin::Master::Utils;
use Munin::Master::HTMLConfig;
use Log::Log4perl qw( :easy );
my @times = ("day", "week", "month", "year");
my $DEBUG = 0;
my $conffile = "$Munin::Common::Defaults::MUNIN_CONFDIR/munin.conf";
my $do_usage = 0;
my $do_version = 0;
my $stdout = 0;
my $force_run_as_root = 0;
my $config;
my $limits;
my $htmltagline;
my %comparisontemplates;
my $tmpldir;
my $htmldir;
my $do_dump = 0;
my $do_fork = 1;
my $max_running=6;
my $running=0;
my $timestamp;
my $htmlconfig;
sub update_timestamp {
# For timestamping graphs
$timestamp = strftime("%Y-%m-%d %T%z (%Z)", localtime);
if ($timestamp =~ /%z/) {
# %z (numeric timezone offset) may not be available, but %Z
# (timeszone name) seems to be universaly supported though the
# timezone names are not really standardized.
$timestamp = strftime("%Y-%m-%d %T%Z", localtime);
}
$htmltagline = "This page was generated by <a href='http://munin-monitoring.org/'>Munin</a> version ".$Munin::Common::Defaults::MUNIN_VERSION." at $timestamp";
}
sub html_startup {
my ($args) = @_;
local @ARGV = @{$args};
$do_usage = 1
unless GetOptions (
"host=s" => [],
"service=s" => [],
"config=s" => \$conffile,
"debug!" => \$DEBUG,
"stdout!" => \$stdout,
"force-run-as-root!" => \$force_run_as_root,
"help" => \$do_usage,
"version!" => \$do_version,
"dump!" => \$do_dump,
"fork!" => \$do_fork,
);
print_usage_and_exit() if $do_usage;
print_version_and_exit() if $do_version;
exit_if_run_by_super_user() unless $force_run_as_root;
munin_readconfig_base($conffile);
# XXX: should not need that part here, yet.
$config = munin_readconfig_part('datafile', 0);
logger_open($config->{'logdir'});
logger_debug() if $DEBUG;
$tmpldir = $config->{tmpldir};
$htmldir = $config->{htmldir};
$max_running = &munin_get($config, "max_html_jobs", $max_running);
update_timestamp();
%comparisontemplates = instanciate_comparison_templates($tmpldir);
}
sub get_config {
my $use_cache = shift;
# usecache should match being in a cgi ($ENV{SCRIPT_NAME})
$htmlconfig = undef; # avoid double ram usage
if ($use_cache) {
$htmlconfig = generate_config($use_cache);
} else {
my $graphs_filename = $config->{dbdir} . "/graphs";
my $graphs_filename_tmp = $graphs_filename . ".tmp." . $$;
$config->{"#%#graphs_fh"} = new IO::File("> $graphs_filename_tmp");
$htmlconfig = generate_config($use_cache);
# Closing the file
$config->{"#%#graphs_fh"} = undef;
# Atomic move
rename($graphs_filename_tmp, $graphs_filename);
# htmlconf cache
# munin-html writes it
# munin-cgi-html reads it
#
# full cron - written, never read
# munin-html and munin-cgi-html - written, and read as cache
# full munin-cgi-html - should not exist!
# and here, we avoid leaving a never-updating cache file
my $cachefile = "$config->{dbdir}/htmlconf.storable";
munin_writeconfig_storable($cachefile, $htmlconfig);
}
return $htmlconfig;
}
sub html_main {
my $staticdir = $config->{staticdir};
copy_web_resources($staticdir, $htmldir);
my $configtime = Time::HiRes::time;
get_config(0);
my $groups = $htmlconfig;
$configtime = sprintf("%.2f", (Time::HiRes::time - $configtime));
INFO "[INFO] config generated ($configtime sec)";
if (munin_get($config,"html_strategy","cron") eq "cgi"){
INFO "[INFO] html_strategy is cgi. Skipping template generation";
return;
}
my $update_time = Time::HiRes::time;
my $lockfile = "$config->{rundir}/munin-html.lock";
INFO "[INFO] Starting munin-html, getting lock $lockfile";
munin_runlock($lockfile);
# Preparing the group tree...
if (!defined($groups) or scalar(%{$groups} eq '0')) {
LOGCROAK "[FATAL] There is nothing to do here, since there are no nodes with any plugins. Please refer to http://munin-monitoring.org/wiki/FAQ_no_graphs";
};
if (defined $groups->{"name"} and $groups->{"name"} eq "root") {
$groups = $groups->{"groups"}; # root->groups
}
if ($do_dump) {
print munin_dumpconfig_as_str($groups);
exit 0;
}
generate_group_templates($groups);
generate_category_templates($htmlconfig->{"globalcats"});
emit_main_index($groups,$timestamp,0);
emit_problem_template(0);
INFO "[INFO] Releasing lock file $lockfile";
munin_removelock("$lockfile");
$update_time = sprintf("%.2f", (Time::HiRes::time - $update_time));
INFO "[INFO] munin-html finished ($update_time sec)";
}
sub find_complinks{
my($type) = @_;
my @links = ();
foreach my $current (qw(day week month year)) {
my $data = {};
if ($type eq $current) {
$data->{'LINK'} = undef;
}
else {
$data->{'LINK'} = "comparison-$current.html";
}
$data->{'NAME'} = $current;
push(@links, $data);
}
return \@links;
}
sub emit_comparison_template {
my ($key, $t, $emit_to_stdout) = @_;
( my $file = $key->{'filename'}) =~ s/index.html$//;
$file .= "comparison-$t.html";
DEBUG "[DEBUG] Creating comparison page $file";
# Rewrite peer urls to point to comparison-$t
my $comparepeers = [];
for my $peer (@{$key->{'peers'}}){
my $comparelink = $peer->{"link"};
next unless $comparelink; # avoid dead links
$comparelink =~ s/index.html$/comparison-$t.html/;
push((@$comparepeers), {"name" => $peer->{"name"}, "link" => $comparelink});
}
# when comparing categories, we're generating the page inside the
# domain, but the images' urls will point inside the node itself,
# or even worse within a category inside it. We strip out the
# extra '../' that is used to generate a relative path which is no
# longer valid.
# Sadly this change is permanent and will influence successive
# responses in a permanent execution environment like fcgid or
# as a systemd socket service. Thus we need to revert it later.
foreach my $cat(@{$key->{'comparecategories'}}) {
foreach my $service(@{$cat->{'services'}}) {
foreach my $node(@{$service->{'nodes'}}) {
foreach my $imgsrc(qw(imgday imgweek imgmonth imgyear
cimgday cimgweek cimgmonth cimgyear
zoomday zoomweek zoommonth zoomyear)) {
next unless defined($node->{$imgsrc});
# keep a copy of the original value (to be restored below)
$node->{"orig_$imgsrc"} = $node->{$imgsrc};
$node->{$imgsrc} =~ s|^\.\./\.\./(?:\.\./)?|../|;
}
}
}
}
$comparisontemplates{$t}->param(
INFO_OPTION => 'Groups on this level',
NAME => $key->{'name'},
GROUPS => $key->{'comparegroups'},
PATH => $key->{'path'},
CSS_NAME => get_css_name(),
R_PATH => $key->{'root_path'},
COMPLINKS => find_complinks($t),
LARGESET => decide_largeset($comparepeers),
PEERS => $comparepeers,
PARENT => $key->{'path'}->[-2]->{'name'},
CATEGORIES => $key->{'comparecategories'},
NCATEGORIES => $key->{'ncomparecategories'},
TAGLINE => $htmltagline,
"COMPARISON-$t" => 1,
ROOTGROUPS => $htmlconfig->{"groups"},
MUNIN_VERSION => $Munin::Common::Defaults::MUNIN_VERSION,
TIMESTAMP => $timestamp,
NGLOBALCATS => $htmlconfig->{"nglobalcats"},
GLOBALCATS => $htmlconfig->{"globalcats"},
NCRITICAL => scalar(@{$htmlconfig->{"problems"}->{"criticals"}}),
NWARNING => scalar(@{$htmlconfig->{"problems"}->{"warnings"}}),
NUNKNOWN => scalar(@{$htmlconfig->{"problems"}->{"unknowns"}}),
);
# store template output before reverting links
my $template_output = $comparisontemplates{$t}->output;
# restore the paths to their original value
foreach my $cat(@{$key->{'comparecategories'}}) {
foreach my $service(@{$cat->{'services'}}) {
foreach my $node(@{$service->{'nodes'}}) {
foreach my $imgsrc(qw(imgday imgweek imgmonth imgyear
cimgday cimgweek cimgmonth cimgyear
zoomday zoomweek zoommonth zoomyear)) {
next unless defined($node->{$imgsrc});
$node->{$imgsrc} = $node->{"orig_$imgsrc"};
delete($node->{"orig_$imgsrc"});
}
}
}
}
if($emit_to_stdout){
print $template_output;
} else {
ensure_dir_exists($file);
open(my $FILE, '>', $file)
or die "Cannot open $file for writing: $!";
print $FILE $template_output;
close $FILE;
}
}
sub emit_graph_template {
my ($key, $emit_to_stdout) = @_;
my $graphtemplate = HTML::Template->new(
filename => "$tmpldir/munin-nodeview.tmpl",
die_on_bad_params => 0,
global_vars => 1,
loop_context_vars => 1,
filter => sub {
my $ref = shift;
$$ref =~ s/URLX/URL$key->{'depth'}/g;
});
DEBUG "[DEBUG] Creating graph(nodeview) page ".$key->{filename};
$graphtemplate->param(
INFO_OPTION => 'Nodes on this level',
GROUPS => $key->{'groups'},
PATH => $key->{'path'},
CSS_NAME => get_css_name(),
R_PATH => $key->{'root_path'},
PEERS => $key->{'peers'},
LARGESET => decide_largeset($key->{'peers'}),
PARENT => $key->{'path'}->[-2]->{'name'},
NAME => $key->{'name'},
CATEGORIES => $key->{'categories'},
NCATEGORIES => $key->{'ncategories'},
TAGLINE => $htmltagline,
ROOTGROUPS => $htmlconfig->{"groups"},
MUNIN_VERSION => $Munin::Common::Defaults::MUNIN_VERSION,
TIMESTAMP => $timestamp,
NGLOBALCATS => $htmlconfig->{"nglobalcats"},
GLOBALCATS => $htmlconfig->{"globalcats"},
NCRITICAL => scalar(@{$htmlconfig->{"problems"}->{"criticals"}}),
NWARNING => scalar(@{$htmlconfig->{"problems"}->{"warnings"}}),
NUNKNOWN => scalar(@{$htmlconfig->{"problems"}->{"unknowns"}}),
);
if($emit_to_stdout){
print $graphtemplate->output;
} else {
my $filename = $key->{'filename'};
ensure_dir_exists($filename);
open(my $FILE, '>', $filename)
or die "Cannot open $filename for writing: $!";
print $FILE $graphtemplate->output;
close $FILE;
}
}
sub emit_category_template {
my ($key, $time, $emit_to_stdout) = @_;
my $graphtemplate = HTML::Template->new(
filename => "$tmpldir/munin-categoryview.tmpl",
die_on_bad_params => 0,
global_vars => 1,
loop_context_vars => 1,
filter => sub {
my $ref = shift;
$$ref =~ s/URLX/URL/g;
},
);
my $filename = $key->{'filename-' . $time};
DEBUG "[DEBUG] Creating global category page ".$filename;
# Manipulate the relative paths for the requested root-level context.
# Sadly this change is permanent and will influence successive
# responses in a permanent execution environment like fcgid or
# as a systemd socket service. Thus we need to revert it later.
foreach my $graphs(@{$key->{'graphs'}}) {
foreach my $graph(@{$graphs->{'graphs'}}) {
foreach my $imgsrc(qw(imgday imgweek imgmonth imgyear
cimgday cimgweek cimgmonth cimgyear
zoomday zoomweek zoommonth zoomyear)) {
# keep a copy of the original value (to be restored below)
$graph->{"orig_$imgsrc"} = $graph->{$imgsrc};
$graph->{$imgsrc} =~ s|^(?:\.\./)+||;
}
}
}
$graphtemplate->param(
PATH => $key->{'path'},
CSS_NAME => get_css_name(),
HOST_URL => $key->{'host_url'},
R_PATH => ".",
"TIME".$time => 1,
NAME => $key->{'name'},
TAGLINE => $htmltagline,
ROOTGROUPS => $htmlconfig->{"groups"},
MUNIN_VERSION => $Munin::Common::Defaults::MUNIN_VERSION,
TIMESTAMP => $timestamp,
NGLOBALCATS => $htmlconfig->{"nglobalcats"},
GLOBALCATS => $htmlconfig->{"globalcats"},
CATEGORY => $key->{"name"},
SERVICES => $key->{"graphs"},
NCRITICAL => scalar(@{$htmlconfig->{"problems"}->{"criticals"}}),
NWARNING => scalar(@{$htmlconfig->{"problems"}->{"warnings"}}),
NUNKNOWN => scalar(@{$htmlconfig->{"problems"}->{"unknowns"}}),
);
# store template output before reverting links
my $template_output = $graphtemplate->output;
# restore the paths to their original value
foreach my $graphs(@{$key->{'graphs'}}) {
foreach my $graph(@{$graphs->{'graphs'}}) {
foreach my $imgsrc(qw(imgday imgweek imgmonth imgyear
cimgday cimgweek cimgmonth cimgyear
zoomday zoomweek zoommonth zoomyear)) {
$graph->{$imgsrc} = $graph->{"orig_$imgsrc"};
delete($graph->{"orig_$imgsrc"});
}
}
}
if($emit_to_stdout){
print $template_output;
} else {
ensure_dir_exists($filename);
open(my $FILE, '>', $filename)
or die "Cannot open $filename for writing: $!";
print $FILE $template_output;
close $FILE;
}
}
sub ensure_dir_exists {
my $dirname = shift;
$dirname =~ s/\/[^\/]*$//;
munin_mkdir_p($dirname, oct(755));
}
sub emit_problem_template {
my ($emit_to_stdout) = @_;
my $graphtemplate = HTML::Template->new(
filename => "$tmpldir/munin-problemview.tmpl",
die_on_bad_params => 0,
global_vars => 1,
loop_context_vars => 1,
);
my $filename = munin_get_html_filename($config);
$filename =~ s/index.html$/problems.html/g;
INFO "[INFO] Creating problem page ".$filename;
# Manipulate the relative paths for the requested root-level context.
# Sadly this change is permanent and will influence successive
# responses in a permanent execution environment like fcgid or
# as a systemd socket service. Thus we need to revert it later.
foreach my $problem_graphs (values %{$htmlconfig->{"problems"}}) {
foreach my $graph(@$problem_graphs) {
foreach my $imgsrc(qw(imgday imgweek imgmonth imgyear
cimgday cimgweek cimgmonth cimgyear
zoomday zoomweek zoommonth zoomyear)) {
next unless defined($graph->{$imgsrc});
# keep a copy of the original value (to be restored below)
$graph->{"orig_$imgsrc"} = $graph->{$imgsrc};
$graph->{$imgsrc} =~ s|^(?:\.\./)+||;
}
}
}
$graphtemplate->param(
CSS_NAME => get_css_name(),
R_PATH => ".",
NAME => "Problem overview",
TAGLINE => $htmltagline,
ROOTGROUPS => $htmlconfig->{"groups"},
MUNIN_VERSION => $Munin::Common::Defaults::MUNIN_VERSION,
TIMESTAMP => $timestamp,
NGLOBALCATS => $htmlconfig->{"nglobalcats"},
GLOBALCATS => $htmlconfig->{"globalcats"},
CRITICAL => $htmlconfig->{"problems"}->{"criticals"},
WARNING => $htmlconfig->{"problems"}->{"warnings"},
UNKNOWN => $htmlconfig->{"problems"}->{"unknowns"},
NCRITICAL => scalar(@{$htmlconfig->{"problems"}->{"criticals"}}),
NWARNING => scalar(@{$htmlconfig->{"problems"}->{"warnings"}}),
NUNKNOWN => scalar(@{$htmlconfig->{"problems"}->{"unknowns"}}),
);
# store template output before reverting links
my $template_output = $graphtemplate->output;
# restore the paths to their original value
foreach my $problem_graphs (values %{$htmlconfig->{"problems"}}) {
foreach my $graph(@$problem_graphs) {
foreach my $imgsrc(qw(imgday imgweek imgmonth imgyear
cimgday cimgweek cimgmonth cimgyear
zoomday zoomweek zoommonth zoomyear)) {
next unless defined($graph->{$imgsrc});
$graph->{$imgsrc} = $graph->{"orig_$imgsrc"};
delete($graph->{"orig_$imgsrc"});
}
}
}
if($emit_to_stdout){
print $template_output;
} else {
ensure_dir_exists($filename);
open(my $FILE, '>', $filename)
or die "Cannot open $filename for writing: $!";
print $FILE $template_output;
close $FILE;
}
}
sub emit_group_template {
my ($key, $emit_to_stdout) = @_;
my $grouptemplate = HTML::Template->new(
filename => "$tmpldir/munin-domainview.tmpl",
die_on_bad_params => 0,
global_vars => 1,
loop_context_vars => 1,
filter => sub {
my $ref = shift;
$$ref =~ s/URLX/URL$key->{'depth'}/g;
});
DEBUG "[DEBUG] Creating group page ".$key->{filename};
$grouptemplate->param(
INFO_OPTION => 'Groups on this level',
GROUPS => $key->{'groups'},
PATH => $key->{'path'},
R_PATH => $key->{'root_path'},
CSS_NAME => get_css_name(),
PEERS => $key->{'peers'},
LARGESET => decide_largeset($key->{'peers'}),
PARENT => $key->{'path'}->[-2]->{'name'} || "Overview",
COMPARE => $key->{'compare'},
TAGLINE => $htmltagline,
ROOTGROUPS => $htmlconfig->{"groups"},
MUNIN_VERSION => $Munin::Common::Defaults::MUNIN_VERSION,
TIMESTAMP => $timestamp,
NGLOBALCATS => $htmlconfig->{"nglobalcats"},
GLOBALCATS => $htmlconfig->{"globalcats"},
NCRITICAL => scalar(@{$htmlconfig->{"problems"}->{"criticals"}}),
NWARNING => scalar(@{$htmlconfig->{"problems"}->{"warnings"}}),
NUNKNOWN => scalar(@{$htmlconfig->{"problems"}->{"unknowns"}}),
);
if($emit_to_stdout){
print $grouptemplate->output;
} else {
my $filename = $key->{'filename'};
ensure_dir_exists($filename);
open(my $FILE, '>', $filename)
or die "Cannot open $filename for writing: $!";
print $FILE $grouptemplate->output;
close $FILE or die "Cannot close $filename after writing: $!";
}
}
sub emit_zoom_template {
my($srv, $emit_to_stdout) = @_;
my $servicetemplate = HTML::Template->new(
filename => "$tmpldir/munin-dynazoom.tmpl",
die_on_bad_params => 0,
global_vars => 1,
loop_context_vars => 1
);
my $pathnodes = $srv->{'path'};
my $peers = $srv->{'peers'};
#remove underscores from peers and title (last path element)
if ($peers){
$peers = [ map { $_->{'name'} =~ s/_/ /g; $_;} @$peers ];
}
$pathnodes->[scalar(@$pathnodes) - 1]->{'pathname'} =~ s/_/ /g;
$servicetemplate->param(
INFO_OPTION => 'Graphs in same category',
SERVICES => [$srv],
PATH => $pathnodes,
PEERS => $peers,
LARGESET => decide_largeset($peers),
R_PATH => $srv->{'root_path'},
CSS_NAME => get_css_name(),
CATEGORY => ucfirst $srv->{'category'},
TAGLINE => $htmltagline,
ROOTGROUPS => $htmlconfig->{"groups"},
MUNIN_VERSION => $Munin::Common::Defaults::MUNIN_VERSION,
TIMESTAMP => $timestamp,
NGLOBALCATS => $htmlconfig->{"nglobalcats"},
GLOBALCATS => $htmlconfig->{"globalcats"},
NCRITICAL => scalar(@{$htmlconfig->{"problems"}->{"criticals"}}),
NWARNING => scalar(@{$htmlconfig->{"problems"}->{"warnings"}}),
NUNKNOWN => scalar(@{$htmlconfig->{"problems"}->{"unknowns"}}),
SHOW_ZOOM_JS => 1,
);
if($emit_to_stdout){
print $servicetemplate->output;
} else {
my $filename = $srv->{'filename'};
ensure_dir_exists($filename);
DEBUG "[DEBUG] Creating service page $filename";
open(my $FILE, '>', $filename)
or die "Cannot open '$filename' for writing: $!";
print $FILE $servicetemplate->output;
close $FILE or die "Cannot close '$filename' after writing: $!";
}
}
sub emit_service_template {
my ($srv, $emit_to_stdout) = @_;
my $servicetemplate = HTML::Template->new(
filename => "$tmpldir/munin-serviceview.tmpl",
die_on_bad_params => 0,
global_vars => 1,
loop_context_vars => 1
);
my $pathnodes = $srv->{'path'};
my $peers = $srv->{'peers'};
#remove underscores from peers and title (last path element)
if ($peers){
$peers = [ map { $_->{'name'} =~ s/_/ /g; $_;} @$peers ];
}
$pathnodes->[scalar(@$pathnodes) - 1]->{'pathname'} =~ s/_/ /g;
$servicetemplate->param(
INFO_OPTION => 'Graphs in same category',
SERVICES => [$srv],
PATH => $pathnodes,
PEERS => $peers,
LARGESET => decide_largeset($peers),
R_PATH => $srv->{'root_path'},
CSS_NAME => get_css_name(),
CATEGORY => ucfirst $srv->{'category'},
TAGLINE => $htmltagline,
ROOTGROUPS => $htmlconfig->{"groups"},
MUNIN_VERSION => $Munin::Common::Defaults::MUNIN_VERSION,
TIMESTAMP => $timestamp,
NGLOBALCATS => $htmlconfig->{"nglobalcats"},
GLOBALCATS => $htmlconfig->{"globalcats"},
NCRITICAL => scalar(@{$htmlconfig->{"problems"}->{"criticals"}}),
NWARNING => scalar(@{$htmlconfig->{"problems"}->{"warnings"}}),
NUNKNOWN => scalar(@{$htmlconfig->{"problems"}->{"unknowns"}}),
);
# No stored filename for this kind of html node.
if($emit_to_stdout){
print $servicetemplate->output;
} else {
my $filename = $srv->{'filename'};
ensure_dir_exists($filename);
DEBUG "[DEBUG] Creating service page $filename";
open(my $FILE, '>', $filename)
or die "Cannot open '$filename' for writing: $!";
print $FILE $servicetemplate->output;
close $FILE or die "Cannot close '$filename' after writing: $!";
}
}
sub decide_largeset {
my ($peers) = @_;
return scalar(@$peers) > $config->{'dropdownlimit'} ? 1 : 0;
}
sub emit_main_index {
# Draw main index
my ($groups, $t, $emit_to_stdout) = @_;
my $template = HTML::Template->new(
filename => "$tmpldir/munin-overview.tmpl",
die_on_bad_params => 0,
loop_context_vars => 1,
global_vars => 1,
filter => sub {
my $ref = shift;
$$ref =~ s/URLX/URL0/g;
},
);
# FIX: this sometimes bugs:
# HTML::Template::param() : attempt to set parameter 'groups' with
# a scalar - parameter is not a TMPL_VAR! at
# /usr/local/share/perl/5.10.0/Munin/Master/HTMLOld.pm line 140
$template->param(
TAGLINE => $htmltagline,
GROUPS => $groups,
CSS_NAME => get_css_name(),
R_PATH => ".",
ROOTGROUPS => $htmlconfig->{"groups"},
MUNIN_VERSION => $Munin::Common::Defaults::MUNIN_VERSION,
TIMESTAMP => $timestamp,
NGLOBALCATS => $htmlconfig->{"nglobalcats"},
GLOBALCATS => $htmlconfig->{"globalcats"},
NCRITICAL => scalar(@{$htmlconfig->{"problems"}->{"criticals"}}),
NWARNING => scalar(@{$htmlconfig->{"problems"}->{"warnings"}}),
NUNKNOWN => scalar(@{$htmlconfig->{"problems"}->{"unknowns"}}),
);
if($emit_to_stdout){
print $template->output;
} else {
my $filename = munin_get_html_filename($config);
ensure_dir_exists($filename);
DEBUG "[DEBUG] Creating main index $filename";
open(my $FILE, '>', $filename)
or die "Cannot open $filename for writing: $!";
print $FILE $template->output;
close $FILE;
}
}
sub copy_web_resources {
my ($staticdir, $htmldir) = @_;
unless(dircopy($staticdir, "$htmldir/static")){
ERROR "[ERROR] Could not copy contents from $staticdir to $htmldir";
die "[ERROR] Could not copy contents from $staticdir to $htmldir";
}
}
sub instanciate_comparison_templates {
my ($tmpldir) = @_;
return (
day => HTML::Template->new(
filename => "$tmpldir/munin-comparison-day.tmpl",
die_on_bad_params => 0,
global_vars => 1,
loop_context_vars => 1
),
week => HTML::Template->new(
filename => "$tmpldir/munin-comparison-week.tmpl",
die_on_bad_params => 0,
global_vars => 1,
loop_context_vars => 1
),
month => HTML::Template->new(
filename => "$tmpldir/munin-comparison-month.tmpl",
global_vars => 1,
die_on_bad_params => 0,
loop_context_vars => 1
),
year => HTML::Template->new(
filename => "$tmpldir/munin-comparison-year.tmpl",
global_vars => 1,
die_on_bad_params => 0,
loop_context_vars => 1
));
}
sub get_css_name{
#NOTE: this will do more in future versions. knuthaug 2009-11-15
return "style.css";
}
sub fork_and_work {
my ($work) = @_;
if (!$do_fork || !$max_running) {
# We're not forking. Do work and return.
DEBUG "[DEBUG] Doing work synchrnonously";
&$work;
return;
}
# Make sure we don't fork too much
while ($running >= $max_running) {
DEBUG
"[DEBUG] Too many forks ($running/$max_running), wait for something to get done";
look_for_child("block");
--$running;
}
my $pid = fork();
if (!defined $pid) {
ERROR "[ERROR] fork failed: $!";
die "fork failed: $!";
}
if ($pid == 0) {
# This block does the real work. Since we're forking exit
# afterwards.
&$work;
# See?!
exit 0;
}
else {
++$running;
DEBUG "[DEBUG] Forked: $pid. Now running $running/$max_running";
while ($running and look_for_child()) {
--$running;
}
}
}
sub generate_category_templates {
my $arr = shift || return;
foreach my $key (@$arr) {
foreach my $time (@times) {
emit_category_template($key, $time, 0);
}
}
}
sub generate_group_templates {
my $arr = shift || return;
return unless ref($arr) eq "ARRAY";
foreach my $key (@$arr) {
if (defined $key and ref($key) eq "HASH") {
if (defined $key->{'ngroups'} and $key->{'ngroups'}) {
fork_and_work(sub {generate_group_templates($key->{'groups'})});
emit_group_template($key,0);
if ($key->{'compare'}) { # Create comparison templates as well
foreach my $t (@times) {
emit_comparison_template($key,$t,0);
}
}
}
if (defined $key->{'ngraphs'} and $key->{'ngraphs'}) {
emit_graph_template($key, 0);
foreach my $category (@{$key->{"categories"}}) {
foreach my $serv (@{$category->{"services"}}) {
unless($serv->{"multigraph"}){
emit_service_template($serv);
#emit_zoom_template($serv);
}
}
}
}
}
}
}
sub print_usage_and_exit {
print "Usage: $0 [options]
Options:
--help View this message.
--debug View debug messages.
--version View version information.
--nofork Compatibility. No effect.
--service <service> Compatibility. No effect.
--host <host> Compatibility. No effect.
--config <file> Use <file> as configuration file.
[/etc/munin/munin.conf]
";
exit 0;
}
1;
=head1 NAME
munin-html - A program to draw html-pages on an Munin installation
=head1 SYNOPSIS
munin-html [options]
=head1 OPTIONS
=over 5
=item B<< --service <service> >>
Compatibility. No effect.
=item B<< --host <host> >>
Compatibility. No effect.
=item B<< --nofork >>
Compatibility. No effect.
=item B<< --config <file> >>
Use E<lt>fileE<gt> as configuration file. [/etc/munin/munin.conf]
=item B<< --help >>
View help message.
=item B<< --[no]debug >>
If set, view debug messages. [--nodebug]
=back
=head1 DESCRIPTION
Munin-html is a part of the package Munin, which is used in combination
with Munin's node. Munin is a group of programs to gather data from
Munin's nodes, graph them, create html-pages, and optionally warn Nagios
about any off-limit values.
Munin-html creates the html pages.
=head1 FILES
/etc/munin/munin.conf
/var/lib/munin/datafile
/var/log/munin/munin-html
/var/www/html/munin/*
/var/run/munin/*
=head1 VERSION
This is munin-html version 2.0.54
=head1 AUTHORS
Knut Haugen, Audun Ytterdal and Jimmy Olsen.
=head1 BUGS
munin-html does, as of now, not check the syntax of the configuration file.
Please report other bugs in the bug tracker at L<http://munin-monitoring.org/>.
=head1 COPYRIGHT
Copyright (C) 2002-2009 Knut Haugen, Audun Ytterdal, and Jimmy Olsen /
Linpro AS.
This is free software; see the source for copying conditions. There is
NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.
This program is released under the GNU General Public License
=head1 SEE ALSO
For information on configuration options, please refer to the man page for
F<munin.conf>.
=cut
# vim:syntax=perl:ts=8