php-syslog-ng 完全版

id:dacci:20070114:1168740226 の完全版。結局、前のエントリーで紹介した方法だと不具合があったので、1つのデーモンとして書き直したバージョン。

/usr/local/sbin/php-syslog-ng

#!/usr/bin/perl -w --

use strict;
use warnings;
use utf8;
use vars qw(@ARGV);

# Libraries ######################################
use POSIX;
use IO::File;
use DBI;

# Configurations #################################
my $DB_HOST   = "localhost";
my $DB_NAME   = "syslog";
my $DB_USER   = "syslogfeeder";
my $DB_PASSWD = "syslogfeeder";

# Constants ######################################
my $PID_FILE = "/var/run/php-syslog-ng.pid";

if (-e $PID_FILE) {
    print("Another instance is running, exitting.\n");
    exit(-1);
}

if ($#ARGV != 0) {
    print("Usage: php-syslog-ng <PIPE NAME>\n");
    exit(-1);
}

my $pipe = undef;
my $db   = undef;

$SIG{"TERM"} = sub {
    $pipe->close()    if (defined $pipe);
    $db->disconnect() if (defined $db);
    unlink $PID_FILE;
    exit(0);
};

if (my $pid = fork()) {
    exit(0);
} elsif (defined $pid) {
    POSIX::setsid();

    my $pidfile = new IO::File(">$PID_FILE");
    $pidfile->print($$);
    $pidfile->close();

    $db = DBI->connect("DBI:mysql:$DB_NAME:$DB_HOST", $DB_USER, $DB_PASSWD) || die($!);
    my $st =
      $db->prepare("INSERT INTO logs (host, facility, priority, level, tag, datetime, program, msg) "
          . "VALUES (?, ?, ?, ?, ?, ?, ?, ?);");

    while (1) {
        $pipe = IO::File->new("$ARGV[0]");

        while (my $line = $pipe->getline()) {
            chomp($line);
            my @params = split(/\t/, $line, 8);
            $st->execute(@params);
        }

        $pipe->close();
    }

    $st->finish();
    $db->disconnect();
    unlink $PID_FILE;
} else {
    die("Failed to fork()\n");
}

/etc/init.d/php-syslog-ng

3行目の 79 21 は、MySQL より後に起動するように調整する。

#!/bin/bash
#
# chkconfig: - 79 21
# description: php-syslog-ng redirection daemon.
# pidfile: /var/run/php-syslog-ng.pid

# Source function library.
. /etc/init.d/functions

PIPE="/tmp/mysql.pipe"
EXEC="/usr/local/sbin/php-syslog-ng"
PROG="`basename $EXEC`"
LOCK="/var/lock/subsys/$PROG"

RETVAL=0

start() {
    [ -e $PIPE ] || action $"Creating named pipe: " mkfifo $PIPE
    echo -n $"Starting $PROG: "
    daemon $EXEC $PIPE
    RETVAL=$?
    echo
    [ $RETVAL -eq 0 ] && touch $LOCK
    return $RETVAL
}

stop() {
    echo -n $"Stopping $PROG: "
    killproc $PROG
    RETVAL=$?
    echo
    [ $RETVAL -eq 0 ] && rm -f $LOCK
    #[ -e $PIPE ] && action $"Deleting named pipe: " rm -f $PIPE
    return $RETVAL
}

rhstatus() {
    status $PROG
}

restart() {
    stop
    start
}

case "$1" in
    start|stop|restart)
        $1
        ;;
    status)
        rhstatus
        ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart}"
        exit 2
esac

あとはサービスが起動するように設定。

 # chkconfig php-syslog-ng on
 # service php-syslog-ng