From 15652bad67f1b2e210b9e026b1c3c6b7bdd26c11 Mon Sep 17 00:00:00 2001 From: Pinga <121483313+getpinga@users.noreply.github.com> Date: Fri, 14 Feb 2025 15:54:15 +0200 Subject: [PATCH] Improvements to the logging system --- automation/composer.json | 3 +- automation/helpers.php | 88 ++++++++++++++++++++++++++++++++++---- das/composer.json | 4 +- das/helpers.php | 88 ++++++++++++++++++++++++++++++++++---- docs/install.sh | 2 +- docs/update1016.sh | 2 + epp/composer.json | 4 +- epp/src/helpers.php | 88 ++++++++++++++++++++++++++++++++++---- rdap/composer.json | 4 +- rdap/helpers.php | 88 ++++++++++++++++++++++++++++++++++---- whois/port43/composer.json | 4 +- whois/port43/helpers.php | 88 ++++++++++++++++++++++++++++++++++---- 12 files changed, 417 insertions(+), 46 deletions(-) diff --git a/automation/composer.json b/automation/composer.json index deb9d10..0d4c634 100644 --- a/automation/composer.json +++ b/automation/composer.json @@ -13,6 +13,7 @@ "phpmailer/phpmailer": "^6.9", "league/plates": "^3.6", "moneyphp/money": "^4.6", - "utopia-php/messaging": "^0.9.1" + "utopia-php/messaging": "^0.9.1", + "filips123/monolog-phpmailer": "^2.0" } } diff --git a/automation/helpers.php b/automation/helpers.php index 5edbd79..6f1debc 100644 --- a/automation/helpers.php +++ b/automation/helpers.php @@ -3,9 +3,15 @@ require_once 'vendor/autoload.php'; use Monolog\Logger; +use MonologPHPMailer\PHPMailerHandler; +use Monolog\Formatter\HtmlFormatter; +use Monolog\Handler\FilterHandler; +use Monolog\Handler\WhatFailureGroupHandler; use Monolog\Handler\StreamHandler; use Monolog\Handler\RotatingFileHandler; use Monolog\Formatter\LineFormatter; +use PHPMailer\PHPMailer\PHPMailer; +use PHPMailer\PHPMailer\Exception; use Ds\Map; use Swoole\Coroutine; use Swoole\Coroutine\Http\Client; @@ -23,32 +29,98 @@ use Money\Exchange\FixedExchange; * @return Logger */ function setupLogger($logFilePath, $channelName = 'app') { - // Create a log channel $log = new Logger($channelName); + + // Load email & pushover configuration + $config = include('/opt/registry/automation/config.php'); - // Set up the console handler + // Console handler (for real-time debugging) $consoleHandler = new StreamHandler('php://stdout', Logger::DEBUG); $consoleFormatter = new LineFormatter( "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n", - "Y-m-d H:i:s.u", // Date format - true, // Allow inline line breaks - true // Ignore empty context and extra + "Y-m-d H:i:s.u", + true, + true ); $consoleHandler->setFormatter($consoleFormatter); $log->pushHandler($consoleHandler); - // Set up the file handler - $fileHandler = new RotatingFileHandler($logFilePath, 0, Logger::DEBUG); + // File handler - Rotates daily, keeps logs for 14 days + $fileHandler = new RotatingFileHandler($logFilePath, 14, Logger::DEBUG); $fileFormatter = new LineFormatter( "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n", - "Y-m-d H:i:s.u" // Date format + "Y-m-d H:i:s.u" ); $fileHandler->setFormatter($fileFormatter); $log->pushHandler($fileHandler); + // Archive logs older than 14 days + archiveOldLogs($logFilePath); + + // Pushover Handler (For CRITICAL, ALERT, EMERGENCY) + if (!empty($config['pushover_key'])) { + $pushoverHandler = new PushoverHandler($config['pushover_key'], Logger::ALERT); + $log->pushHandler($pushoverHandler); + } + + // Email Handler (For CRITICAL, ALERT, EMERGENCY) + if (!empty($config['mailer_smtp_host'])) { + // Create a PHPMailer instance + $mail = new PHPMailer(true); + try { + $mail->isSMTP(); + $mail->Host = $config['mailer_smtp_host']; + $mail->SMTPAuth = true; + $mail->Username = $config['mailer_smtp_username']; + $mail->Password = $config['mailer_smtp_password']; + $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; + $mail->Port = $config['mailer_smtp_port']; + $mail->setFrom($config['mailer_from'], 'Registry System'); + $mail->addAddress($config['iana_email']); + + // Attach PHPMailer to Monolog + $mailerHandler = new PHPMailerHandler($mail); + $mailerHandler->setFormatter(new HtmlFormatter); + + $filteredMailHandler = new FilterHandler($mailerHandler, Logger::ALERT, Logger::EMERGENCY); + $safeMailHandler = new WhatFailureGroupHandler([$filteredMailHandler]); + $log->pushHandler($safeMailHandler); + } catch (Exception $e) { + error_log("Failed to initialize PHPMailer: " . $e->getMessage()); + } + } + return $log; } +function archiveOldLogs($logFilePath) { + $logDir = dirname($logFilePath); + $backupDir = '/opt/backup'; + + if (!is_dir($backupDir)) { + mkdir($backupDir, 0755, true); + } + + $logFiles = glob($logDir . '/*.log'); // Get all log files + $thresholdDate = strtotime('-14 days'); // Logs older than 14 days + + foreach ($logFiles as $file) { + if (filemtime($file) < $thresholdDate) { + $filename = basename($file); + $monthYear = date('F-Y', filemtime($file)); + $zipPath = $backupDir . "/logs-{$monthYear}.zip"; + + // Open or create ZIP archive + $zip = new ZipArchive(); + if ($zip->open($zipPath, ZipArchive::CREATE) === true) { + $zip->addFile($file, $filename); + $zip->close(); + unlink($file); // Delete original log after archiving + } + } + } +} + function fetchCount($pdo, $tableName) { // Calculate the end of the previous day $endOfPreviousDay = date('Y-m-d 23:59:59', strtotime('-1 day')); diff --git a/das/composer.json b/das/composer.json index ac0613b..b8e074c 100644 --- a/das/composer.json +++ b/das/composer.json @@ -1,6 +1,8 @@ { "require": { "monolog/monolog": "^3.7", - "namingo/rately": "^0.1.0" + "namingo/rately": "^0.1.0", + "phpmailer/phpmailer": "^6.9", + "filips123/monolog-phpmailer": "^2.0" } } diff --git a/das/helpers.php b/das/helpers.php index 977072e..10c8bfe 100644 --- a/das/helpers.php +++ b/das/helpers.php @@ -3,9 +3,15 @@ require_once 'vendor/autoload.php'; use Monolog\Logger; +use MonologPHPMailer\PHPMailerHandler; +use Monolog\Formatter\HtmlFormatter; +use Monolog\Handler\FilterHandler; +use Monolog\Handler\WhatFailureGroupHandler; use Monolog\Handler\StreamHandler; use Monolog\Handler\RotatingFileHandler; use Monolog\Formatter\LineFormatter; +use PHPMailer\PHPMailer\PHPMailer; +use PHPMailer\PHPMailer\Exception; /** * Sets up and returns a Logger instance. @@ -15,32 +21,98 @@ use Monolog\Formatter\LineFormatter; * @return Logger */ function setupLogger($logFilePath, $channelName = 'app') { - // Create a log channel $log = new Logger($channelName); + + // Load email & pushover configuration + $config = include('/opt/registry/automation/config.php'); - // Set up the console handler + // Console handler (for real-time debugging) $consoleHandler = new StreamHandler('php://stdout', Logger::DEBUG); $consoleFormatter = new LineFormatter( "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n", - "Y-m-d H:i:s.u", // Date format - true, // Allow inline line breaks - true // Ignore empty context and extra + "Y-m-d H:i:s.u", + true, + true ); $consoleHandler->setFormatter($consoleFormatter); $log->pushHandler($consoleHandler); - // Set up the file handler - $fileHandler = new RotatingFileHandler($logFilePath, 0, Logger::DEBUG); + // File handler - Rotates daily, keeps logs for 14 days + $fileHandler = new RotatingFileHandler($logFilePath, 14, Logger::DEBUG); $fileFormatter = new LineFormatter( "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n", - "Y-m-d H:i:s.u" // Date format + "Y-m-d H:i:s.u" ); $fileHandler->setFormatter($fileFormatter); $log->pushHandler($fileHandler); + // Archive logs older than 14 days + archiveOldLogs($logFilePath); + + // Pushover Handler (For CRITICAL, ALERT, EMERGENCY) + if (!empty($config['pushover_key'])) { + $pushoverHandler = new PushoverHandler($config['pushover_key'], Logger::ALERT); + $log->pushHandler($pushoverHandler); + } + + // Email Handler (For CRITICAL, ALERT, EMERGENCY) + if (!empty($config['mailer_smtp_host'])) { + // Create a PHPMailer instance + $mail = new PHPMailer(true); + try { + $mail->isSMTP(); + $mail->Host = $config['mailer_smtp_host']; + $mail->SMTPAuth = true; + $mail->Username = $config['mailer_smtp_username']; + $mail->Password = $config['mailer_smtp_password']; + $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; + $mail->Port = $config['mailer_smtp_port']; + $mail->setFrom($config['mailer_from'], 'Registry System'); + $mail->addAddress($config['iana_email']); + + // Attach PHPMailer to Monolog + $mailerHandler = new PHPMailerHandler($mail); + $mailerHandler->setFormatter(new HtmlFormatter); + + $filteredMailHandler = new FilterHandler($mailerHandler, Logger::ALERT, Logger::EMERGENCY); + $safeMailHandler = new WhatFailureGroupHandler([$filteredMailHandler]); + $log->pushHandler($safeMailHandler); + } catch (Exception $e) { + error_log("Failed to initialize PHPMailer: " . $e->getMessage()); + } + } + return $log; } +function archiveOldLogs($logFilePath) { + $logDir = dirname($logFilePath); + $backupDir = '/opt/backup'; + + if (!is_dir($backupDir)) { + mkdir($backupDir, 0755, true); + } + + $logFiles = glob($logDir . '/*.log'); // Get all log files + $thresholdDate = strtotime('-14 days'); // Logs older than 14 days + + foreach ($logFiles as $file) { + if (filemtime($file) < $thresholdDate) { + $filename = basename($file); + $monthYear = date('F-Y', filemtime($file)); + $zipPath = $backupDir . "/logs-{$monthYear}.zip"; + + // Open or create ZIP archive + $zip = new ZipArchive(); + if ($zip->open($zipPath, ZipArchive::CREATE) === true) { + $zip->addFile($file, $filename); + $zip->close(); + unlink($file); // Delete original log after archiving + } + } + } +} + function isIpWhitelisted($ip, $pdo) { $stmt = $pdo->prepare("SELECT COUNT(*) FROM registrar_whitelist WHERE addr = ?"); $stmt->execute([$ip]); diff --git a/docs/install.sh b/docs/install.sh index 658bae8..5260e06 100644 --- a/docs/install.sh +++ b/docs/install.sh @@ -117,7 +117,7 @@ if [[ ("$OS" == "Ubuntu" && "$VER" == "22.04") || ("$OS" == "Ubuntu" && "$VER" = apt update -y echo "Installing PHP and required extensions..." - apt install -y ${PHP_VERSION} ${PHP_VERSION}-bcmath ${PHP_VERSION}-cli ${PHP_VERSION}-common ${PHP_VERSION}-curl ${PHP_VERSION}-ds ${PHP_VERSION}-fpm ${PHP_VERSION}-gd ${PHP_VERSION}-gmp ${PHP_VERSION}-gnupg ${PHP_VERSION}-igbinary ${PHP_VERSION}-imap ${PHP_VERSION}-intl ${PHP_VERSION}-mbstring ${PHP_VERSION}-opcache ${PHP_VERSION}-readline ${PHP_VERSION}-redis ${PHP_VERSION}-soap ${PHP_VERSION}-swoole ${PHP_VERSION}-uuid ${PHP_VERSION}-xml + apt install -y ${PHP_VERSION} ${PHP_VERSION}-bcmath ${PHP_VERSION}-cli ${PHP_VERSION}-common ${PHP_VERSION}-curl ${PHP_VERSION}-ds ${PHP_VERSION}-fpm ${PHP_VERSION}-gd ${PHP_VERSION}-gmp ${PHP_VERSION}-gnupg ${PHP_VERSION}-igbinary ${PHP_VERSION}-imap ${PHP_VERSION}-intl ${PHP_VERSION}-mbstring ${PHP_VERSION}-opcache ${PHP_VERSION}-readline ${PHP_VERSION}-redis ${PHP_VERSION}-soap ${PHP_VERSION}-swoole ${PHP_VERSION}-uuid ${PHP_VERSION}-xml ${PHP_VERSION}-zip # Set timezone to UTC if it's not already currentTimezone=$(timedatectl status | grep "Time zone" | awk '{print $3}') diff --git a/docs/update1016.sh b/docs/update1016.sh index db9f4bc..b69b498 100644 --- a/docs/update1016.sh +++ b/docs/update1016.sh @@ -64,6 +64,8 @@ systemctl stop msg_worker echo "Clearing cache..." php /var/www/cp/bin/clear_cache.php +apt install -y php8.3-zip + # Clone the new version of the repository echo "Cloning v1.0.16 from the repository..." git clone --branch v1.0.16 --single-branch https://github.com/getnamingo/registry /opt/registry1016 diff --git a/epp/composer.json b/epp/composer.json index 4882902..7c921cc 100644 --- a/epp/composer.json +++ b/epp/composer.json @@ -7,6 +7,8 @@ "league/flysystem": "^3.28", "selective/xmldsig": "^3.1", "namingo/rately": "^0.1.0", - "moneyphp/money": "^4.6" + "moneyphp/money": "^4.6", + "phpmailer/phpmailer": "^6.9", + "filips123/monolog-phpmailer": "^2.0" } } diff --git a/epp/src/helpers.php b/epp/src/helpers.php index 46f1e6e..70dbaa2 100644 --- a/epp/src/helpers.php +++ b/epp/src/helpers.php @@ -3,9 +3,15 @@ require_once __DIR__ . '/../vendor/autoload.php'; use Monolog\Logger; +use MonologPHPMailer\PHPMailerHandler; +use Monolog\Formatter\HtmlFormatter; +use Monolog\Handler\FilterHandler; +use Monolog\Handler\WhatFailureGroupHandler; use Monolog\Handler\StreamHandler; use Monolog\Handler\RotatingFileHandler; use Monolog\Formatter\LineFormatter; +use PHPMailer\PHPMailer\PHPMailer; +use PHPMailer\PHPMailer\Exception; use Pdp\Domain; use Pdp\TopLevelDomains; use League\Flysystem\Local\LocalFilesystemAdapter; @@ -26,32 +32,98 @@ use Money\Exchange\FixedExchange; * @return Logger */ function setupLogger($logFilePath, $channelName = 'app') { - // Create a log channel $log = new Logger($channelName); + + // Load email & pushover configuration + $config = include('/opt/registry/automation/config.php'); - // Set up the console handler + // Console handler (for real-time debugging) $consoleHandler = new StreamHandler('php://stdout', Logger::DEBUG); $consoleFormatter = new LineFormatter( "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n", - "Y-m-d H:i:s.u", // Date format - true, // Allow inline line breaks - true // Ignore empty context and extra + "Y-m-d H:i:s.u", + true, + true ); $consoleHandler->setFormatter($consoleFormatter); $log->pushHandler($consoleHandler); - // Set up the file handler - $fileHandler = new RotatingFileHandler($logFilePath, 0, Logger::DEBUG); + // File handler - Rotates daily, keeps logs for 14 days + $fileHandler = new RotatingFileHandler($logFilePath, 14, Logger::DEBUG); $fileFormatter = new LineFormatter( "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n", - "Y-m-d H:i:s.u" // Date format + "Y-m-d H:i:s.u" ); $fileHandler->setFormatter($fileFormatter); $log->pushHandler($fileHandler); + // Archive logs older than 14 days + archiveOldLogs($logFilePath); + + // Pushover Handler (For CRITICAL, ALERT, EMERGENCY) + if (!empty($config['pushover_key'])) { + $pushoverHandler = new PushoverHandler($config['pushover_key'], Logger::ALERT); + $log->pushHandler($pushoverHandler); + } + + // Email Handler (For CRITICAL, ALERT, EMERGENCY) + if (!empty($config['mailer_smtp_host'])) { + // Create a PHPMailer instance + $mail = new PHPMailer(true); + try { + $mail->isSMTP(); + $mail->Host = $config['mailer_smtp_host']; + $mail->SMTPAuth = true; + $mail->Username = $config['mailer_smtp_username']; + $mail->Password = $config['mailer_smtp_password']; + $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; + $mail->Port = $config['mailer_smtp_port']; + $mail->setFrom($config['mailer_from'], 'Registry System'); + $mail->addAddress($config['iana_email']); + + // Attach PHPMailer to Monolog + $mailerHandler = new PHPMailerHandler($mail); + $mailerHandler->setFormatter(new HtmlFormatter); + + $filteredMailHandler = new FilterHandler($mailerHandler, Logger::ALERT, Logger::EMERGENCY); + $safeMailHandler = new WhatFailureGroupHandler([$filteredMailHandler]); + $log->pushHandler($safeMailHandler); + } catch (Exception $e) { + error_log("Failed to initialize PHPMailer: " . $e->getMessage()); + } + } + return $log; } +function archiveOldLogs($logFilePath) { + $logDir = dirname($logFilePath); + $backupDir = '/opt/backup'; + + if (!is_dir($backupDir)) { + mkdir($backupDir, 0755, true); + } + + $logFiles = glob($logDir . '/*.log'); // Get all log files + $thresholdDate = strtotime('-14 days'); // Logs older than 14 days + + foreach ($logFiles as $file) { + if (filemtime($file) < $thresholdDate) { + $filename = basename($file); + $monthYear = date('F-Y', filemtime($file)); + $zipPath = $backupDir . "/logs-{$monthYear}.zip"; + + // Open or create ZIP archive + $zip = new ZipArchive(); + if ($zip->open($zipPath, ZipArchive::CREATE) === true) { + $zip->addFile($file, $filename); + $zip->close(); + unlink($file); // Delete original log after archiving + } + } + } +} + function checkLogin($db, $clID, $pw) { $stmt = $db->prepare("SELECT pw FROM registrar WHERE clid = :username"); $stmt->execute(['username' => $clID]); diff --git a/rdap/composer.json b/rdap/composer.json index ac0613b..b8e074c 100644 --- a/rdap/composer.json +++ b/rdap/composer.json @@ -1,6 +1,8 @@ { "require": { "monolog/monolog": "^3.7", - "namingo/rately": "^0.1.0" + "namingo/rately": "^0.1.0", + "phpmailer/phpmailer": "^6.9", + "filips123/monolog-phpmailer": "^2.0" } } diff --git a/rdap/helpers.php b/rdap/helpers.php index b4c1f58..5b9fb00 100644 --- a/rdap/helpers.php +++ b/rdap/helpers.php @@ -3,9 +3,15 @@ require_once 'vendor/autoload.php'; use Monolog\Logger; +use MonologPHPMailer\PHPMailerHandler; +use Monolog\Formatter\HtmlFormatter; +use Monolog\Handler\FilterHandler; +use Monolog\Handler\WhatFailureGroupHandler; use Monolog\Handler\StreamHandler; use Monolog\Handler\RotatingFileHandler; use Monolog\Formatter\LineFormatter; +use PHPMailer\PHPMailer\PHPMailer; +use PHPMailer\PHPMailer\Exception; /** * Sets up and returns a Logger instance. @@ -15,32 +21,98 @@ use Monolog\Formatter\LineFormatter; * @return Logger */ function setupLogger($logFilePath, $channelName = 'app') { - // Create a log channel $log = new Logger($channelName); + + // Load email & pushover configuration + $config = include('/opt/registry/automation/config.php'); - // Set up the console handler + // Console handler (for real-time debugging) $consoleHandler = new StreamHandler('php://stdout', Logger::DEBUG); $consoleFormatter = new LineFormatter( "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n", - "Y-m-d H:i:s.u", // Date format - true, // Allow inline line breaks - true // Ignore empty context and extra + "Y-m-d H:i:s.u", + true, + true ); $consoleHandler->setFormatter($consoleFormatter); $log->pushHandler($consoleHandler); - // Set up the file handler - $fileHandler = new RotatingFileHandler($logFilePath, 0, Logger::DEBUG); + // File handler - Rotates daily, keeps logs for 14 days + $fileHandler = new RotatingFileHandler($logFilePath, 14, Logger::DEBUG); $fileFormatter = new LineFormatter( "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n", - "Y-m-d H:i:s.u" // Date format + "Y-m-d H:i:s.u" ); $fileHandler->setFormatter($fileFormatter); $log->pushHandler($fileHandler); + // Archive logs older than 14 days + archiveOldLogs($logFilePath); + + // Pushover Handler (For CRITICAL, ALERT, EMERGENCY) + if (!empty($config['pushover_key'])) { + $pushoverHandler = new PushoverHandler($config['pushover_key'], Logger::ALERT); + $log->pushHandler($pushoverHandler); + } + + // Email Handler (For CRITICAL, ALERT, EMERGENCY) + if (!empty($config['mailer_smtp_host'])) { + // Create a PHPMailer instance + $mail = new PHPMailer(true); + try { + $mail->isSMTP(); + $mail->Host = $config['mailer_smtp_host']; + $mail->SMTPAuth = true; + $mail->Username = $config['mailer_smtp_username']; + $mail->Password = $config['mailer_smtp_password']; + $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; + $mail->Port = $config['mailer_smtp_port']; + $mail->setFrom($config['mailer_from'], 'Registry System'); + $mail->addAddress($config['iana_email']); + + // Attach PHPMailer to Monolog + $mailerHandler = new PHPMailerHandler($mail); + $mailerHandler->setFormatter(new HtmlFormatter); + + $filteredMailHandler = new FilterHandler($mailerHandler, Logger::ALERT, Logger::EMERGENCY); + $safeMailHandler = new WhatFailureGroupHandler([$filteredMailHandler]); + $log->pushHandler($safeMailHandler); + } catch (Exception $e) { + error_log("Failed to initialize PHPMailer: " . $e->getMessage()); + } + } + return $log; } +function archiveOldLogs($logFilePath) { + $logDir = dirname($logFilePath); + $backupDir = '/opt/backup'; + + if (!is_dir($backupDir)) { + mkdir($backupDir, 0755, true); + } + + $logFiles = glob($logDir . '/*.log'); // Get all log files + $thresholdDate = strtotime('-14 days'); // Logs older than 14 days + + foreach ($logFiles as $file) { + if (filemtime($file) < $thresholdDate) { + $filename = basename($file); + $monthYear = date('F-Y', filemtime($file)); + $zipPath = $backupDir . "/logs-{$monthYear}.zip"; + + // Open or create ZIP archive + $zip = new ZipArchive(); + if ($zip->open($zipPath, ZipArchive::CREATE) === true) { + $zip->addFile($file, $filename); + $zip->close(); + unlink($file); // Delete original log after archiving + } + } + } +} + function mapContactToVCard($contactDetails, $role, $c) { // Determine which type of disclosure to use $disclose_name = ($contactDetails['type'] == 'loc') ? $contactDetails['disclose_name_loc'] : $contactDetails['disclose_name_int']; diff --git a/whois/port43/composer.json b/whois/port43/composer.json index ac0613b..b8e074c 100644 --- a/whois/port43/composer.json +++ b/whois/port43/composer.json @@ -1,6 +1,8 @@ { "require": { "monolog/monolog": "^3.7", - "namingo/rately": "^0.1.0" + "namingo/rately": "^0.1.0", + "phpmailer/phpmailer": "^6.9", + "filips123/monolog-phpmailer": "^2.0" } } diff --git a/whois/port43/helpers.php b/whois/port43/helpers.php index edd4e2b..d1bbaee 100644 --- a/whois/port43/helpers.php +++ b/whois/port43/helpers.php @@ -3,9 +3,15 @@ require_once 'vendor/autoload.php'; use Monolog\Logger; +use MonologPHPMailer\PHPMailerHandler; +use Monolog\Formatter\HtmlFormatter; +use Monolog\Handler\FilterHandler; +use Monolog\Handler\WhatFailureGroupHandler; use Monolog\Handler\StreamHandler; use Monolog\Handler\RotatingFileHandler; use Monolog\Formatter\LineFormatter; +use PHPMailer\PHPMailer\PHPMailer; +use PHPMailer\PHPMailer\Exception; /** * Sets up and returns a Logger instance. @@ -15,32 +21,98 @@ use Monolog\Formatter\LineFormatter; * @return Logger */ function setupLogger($logFilePath, $channelName = 'app') { - // Create a log channel $log = new Logger($channelName); + + // Load email & pushover configuration + $config = include('/opt/registry/automation/config.php'); - // Set up the console handler + // Console handler (for real-time debugging) $consoleHandler = new StreamHandler('php://stdout', Logger::DEBUG); $consoleFormatter = new LineFormatter( "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n", - "Y-m-d H:i:s.u", // Date format - true, // Allow inline line breaks - true // Ignore empty context and extra + "Y-m-d H:i:s.u", + true, + true ); $consoleHandler->setFormatter($consoleFormatter); $log->pushHandler($consoleHandler); - // Set up the file handler - $fileHandler = new RotatingFileHandler($logFilePath, 0, Logger::DEBUG); + // File handler - Rotates daily, keeps logs for 14 days + $fileHandler = new RotatingFileHandler($logFilePath, 14, Logger::DEBUG); $fileFormatter = new LineFormatter( "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n", - "Y-m-d H:i:s.u" // Date format + "Y-m-d H:i:s.u" ); $fileHandler->setFormatter($fileFormatter); $log->pushHandler($fileHandler); + // Archive logs older than 14 days + archiveOldLogs($logFilePath); + + // Pushover Handler (For CRITICAL, ALERT, EMERGENCY) + if (!empty($config['pushover_key'])) { + $pushoverHandler = new PushoverHandler($config['pushover_key'], Logger::ALERT); + $log->pushHandler($pushoverHandler); + } + + // Email Handler (For CRITICAL, ALERT, EMERGENCY) + if (!empty($config['mailer_smtp_host'])) { + // Create a PHPMailer instance + $mail = new PHPMailer(true); + try { + $mail->isSMTP(); + $mail->Host = $config['mailer_smtp_host']; + $mail->SMTPAuth = true; + $mail->Username = $config['mailer_smtp_username']; + $mail->Password = $config['mailer_smtp_password']; + $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; + $mail->Port = $config['mailer_smtp_port']; + $mail->setFrom($config['mailer_from'], 'Registry System'); + $mail->addAddress($config['iana_email']); + + // Attach PHPMailer to Monolog + $mailerHandler = new PHPMailerHandler($mail); + $mailerHandler->setFormatter(new HtmlFormatter); + + $filteredMailHandler = new FilterHandler($mailerHandler, Logger::ALERT, Logger::EMERGENCY); + $safeMailHandler = new WhatFailureGroupHandler([$filteredMailHandler]); + $log->pushHandler($safeMailHandler); + } catch (Exception $e) { + error_log("Failed to initialize PHPMailer: " . $e->getMessage()); + } + } + return $log; } +function archiveOldLogs($logFilePath) { + $logDir = dirname($logFilePath); + $backupDir = '/opt/backup'; + + if (!is_dir($backupDir)) { + mkdir($backupDir, 0755, true); + } + + $logFiles = glob($logDir . '/*.log'); // Get all log files + $thresholdDate = strtotime('-14 days'); // Logs older than 14 days + + foreach ($logFiles as $file) { + if (filemtime($file) < $thresholdDate) { + $filename = basename($file); + $monthYear = date('F-Y', filemtime($file)); + $zipPath = $backupDir . "/logs-{$monthYear}.zip"; + + // Open or create ZIP archive + $zip = new ZipArchive(); + if ($zip->open($zipPath, ZipArchive::CREATE) === true) { + $zip->addFile($file, $filename); + $zip->close(); + unlink($file); // Delete original log after archiving + } + } + } +} + function parseQuery($data) { $data = trim($data);