#! /bin/sh -e

# $Id: lr_log2report.in,v 1.66 2002/01/20 22:03:17 flacoste Exp $

#
# Copyright (C) 2000-2001 Stichting LogReport Foundation LogReport@LogReport.org
# 
#     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.
# 
#     You should have received a copy of the GNU General Public License
#     along with this program (see COPYING); if not, check with
#     http://www.gnu.org/copyleft/gpl.html or write to the Free Software 
#     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
#

PROGRAM=lr_log2report

# dereference sysconfdir's prefix dependency
prefix="/usr"
etcdir="/etc/lire"

. $etcdir/profile_lean

# an id which could be used to identify the source of the logfile, e.g.
# by setting it in the subject of the email containing a logfile
test -z "$LR_EXTID" && LR_EXTID='localhost'
export LR_EXTID

test -z "$LR_ID" && LR_ID=`lr_tag`
export LR_ID
tag="all all $LR_ID $PROGRAM"

echo >&2 "$tag info started with $*"

# max value for error lines / log lines.
# When there is more then 5% error rate, we suspect there is a bogus log file
MAXERRORRATE="0.05"

# get options (x)
OUTPUTFORMAT=""
while getopts :o:ih\? o; do
    case $o in
        o)  OUTPUTFORMAT=$OPTARG
            ;;
	i)
	    include_image=1
	    ;;
        h | "?")
            echo >&2 "$tag notice usage [-i] [-o <outputformat>] errorfile superservice service [flags...]"
            exit 0
            ;;
        *)
            echo >&2 "$tag err usage [-i] [-o <outputformat>] errorfile superservice service [flags...]"
            exit 1
            ;;
    esac
done

# yes, the '|| true' is needed. solaris' /bin/sh feels it should bawl out when
# encountering an 'expr 1 - 1', while running -e
shift `expr $OPTIND - 1 || true`

if test $# -lt 3
then
    echo >&2 "$tag err usage [-i] [-o <outputformat>] errorfile superservice service [flags...]"
    exit 1
fi

ERRFILE="$1"; shift

# e.g. www
SUPERSERVICE="$1"; shift

# e.g. apache
SERVICE="$1"; shift
FLAGS="$@"

tag="$SUPERSERVICE $SERVICE $LR_ID $PROGRAM"

# source these ones (again), using SERVICE and SUPERSERVICE
. $etcdir/defaults
. $etcdir/profile_lean

if test -z "$OUTPUTFORMAT"
then
    OUTPUTFORMAT="$DEFAULT_OUTPUT_FORMAT"
fi

# INCLUDEIMAGES only turn on images for supported format
if test -n "$INCLUDEIMAGES"
then
    case $OUTPUTFORMAT in
    pdf|html|docbookx|xhtml|rtf)
	image_flag="-i"
	;;
    *)
	;;
    esac
else
    if test -n "$include_image"
    then
	image_flag="-i"
    else
	image_flag=""
    fi
fi

# do a test for support before possibly unnecessary log file analysis
case $OUTPUTFORMAT in
    xml|txt|pdf|html|docbookx|xhtml|rtf)
        ;;
    logml)
        case $SUPERSERVICE in
        www|email)
	    ;;
        *)
	    echo >&2 "$tag err format logml can only be used for the www and email superservice"
	    exit 1
        esac
        ;;
    *)
        echo >&2 "$tag err format $OUTPUTFORMAT is not supported"
        exit 1
        ;;
esac
lr_check_prereq $image_flag $OUTPUTFORMAT || exit 1

echo >&2 "$tag info output format $OUTPUTFORMAT"

if touch $ERRFILE 2>/dev/null
then
    # creation of errorfile indicates an error. we shouldn't create it now.
    rm $ERRFILE
else
    echo >&2 "$tag err cannot touch errorfile $ERRFILE, exiting"
    exit 1
fi

if test ! -d "$TMPDIR"
then
    echo >&2 "$tag notice dir $TMPDIR does not exist, creating it"
    if mkdir $TMPDIR
    then
        :
    else
        echo >&2 "$tag err cannot create $TMPDIR, exiting"
        exit 1
    fi
fi

LOGFILE=$TMPDIR/$PROGRAM.$SERVICE.$LR_ID.log

cat > $LOGFILE

echo >&2 "$tag info gonna run lr_log2xml $SUPERSERVICE $SERVICE $FLAGS"

XMLREPORTFILE=$TMPDIR/$PROGRAM.$SERVICE.$LR_ID.report.xml

if lr_log2xml $SUPERSERVICE $SERVICE $FLAGS < $LOGFILE > $XMLREPORTFILE
then
    :
