diff --git a/optimize_archive_tables.sh b/optimize_archive_tables.sh new file mode 100755 index 0000000..6e7efca --- /dev/null +++ b/optimize_archive_tables.sh @@ -0,0 +1,387 @@ +#!/usr/bin/env bash + +script_name="$(basename $(realpath $0))" +working_dir="$(dirname $(realpath $0))" + +conf_file="${working_dir}/conf/${script_name%%.*}.conf" + +LOCK_DIR="/tmp/${script_name%%.*}.LOCK" + +error_log="${LOCK_DIR}/error.log" + + +# ------------- +# - Default values +# ------------- + +php_bin=/usr/local/php/bin/php + +DEFAULT_MATOMO_PREFIX="matomo" + +DEFAULT_MYSQL_CREDENTIAL_ARGS="--defaults-file=/usr/local/mysql/sys-maint.cnf" +DEFAULT_HTTP_USER=www-data + +VERBOSE=false + + + +# ------------- +# --- Some functions +# ------------- + +clean_up() { + + # Perform program exit housekeeping + rm -rf "$LOCK_DIR" + blank_line + exit $1 +} + +usage() { + + blank_line + [[ -n "$1" ]] && error "$1" + + [[ $terminal ]] && echo -e " + +\033[1mUsage:\033[m + + $(basename $0) [-h] [-v] [-s ] + + +\033[1mDescription\033[m + + Script does the foloeing two things: + + 1. Triggers an OPTIMIZE TABLE on such Matomo tables containing archives of the last + two month (and maybe lower your disk usage). + + 2. The data for annual reports is stored in the archives for January of the + appropriate year, so thees tables will also be optimized as well. + + +\033[1mOptions\033[m + + -h + Prints this help. + + -s + The directory contains the matomo instances on this server. + + -v + Verbose Mode. Applies only, if script is running in a console, or in otherwords: + parameter has no effect, if script is running as a cronjob. + +\033[1mFiles\033[m + + $conf_file: Configuration file +" + +clean_up 1 +} + +echononl(){ + if $terminal ; then + echo X\\c > /tmp/shprompt$$ + if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then + echo "$*\\c" 1>&2 + else + echo -e -n "$*" 1>&2 + fi + rm /tmp/shprompt$$ + fi +} +info (){ + if $terminal ; then + echo "" + echo -e " [ \033[32m\033[1mInfo\033[m ]: $*" + echo "" + fi +} +warn (){ + if $terminal ; then + echo "" + echo -e " [ \033[33m\033[1mWarn\033[m ] $*" + echo "" + fi +} + +fatal(){ + echo "" + if $terminal ; then + echo -e " [ \033[31m\033[1mFatal\033[m ] $*" + else + echo -e " [ Fatal ] $*" + fi + echo "" + if $terminal ; then + echo -e " \033[1mScript terminated\033[m.." + else + echo -e " Script terminated.." + fi + echo "" + rm -rf $LOCK_DIR + exit 1 +} + + +error (){ + echo "" + if $terminal ; then + echo -e " [ \033[31m\033[1mError\033[m ]: $*" + else + echo " [ Error ] $*" + fi + echo "" +} + +error_cron(){ + echo + echo "----" + echo "$1" + echo + echo "$2" + echo +} +echo_ok() { + if $terminal ; then + echo -e "\033[85G[ \033[32mok\033[m ]" + fi +} +echo_failed(){ + if $terminal ; then + echo -e "\033[85G[ \033[1;31mfailed\033[m ]" + fi +} + +blank_line() { + if $terminal ; then + echo "" + fi +} + +get_sld_domain() { + + # Set IFS to dot, so that we can split $@ on dots instead of spaces. + local IFS='.' + + # Break up arguments passed to shorthost so that each domain zone is + # a new index in an array. + zones=($@) + + index_tld="$((${#zones[@]}-1))" + index_sld="$((index_tld-1))" + + echo ${zones[$index_sld]}.${zones[$index_tld]} + +} + + + +# ------------- +# - Job is already running? +# ------------- + +# - If job already runs, stop execution.. +# - +if mkdir "$LOCK_DIR" 2> /dev/null ; then + + ## - Remove lockdir when the script finishes, or when it receives a signal + trap clean_up SIGHUP SIGINT SIGTERM + +else + + datum="$(date +"%d.%m.%Y %H:%M")" + + msg="[ Error ]: A previos instance of \"`basename $0`\" seems already be running.\n\n Exiting now.." + + echo "" + echo "[ Error ]: A previos instance of that script \"`basename $0`\" seems already be running." + echo "" + echo -e " Exiting now.." + echo "" + + exit 1 + +fi + + +# ------------- +# - Check some prerequisites +# ------------- + +# - Is this script running on terminal ? +# - +if [[ -t 1 ]] ; then + terminal=true +else + terminal=false +fi + + +# ========== +# - Begin Main Script +# ========== + +# ---------- +# - Headline +# ---------- + +if $terminal ; then + echo "" + echo -e "\033[1m----------\033[m" + echo -e "\033[32m\033[1mRunning script \033[m\033[1m$script_name\033[32m .. \033[m" + echo -e "\033[1m----------\033[m" +fi + + +# ---------- +# - Read Configurations from $conf_file +# ---------- + +if [[ -f "$conf_file" ]]; then + source "$conf_file" +else + warn "No configuration file '$conf_file' present." +fi + + +# ---------- +# - Read in Commandline arguments +# ---------- + +while getopts hs:v opt ; do + case $opt in + v) VERBOSE=true + ;; + s) STATS_BASE_DIR=$OPTARG + ;; + h) usage + ;; + esac +done + +cd /tmp + +[[ -n "$MYSQL_CREDENTIAL_ARGS" ]] || MYSQL_CREDENTIAL_ARGS="$DEFAULT_MYSQL_CREDENTIAL_ARGS" +[[ -n "$HTTP_USER" ]] || HTTP_USER="$DEFAULT_HTTP_USER" + +if [[ -z "$STATS_HOSTNAME" ]]; then + STATS_HOSTNAME="stats.$(get_sld_domain "$(hostname -f)")" +fi + +[[ -n "$STATS_BASE_DIR" ]] || STATS_BASE_DIR="/var/www/${STATS_HOSTNAME}" + +if [[ ! -d "$STATS_BASE_DIR" ]]; then + fatal "Directory \033[1m$STATS_BASE_DIR\033[m do not exits!." +fi + +if [[ -z "$MATOMO_PREFIX" ]]; then + if $(ls ${STATS_BASE_DIR}/matomo* > /dev/null 2>&1) ; then + MATOMO_PREFIX="matomo" + elif $(ls ${STATS_BASE_DIR}/piwik* > /dev/null 2>&1) ; then + MATOMO_PREFIX="piwik" + else + error "No matomo instances found on this server." + fi +else + if ! $(ll ${STATS_BASE_DIR}/${MATOMO_PREFIX}* > /dev/null 2>&1) ; then + error "No matomo instances found on this server (${STATS_BASE_DIR}/${MATOMO_PREFIX}*)." + fi +fi + +if $terminal ; then + echo "" + echo " HTTP_USER.................: $HTTP_USER" + echo " MYSQL_CREDENTIAL_ARGS.....: $MYSQL_CREDENTIAL_ARGS" + echo " STATS_HOSTNAME............: $STATS_HOSTNAME" + echo " STATS_BASE_DIR............: $STATS_BASE_DIR" + echo " MATOMO_PREFIX.............: $MATOMO_PREFIX" + echo "" +fi + + + +echononl " Get matomo databases (names)" +databases="$(mysql $MYSQL_CREDENTIAL_ARGS -N -s -e "show databases" 2> $error_log | grep ${MATOMO_PREFIX}_ 2>> $error_log)" +if [[ $? -gt 0 ]] ;then + echo_failed + [[ -s "$error_log" ]] && error "$(cat $error_log)" +else + echo_ok +fi + +if [[ -z "$databases" ]] ; then + error "No matomo databses found." + clean_up 1 +fi + + +declare -i sum_errors=0 +for db_name in $databases ; do + + if [ -f "$STATS_BASE_DIR/$db_name/console" ];then + + blank_line + + echononl " Optimze archive tables of the last 2 month - Database \033[1m$db_name\033[m" + + # - Archive Reports + # - + su $HTTP_USER -s /bin/bash \ + -c "$php_bin $STATS_BASE_DIR/$db_name/console database:optimize-archive-tables last2" \ + > $error_log 2>&1 + if [[ $? -ne 0 ]]; then + let "sum_errors += 1" + echo_failed + error "Error while optimizing archive tables of the lst 2 month for database \"$db_name\" + +$(cat $error_log)" + else + echo_ok + if $VERBOSE ; then + echo + echo "$(cat $error_log)" + echo + echo + fi + fi + + echononl " Optimze archive tables of january this yaer - Database \033[1m$db_name\033[m" + + # - Archive Reports + # - + su $HTTP_USER -s /bin/bash \ + -c "$php_bin $STATS_BASE_DIR/$db_name/console database:optimize-archive-tables january" \ + > $error_log 2>&1 + if [[ $? -ne 0 ]]; then + let "sum_errors += 1" + echo_failed + error "Error while optimizing archive tables january this year for database \"$db_name\" + +$(cat $error_log)" + else + echo_ok + if $VERBOSE ; then + echo + echo "$(cat $error_log)" + echo + echo + fi + fi + + else + + error "Script \"$STATS_BASE_DIR/$db_name/console\" for database \"$db_name\" not found!" + continue + fi + +done + +if [[ $sum_errors -eq 0 ]]; then + info "Script ended successfully." +else + error "Script ended with ${sum_errors} error(s)!" +fi + +clean_up 0