Version 0.2.2.
Remove -g option as it was broken and would never work. Open and read from file descriptor for input rather than keep accessing a file. Re-worked code around the user changing facility - it now actually works \o/. Minor tweeks to the help text.
This commit is contained in:
parent
8bf8462b1d
commit
1adf0ee2b9
1 changed files with 22 additions and 43 deletions
65
lumberjack
65
lumberjack
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
# Script details.
|
# Script details.
|
||||||
NAME="${0##*/}"
|
NAME="${0##*/}"
|
||||||
VERSION="0.2.1"
|
VERSION="0.2.2"
|
||||||
|
|
||||||
|
|
||||||
# Functions.
|
# Functions.
|
||||||
|
|
@ -86,12 +86,6 @@ display_help() {
|
||||||
-f Request flushing of the log file to disk after every write.
|
-f Request flushing of the log file to disk after every write.
|
||||||
This may significantly reduce performance and result in a lot of
|
This may significantly reduce performance and result in a lot of
|
||||||
disk writes. Best to let the kernel do appropriate buffering.
|
disk writes. Best to let the kernel do appropriate buffering.
|
||||||
-g <group> Set name of the group to run with. Override the usual
|
|
||||||
behaviour of using the primary group membership of the user
|
|
||||||
specified with -u and run with this GID. Log files created by
|
|
||||||
lumberjack will be owned by this group. The default is to run
|
|
||||||
with the primary group that executed lumberjack, which is
|
|
||||||
usually root. This option is only available to root.
|
|
||||||
-h Display this help.
|
-h Display this help.
|
||||||
-i <pipe> Read input from the pipe/FIFO at <pipe>, rather than stdin.
|
-i <pipe> Read input from the pipe/FIFO at <pipe>, rather than stdin.
|
||||||
If the pipe/FIFO does not exist, it will be created. Use '-o'
|
If the pipe/FIFO does not exist, it will be created. Use '-o'
|
||||||
|
|
@ -112,7 +106,7 @@ display_help() {
|
||||||
-mp <umask> Set the umask used when creating the pipe. Default: $PIPE_UMASK.
|
-mp <umask> Set the umask used when creating the pipe. Default: $PIPE_UMASK.
|
||||||
Useful umasks are: 066 and 006.
|
Useful umasks are: 066 and 006.
|
||||||
-o <owner> Set the owner of the pipe/FIFO automatically created if none
|
-o <owner> Set the owner of the pipe/FIFO automatically created if none
|
||||||
already exists, and -i is used. The <owner> should be in the
|
already exists, and '-i' is used. The <owner> should be in the
|
||||||
format [user]:[group], where [user] or [group] is optional, but
|
format [user]:[group], where [user] or [group] is optional, but
|
||||||
not both. The ownership is changed before any user or group
|
not both. The ownership is changed before any user or group
|
||||||
switching is performed. This option is only available to root.
|
switching is performed. This option is only available to root.
|
||||||
|
|
@ -130,12 +124,11 @@ display_help() {
|
||||||
<basedir> and <template>.
|
<basedir> and <template>.
|
||||||
-s <facility> Set the syslog facility to be used for logging. Default: $SYSLOG_FACILITY.
|
-s <facility> Set the syslog facility to be used for logging. Default: $SYSLOG_FACILITY.
|
||||||
-u <user> Set name of the user to run with. With this option, as soon as
|
-u <user> Set name of the user to run with. With this option, as soon as
|
||||||
lumberjack starts it will re-exec itself, running as this user.
|
$NAME starts it will re-exec itself to run as this user.
|
||||||
Without the -g option, the primary group of <user> is used for
|
Log files created by $NAME will be owned by this user and
|
||||||
the running GID. Log files created by lumberjack will be owned
|
its primary group. The default is to run as the user that
|
||||||
by this user. The default is to run as the user that executed
|
executed $NAME, which is usually root. This option is
|
||||||
lumberjack, which is usually root. This option is only
|
only available to root.
|
||||||
available to root.
|
|
||||||
-v Display version and copyright information.
|
-v Display version and copyright information.
|
||||||
-z Enable compression of the old log files.
|
-z Enable compression of the old log files.
|
||||||
-- Cease option processing and begin argument parsing.
|
-- Cease option processing and begin argument parsing.
|
||||||
|
|
@ -151,8 +144,8 @@ display_help() {
|
||||||
template may also include any %-prefixed format strings
|
template may also include any %-prefixed format strings
|
||||||
recognised by the strftime(3) function. See below for examples.
|
recognised by the strftime(3) function. See below for examples.
|
||||||
The template can not start with a / - it is relative to the
|
The template can not start with a / - it is relative to the
|
||||||
<basedir>. Unless the -p option is used, all directories up to
|
<basedir>. Unless the '-p' option is used, all directories up
|
||||||
- but not including - the first directory with non-escaped
|
to - but not including - the first directory with non-escaped
|
||||||
%-format strings of the <template> must already exist for the
|
%-format strings of the <template> must already exist for the
|
||||||
log lines to be written to the file.
|
log lines to be written to the file.
|
||||||
|
|
||||||
|
|
@ -190,6 +183,8 @@ EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
exit_handler() {
|
exit_handler() {
|
||||||
|
(( INPUTFD != 0 )) && { exec {INPUTFD}>&-; } 2>/dev/null
|
||||||
|
|
||||||
(( FLAGS[created-fifo] == 1 )) && {
|
(( FLAGS[created-fifo] == 1 )) && {
|
||||||
rm -f "$INPUT" 2>/dev/null || syslog "warn" "failed to remove pipe/fifo: $INPUT"
|
rm -f "$INPUT" 2>/dev/null || syslog "warn" "failed to remove pipe/fifo: $INPUT"
|
||||||
}
|
}
|
||||||
|
|
@ -341,7 +336,8 @@ ORIG_ARGS=()
|
||||||
# Some detaults.
|
# Some detaults.
|
||||||
COMPRESSOR_ARGS=( "-9" )
|
COMPRESSOR_ARGS=( "-9" )
|
||||||
COMPRESSOR="gzip" # Use gzip by default as log processing utils can often natively read gzipped files.
|
COMPRESSOR="gzip" # Use gzip by default as log processing utils can often natively read gzipped files.
|
||||||
INPUT="/dev/stdin"
|
INPUT=""
|
||||||
|
INPUTFD="0"
|
||||||
MAXJOBS="4"
|
MAXJOBS="4"
|
||||||
LINKFILE=""
|
LINKFILE=""
|
||||||
DIR_UMASK="022"
|
DIR_UMASK="022"
|
||||||
|
|
@ -350,7 +346,6 @@ PIPE_UMASK="066"
|
||||||
PIPE_OWNER=""
|
PIPE_OWNER=""
|
||||||
SYSLOG_FACILITY="user"
|
SYSLOG_FACILITY="user"
|
||||||
RUNAS_USER=""
|
RUNAS_USER=""
|
||||||
RUNAS_GROUP=""
|
|
||||||
FLAGS=([flush]=0 [raw]=0 [compress]=0 [make-parents]=0 [created-fifo]=0 [timed-out]=0 [basedir-vanished]=0 [basedir-notdir]=0)
|
FLAGS=([flush]=0 [raw]=0 [compress]=0 [make-parents]=0 [created-fifo]=0 [timed-out]=0 [basedir-vanished]=0 [basedir-notdir]=0)
|
||||||
|
|
||||||
# trap signals.
|
# trap signals.
|
||||||
|
|
@ -387,14 +382,6 @@ while :; do
|
||||||
shift
|
shift
|
||||||
continue
|
continue
|
||||||
;;
|
;;
|
||||||
-g)
|
|
||||||
# Set the group to run as.
|
|
||||||
(( UID != 0 )) && die "only root can use -g"
|
|
||||||
getent group "$2" >/dev/null 2>&1 || die "invalid group given for -g: $2"
|
|
||||||
RUNAS_GROUP="$2"
|
|
||||||
shift 2
|
|
||||||
continue
|
|
||||||
;;
|
|
||||||
-h|-help|--help)
|
-h|-help|--help)
|
||||||
# Show the help screen and exit.
|
# Show the help screen and exit.
|
||||||
display_help
|
display_help
|
||||||
|
|
@ -534,7 +521,7 @@ TEMPLATE="$2"
|
||||||
[[ "${BASEDIR:0:1}" != "/" ]] && die "must be an absolute path: $BASEDIR"
|
[[ "${BASEDIR:0:1}" != "/" ]] && die "must be an absolute path: $BASEDIR"
|
||||||
[[ ! -e "$BASEDIR" ]] && die "base directory does not exist: $BASEDIR"
|
[[ ! -e "$BASEDIR" ]] && die "base directory does not exist: $BASEDIR"
|
||||||
[[ ! -d "$BASEDIR" ]] && die "not a directory: $BASEDIR"
|
[[ ! -d "$BASEDIR" ]] && die "not a directory: $BASEDIR"
|
||||||
[[ ! -w "$BASEDIR" ]] && die "no write permission: $BASEDIR"
|
(( "${FLAGS[make-parents]}" == 1 )) && [[ ! -w "$BASEDIR" ]] && die "no write permission: $BASEDIR"
|
||||||
[[ "${TEMPLATE: 0:1}" == "/" ]] && die "template cannot start with '/' - must be a relative path: $TEMPLATE"
|
[[ "${TEMPLATE: 0:1}" == "/" ]] && die "template cannot start with '/' - must be a relative path: $TEMPLATE"
|
||||||
[[ "${TEMPLATE: -1:1}" == "/" ]] && die "template cannot end with '/' - path must be a filename: $TEMPLATE"
|
[[ "${TEMPLATE: -1:1}" == "/" ]] && die "template cannot end with '/' - path must be a filename: $TEMPLATE"
|
||||||
(( FLAGS[raw] == 0 )) && [[ ! "$TEMPLATE" =~ .*\{\} ]] && die "template must include at least one '{}': $TEMPLATE"
|
(( FLAGS[raw] == 0 )) && [[ ! "$TEMPLATE" =~ .*\{\} ]] && die "template must include at least one '{}': $TEMPLATE"
|
||||||
|
|
@ -542,7 +529,7 @@ TEMPLATE="$2"
|
||||||
(( FLAGS[raw] != 0 )) && [[ "$LINKFILE" =~ .*\{\} ]] && die "link name cannot include '{}': $LINKFILE"
|
(( FLAGS[raw] != 0 )) && [[ "$LINKFILE" =~ .*\{\} ]] && die "link name cannot include '{}': $LINKFILE"
|
||||||
|
|
||||||
# If input is to be a pipe/FIFO, create it if necessary.
|
# If input is to be a pipe/FIFO, create it if necessary.
|
||||||
[[ "$INPUT" != "/dev/stdin" ]] && {
|
[[ -n "$INPUT" ]] && {
|
||||||
if [[ ! -e "$INPUT" ]]; then
|
if [[ ! -e "$INPUT" ]]; then
|
||||||
umask "$PIPE_UMASK"
|
umask "$PIPE_UMASK"
|
||||||
mkfifo "$INPUT" 2>/dev/null || die "failed to create pipe/FIFO: $INPUT"
|
mkfifo "$INPUT" 2>/dev/null || die "failed to create pipe/FIFO: $INPUT"
|
||||||
|
|
@ -553,20 +540,12 @@ TEMPLATE="$2"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Apply user and group settings.
|
# Apply user and setting.
|
||||||
# shellcheck disable=SC2093
|
# shellcheck disable=SC2093
|
||||||
if [[ -n "$RUNAS_USER" ]]; then
|
[[ -n "$RUNAS_USER" ]] && { exec -a "su" /bin/su - "$RUNAS_USER" -- "$0" "${ORIG_ARGS[@]}" "$BASEDIR" "$TEMPLATE" || die "failed to exec to change user"; }
|
||||||
if [[ -n "$RUNAS_GROUP" ]]; then
|
|
||||||
exec su -g "$RUNAS_GROUP" -- "$RUNAS_USER" "$0" "${ORIG_ARGS[@]}" "$BASEDIR" "$TEMPLATE"
|
# If input is to be a pipe/FIFO, open it.
|
||||||
die "failed to exec to change user and group"
|
[[ -n "$INPUT" ]] && { exec {INPUTFD}<"$INPUT" || die "failed to open pipe/FIFO for reading: $INPUT"; }
|
||||||
else
|
|
||||||
exec su -- "$RUNAS_USER" "$@" "${ORIG_ARGS[@]}" "$BASEDIR" "$TEMPLATE"
|
|
||||||
die "failed to exec to change user"
|
|
||||||
fi
|
|
||||||
elif [[ -n "$RUNAS_GROUP" ]]; then
|
|
||||||
exec sg -- "$RUNAS_GROUP" "$0" "${ORIG_ARGS[@]}"
|
|
||||||
die "failed to exec to change group"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Main loop
|
# Main loop
|
||||||
while :; do
|
while :; do
|
||||||
|
|
@ -587,7 +566,7 @@ while :; do
|
||||||
# Note: The $(...) expansion should *not* be quoted in this instance, and the space between
|
# Note: The $(...) expansion should *not* be quoted in this instance, and the space between
|
||||||
# $( and (( is necessary to quiet shellcheck.
|
# $( and (( is necessary to quiet shellcheck.
|
||||||
# shellcheck disable=SC2046
|
# shellcheck disable=SC2046
|
||||||
read -r -t "$TTNM" $( (( FLAGS[raw] == 0 )) && printf "%s" "LOG_VHOST") LOG_DATA <"$INPUT"
|
read -r -t "$TTNM" -u "$INPUTFD" $( (( FLAGS[raw] == 0 )) && printf "%s" "LOG_VHOST") LOG_DATA
|
||||||
ERR="$?"
|
ERR="$?"
|
||||||
|
|
||||||
# Determine how the read above was exited.
|
# Determine how the read above was exited.
|
||||||
|
|
@ -595,7 +574,7 @@ while :; do
|
||||||
# If 'read' timed out, set a marker.
|
# If 'read' timed out, set a marker.
|
||||||
FLAGS[timed-out]=1
|
FLAGS[timed-out]=1
|
||||||
elif (( ERR == 1 )); then
|
elif (( ERR == 1 )); then
|
||||||
[[ "$INPUT" == "/dev/stdin" ]] && {
|
(( INPUTFD == 0 )) && {
|
||||||
# stdin has been closed by the parent, quit gracefully by raising a SIGTERM.
|
# stdin has been closed by the parent, quit gracefully by raising a SIGTERM.
|
||||||
kill -TERM "$$"
|
kill -TERM "$$"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue