diff --git a/files/usr/local/bin/logs-to-archive.sh b/files/usr/local/bin/logs-to-archive.sh new file mode 100644 index 0000000000000000000000000000000000000000..de3382e7eef533237f18f0a0775de0eeb35f9ce2 --- /dev/null +++ b/files/usr/local/bin/logs-to-archive.sh @@ -0,0 +1,130 @@ +#!/usr/bin/env bash + +### META +# AUTHORS: +# - Jörg Sachse (<Joerg.Sachse@slub-dresden.de>) + +#hh logs-to-archive.sh - moves old logs to logarchive directory +#hh +#hh Usage: logs-to-archive.sh [-h] [-V] [-m] [-M] +#hh +#hh Options: +#hh You can use the following CLI arguments to configure the behaviour of +#hh scriptname.sh. Please note that the CLI arguments need to be space +#hh separated. Combining arguments like "-cw" is currently NOT supported. +#hh +#hh -h, --help +#hh Show this help and exit. +#hh -V, --version +#hh Show version number and exit. +#hh -m, --man, --manpage, --manual +#hh Create a manpage from this help section and exit. +#hh Requires "help2man". +#hh -M, --showman +#hh Print the Manpage. +#hh Requires "help2man". +#hh +#hh Examples: +#hh scriptname.sh -flag What happens here? + + + +### DEFAULTS + +RED="\\e[31m" +WHITE="\\e[0m" +ERROR="${RED}[ERROR]\t${WHITE}" +# INFO="[INFO]\t" + + + +### INIT + +# SCRIPTPATH="$( dirname "$( realpath "$0" )" )" +# SCRIPTNAME="$( basename "${0}" )" + +# list external required binaries here (space separated) +REQUIREMENTS="help2man man gzip" +for REQUIREMENT in ${REQUIREMENTS}; do + command -v "${REQUIREMENT}" >/dev/null 2>&1 || { echo >&2 "${ERROR} '${REQUIREMENT}' required but not installed. Aborting."; exit 1; } +done + + + +### FUNCTIONS + +# Don't just call this function "help()", as that's a reserved command in Bash. +comment_help() { + sed -rn 's/^#hh ?//;T;p' "$0" +} + +create_manpage(){ + # https://www.gnu.org/software/help2man/ + help2man --section 1 --source="SLUB Dresden" --no-info "${0}" | gzip > ./"$( basename "${0}" ".sh" ).gz" +} + +show_manpage(){ + help2man --section 1 --source="SLUB Dresden" --no-info "${0}" | man -l - +} + +get_cli_args(){ + while [[ $# -gt 0 ]]; do + case ${1} in + -h|--help) + comment_help + exit 0 + ;; + -V|--version) + echo "$( basename "${0}" ) v1.0.0" + echo -e "\n\nCopyright (C)\n" + echo "This software is licensed under the GNU General Public License version 3 (GNU GPLv3)." + exit 0 + ;; + -m|--man|--manpage|--manual) + create_manpage + exit 0 + ;; + -M|--showman) + show_manpage + exit 0 + ;; + *) + echo "'${1}' is not a valid parameter. Please use '$( basename "${0}" ) --help'. Exiting." + exit 1 + ;; + esac + done +} + + + +### MAIN + +get_cli_args "${@}" + +LOGDIR="/operational_shared/logs/" +if [[ -d "${LOGDIR}/${HOSTNAME}/" ]]; then + cd "${LOGDIR}/${HOSTNAME}/" || exit 1 +else + cd "${LOGDIR}/${HOSTNAME}.$( dnsdomainname )/" || exit 1 +fi +LOGARCHIVE_BASE="$( pwd )/log_archive/" + +read -r CURRENT_YEAR CURRENT_MONTH <<< "$( IFS=" " date '+%Y %m' )" + +for LOGFILE in *; do + read -r YEAR MONTH <<< "$( IFS=" " echo "${LOGFILE}" | sed -r -n "s/(cantaloupe_access-|cantaloupe_application-|gc\.log\.|server\.log\.|solr\.log\.)(20..)-(..)-...*/\2 \3/p" )"; + if [[ ! -d "${LOGARCHIVE_BASE}/${YEAR}/${MONTH}/" ]]; then mkdir -p "${LOGARCHIVE_BASE}/${YEAR}/${MONTH}/"; fi + if [[ ( $((YEAR)) -ne $((CURRENT_YEAR)) ) || \ + (( $((YEAR)) -eq $((CURRENT_YEAR)) ) && ( 10#${MONTH} -lt 10#${CURRENT_MONTH} )) ]]; \ + then + if [[ (-f "${LOGFILE}") && $(echo "${LOGFILE}" | grep -e "${YEAR}-${MONTH}-") ]]; then + mv "${LOGFILE}" "${LOGARCHIVE_BASE}/${YEAR}/${MONTH}/" + fi + fi +done + + +exit 0 + + diff --git a/files/usr/local/lib/systemd/system/logs-to-archive.service b/files/usr/local/lib/systemd/system/logs-to-archive.service new file mode 100644 index 0000000000000000000000000000000000000000..b34ea3a19d0351d2e179cb82547e3dda215f0e27 --- /dev/null +++ b/files/usr/local/lib/systemd/system/logs-to-archive.service @@ -0,0 +1,34 @@ +[Unit] +Description=Cleanup Daemon for Rosetta logs. This will move older Rosetta logs to the log archive that is divided into dated subdirectories. +After=network.target + +[Service] +ExecStart=/usr/local/bin/logs-to-archive.sh +ExecReload=/bin/kill -HUP $MAINPID +KillMode=process +Restart=on-failure +Type=simple + +### Security features +# documented at https://www.freedesktop.org/software/systemd/man/systemd.exec.html +#ProtectSystem=strict +#ProtectHome=read-only +#ProtectHostname=true +#ProtectClock=true +#ProtectKernelTunables=true +#ProtectKernelModules=true +#ProtectKernelLogs=true +#ProtectControlGroups=true +#LockPersonality=true +#MemoryDenyWriteExecute=true +#RestrictRealtime=true +#RestrictSUIDSGID=true +## RemoveIPC=true +## PrivateMounts=true +## MountFlags= +## SystemCallFilter is a Whitelist!!! +#SystemCallFilter=@aio,@basic-io,@debug,@file-system,@network-io +#SystemCallErrorNumber=1337 + +[Install] +WantedBy=multi-user.target diff --git a/files/usr/local/lib/systemd/system/logs-to-archive.timer b/files/usr/local/lib/systemd/system/logs-to-archive.timer new file mode 100644 index 0000000000000000000000000000000000000000..595df9588aef5fc132d9d82dcadd7c9efb29483f --- /dev/null +++ b/files/usr/local/lib/systemd/system/logs-to-archive.timer @@ -0,0 +1,11 @@ +[Unit] +Description=Cleanup Daemon for Rosetta logs + +[Timer] +Unit=logs-to-archive.service +Persistent=true +OnCalendar=monthly + +[Install] +WantedBy=default.target + diff --git a/tasks/rosetta/install_log_archival.yml b/tasks/rosetta/install_log_archival.yml new file mode 100644 index 0000000000000000000000000000000000000000..86225fa8d2711cd12bcd550e716d4f539510b2ac --- /dev/null +++ b/tasks/rosetta/install_log_archival.yml @@ -0,0 +1,24 @@ +--- +- name: install log archival script and systemd units + ansible.builtin.copy: + src: "{{ item.file }}" + dest: "/{{ item.file }}" + mode: "{{ item.mode | default('0644') }}" + owner: "{{ vault_rosetta_user }}" + group: "{{ vault_rosetta_group }}" + loop: + - file: "usr/local/bin/logs-to-archive.sh" + mode: "0755" + - file: "usr/local/lib/systemd/system/logs-to-archive.service" + - file: "usr/local/lib/systemd/system/logs-to-archive.timer" + +- name: start & enable units + ansible.builtin.systemd: + unit: "logs-to-archive.{{ item.u }}" + enabled: true + state: "{{ item.s | default(omit) }}" + daemon_reload: true + loop: + - u: "service" + - u: "timer" + s: "started" diff --git a/tasks/rosetta/main_rosetta.yml b/tasks/rosetta/main_rosetta.yml index 2e0eef48bd72e317635a9ece804030bf57eceba2..68354084ce82b3f22ffc58387801c7ecf8cccb5d 100644 --- a/tasks/rosetta/main_rosetta.yml +++ b/tasks/rosetta/main_rosetta.yml @@ -37,3 +37,6 @@ - name: configure Tomcat server ansible.builtin.import_tasks: "rosetta/configure_tomcat.yml" tags: [rosetta, tomcat, java] +- name: install log archival for Rosetta logs + ansible.builtin.import_tasks: "install_log_archival.yml" + tags: [rosetta, log, logs]