allinurl / goaccess

GoAccess is a real-time web log analyzer and interactive viewer that runs in a terminal in *nix systems or through your browser.
https://goaccess.io
MIT License
18.6k stars 1.11k forks source link

Website monitoring with GoAccess: Permission denied #2509

Open hannibalxyz opened 1 year ago

hannibalxyz commented 1 year ago

Hello,   I would be happy if anyone could help me out with an issue, unfortunately I have little knowledge with self hosting, GoAccess and everything that comes with it.   I work at a small company and an ex-colleague of mine set up GoAccess as an alternative to Google Analytics in order to monitor traffic for our website before he left.   All the files and the update_report.sh file are located in a folder stored on our firm’s google drive (and until recently everything worked fine). Recently my mac had an update and the location for google drive changed. After that the order to update the report did not work any more, the terminal responded with “there is no such file or directory”.   I opended the update_report.sh file and changed the location (DIR =)  to what I think is the new location of the files and tried again. Now I get the respond “permission denied”. So I think the location of everything should be fine, but something else is not?   Also I’m not even sure if GoAccess is still properly installed on my mac since the last update, is there any way to check?   Thanks so much in advance for your help!

allinurl commented 1 year ago

Sure, could you share the contents of the script? Thanks.

hannibalxyz commented 1 year ago

Hi,

thanks for responding! This is the script my ex-colleague wrote (also with his comments in german). I only changed the "DIR" after the google drive update., everything else is untouched. Just changed some data in it for privacy reasons in the copy I'm posting here.

#!/bin/bash
# lzi Mai 2021 - August 2022

# Variablen können hier geändert werden, wenn sich Dateipfade o. Ä. ändern; Achtung wenn Logfilename oder Datenbank geändert wird: GoAccess nutzt Datei im Datenbankordner ($LOG.persistent), um neue Logs mit bisherigen zu vergleichen (Inhalt der Datei ist für Vergleich egal, es geht um die Existenz der Datei selbst, siehe manpage). Wenn ein anderer Name angegeben wird, treten Dopplungen in Datenbank auf, wenn neues Logfile bereits vorhandene Daten enthält.
REPORT="goaccess_Report.html"
DIR="/Users/xxx/Library/CloudStorage/GoogleDrive-xxx/.shortcut-targets-by-id/0B0FD4FjgwxscQ0l4T3JVODhzVEk/Kommunikation & Marketing/Website /Analyse/Besucheranalyse"
DB="goaccess_Datenbank"
SSH_USER="c455294-part"
WEBSITE="xxx"
LOG_PER="access_anonymized.log.persistent"
MSG_CON="Verbindung zu Server wird hergestellt, um aktuelles Logfile zu erstellen. Bei Aufforderung SSH-Passwort eingeben.\n"
MSG_FAIL="Achtung: Verbindung zu Server fehlgeschlagen oder Skript auf Server nicht ausführbar. Aktuelles Logfile konnte nicht erstellt werden. Falls vorhanden, wird bestehendes Logfile verwendet.\n"
PERSISTENT_INFO="# DIESE DATEI NICHT LÖSCHEN\n# Hier werden bei Aktualisierungen Log-Daten zwischengespeichert. Die Datei muss bestehen bleiben, damit GoAccess die Zeitstempel mit bereits vorhandenen Daten abgleichen kann. Dies ist nur möglich, wenn der inode der Datei gleich bleibt.\n# Letztes Update: $( date +%Y%m%d )\n"

check_persist () {
    # Check, ob LOG.persistent vorhanden ist. Wenn vorhanden, werden die Zeitstempel des neuen Logfiles mit dem letzten Zeitstempel der Datenbank verglichen.
    printf "###\n"
    if [[ ! -f "$DB/$LOG_PER" ]]
    then
        printf "Achtung: Keine dauerhafte Logfile-Datei vorhanden. An sich kein Problem, aber falls im heruntergeladenen Logfile Einträge vorhanden sind, die bereits in die Datenbank eingefügt wurden, werden diese gedoppelt.\n"
        read -p "Fortfahen? [j/N] " PROMPT
        if [[ $PROMPT != "j" && $PROMPT != "J" ]]
        then
            printf "Aktualisierung abgebrochen.\n"
            exit 0
        fi
    else
        LAST_UPDATE=$( grep -E "^# Letztes Update" "$DB/$LOG_PER" | sed -E 's/^# Letztes Update: ([0-9]+)/\1/' )
        printf "Letzte Aktualisierung: $( date -jf %Y%m%d $LAST_UPDATE '+%d.%m.%Y' )\n"
    fi
    printf "###\n\n"
}

