zeek/auxil/zeekctl/bin/archive-log
Patrick Kelley 8fd444092b initial
2025-05-07 15:35:15 -04:00

160 lines
4.7 KiB
Bash
Executable File

#! /usr/bin/env bash
#
# Zeek postprocessor script to archive log files.
#
# archive-log <file_name> <base_name> <timestamp-when-opened> <timestamp-when-closed> <terminating> <writer>
#
# file_name: the rotated log filename that we need to archive (the filename
# format doesn't really matter).
# base_name: base name of the log (e.g. "conn").
# timestamp-when-opened: timestamp when log file was created (must be in the
# format YY-MM-DD_HH.MM.SS).
# timestamp-when-closed: timestamp when log file was finished (must be in the
# format YY-MM-DD_HH.MM.SS).
# terminating: 0 during normal log rotation, or 1 if Zeek is shutting down.
# writer: a string indicating the log writer type, such as "ascii".
#
# Example:
# archive-log conn.2015-01-20-15-23-42.log conn 15-01-20_15.23.42 15-01-20_16.00.00 0 ascii
# Create a PID file so that the post-terminate script knows when we're done.
echo $$ > .archive-log.running.$$.tmp
sig_handler()
{
rm .archive-log.running.$$.tmp
}
# Make sure PID file is removed upon exit from this script
trap sig_handler 0
# This timestamp will be used by the post-terminate script to give a start time
# to archive-log.
now=`date +%y-%m-%d_%H.%M.%S`
. `dirname $0`/zeekctl-config.sh
# Make sure all parameters are supplied.
if [ $# -ne 6 ]; then
echo "Error: incorrect number of arguments provided.
archive-log:
Zeek postprocessor script to archive log files.
Usage:
$ archive-log file_name base_name start_timestamp end_timestamp terminating writer
file_name: the rotated log filename that we need to archive
base_name: base name of the log (e.g. 'conn').
start_timestamp: timestamp when log file was created (format YY-MM-DD_HH.MM.SS).
end_timestamp: timestamp when log file was finished (format YY-MM-DD_HH.MM.SS).
terminating: 0 during normal log rotation, or 1 if Zeek is shutting down.
writer: a string indicating the log writer type, such as 'ascii'.
Example:
$ archive-log conn.2015-01-20-15-23-42.log conn 15-01-20_15.23.42 15-01-20_16.00.00 0 ascii"
exit 1
fi
file_name=$1
base_name=$2
from=$3
to=$4
terminating=$5
writer=$6
# Verify if the given timestamp is in the correct format (YY-MM-DD_HH.MM.SS).
check_timestamp() {
res=`echo $2 | sed 's/[0-9][0-9]-[0-1][0-9]-[0-3][0-9]_[0-2][0-9][.][0-5][0-9][.][0-5][0-9]/VALID/'`
if [ "$res" != "VALID" ]; then
echo "archive-log: $1 time must be in format YY-MM-DD_HH.MM.SS: $2" >&2
exit 1
fi
}
check_timestamp start $from
check_timestamp end $to
# Convert timestamp format from YY-MM-DD_HH.MM.SS to YYYY-MM-DD-HH-MM-SS
century=`date +%C`
from=`echo $century$from | sed 's/[_.]/-/g'`
to=`echo $century$to | sed 's/[_.]/-/g'`
# Extract file extension from filename
gzipped=0
ext=`echo $file_name | sed 's/^.*\.//'`
if [ "$ext" = "gz" ]; then
# Log file is compressed, so get file extension before the ".gz" extension
gzipped=1
fname=${file_name%.$ext}
ext=`echo $fname | sed 's/^.*\.//'`
fi
if [ ! -f "${makearchivename}" ]; then
echo "archive-log: zeekctl option makearchivename is not set correctly" >&2
exit 1
fi
# Compute the archived log filename
dest=`"${makearchivename}" $base_name.$ext $writer $from $to`
if [ -z "$dest" ]; then
echo "archive-log: ${makearchivename} did not return a file name" >&2
exit 1
fi
# If log is compressed, then preserve the ".gz" extension.
if [ $gzipped -ne 0 ]; then
dest=$dest.gz
fi
# If $dest is a relative path, then add ${logdir}
echo $dest | grep -q '^/'
if [ $? -ne 0 ]; then
if [ -z "${logdir}" ]; then
echo "archive-log: zeekctl option logdir is not set" >&2
exit 1
fi
dest="${logdir}/$dest"
fi
dest_dir=`dirname "$dest"`
mkdir -p "$dest_dir" # Makes sure all parent directories exist.
if [ $? -ne 0 ]; then
echo "archive-log: failed to create log archive directory: $dest_dir" >&2
exit 1
fi
# Record time of last rotation (the post-terminate script passes this to
# archive-log when Zeek crashes, so it must be in the format that archive-log
# expects).
echo $now > .rotated.$base_name
# Run other postprocessors.
if [ -d "${postprocdir}" ]; then
for pp in "${postprocdir}"/*; do
nice "$pp" $@
done
fi
# Test if the log still exists in case one of the postprocessors archived it.
if [ ! -f $file_name ]; then
exit 0
fi
if [ "${compresslogsinflight}" = "0" ] && [ "${compresslogs}" = "1" ] && [ -n "${compresscmd}" ] && [ $gzipped -eq 0 ]; then
dest="$dest.${compressextension}"
nice ${compresscmd} < $file_name > "$dest"
else
nice mv $file_name "$dest"
fi
if [ $? -ne 0 ]; then
echo "archive-log: possibly failed to archive log file $file_name to $dest" >&2
exit 1
fi
rm -f $file_name