else
    echo >&2 "$tag err lr_log2xml $SUPERSERVICE $SERVICE $FLAGS failed"
    echo >&2 "$tag notice keeping $XMLREPORTFILE for debug"
    echo >&2 "$tag notice you might like to inspect and clean up the Lire database in $LR_DBFILE"
    rm -f $LOGFILE
    { cat <<EOT
FATAL ERROR: We failed to generate a report from your log file.

This is probably because your log file isn't a $SERVICE log file.
Please verify that your submitted log file is a valid $SERVICE log
file.

This error could also be caused by an encoding problem caused by your
mailer. Some mailers are known to wrap long lines by inserting newline
characters. This breaks our log parser. Compressing the log file using
zip or gzip and sending it as a regular MIME attachment can help
prevent this behavior.

Contact the administrator of this responder for more help.

EOT
} > $ERRFILE
    exit 1
fi

tmpfile=$TMPDIR/$PROGRAM.$SERVICE.$LR_ID.lines
if lr_db_fetch $LR_ID errorlines > $tmpfile
then
    ERRORLINES=`cat $tmpfile`
    rm $tmpfile
else
    echo >&2 "$tag crit lr_db_fetch $LR_ID errorlines failed, exiting"
    echo >&2 "$tag notice keeping $tmpfile for debug"
    exit 1
fi
if lr_db_fetch $LR_ID dlflines > $tmpfile
then
    DLFLINES=`cat $tmpfile`
    rm $tmpfile
else
    echo >&2 "$tag crit lr_db_fetch $LR_ID dlflines failed, exiting"
    echo >&2 "$tag notice keeping $tmpfile for debug"
    exit 1
fi
if lr_db_fetch $LR_ID loglines > $tmpfile
then
    LOGLINES=`cat $tmpfile`
    rm $tmpfile
else
    echo >&2 "$tag crit lr_db_fetch $LR_ID loglines failed, exiting"
    echo >&2 "$tag notice keeping $tmpfile for debug"
    exit 1
fi

if test -z "$ARCHIVE"
then
    # we can purge loglines, dlflines and errorlines from the archive now, 
    # we're the only using it
    if lr_db_purge $LR_ID dlflines $DLFLINES
    then
        :
    else
        echo >&2 "$tag crit lr_db_purge $LR_ID dlflines $DLFLINES failed, exiting"
        echo >&2 "$tag notice keeping $tmpfile for debug"
        exit 1
    fi
    if lr_db_purge $LR_ID errorlines $ERRORLINES
    then
        :
    else
        echo >&2 "$tag crit lr_db_purge $LR_ID errorlines $ERRORLINES failed, exiting"
        echo >&2 "$tag notice keeping $tmpfile for debug"
        exit 1
    fi
    if lr_db_purge $LR_ID loglines $LOGLINES
    then
        :
    else
        echo >&2 "$tag crit lr_db_purge $LR_ID loglines $LOGLINES failed, exiting"
        echo >&2 "$tag notice keeping $tmpfile for debug"
        exit 1
    fi
fi

if test 0 -lt "$LOGLINES"
then
    OK=`/usr/bin/perl -e "print \"1\\n\" if $ERRORLINES / $LOGLINES < $MAXERRORRATE"`
else
    # Empty log file, this is not an error 
    OK=1
fi

if test 1 != "$OK"
then
    echo >&2 "$tag warning probably bogus log: $LOGLINES lines in log, while found $ERRORLINES lines with errors"

    { cat <<EOT
WARNING: Logfile may be bogus. $ERRORLINES lines on the $LOGLINES lines in the
log had errors.

This may be because you sent a log file that doesn't strictly contain
$SERVICE logs. This is probable if you sent a syslog log file without
filtering it to keep only the logs relevant to the $SERVICE service.

It could also be because you sent a log file in the wrong format or
a file that isn't a $SERVICE log file.

A report was generated for the $DLFLINES lines that could be extracted
from your log file.

EOT
} > $ERRFILE

fi

