Installing and configuring centralized syslog-ng
By: Gary Tay, gary_tay@platts.com
Updated: 8-Jul-2003
Purpose:
This document describes the steps involved in setting up syslog-ng, a replacement of UNIX/Linux syslog, system message logging system, on a centralized syslog-ng server, such that the syslog messages get logged into
1. Text files under /var/log/$HOST
2. MySQL database syslog.logs table
With the help of Apache/PHP and php-syslog-ng, these messages could be browsed or queried using Web Interface.
Freeware tools used:
· syslog-ng 1.6RC1- a replacement for UNIX/Linux syslog daemon, http://www.balabit.com/products/syslog_ng/
· Apache 2.0.46 - http://www.apache.org
· MySQL 4.0.13 - http://www.mysql.com
· PHP 4.3.3RC2 - http://www.php.net
· php-syslog-ng 1.3 - http://www.vermeer.org/projects/php-syslog-ng
· Instructions and scripts from http://www.vermeer.org
· Other information: see http://www.loganalysis.org
Testing Environment: currently “Proof of Concept” in development environment
Central Server:
nywplbb2.platts.mcgraw-hill.com
Monitored Clients:
From nyppldev10.platts.mcgraw-hill.com
To nyppldev19.platts.mcgraw-hill.com
Step 1: Install and configure syslog-ng at central server
- ftp syslog-ng-1.6.0rc1.tar to /var/tmp
- extract source files, configure and compile syslog-ng
- create a UNIX “pipe” file in /tmp for MySQL database row insertion
# mkfifo /tmp/mysql.pipe
- create /usr/local/etc/syslog-ng/syslog-ng.conf using Appendix 1.1
- note the key statement here:
# Log syslog-ng to mysql database
destination d_mysql {
pipe("/tmp/mysql.pipe" template("INSERT INTO logs (host, facility, priority, level, tag, date, time, program, msg) VALUES ( '$HOST', '$FACILITY', '$PRIORITY', '$LEVEL', '$TAG', '$YEAR-$MONTH-$DAY', '$HOUR:$MIN:$SEC', '$PROGRAM', '$MSG' );\n") template-escape(yes));
};
- disable current syslog server
# cd /etc/rc2.d
# mv S74syslog s74syslog
# /etc/init.d/syslog stop
- create /etc/init.d/syslog-ng using Appendix 1.2 and set permission
# chmod 740 /etc/init.d/syslog-ng
- enable new syslog-ng server
# cd /etc/rc2.d
# ln –s /etc/init.d/syslog-ng S74syslog-ng
# /etc/init.d/syslog-ng start
- for Solaris 9, modify /etc/logadm.conf for log files rotation, using Appendix 1.3
Step 2: Install and configure syslog-ng at monitored clients
- ftp syslog-ng-1.6.0rc1.tar to /var/tmp
- extract source files, configure and compile syslog-ng
- create /usr/local/etc/syslog-ng/syslog-ng.conf using Appendix 2.1
- disable current syslog server
# cd /etc/rc2.d
# mv S74syslog s74syslog
# /etc/init.d/syslog stop
- create /etc/init.d/syslog-ng using Appendix 1.2 and set permission
# chmod 740 /etc/init.d/syslog-ng
- enable new syslog-ng server
# cd /etc/rc2.d
# ln –s /etc/init.d/syslog-ng S74syslog-ng
# /etc/init.d/syslog-ng start
- for Solaris 9, modify /etc/logadm.conf for log files rotation, using Appendix 1.3
Step 3: Install and configure Apache, MySQL & PHP at Central Server
- ftp httpd-2.0.46.tar to /var/tmp
- extract source file, configure and compile Apache with DSO support
# ./configure –enable-so
# make
# make install
- change Apache files owner:group to nobody:nobody
# cd /usr/local
# chown –R nobody:nobody apache2
- change Apache startup owner:group and create a Virtual Server with Virtual Directory (Alias) /syslog pointing to /var/log/
edit /usr/local/apache2/conf/httpd.conf, add/modify the following lines
User nobody
#Group #-1
Group nobody
ServerAdmin gary_tay@platts.com
DocumentRoot /usr/local/apache2/htdocs
ServerName nywplbb2.platts.mcgraw-hill.com
ErrorLog logs/nywplbb2-error_log
CustomLog logs/nywplbb2-access_log common
Alias /syslog "/var/log/"
Options Indexes FollowSymLinks MultiViews IncludesNoExec
AddOutputFilter Includes html
AllowOverride None
Order allow,deny
Allow from all
- disable Solaris 9 built-in Apache (1.3.X) server
# cd /etc/rc3.d
# mv S50apache s50apache
# /etc/init.d/apache stop
- create /etc/init.d/apache2 using Appendix 3.1 and set permission
# chmod 740 /etc/init.d/apache2
- enable new Apache server
# cd /etc/rc3.d
# ln –s /etc/init.d/apache2 S50apache2
# /etc/init.d/apache2 start
- ftp mysql-standard-4.0.13-sun-solaris2.8-sparc.tar to /var/tmp
- extract source file, configure and compile MySQL
# ./configure
# make
# make install
- run “mysql_install_db” to initialize data directory and create grant tables
# cd /usr/local/mysql
# ./scripts/mysql_install_db
- change MySQL program + data files owner:group to nobody:nobody or mysql:mysql if you have created the account and group
# cd /usr/local
# chown –R nobody:nobody mysql
- install Perl DBI, DBD:mysql and CGI support
# perl –MCPAN –e shell
cpan> install DBI
cpan> install DBD:mysql
cpan> install CGI
- create /etc/init.d/mysql.server using sample from source files
# cp /usr/local/mysql/support-files/mysql.server /etc/init.d
# chmod 740 /etc/init.d/mysql.server
- edit /etc/my.cnf, change startup owner from “root” to “nobody”
[mysqld]
user = nobody
- enable new MySQL server
# /etc/init.d/mysql.server start
- ftp php4-STABLE-latest.tar (4.3.3RC2) to /var/tmp
- extract source files, configure and compile PHP with MySQL and Apache APXS2 support
# ./configure –with-mysql=/usr/local/mysql \
–with-apxs2=/usr/local/apache2/bin/apxs2
# make
# make install
- copy initial php.ini
# cp php.ini-dist /usr/local/lib/php.ini
- edit /usr/local/lib/php.ini and turn on Global Variable support (required by php-syslog-ng)
;register_globals = Off
register_globals = On
- edit /usr/local/apache2/conf/httpd.conf, add/modify PHP module support
LoadModule php4_module modules/libphp4.so
AddType application/x-httpd-php .php
AddType application/x-httpd-php .phtml
DirectoryIndex index.html index.html.var index.cgi index.pl index.php index.phtml
Also add/modify CGI support
AllowOverride None
Options None
Order allow,deny
Allow from all
AddHandler cgi-script .cgi
AddHandler cgi-script .pl
- restart Apache
# /etc/init.d/apache2 stop
# /etc/init.d/apache2 start
Step 4: Create syslog DB, logs table and syslog user at Central Server
- create 2x .sql and 2x .sh scripts
Content of create_syslog_table.sql:
CREATE DATABASE syslog;
USE syslog;
CREATE TABLE logs (
host varchar(32) default NULL,
facility varchar(10) default NULL,
priority varchar(10) default NULL,
level varchar(10) default NULL,
tag varchar(10) default NULL,
date date default NULL,
time time default NULL,
program varchar(15) default NULL,
msg text,
seq int(10) unsigned NOT NULL auto_increment,
PRIMARY KEY (seq),
KEY host (host),
KEY seq (seq),
KEY program (program),
KEY time (time),
KEY date (date),
KEY priority (priority),
KEY facility (facility)
) TYPE=MyISAM;
Content of create_syslog_user.sh:
/usr/local/mysql/bin/mysql -u root -p
Content of create_syslog_user.sql:
GRANT ALL ON syslog.* TO syslog@localhost IDENTIFIED BY 'secret';
Content of create_syslog_user.sh:
/usr/local/mysql/bin/mysql -u root -p
- run “/usr/local/etc/syslog-ng/create_syslog_table.sh”
- run “/usr/local/etc/syslog-ng/create_syslog_user.sh”
Step 5: Create and run syslog piping script in background
- create pipe_syslog_table.sh
Content of pipe_syslog_table.sh
#!/usr/bin/sh
#
# pipe_syslog_table.sh
#
# run this script in background mode
# i.e. nohup ./pipe_syslog_table.sh & >/dev/null 2>/dev/null
#
PATH=$PATH:/usr/local/mysql/bin; export PATH
if [ -p /tmp/mysql.pipe ]; then
while [ -p /tmp/mysql.pipe ]
do
mysql -u syslog --password=secret syslog
done
else
mkfifo /tmp/mysql.pipe
fi
- run “/usr/local/etc/pipe_syslog_table.sh” using “nohup” and background mode
# nohup /usr/local/etc/pipe_syslog_table.sh &
Step 6: Install and configure php-syslog-ng at Central Server
- ftp php-syslog-ng-1.3.tar to /var/tmp
- extract source files, move and rename it to /usr/local/apache2/htdocs
# mv /var/tmp/php-syslog-ng-1.3 /usr/local/apache2/htdocs/php-syslog-ng
- move images files one level up
# cd /usr/local/apache2/htdocs/php-syslog-ng
# mv images ..
- edit /usr/local/apache2/htdocs/php-syslog-ng/dbinfo.inc.php and add/modify password of MySQL “syslog” user
//$password = "db_password";
$password = "secret";
- optionally modify /usr/local/apache2/htdocs/php-syslog-ng/index.php and /usr/local/apache2/htdocs/php-syslog-ng/results.php to display your company logo file
- a version of results.php with color coded Priority Level display is shown in Appendix 6.1
Step 7: Restart syslog-ng at Central Server and verify logging
- perform “select” or “count” statement to verify if syslog messages are logged
# /usr/local/mysql/bin/mysql -u syslog -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 191 to server version: 4.0.13-standard
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> use syslog
Database changed
mysql> select count(*) from logs;
+----------+
| count(*) |
+----------+
| 11484 |
+----------+
1 row in set (0.03 sec)
mysql>
- access the syslog-ng URLs:
Text logging to /var/log/$HOST
http://nywplbb2.platts.mcgraw-hill.com/syslog
or
MySQL logging to syslog.logs table
http://nywplbb2.platts.mcgraw-hill.com/php-syslog-ng
Appendix 1.1: /usr/local/etc/syslog-ng/syslog-ng.conf
(for Central Server)
# Severity levels: from less to more
# debug -> info -> notice -> warn -> err -> crit -> alert -> emerg
options { sync(0); };
#Un-comment the next line for Linux box
#source src_local { unix-stream("/dev/log"); internal(); };
#Un-comment the next line for Solaris box
source src { sun-streams("/dev/log" door("/etc/.syslog_door")); internal()
; };
# Define source for remote logging
source net { udp(ip(0.0.0.0) port(514));};
# Define destination for local logging
destination console { usertty("root"); };
destination messages { file("/var/adm/messages"); };
destination syslog { file("/var/log/syslog"); };
destination authlog { file("/var/log/auth.log"); };
destination cronlog { file("/var/log/cron.log"); };
destination daemonlog { file("/var/log/daemon.log"); };
destination kernlog { file("/var/log/kern.log"); };
destination maillog { file("/var/log/mail.log"); };
destination userlog { file("/var/log/user.log"); };
# Define destination for remote logging
destination net_messages {
file("/var/adm/$HOST/messages" owner(root) group(nobody) perm(0640) dir_perm(0750) create_dirs(yes));
};
destination net_syslog {
file("/var/log/$HOST/syslog" owner(root) group(nobody) perm(0640) dir_perm(0750) create_dirs(yes));
};
destination net_authlog {
file("/var/log/$HOST/auth.log" owner(root) group(nobody) perm(0640) dir_perm(0750) create_dirs(yes));
};
destination net_cronlog {
file("/var/log/$HOST/cron.log" owner(root) group(nobody) perm(0640) dir_perm(0750) create_dirs(yes));
};
destination net_daemonlog {
file("/var/log/$HOST/daemon.log" owner(root) group(nobody) perm(0640) dir_perm(0750) create_dirs(yes));
};
destination net_kernlog {
file("/var/log/$HOST/kern.log" owner(root) group(nobody) perm(0640) dir_perm(0750) create_dirs(yes));
};
destination net_maillog {
file("/var/log/$HOST/mail.log" owner(root) group(nobody) perm(0640) dir_perm(0750) create_dirs(yes));
};
destination net_userlog {
file("/var/log/$HOST/user.log" owner(root) group(nobody) perm(0640) dir_perm(0750) create_dirs(yes));
};
# Log syslog-ng to mysql database
destination d_mysql {
pipe("/tmp/mysql.pipe" template("INSERT INTO logs (host, facility, priority, level, tag, date, time, program, msg) VALUES ( '$HOST', '$FACILITY', '$PRIORITY', '$LEVEL', '$TAG', '$YEAR-$MONTH-$DAY', '$HOUR:$MIN:$SEC', '$PROGRAM', '$MSG' );\n") template-escape(yes));
};
# Define filters
filter f_console { level(alert..emerg); };
filter f_messages { level(err..emerg); };
filter f_syslog { level(info..warn); };
filter f_authlog { facility(auth); };
filter f_cronlog { facility(cron); };
filter f_daemonlog { facility(daemon); };
filter f_kernlog { facility(kern); };
filter f_maillog { facility(mail); };
filter f_userlog { facility(user); };
# Local logging
log { source(src); filter(f_console); destination(console); };
log { source(src); filter(f_messages); destination(messages); };
log { source(src); filter(f_syslog); destination(syslog); };
log { source(src); filter(f_authlog); destination(authlog); };
log { source(src); filter(f_cronlog); destination(cronlog); };
log { source(src); filter(f_daemonlog); destination(daemonlog); };
log { source(src); filter(f_kernlog); destination(kernlog); };
log { source(src); filter(f_maillog); destination(maillog); };
log { source(src); filter(f_userlog); destination(userlog); };
# Remote logging
log { source(net); filter(f_messages); destination(net_messages); };
log { source(net); filter(f_syslog); destination(net_syslog); };
log { source(net); filter(f_authlog); destination(net_authlog); };
log { source(net); filter(f_cronlog); destination(net_cronlog); };
log { source(net); filter(f_daemonlog); destination(net_daemonlog); };
log { source(net); filter(f_kernlog); destination(net_kernlog); };
log { source(net); filter(f_maillog); destination(net_maillog); };
log { source(net); filter(f_userlog); destination(net_userlog); };
# Remote logging into MySQL
log { source(net); destination(d_mysql); };
Appendix 1.2: /etc/init.d/syslog-ng
(same for central server and all monitored clients)
#!/sbin/sh
# syslog-ng
case "$1" in
'start')
if [ -f /usr/local/etc/syslog-ng/syslog-ng.conf -a -f /usr/local/sbin/syslog-ng ]; then
echo 'syslog-ng service starting.'
#
# Before syslog-ng starts, save any messages from previous
# crash dumps so that messages appear in chronological order.
#
/usr/bin/savecore -m
if [ -r /etc/dumpadm.conf ]; then
. /etc/dumpadm.conf
[ -n "$DUMPADM_DEVICE" -a \
"x$DUMPADM_DEVICE" != xswap ] && \
/usr/bin/savecore -m -f $DUMPADM_DEVICE
fi
/usr/local/sbin/syslog-ng
fi
;;
'stop')
if [ -f /var/run/syslog-ng.pid ]; then
syspid=`/usr/bin/cat /var/run/syslog-ng.pid`
[ "$syspid" -gt 0 ] && kill -15 $syspid
fi
;;
*)
echo "Usage: $0 { start | stop }"
exit 1
;;
esac
Appendix 1.3: /etc/logadm.conf
(same for central server and monitored client)
# gtay, 25-Apr-2003, syslog-ng implementation, disabled next 2 lines
#/var/log/syslog -C 8 -P 'Sat Apr 5 08:10:00 2003' -a 'kill -HUP `cat /var/run/syslog.pid`'
#/var/adm/messages -C 4 -P 'Wed Apr 9 07:10:00 2003' -a 'kill -HUP `cat /var/run/syslog.pid`'
# gtay, 25-Apr-2003, syslog-ng implementation, added next 8 lines
/var/log/syslog -C 8 -P 'Sat Jul 5 07:10:04 2003' -a 'kill -HUP `cat /var/run/syslog-ng.pid`'
/var/adm/messages -C 4 -P 'Tue Jul 1 07:10:02 2003' -a 'kill -HUP `cat /var/run/syslog-ng.pid`'
/var/log/auth.log -C 4 -P 'Tue Jul 1 07:10:02 2003' -a 'kill -HUP `cat /var/run/syslog-ng.pid`'
/var/log/cron.log -C 4 -P 'Mon Apr 21 09:37:16 2003' -a 'kill -HUP `cat /var/run/syslog-ng.pid`'
/var/log/daemon.log -C 4 -P 'Tue Jul 1 07:10:02 2003' -a 'kill -HUP `cat /var/run/syslog-ng.pid`'
/var/log/kern.log -C 4 -P 'Fri Jul 4 07:10:04 2003' -a 'kill -HUP `cat /var/run/syslog-ng.pid`'
/var/log/mail.log -C 4 -P 'Tue Jul 1 07:10:02 2003' -a 'kill -HUP `cat /var/run/syslog-ng.pid`'
/var/log/user.log -C 4 -P 'Thu Jul 3 07:10:02 2003' -a 'kill -HUP `cat /var/run/syslog-ng.pid`'
Appendix 2.1: /usr/local/etc/syslog-ng/syslog-ng.conf
(for all Monitored Clients)
# Severity levels: from less to more
# debug -> info -> notice -> warn -> err -> crit -> alert -> emerg
options { sync(0); };
#Un-comment the next line for Linux box
#source src_local { unix-stream("/dev/log"); internal(); };
#Un-comment the next line for Solaris box
source src { sun-streams("/dev/log" door("/etc/.syslog_door")); internal()
; };
# Define destination for remote logging
destination loghost { udp("nywplbb2.platts.mcgraw-hill.com" port(514));};
# Define destination for local logging
destination console { usertty("root"); };
destination messages { file("/var/adm/messages"); };
destination syslog { file("/var/log/syslog"); };
destination authlog { file("/var/log/auth.log"); };
destination cronlog { file("/var/log/cron.log"); };
destination daemonlog { file("/var/log/daemon.log"); };
destination kernlog { file("/var/log/kern.log"); };
destination maillog { file("/var/log/mail.log"); };
destination userlog { file("/var/log/user.log"); };
# Define filters
filter f_console { level(alert..emerg); };
filter f_messages { level(err..emerg); };
filter f_syslog { level(info..warn); };
filter f_authlog { facility(auth); };
filter f_cronlog { facility(cron); };
filter f_daemonlog { facility(daemon); };
filter f_kernlog { facility(kern); };
filter f_maillog { facility(mail); };
filter f_userlog { facility(user); };
# Local logging
log { source(src); filter(f_console); destination(console); };
log { source(src); filter(f_messages); destination(messages); };
log { source(src); filter(f_syslog); destination(syslog); };
log { source(src); filter(f_authlog); destination(authlog); };
log { source(src); filter(f_cronlog); destination(cronlog); };
log { source(src); filter(f_daemonlog); destination(daemonlog); };
log { source(src); filter(f_kernlog); destination(kernlog); };
log { source(src); filter(f_maillog); destination(maillog); };
log { source(src); filter(f_userlog); destination(userlog); };
# Remote logging
log { source(src); destination(loghost); };
Appendix 3.1: /etc/init.d/apache2
#!/sbin/sh
#
APACHE_HOME=/usr/local/apache2
CONF_FILE=/usr/local/apache2/conf/httpd.conf
PIDFILE=/usr/local/apache2/logs/httpd.pid
if [ ! -f ${CONF_FILE} ]; then
exit 0
fi
status=`${APACHE_HOME}/bin/httpd -k $1 2>&1`
if [ $? != 0 ]; then
echo "$status"
exit 1
fi
exit 0
Appendix 6.1: /usr/local/apache2/htdocs/php-syslog-ng/results.php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2002 Michael Earls |
| |
| 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. |
+-------------------------------------------------------------------------+
| php-syslog-ng: php4 mysql syslog-ng |
+-------------------------------------------------------------------------+
| This code is currently maintained and debugged by Michael Earls, any |
| questions or comments regarding this code should be directed to: |
| - michael@michaelearls.com |
+-------------------------------------------------------------------------+
| - vermeer - http://www.vermeer.org/ |
+-------------------------------------------------------------------------+
*/
?>
PLATTS, McGraw-Hill Centralized Syslog-NG Monitor Search Results
PLATTS, McGraw-Hill Centralized Syslog-NG Monitor Search Results
SEVERITY LEGENED INFO DEBUG NOTICE WARNING ERR CRIT ALERT EMERG
// begin script
include("dbinfo.inc.php");
@ $db = mysql_pconnect("$hostname", "$username", "$password");
if (!$db)
{
echo "Error: Could not connect to database. Please try again later.";
exit;
}
mysql_select_db("$dbName");
$where = "";
$query = "select * from logs";
if($host!="*")
$where = "host='".$host."' ";
if($priority!="*")
{
if($where!="") $where = $where." and ";
$where = $where." priority='".$priority."' ";
}
if($date!="*")
{
if($where !="") $where = $where." and ";
$where = $where." date='".$date."' ";
}
if($where !="")
$query = $query." where ".$where." order by time and date";
else
$query = $query." order by time and date";
$result = mysql_query($query);
$num_results = mysql_num_rows($result);
if (empty($offset)) {
$offset=1;
}
$offsettemp=$offset-1;
$results = mysql_query("$query limit $offsettemp, $limit");
echo "Number of Syslog Entries: ".$num_results." ";
echo "
echo "";
echo "
";
echo "Result Page: ";
if ($offset!=1) { // bypass PREV link if offset is 0
$prevoffset=$offset-$limit ;
print "PREV \n";
}
$pages=intval($num_results/$limit);
if ($num_results%$limit) {
$pages++;
}
for ($i=1;$i<=$pages;$i++) {
$newoffset=$limit*($i-1)+1;
if ((intval($offset/$limit)+1)==$i )
print "$i \n";
else
print "$i \n";
}
if (!(intval($offset/$limit)+1==$pages) && $pages!=1) {
// not last page so give NEXT link
$newoffset=$offset+$limit;
print "NEXT \n";
}
?>
== End of doc ===