Nagios是一款开源的免费网络监视工具,能有效监控Windows、Linux和Unix的主机状态,交换机路由器等网络设置,打印机等。在系统或服务状态异常时发出邮件或短信报警第一时间通知网站运维人员,在状态恢复后发出正常的邮件或短信通知。
--以上来自百度百科nagios
作为监控,nagios的确是最佳选择,它能有效地监控各种网络服务(WEB服务,邮件服务……),并且可以在服务异常时,第一时间通知系统管理员。监控的各种服务,有些既可以通过插件来完成,有些也可以写自定义监控程序。
我这里用的是nagios3.2.3版本,系统是Red Hat Enterprise Linux AS release 4 (Nahant Update 7)(用centos 5.5 5.6 5.7版本也可以)。我的WEB服务平台是LNMP,需要安装LNMP平台的,请参考我的另一篇文章,《安装LNMP》。
(1)所需要准备的软件(nagios与nagios-plugins的版本不需要对应)
-
nagios-3.2.3.tar.gz
-
nagios-plugins-1.4.15.tar.gz
-
FCGI-0.74.tar.gz
-
FCGI-ProcManager-0.24.tar.gz
(2)创建用户及群组:
-
useradd nagios #nagios为安全起见,服务用此用户启动
-
groupadd nagcmd #这个群组主要是让WEB页面可以设置nagios
-
usermod -G nagcmd nagios
-
usermod -G nagcmd www #把WEB服务的启动用户加入群组
-
因为nagios用户不需要登录,所以修改passwd文件
-
vi /etc/passwd
-
把nagios:x:513:513::/home/nagios:/bin/bash改为nagios:x:513:513::/home/nagios:/sbin/nologin
(3)安装nagios及插件,及启动
-
tar -zxvf nagios-3.2.3.tar.gz
-
cd nagios
-
cd nagios-3.2.3
-
./configure --prefix=/usr/local/nagios/ --with-group=nagios --with-user=nagios --with-command-group=nagcmd --with-gd-lib=/usr/local/gd/lib/ --with-gd-inc=/usr/local/gd/include/
-
make all && make install && make install-init && make install-config && make install-commandmode
-
-
tar -zxvf nagios-plugins-1.4.15.tar.gz
-
cd nagios-plugins-1.4.15
-
./configure --prefix=/usr/local/nagios/
-
make && make install
mkdir -p /usr/local/nagios/share/nagios
ln -s /usr/local/nagios/share/images /usr/local/nagios/share/nagios/images
service nagios start
(4)安装perl (FastCGI),并配置nginx。
由于nagios含有CGIs程序,要让要在web页面显示nagios监控情况,必须要让nginx支持perl cgi
-
tar -zxvf FCGI-0.74.tar.gz
-
cd FCGI-0.74
-
perl Makefile.PL
-
make && make install
-
-
tar -zxvf FCGI-ProcManager-0.24.tar.gz
-
cd FCGI-ProcManager-0.24
-
perl Makefile.PL
-
make && make install
-
-
或者直接用yum安装
-
yum install perl*
-
perl -MCPAN -e 'install FCGI'
-
perl -MCPAN -e 'install FCGI::ProcManager'
vi /usr/bin/cgiwrap-fcgi.pl 输入如下代码,保存
-
-
#!/usr/bin/perl -w
-
use FCGI;
-
use Socket;
-
use FCGI::ProcManager;
-
sub shutdown { FCGI::CloseSocket($socket); exit; }
-
sub restart { FCGI::CloseSocket($socket); &main; }
-
use sigtrap 'handler', \&shutdown, 'normal-signals';
-
use sigtrap 'handler', \&restart, 'HUP';
-
require 'syscall.ph';
-
use POSIX qw(setsid);
-
-
#&daemonize; we don't daemonize when running under runsv
-
#this keeps the program alive or something after exec'ing perl scripts
-
END() { }
-
BEGIN() { }
-
{
-
no warnings;
-
*CORE::GLOBAL::exit = sub { die "fakeexit\nrc=" . shift() . "\n"; };
-
};
-
eval q{exit};
-
if ($@) {
-
exit unless $@ =~ /^fakeexit/;
-
}
-
&main;
-
-
sub daemonize() {
-
chdir '/' or die "Can't chdir to /: $!";
-
defined( my $pid = fork ) or die "Can't fork: $!";
-
exit if $pid;
-
setsid() or die "Can't start a new session: $!";
-
umask 0;
-
}
-
-
sub main {
-
-
#$socket = FCGI::OpenSocket( "127.0.0.1:8999", 10 ); #use IP sockets
-
#$socket = FCGI::OpenSocket( "/var/run/nginx/perl_cgi-dispatch.sock", 10 ); #use UNIX sockets - user running this script must have w access to the 'nginx' folder!!
-
#foreach $item (keys %ENV) { delete $ENV{$item}; }
-
$proc_manager = FCGI::ProcManager->new( {n_processes => 5} );
-
$socket = FCGI::OpenSocket( "127.0.0.1:8999", 10 ); #use UNIX sockets - user running this script must have w access to the 'nginx' folder!!
-
$request =
-
FCGI::Request( \*STDIN, \*STDOUT, \*STDERR, \%req_params, $socket,
-
&FCGI::FAIL_ACCEPT_ON_INTR );
-
$proc_manager->pm_manage();
-
if ($request) { request_loop() }
-
FCGI::CloseSocket($socket);
-
}
-
-
sub request_loop {
-
while ( $request->Accept() >= 0 ) {
-
$proc_manager->pm_pre_dispatch();
-
-
#processing any STDIN input from WebServer (for CGI-POST actions)
-
$stdin_passthrough = '';
-
{ no warnings; $req_len = 0 $req_params{'CONTENT_LENGTH'}; };
-
if ( ( $req_params{'REQUEST_METHOD'} eq 'POST' ) && ( $req_len != 0 ) )
-
{
-
my $bytes_read = 0;
-
while ( $bytes_read < $req_len ) {
-
my $data = '';
-
my $bytes = read( STDIN, $data, ( $req_len - $bytes_read ) );
-
last if ( $bytes == 0 || !defined($bytes) );
-
$stdin_passthrough .= $data;
-
$bytes_read = $bytes;
-
}
-
}
-
-
#running the cgi app
-
if (
-
( -x $req_params{SCRIPT_FILENAME} ) && #can I execute this?
-
( -s $req_params{SCRIPT_FILENAME} ) && #Is this file empty?
-
( -r $req_params{SCRIPT_FILENAME} ) #can I read this file?
-
)
-
{
-
pipe( CHILD_RD, PARENT_WR );
-
pipe( PARENT_ERR, CHILD_ERR );
-
my $pid = open( CHILD_O, "-|" );
-
unless ( defined($pid) ) {
-
print("Content-type: text/plain\r\n\r\n");
-
print
-
"Error: CGI app returned no output - Executing $req_params{SCRIPT_FILENAME} failed !\n";
-
next;
-
}
-
$oldfh = select(PARENT_ERR);
-
$| = 1;
-
select(CHILD_O);
-
$| = 1;
-
select($oldfh);
-
if ( $pid > 0 ) {
-
close(CHILD_RD);
-
close(CHILD_ERR);
-
print PARENT_WR $stdin_passthrough;
-
close(PARENT_WR);
-
$rin = $rout = $ein = $eout = '';
-
vec( $rin, fileno(CHILD_O), 1 ) = 1;
-
vec( $rin, fileno(PARENT_ERR), 1 ) = 1;
-
$ein = $rin;
-
$nfound = 0;
-
-
while ( $nfound =
-
select( $rout = $rin, undef, $ein = $eout, 10 ) )
-
{
-
die "$!" unless $nfound != -1;
-
$r1 = vec( $rout, fileno(PARENT_ERR), 1 ) == 1;
-
$r2 = vec( $rout, fileno(CHILD_O), 1 ) == 1;
-
$e1 = vec( $eout, fileno(PARENT_ERR), 1 ) == 1;
-
$e2 = vec( $eout, fileno(CHILD_O), 1 ) == 1;
-
-
if ($r1) {
-
while ( $bytes = read( PARENT_ERR, $errbytes, 4096 ) ) {
-
print STDERR $errbytes;
-
}
-
if ($!) {
-
$err = $!;
-
die $!;
-
vec( $rin, fileno(PARENT_ERR), 1 ) = 0
-
unless ( $err == EINTR or $err == EAGAIN );
-
}
-
}
-
if ($r2) {
-
while ( $bytes = read( CHILD_O, $s, 4096 ) ) {
-
print $s;
-
}
-
if ( !defined($bytes) ) {
-
$err = $!;
-
die $!;
-
vec( $rin, fileno(CHILD_O), 1 ) = 0
-
unless ( $err == EINTR or $err == EAGAIN );
-
}
-
}
-
last if ( $e1 || $e2 );
-
}
-
close CHILD_RD;
-
close PARENT_ERR;
-
waitpid( $pid, 0 );
-
} else {
-
foreach $key ( keys %req_params ) {
-
$ENV{$key} = $req_params{$key};
-
}
-
-
# cd to the script's local directory
-
if ( $req_params{SCRIPT_FILENAME} =~ /^(.*)\/[^\/] $/ ) {
-
chdir $1;
-
}
-
close(PARENT_WR);
-
-
#close(PARENT_ERR);
-
close(STDIN);
-
close(STDERR);
-
-
#fcntl(CHILD_RD, F_DUPFD, 0);
-
syscall( &SYS_dup2, fileno(CHILD_RD), 0 );
-
syscall( &SYS_dup2, fileno(CHILD_ERR), 2 );
-
-
#open(STDIN, "<&CHILD_RD");
-
exec( $req_params{SCRIPT_FILENAME} );
-
die("exec failed");
-
}
-
} else {
-
print("Content-type: text/plain\r\n\r\n");
-
print
-
"Error: No such CGI app - $req_params{SCRIPT_FILENAME} may not exist or is not executable by this process.\n";
-
}
-
}
-
}
运行脚本nohup perl /usr/local/bin/cgiwrap-fcgi.pl >/dev/null 2>&1 &
并把这一句加入/etc/rc.local文件中,让其开机执行
配置nginx,vi /usr/local/nginx/conf/nginx.conf
-
server
-
{
-
listen 80;
-
server_name wisp.nagios.com;
-
index index.html index.htm index.php;
-
root /usr/local/nagios/share;
-
access_log /usr/local/nagios/access_nagios.log main;
-
-
location ~ .*\.(php|php5)?$
-
{
-
fastcgi_pass 127.0.0.1:9000;
-
fastcgi_index index.php;
-
include fcgi.conf;
-
}
-
-
location ~ \.cgi$
-
{
-
root /usr/local/nagios/sbin;
-
rewrite ^/nagios/cgi-bin/(.*)\.cgi /$1.cgi break;
-
fastcgi_index index.cgi;
-
fastcgi_pass 127.0.0.1:8999;
-
-
fastcgi_param SCRIPT_FILENAME /usr/local/nagios/sbin$fastcgi_script_name;
-
fastcgi_param QUERY_STRING $query_string;
-
-
fastcgi_param REMOTE_ADDR $remote_addr;
-
fastcgi_param REMOTE_PORT $remote_port;
-
fastcgi_param REQUEST_METHOD $request_method;
-
fastcgi_param REQUEST_URI $request_uri;
-
-
#fastcgi_param SCRIPT_NAME $fastcgi_script_name;
-
fastcgi_param SERVER_ADDR $server_addr;
-
fastcgi_param SERVER_NAME $server_name;
-
fastcgi_param SERVER_PORT $server_port;
-
fastcgi_param SERVER_PROTOCOL $server_protocol;
-
fastcgi_param SERVER_SOFTWARE nginx;
-
-
fastcgi_param CONTENT_LENGTH $content_length;
-
fastcgi_param CONTENT_TYPE $content_type;
-
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
-
fastcgi_param HTTP_ACCEPT_ENCODING gzip,deflate;
-
fastcgi_param HTTP_ACCEPT_LANGUAGE zh-cn;
-
}
-
}
绑host或者在上面的配置用上真实域名,在浏览器里输入(或者你的域名),即可看到nagios的监控页面。
阅读(2620) | 评论(0) | 转发(0) |