case $OUTPUTFORMAT in
    xml) 
        echo >&2 "$tag info generating raw XML output, not doing lr_xml2ascii"
        cat $XMLREPORTFILE
        ;;
    txt)
        OK=
        echo >&2 "$tag info gonna run lr_xml2ascii on $XMLREPORTFILE"
        lr_xml2ascii < $XMLREPORTFILE && OK=1

        if test -n "$OK"
        then
            echo >&2 "$tag info succeeded in generating ascii"
        else
            echo >&2 "$tag err lr_xml2ascii failed"
            { cat <<EOT
Could not generate an ascii report from your log file.
EOT
} >> $ERRFILE
            echo >&2 "$tag notice keeping $XMLREPORTFILE for debugging."
            exit 1
        fi
        echo >&2 "$tag info lr_xml2ascii finished"
        ;;
    html)
        OK=
	lr_xml2html $image_flag $XMLREPORTFILE && OK=1

        if test -n "$OK"
        then
            echo >&2 "$tag info succeeded in generating HTML"
        else
            echo >&2 "$tag err lr_xml2html failed"
            { cat <<EOT
Could not generate an html report from your log file.
EOT
} >> $ERRFILE
            echo >&2 "$tag notice keeping $XMLREPORTFILE for debugging."
            exit 1
        fi
        echo >&2 "$tag info lr_xml2html finished"
        ;;
    rtf)
        OK=
	lr_xml2rtf $image_flag $XMLREPORTFILE && OK=1

        if test -n "$OK"
        then
            echo >&2 "$tag info succeeded in generating RTF"
        else
            echo >&2 "$tag err lr_xml2rtf failed"
            { cat <<EOT
Could not generate an RTF report from your log file.
EOT
} >> $ERRFILE
            echo >&2 "$tag notice keeping $XMLREPORTFILE for debugging."
            exit 1
        fi
        echo >&2 "$tag info lr_xml2rtf finished"
        ;;
    pdf)
        OK=
        lr_xml2pdf $image_flag $XMLREPORTFILE && OK=1

        if test -n "$OK"
        then
            echo >&2 "$tag info succeeded in generating PDF"
        else
            echo >&2 "$tag err lr_xml2pdf failed"
            { cat <<EOT
Could not generate a PDF report from your log file.
EOT
} >> $ERRFILE
            echo >&2 "$tag notice keeping $XMLREPORTFILE for debugging."
            exit 1
        fi
        echo >&2 "$tag info lr_xml2pdf finished"
        ;;
    docbookx)
        OK=
        lr_xml2dbx $image_flag $XMLREPORTFILE && OK=1

        if test -n "$OK"
        then
            echo >&2 "$tag info succeeded in generating DocBook XML"
        else
            echo >&2 "$tag err lr_xml2dbx failed"
            { cat <<EOT
Could not generate a DocBook XML report from your log file.
EOT
} >> $ERRFILE
            echo >&2 "$tag notice keeping $XMLREPORTFILE for debugging."
            exit 1
        fi
        echo >&2 "$tag info lr_xml2dbx finished"
        ;;
    logml)
        OK=
        lr_xml2logml $XMLREPORTFILE && OK=1

        if test -n "$OK"
        then
            echo >&2 "$tag info succeeded in generating LogML"
        else
            echo >&2 "$tag err lr_xml2logml failed"
            { cat <<EOT
Could not generate a LogML report from your log file.
EOT
} >> $ERRFILE
            echo >&2 "$tag notice keeping $XMLREPORTFILE for debugging."
            exit 1
        fi
        echo >&2 "$tag info lr_xml2logml finished"
        ;;
    xhtml)
        OK=
        lr_xml2xhtml $image_flag $XMLREPORTFILE && OK=1

        if test -n "$OK"
        then
            echo >&2 "$tag info succeeded in generating XHTML"
        else
            echo >&2 "$tag err lr_xml2xhtml failed"
            { cat <<EOT
Could not generate an xhtml report from your log file.
EOT
} >> $ERRFILE
            echo >&2 "$tag notice keeping $XMLREPORTFILE for debugging."
            exit 1
        fi
        echo >&2 "$tag info lr_xml2xhtml finished"
        ;;
    *)
        echo >&2 "$tag err format $OUTPUTFORMAT is not supported"
        exit 1
        ;;
esac


if test -n "$ARCHIVE"
then
    TMPFILE=$TMPDIR/$PROGRAM.$SERVICE.$LR_ID.$$.time_span
    if lr_db_fetch $LR_ID time_span > $TMPFILE
    then
        echo >&2 "$tag info lr_db_fetch $LR_ID timespan succeeded"
        LR_TIME=`cat $TMPFILE`
        rm $TMPFILE
    else
        echo >&2 "$tag crit lr_db_fetch $LR_ID timespan failed, exiting"
        echo >&2 "$tag notice keeping $TMPFILE for debugging"
        exit 1
    fi

    ARCHIVEDIR=$LR_ARCHIVEDIR/report/xml/$SUPERSERVICE/complete/$LR_EXTID
    ARCHIVEFILE=$ARCHIVEDIR/$LR_TIME

    LOGARCHIVEDIR=$LR_ARCHIVEDIR/log/raw/$SUPERSERVICE/complete/$LR_EXTID
    LOGARCHIVEFILE=$LOGARCHIVEDIR/$LR_TIME

    echo >&2 "$tag notice storing $XMLREPORTFILE in $ARCHIVEFILE"
    echo >&2 "$tag notice storing $LOGFILE in $LOGARCHIVEFILE"
    test -d $ARCHIVEDIR || mkdir -p $ARCHIVEDIR
    test -d $LOGARCHIVEDIR || mkdir -p $LOGARCHIVEDIR
    mv $XMLREPORTFILE $ARCHIVEFILE
    mv $LOGFILE $LOGARCHIVEFILE
elif test -n "$KEEP"
then
    echo >&2 "$tag notice keeping $XMLREPORTFILE on your request. remove manually."
    echo >&2 "$tag notice keeping $LOGFILE on your request. remove manually."
else
    rm $XMLREPORTFILE
    rm $LOGFILE
fi

# TODO : we should run lr_db_purge, to purge all data now obsoleted...
# or periodically run separate lr_maintenance script?

echo >&2 "$tag info stopped"


