#! /usr/bin/perl -w

# Ce script réécrit le log mysql-slow en temps réel (utilisation de cronolog).
# Le log généré sera utilisé pour générer des statistiques.
# Avantages :
# - le log de mysql est verbeux, on le réécrit en supprimant ce qui n'est pas utile.
#   Le script qui s'occupe des stats sera donc plus simple et plus efficient.
# - on utilise cronolog, donc le log est clairement délimité dans le temps.
# - si le format de log change, les scripts qui génèrent les stats ne devront pas changer.
#   Seul ce script devra être modifié.

# Format d'origine :

# Time: 050902  6:26:05
# User@Host: gsauvanet2[gsauvanet2] @ bizmachine9.co.fr.clara.net [212.43.241.154]
# Query_time: 13  Lock_time: 0  Rows_sent: 80  Rows_examined: 415257
#

use strict;
use File::Tail;
use Proc::Daemon;

Proc::Daemon::Init;

my $debug = 0;

my $logfile = "/var/log/mysql/mysql-slow.log";
my $cronolog_logfile = "/var/log/mysql/cronolog/\%Y/\%m/\%d/mysql-slow.log";
my $error_logfile = "/var/log/mysql/mysql-slow-queries-logger.log";
my $cronolog = "/usr/bin/cronolog";

open(ERROR_LOG, ">> $error_logfile") || die "Impossible d'ouvrir $error_logfile";
ERROR_LOG->autoflush(1);

if (!open(CRONOLOG, "| $cronolog $cronolog_logfile")) {
	log_error("Impossible d'exécuter cronolog");
	exit(1);
}

my $ref = tie *LOG, "File::Tail", (name => $logfile, interval => 1, maxinterval => 5, resetafter => 10);

if (!$ref) {
	log_error("Impossible d'ouvrir $logfile");
	exit(1);
}

log_error(sprintf("Début %s", scalar localtime));

my $in_record = 0;

my ($slow_query_user, $slow_query_host, $slow_query_time);
my $timestamp;

while (<LOG>) {
    chomp;

    log_debug("");
    log_debug("Ligne examinée : \"$_\"") if $debug;

    if (! $in_record) {
        log_debug("in_record = 0") if $debug;
        # Si début d'un nouvel enregistrement
        # Time: 050902  6:26:05
        if (/#\s+Time:\s+\d+\s+(\d+:\d+:\d+)/) {
            $in_record = 1;
            $timestamp = $1;
            log_debug("in_record => 1, timestamp => $timestamp") if $debug;
        }
        else {
            log_debug("Format inattendu OK (in_record = 0)") if $debug;
        }
    }
    # Sinon, on est au milieu d'un enregistrement
    else {
        log_debug("in_record = 1") if $debug;

        # User@Host: gsauvanet2[gsauvanet2] @ bizmachine9.co.fr.clara.net [212.43.241.154]
        if (/^#\s+User\@Host:\s+(\S+)\[\S+\]\s*@\s*(\S+)/) {
            $slow_query_user = $1;
            $slow_query_host = $2;
            log_debug("user = $slow_query_user, host = $slow_query_host") if $debug;
        }

        # Query_time: 13  Lock_time: 0  Rows_sent: 80  Rows_examined: 415257
        elsif (/^#\s+Query_time:\s+(\d+)/) {
            $slow_query_time = $1;
            log_debug("slow_query_time = $slow_query_time") if $debug;
        }

        # On a dû récupéré toutes les infos
        elsif (defined($timestamp) && defined($slow_query_user) &&
                            defined($slow_query_host) && defined($slow_query_time)) {
            log_print("$timestamp $slow_query_user $slow_query_host $slow_query_time");
            log_debug("Log : $timestamp $slow_query_user $slow_query_host $slow_query_time");
            $timestamp = $slow_query_user = $slow_query_host = $slow_query_time = undef;
            $in_record = 0;
            log_debug("in_record = 0");
        }

        else {
            log_error("Problème lecture du log, ligne \"$_\"");
            # On se replace dans les conditions initiales
            $slow_query_user = $slow_query_host = $slow_query_time = undef;
            $in_record = 0;
        }
    }
}

sub log_error {
	my $message = shift;
	print ERROR_LOG "$message\n";
}

sub log_debug {
	my $message = shift;
	print "$message\n";
}

sub log_print {
	my $message = shift;
	print CRONOLOG $message;
	print CRONOLOG "\n";
}