update () {
    printf "###\n"
    printf "Verzeichnis für Analysedaten: \"$DIR\"\n"
    printf "Name von Logfile auf Server: \"$LOG\"\n"
    printf "###\n\n"

    printf "###\n"
    printf "$MSG_CON"
    # anonymisiertes Logfile vom Website-Server auf lokales Gerät (bzw. Google Drive) kopieren; anonymisierte Logfiles werden automatisch wöchentlich auf dem Server per Cron-Job erstellt (Einrichtung auf Hosting-Portal)
    scp $SSH_USER@$WEBSITE:"/home/$SSH_USER/$LOG" "$LOG"
    if [[ $? != 0 ]]
    then
        printf "Fehler: Verbindung zu Server fehlgeschlagen oder Logfile nicht gefunden. Analysereport wurde nicht aktualisiert.\n"
        printf "###\n"
        exit 1
    fi
    printf "###\n\n"

    if [[ -f "$LOG" ]]
    then
        # Zwischenspeichern von neuen Logs in LOG.persistent, damit diese Datei für GoAccess immer die Inputdatei ist -> GoAccess nimmt an, dass es sich um ein inkrementelles Logfile handelt und gleicht Zeitstempel mit Datenbank ab
        cat "$LOG" > "$DB/$LOG_PER"
        printf "###\n"
        printf "Analysedatenbank wird aktualisiert, aktualisierter Report wird erstellt.\n"
        # Erstellung von Bericht und Aktualisierung der Datenbank mit GoAccess:
        # LC_TIME auf Englisch setzen, weil Datumsformat in Logfile auf Englisch ist
        # Output als HTML
        # --log-format ist COMBINED, ist Voreinstellung bei Logs von nginx-Servern
        # --all-static-files: auch statische Dateien mit query strings als solche behandeln (z. B. .css?ver=x.x.x)
        # --static-file: nicht eh schon erfasste (wie CSS und JS) statische Dateien als solche markieren (Schriftarten, Logos, Icons etc.)
        # IPs werden anonymisiert (letztes Oktett)
        # --ignore-crawlers: Bots/Crawlers ignorieren
        # --ignore-panel=HOSTS: Hostnamen/IPs ausblenden, weil eh anonymisiert
        # --enable-panel=KEYPHRASES: zeige Suchbegriffe von Google aus http-requests an (sind aber meistens verschlüsselt und deshalb nicht sichtbar)
        # --restore: Datenbank laden
        # --persist: in Datenbank schreiben
        # --db-path: Pfad zur Datenbank (default: /tmp)
        # --html-custom-css: angepasster CSS im YOUSE-CD
        # --html-prefs: Voreinstellungen für HTML
        LC_TIME="en_US.UTF-8" goaccess "$DB/$LOG_PER" -o "$REPORT" --log-format=COMBINED --all-static-files --static-file=.svg --static-file=.ttf --static-file=.woff2 --static-file=.webmanifest --static-file=.webm --static-file=.ico --anonymize-ip --ignore-crawlers --ignore-panel=HOSTS --enable-panel=KEYPHRASES --restore --persist --db-path "$DB" --html-custom-css="resources/app_youse.css" --html-prefs='{"theme":"darkGray"}'
        if [[ $? == 0 ]]
        then
            printf "Analysedatenbank und Report wurden erfolgreich aktualisiert.\n"
            printf "Aktueller Report: \"$DIR/$REPORT\"\n"
            printf "###\n"
        else
            printf "Fehler beim Aktualisieren der Analysedatenbank und Erstellung des Reports.\n"
            printf "###\n"
            printf "$PERSISTENT_INFO" > "$DB/$LOG_PER"
            rm "$LOG"
            exit 1
        fi
    else
        printf "Fehler: Logfile konnte nicht gefunden werden.\n"
        printf "###\n"
        printf "$PERSISTENT_INFO" > "$DB/$LOG_PER"
        exit 1
    fi
    # zwischengespeicherte Logdaten löschen, ohne die Referenzdatei für GoAccess zu löschen
    printf "$PERSISTENT_INFO" > "$DB/$LOG_PER"
    rm "$LOG"
}

