#!/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