#!/usr/bin/perl use strict; use warnings; use FindBin; use lib "$FindBin::Bin/extlib/lib/perl5"; use lib "$FindBin::Bin/lib"; use File::Basename; use Getopt::Long; use Plack::Loader; use Plack::Builder; use Plack::Builder::Conditionals; use Plack::Util; use GrowthForecast; use GrowthForecast::Web; use GrowthForecast::Worker; use Proclet; use File::ShareDir qw/dist_dir/; use Cwd; use File::Path qw/mkpath/; use Log::Minimal; use Pod::Usage; my $port = 5125; my $host = 0; my @front_proxy; my @allow_from; Getopt::Long::Configure ("no_ignore_case"); GetOptions( 'port=s' => \$port, 'host=s' => \$host, 'front-proxy=s' => \@front_proxy, 'allow-from=s' => \@allow_from, 'disable-1min-metrics' => \my $disable_short, 'with-mysql=s' => \my $mysql, 'data-dir=s' => \my $data_dir, "h|help" => \my $help, ); if ( $help ) { pod2usage(-verbose=>2,-exitval=>0); } if ( $mysql ) { eval { require GrowthForecast::Data::MySQL }; die "Cannot load MySQL: $@" if $@; } my $root_dir = File::Basename::dirname(__FILE__); if ( ! -f "$root_dir/lib/GrowthForecast.pm" ) { $root_dir = dist_dir('GrowthForecast'); } if ( !$data_dir ) { $data_dir = $root_dir . '/data'; } else { $data_dir = Cwd::realpath($data_dir); } { if ( ! -d $data_dir ) { mkpath($data_dir) or die "cannot create data directory '$data_dir': $!"; } open( my $fh, '>', "$data_dir/$$.tmp") or die 'cannot create file in data_dir: $!'; close($fh); unlink("$data_dir/$$.tmp"); } my $proclet = Proclet->new; $proclet->service( code => sub { local $0 = "$0 (GrowthForecast::Worker 1min)"; my $worker = GrowthForecast::Worker->new( root_dir => $root_dir, data_dir => $data_dir, mysql => $mysql, ); $worker->run('short'); } ) if !$disable_short; $proclet->service( code => sub { local $0 = "$0 (GrowthForecast::Worker)"; my $worker = GrowthForecast::Worker->new( root_dir => $root_dir, data_dir => $data_dir, mysql => $mysql ); $worker->run; } ); $proclet->service( code => sub { local $0 = "$0 (GrowthForecast::Web)"; my $web = GrowthForecast::Web->new( root_dir => $root_dir, data_dir => $data_dir, short => !$disable_short, mysql => $mysql, ); my $app = builder { enable 'Lint'; enable 'StackTrace'; if ( @front_proxy ) { enable match_if addr(\@front_proxy), 'ReverseProxy'; } if ( @allow_from ) { enable match_if addr('!',\@allow_from), sub { sub { [403,['Content-Type','text/plain'], ['Forbidden']] } }; } enable sub { my $app = shift; sub { my $env = shift; my $res = $app->($env); Plack::Util::response_cb($res, sub { my $res = shift; Plack::Util::header_set($res->[1], 'X-Powered-By', 'GrowthForecast/'.$GrowthForecast::VERSION); }); } }; enable 'Static', path => qr!^/(?:(?:css|js|images)/|favicon\.ico$)!, root => $root_dir . '/public'; enable 'Scope::Container'; $web->psgi; }; my $loader = Plack::Loader->load( 'Starlet', port => $port, host => $host || 0, max_workers => 4, ); infof( "GrowthForecast::Web starts listen on %s:%s", $host || 0, $port ); $loader->run($app); } ); $proclet->run; __END__ =head1 NAME growthforecast.pl - Lightning Fast Graphing/Visualization =head1 SYNOPSIS % growthforecast.pl --data-dir=/path/to/dir =head1 DESCRIPTION GrowthForecast is graphing/visualization web tool built on RRDtool =head1 INSTALL =over 4 =item Install dependicies To install growthforecast, these libraries are needed. =over 4 =item * glib =item * xml2 =item * pango =item * cairo =back (CentOS) $ sudo yum groupinstall "Development Tools" $ sudo yum install pkgconfig glib2-devel gettext libxml2-devel pango-devel cairo-devel (Ubuntu) $ sudo apt-get build-dep rrdtool =item Install GrowthForecast $ cpanm GrowthForecast It's recommencd to using perlbrew =back =head1 OPTIONS =over 4 =item --data-dir A directory to store rrddata and metadata =item --port TCP port listen on. Default is 5125 =item --host IP address to listn on =item --front-proxy IP addresses or CIDR of reverse proxy =item --allow-from IP addresses or CIDR to allow access from. Default is empty (allow access from any remote ip address) =item --disable-1min-metrics don't generate 1min rrddata and graph Default is "1" (enabled) =item --with-mysql DB connection setting to store metadata. format like dbi:mysql:[dbname];hostname=[hostnaem] Default is no mysql setting. GrowthForecast save metadata to SQLite =item -h --help Display help =back =head1 MYSQL Setting GrowthForecast uses SQLite as metadata by default. And also supports MySQL GrowthForeacst needs thease MySQL privileges. =over 4 =item * CREATE =item * ALTER =item * DELETE =item * INSERT =item * UPDATE =item * SELECT =back Sample GRANT statement mysql> GRANT statement sample> GRANT CREATE, ALTER, DELETE, INSERT, UPDATE, SELECT \\ ON growthforecast.* TO 'www'\@'localhost' IDENTIFIED BY foobar; Give USERNAME and PASSWORD to GrowthForecast by environment value $ MYSQL_USER=www MYSQL_PASSWORD=foobar growthforecast.pl \\ --data-dir /home/user/growthforeacst \\ -with-mysql dbi:mysql:growthforecast;hostname=localhost AUTHOR Masahiro Nagano LICENSE This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.