# goAccess hat Probleme mit "&" im Pfadnamen, deshalb hier schon ins Arbeitsverzeichnis wechseln
cd "$DIR"

if [[ "$2" != "" ]]
then
    echo "Achtung: mehrere Argumente angegeben. Nur das erste Argument (\"$1\") wird verwendet."
fi

if [[ "$1" == "-a" || "$1" == "--auto" ]]
then
    check_persist
    if [[ ! "$LAST_UPDATE" == "" ]]
    then
        CUTOFF_UPTODATE=$(date -v -$(date '+%u')d '+%Y%m%d') 
        if [[ "$LAST_UPDATE" -gt "$CUTOFF_UPTODATE" ]]
        then
            printf "###\n"
            printf "Datenbank auf aktuellem Stand (bis vergangenen Sonntag). Für tagesaktuelle Daten \"--force-update\" verwenden.\n"
            printf "###\n"
            exit 0
        fi
        CUTOFF_PREV=$(date -v -$(( $(date '+%u') + 14 ))d '+%Y%m%d') 
        CUTOFF_CURR=$(date -v -$(( $(date '+%u') + 7 ))d '+%Y%m%d') 
        if [[ "$LAST_UPDATE" -le "$CUTOFF_PREV" ]]
        then
            printf "###\n"
            printf "$MSG_CON"
            # Montag vor dem letzten Update
            LAST_UPDATE_MON=$(date -r $(date -jf '%Y%m%d' $LAST_UPDATE '+%s') -v -$(( $(date -jf '%Y%m%d' $LAST_UPDATE '+%u') - 1 ))d '+%Y%m%d')
            ssh $SSH_USER@$WEBSITE "/web/export_logs.sh --$LAST_UPDATE_MON-$CUTOFF_PREV"
            if [[ $? != 0 ]]
            then
                printf "$MSG_FAIL"
            fi
            LOG="access_anonymized_custom.log"
            printf "###\n\n"
            update
        fi
        if [[ "$LAST_UPDATE" -le "$CUTOFF_CURR" ]]
        then
            LOG="access_anonymized_previous.log"
            update
        fi
    fi
    LOG="access_anonymized.log"
    update
elif [[ "$1" == "-f" || "$1" == "--force-update" ]]
then
    printf "###\n"
    printf "$MSG_CON"
    # Ausführen von Skript auf Website-Server, mit dem aktuelle access.log Datei kopiert und anonymisiert wird (letztes Oktett der IP = 0)
    ssh $SSH_USER@$WEBSITE "/web/export_logs.sh --current"
    if [[ $? != 0 ]]
    then
        printf "$MSG_FAIL"
    fi
    LOG="access_anonymized_current.log"
    printf "###\n\n"
    check_persist
    update
elif [[ "$1" == "-l" || "$1" == "--last" ]]
then
    LOG="access_anonymized.log"
    check_persist
    update
elif [[ "$1" == "-p" || "$1" == "--previous" ]]
then
    LOG="access_anonymized_previous.log"
    check_persist
    update
elif echo "$1" | grep -E '^--[0-9]{8}-[0-9]{8}$' > /dev/null
then
    printf "###\n"
    printf "$MSG_CON"
    # Ausführen von Skript auf Website-Server, mit dem aktuelle access.log Datei kopiert und anonymisiert wird (letztes Oktett der IP = 0)
    ssh $SSH_USER@$WEBSITE "/web/export_logs.sh $1"
    if [[ $? != 0 ]]
    then
        printf "$MSG_FAIL"
    fi
    LOG="access_anonymized_custom.log"
    printf "###\n\n"
    check_persist
    update
