logs: standardise log filenames to xamxam-{service}-{date}.log

This commit is contained in:
Pontoporeia
2026-08-24 11:34:34 +02:00
parent 7b6d79c133
commit d2cef85966
25 changed files with 442 additions and 83 deletions
+2 -2
View File
@@ -9,8 +9,8 @@
# RETENTION_DAYS=90 /usr/local/bin/backup-sqlite.sh # 90 days
#
# Expected to be run from cron:
# 0 * * * * /usr/local/bin/backup-sqlite.sh >> /var/log/sqlite-backup.log 2>&1
# 0 2 * * * RETENTION_DAYS=90 /usr/local/bin/backup-sqlite.sh >> /var/log/sqlite-backup.log 2>&1
# 0 * * * * /usr/local/bin/backup-sqlite.sh >> /var/log/xamxam-backup-$(date +%Y-%m-%d).log 2>&1
# 0 2 * * * RETENTION_DAYS=90 /usr/local/bin/backup-sqlite.sh >> /var/log/xamxam-backup-$(date +%Y-%m-%d).log 2>&1
set -euo pipefail
+24 -6
View File
@@ -1,31 +1,49 @@
#!/usr/bin/env php
<?php
/**
* cleanup-drafts.php — Delete orphaned draft theses older than 24h.
* cleanup-drafts.php — Delete orphaned draft theses older than a threshold.
*
* Draft theses are created with status='draft' during the two-phase commit
* in ThesisCreateController. If the file phase throws after COMMIT, the
* draft remains orphaned — no files attached, but blocks the identifier.
*
* The eligibility age defaults to 7 days (168 hours) and can be overridden
* with the OLDER_THAN_HOURS environment variable:
* OLDER_THAN_HOURS=24 php scripts/cleanup-drafts.php
*
* Usage:
* php scripts/cleanup-drafts.php # dry-run (list candidates)
* php scripts/cleanup-drafts.php --no-dry-run # actually delete
* php /tmp/cleanup-drafts.php # dry-run (list candidates)
* php /tmp/cleanup-drafts.php --no-dry-run # actually delete
*
* Exit codes: 0 on success, 1 on error.
*/
declare(strict_types=1);
$root = dirname(__DIR__);
define('APP_ROOT', $root . '/app');
// Resolve APP_ROOT robustly. In production the app code is deployed flat under
// /var/www/xamxam/ (src/, storage/, templates/ at the root, no app/ subdir), and
// this script may itself live in /tmp. Always point at /var/www/xamxam in
// non-CLI-SAPI contexts; local dev (cli-server) keeps the app/ subdir layout.
$prodRoot = '/var/www/xamxam';
if (is_dir($prodRoot . '/src') && is_file($prodRoot . '/src/Database.php')) {
define('APP_ROOT', $prodRoot);
} else {
define('APP_ROOT', dirname(__DIR__) . '/app');
}
require_once APP_ROOT . '/src/Database.php';
$dryRun = !in_array('--no-dry-run', $argv, true);
// Eligibility threshold: default 7 days (168h); overridable via env.
$olderThanHours = (int) (getenv('OLDER_THAN_HOURS') ?: 168);
if ($olderThanHours < 1) {
$olderThanHours = 168;
}
try {
$db = new Database();
$result = $db->cleanupOrphanedDrafts(24, $dryRun);
$result = $db->cleanupOrphanedDrafts($olderThanHours, $dryRun);
} catch (Exception $e) {
error_log('[cleanup-drafts] Error: ' . $e->getMessage());
exit(1);
+6 -6
View File
@@ -8,12 +8,12 @@ echo "Creating investigation directory..."
mkdir -p ~/crash_investigation
echo "Copying nginx logs..."
sudo cp /var/log/nginx/xamxam_error.log ~/crash_investigation/
sudo cp /var/log/nginx/xamxam_error.log.1 ~/crash_investigation/ 2>/dev/null || true
sudo cp /var/log/nginx/xamxam_access.log ~/crash_investigation/
sudo cp /var/log/nginx/xamxam_access.log.1 ~/crash_investigation/ 2>/dev/null || true
sudo cp /var/log/nginx/xamxam_error.log.2.gz ~/crash_investigation/ 2>/dev/null || true
sudo cp /var/log/nginx/xamxam_access.log.2.gz ~/crash_investigation/ 2>/dev/null || true
sudo cp /var/log/nginx/xamxam-nginx-error.log ~/crash_investigation/
sudo cp /var/log/nginx/xamxam-nginx-error.log.1 ~/crash_investigation/ 2>/dev/null || true
sudo cp /var/log/nginx/xamxam-nginx-access.log ~/crash_investigation/
sudo cp /var/log/nginx/xamxam-nginx-access.log.1 ~/crash_investigation/ 2>/dev/null || true
sudo cp /var/log/nginx/xamxam-nginx-error.log.2.gz ~/crash_investigation/ 2>/dev/null || true
sudo cp /var/log/nginx/xamxam-nginx-access.log.2.gz ~/crash_investigation/ 2>/dev/null || true
echo "Exporting journal from previous boot..."
sudo journalctl -b -1 --no-pager > ~/crash_investigation/journal_previous_boot.log 2>&1
+8
View File
@@ -89,6 +89,14 @@ chown www-data:xamxam /var/www/xamxam/storage/tmp/php-uploads
chmod 2775 /var/www/xamxam/storage/tmp/php-uploads
ok "PHP upload temp dir: /var/www/xamxam/storage/tmp/php-uploads"
# Ensure the application log directory exists and is writable by php-fpm.
# App logs (Monolog) go to /var/log/xamxam/xamxam-{channel}-YYYY-MM-DD.log in
# production; without this the logger falls back to NullHandler (silent).
mkdir -p /var/log/xamxam
chown www-data:xamxam /var/log/xamxam
chmod 2775 /var/log/xamxam
ok "Log dir: /var/log/xamxam owned by www-data:xamxam (2775)"
# ── Step 2: Nginx config ──────────────────────────────────────────────────────
printf "\n📋 Step 2: Deploying nginx configuration...\n"
echo "--------------------------------------------"
+151
View File
@@ -0,0 +1,151 @@
#!/bin/bash
# migrate-log-names.sh — rename (and relocate) pre-existing log files to the
# xamxam-{service}-{date}.log convention under the standard /var/log root.
#
# Why: the app adopted a uniform log naming scheme where production app logs
# live under /var/log/xamxam/ (system standard), nginx under /var/log/nginx/,
# and cron jobs under /var/log/:
# /var/log/xamxam/xamxam-{channel}-YYYY-MM-DD.log (app/admin/error/audit)
# /var/log/nginx/xamxam-nginx-{access,error}.log (nginx, fixed live name)
# /var/log/xamxam-{backup,cleanup}-YYYY-MM-DD.log (cron jobs)
# but logs written before that change still carry the old names/locations
# (storage/logs/admin-*.log, xamxam_error.log, sqlite-backup.log, …). This
# script renames and moves those in place so they follow the same pattern and
# stay visible to the admin log viewer (which globs for xamxam-{channel}-*.log).
#
# Behaviour:
# - Idempotent: files already matching the target pattern are skipped.
# - Non-destructive: never overwrites an existing destination. If the
# destination already exists the source is left untouched and a warning
# is printed so you can merge/decide manually.
# - Dry-run by default; pass --apply to actually rename.
# - Uses each file's own mtime as its date (app/cron logs embed the date in
# their name already; nginx/cron flat files derive one from mtime).
#
# Usage (run on the server):
# sudo bash /tmp/migrate-log-names.sh # preview only
# sudo bash /tmp/migrate-log-names.sh --apply # perform the renames
#
# Install: just deploy-script migrate-log-names (uploads this file to /tmp)
set -euo pipefail
# ── Helpers ────────────────────────────────────────────────────────────────────
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
info() { printf "ℹ️ %s\n" "$*"; }
ok() { printf "${GREEN}✓${NC} %s\n" "$*"; }
warn() { printf "${YELLOW}!${NC} %s\n" "$*"; }
err() { printf "${RED}✗${NC} %s\n" "$*" >&2; }
APPLY=0
[ "${1:-}" = "--apply" ] && APPLY=1
APP_LOGS_OLD_DIR="/var/www/xamxam/storage/logs"
APP_LOGS_DIR="/var/log/xamxam"
NGINX_LOGS_DIR="/var/log/nginx"
# ── App channels (Monolog rotating files) ─────────────────────────────────────
# App logs now live under /var/log/xamxam (production). Handle both the old
# location (storage/logs, pre-move) and files already in the new location that
# still carry the old naming (missing xamxam- prefix).
# Old: {channel}-YYYY-MM-DD.log New: xamxam-{channel}-YYYY-MM-DD.log
# Old bare base also possible: {channel}.log (no date)
CHANNELS=(app admin error audit)
changed=0
for ch in "${CHANNELS[@]}"; do
# Source directory: prefer the old storage/logs location for files that
# predate the move; also scan the new /var/log/xamxam in case a previous
# partial migration already moved (but did not rename) some files.
for srcdir in "$APP_LOGS_OLD_DIR" "$APP_LOGS_DIR"; do
[ -d "$srcdir" ] || continue
# Dated files: {channel}-YYYY-MM-DD.log → xamxam-{channel}-YYYY-MM-DD.log
for src in "$srcdir"/"$ch"-20[0-9][0-9]-[0-9][0-9]-[0-9][0-9].log; do
[ -e "$src" ] || continue
base=$(basename "$src")
dst="$APP_LOGS_DIR/xamxam-$base"
if [ -e "$dst" ]; then
warn "skip (dest exists): $base"
continue
fi
if [ "$APPLY" -eq 1 ]; then
mv "$src" "$dst" && ok "moved $srcdir/$base → $dst"
else
info "[dry-run] $srcdir/$base → $dst"
fi
changed=$((changed + 1))
done
# Bare base file (rare, pre-rotation): {channel}.log → xamxam-{channel}.log
src="$srcdir/$ch.log"
if [ -f "$src" ]; then
dst="$APP_LOGS_DIR/xamxam-$ch.log"
if [ -e "$dst" ]; then
warn "skip (dest exists): $ch.log"
elif [ "$APPLY" -eq 1 ]; then
mv "$src" "$dst" && ok "moved $srcdir/$ch.log → $dst"
else
info "[dry-run] $srcdir/$ch.log → $dst"
fi
changed=$((changed + 1))
fi
done
done
[ "$changed" -eq 0 ] && info " none found"
# ── nginx logs (fixed live name + logrotate .N / .N.gz rotations) ─────────────
# Old: xamxam_error.log[.N[.gz]] New: xamxam-nginx-error.log[.N[.gz]]
# Old: xamxam_access.log[.N[.gz]] New: xamxam-nginx-access.log[.N[.gz]]
info "nginx logs — $NGINX_LOGS_DIR"
for kind in access error; do
# Match the live file and any rotations (.1, .2.gz, …)
for src in "$NGINX_LOGS_DIR"/xamxam_"$kind".log*; do
[ -e "$src" ] || continue
base=$(basename "$src")
# strip the leading xamxam_{kind}.log, keep the rotation suffix
suffix=${base#xamxam_"$kind".log}
dst="$NGINX_LOGS_DIR/xamxam-nginx-$kind.log$suffix"
if [ -e "$dst" ]; then
warn "skip (dest exists): $base"
continue
fi
if [ "$APPLY" -eq 1 ]; then
mv "$src" "$dst" && ok "renamed $base → $(basename "$dst")"
else
info "[dry-run] $base → $(basename "$dst")"
fi
changed=$((changed + 1))
done
done
# ── Flat cron logs (derive a date from mtime) ────────────────────────────────
# Old: /var/log/sqlite-backup.log → /var/log/xamxam-backup-YYYY-MM-DD.log
# Old: /var/log/xamxam-cleanup.log → /var/log/xamxam-cleanup-YYYY-MM-DD.log
info "cron logs — /var/log"
rename_cron_log() {
local src="$1" svc="$2"
[ -f "$src" ] || return 0
local d
d=$(date -r "$src" +%Y-%m-%d 2>/dev/null || stat -c %y "$src" | cut -d' ' -f1)
local dst="/var/log/xamxam-$svc-$d.log"
if [ -e "$dst" ]; then
warn "skip (dest exists): $(basename "$src")"
return 0
fi
if [ "$APPLY" -eq 1 ]; then
mv "$src" "$dst" && ok "renamed $(basename "$src") → $(basename "$dst")"
else
info "[dry-run] $(basename "$src") → $(basename "$dst")"
fi
changed=$((changed + 1))
}
rename_cron_log /var/log/sqlite-backup.log backup
rename_cron_log /var/log/xamxam-cleanup.log cleanup
echo ""
if [ "$APPLY" -eq 0 ]; then
info "Dry-run complete. Re-run with --apply to perform the renames."
else
ok "Renames complete ($changed changed)."
fi
+6 -7
View File
@@ -88,13 +88,12 @@ chown -R "$WEB_USER:$APP_GROUP" "$APP_DIR/storage/cache"
chmod -R 2775 "$APP_DIR/storage/cache"
ok "Cache dirs: created and owned by $WEB_USER:$APP_GROUP"
# ── 8. Provision /var/log/xamxam.log ─────────────────────────────────────────
if [ ! -f /var/log/xamxam.log ]; then
touch /var/log/xamxam.log
fi
chown "$WEB_USER:$APP_GROUP" /var/log/xamxam.log
chmod 640 /var/log/xamxam.log
ok "/var/log/xamxam.log: owned by $WEB_USER:$APP_GROUP (640)"
# ── 8. Provision app log directory (/var/log/xamxam) ──────────────────────────────
LOG_DIR="/var/log/xamxam"
mkdir -p "$LOG_DIR"
chown "$WEB_USER:$APP_GROUP" "$LOG_DIR"
chmod 2775 "$LOG_DIR"
ok "/var/log/xamxam: owned by $WEB_USER:$APP_GROUP (2775)"
printf "\n"
ok "Setup complete."