elif [[ "$1" == "-d" || "$1" == "--dry" ]]
then
    # Befehl anpassen, um angepassten Report zu erstellen ohne Datenbank zu verändern; erste Zeile ist default
    OPTIONS="--anonymize-ip --ignore-crawlers --ignore-panel=HOSTS --enable-panel=KEYPHRASES"
    #OPTIONS="--anonymize-ip --ignore-crawlers --ignore-panel=HOSTS --enable-panel=KEYPHRASES --http-protocol=no --http-method=no"
    printf "###\n"
    printf "Report wird aktualisiert. Analysedatenbank wird nicht verändert.\n"
    LC_TIME="en_US.UTF-8" goaccess -o "$REPORT" --log-format=COMBINED --all-static-files --static-file=.svg --static-file=.ttf --static-file=.woff2 --static-file=.webmanifest --static-file=.webm --static-file=.ico $OPTIONS --restore --db-path "$DB" --html-custom-css="resources/app_youse.css" --html-prefs='{"theme":"darkGray"}'
    if [[ $? == 0 ]]
    then
        printf "Report wurde erfolgreich aktualisiert. Analysedatenbank wurde nicht verändert.\n"
        printf "Aktueller Report: \"$DIR/$REPORT\"\n"
        printf "###\n"
    else
        printf "Fehler beim Aktualisieren des Reports. Analysedatenbank wurde nicht verändert.\n"
        printf "###\n"
        exit 1
    fi
    exit 0
else
    # Anzeigen von Hilfe, wenn unbekanntes Argument (oder -h/--help) angegeben wird
    printf "Skript zur Aktualisierung des Berichts über die Zugriffsdaten auf unserer Website.\n\n\
        Nutzung:\n\
        -h, --help:\t\tHilfe anzeigen (so wie hier geschehen)\n\
        -a, --auto:\t\tLogdaten seit der letzten Aktualisierung (bzw. dem Montag davor, falls es keiner war) bis einschließlich zum vergangenen Sonntag verwenden (empfohlen).\n\
        -f, --force-update:\tDie aktuellsten Logdaten herunterladen. Standardmäßig werden die Daten wöchentlich aktualisiert (Montag um 01:00 Uhr).\n\
        -l, --last:\t\tDie Logdaten von letzter Aktualisierung verwenden (letzte Woche).\n\
        -p, --previous:\t\tDie Logdaten von vorletzter Aktualisierung verwenden (vorletzte Woche).\n\
        --yyyymmdd-yyyymmdd:\tDie Logdaten von spezifiziertem Zeitraum verwenden.\n\
        -d, --dry\t\tNur den Report aktualisieren, ohne neue Logdaten herunterzuladen und die Datenbank zu aktualisieren.\n"
    exit 0
fi

exit 0
hannibalxyz commented 1 year ago

Sorry for the weird layout, on my computer everything is just text and not formatted, I'm not familiar how to change that on here.

allinurl commented 1 year ago

I'd say to double check that you have access to "/Users/xxx/Library/CloudStorage/GoogleDrive-xxx/.shortcut-targets-by-id/0B0FD4FjgwxscQ0l4T3JVODhzVEk/Kommunikation & Marketing/Website /Analyse/Besucheranalyse", probably opening the file from the shell may be the first step. Let me know if that helps.

hannibalxyz commented 1 year ago

I'd say to double check that you have access to "/Users/xxx/Library/CloudStorage/GoogleDrive-xxx/.shortcut-targets-by-id/0B0FD4FjgwxscQ0l4T3JVODhzVEk/Kommunikation & Marketing/Website /Analyse/Besucheranalyse", probably opening the file from the shell may be the first step. Let me know if that helps.

Hi, yes I have access to the file and can open it, if you mean that? But if I use the terminal I still have the same "permission denied".

allinurl commented 1 year ago

It appears that you are currently operating as a different user or a user without the necessary permissions to read the file. To identify the owner of the file, please execute the following command: ls -lath /Users/xxx/Library/CloudStorage/Goo....

hannibalxyz commented 1 year ago

It appears that you are currently operating as a different user or a user without the necessary permissions to read the file. To identify the owner of the file, please execute the following command: ls -lath /Users/xxx/Library/CloudStorage/Goo....

Hi thank for your answer! The command is not working for me. But I checked in GDrive, my account is the owner of the file as well as some other people. Maybe it could work if I save the file locally on my mac and change the DIR again?