From 80835d6a083cb93a27be81fc2e80c871dbcc096e Mon Sep 17 00:00:00 2001 From: "Florine W. Dekker" Date: Mon, 20 Mar 2023 13:55:31 +0100 Subject: [PATCH] Create separate log for database events Breaking: The option `[logger.file]` has been renamed to `[logger.filename]` for consistency. --- README.md | 8 ++-- composer.json | 2 +- composer.lock | Bin 77850 -> 77850 bytes package-lock.json | Bin 223332 -> 223332 bytes package.json | 2 +- src/main/api.php | 2 +- src/main/config.default.ini.php | 14 ++++-- .../com/fwdekker/deathnotifier/Database.php | 22 ++++----- .../com/fwdekker/deathnotifier/LoggerUtil.php | 45 +++++++++++++----- .../tracking/UpdateTrackingsAction.php | 12 +++-- .../com/fwdekker/deathnotifier/ConfigTest.php | 2 +- 11 files changed, 71 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 1cfdc01..4c39ca4 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ This tool regularly checks if people are still alive according to Wikipedia, and * [npm](https://www.npmjs.com/) ### Setting up -Install the latest dependencies. +Install the dependencies. Run this after cloning the repo, and each time after pulling new commits. ```shell composer.phar install @@ -87,10 +87,12 @@ For example, you can add the following lines to your crontab (e.g. using `sudo - Replace `secret_password` with the password you configured in `config.ini.php`. ### Logs -It is recommended to also use a tool such as `newsyslog` to manage log rotation. +It is recommended to also use a tool such as +[`newsyslog`](https://man.freebsd.org/cgi/man.cgi?query=newsyslog.conf&sektion=5) to manage log rotation. For example, create the file `/etc/newsyslog.conf.d/death-notifier.conf` with the following contents: ``` -/var/www/death-notifier/.death-notifier.log www:www 644 7 * @T00 JpE +/var/www/death-notifier/.death-notifier.log www:www 600 7 * @T00 JE +/var/www/death-notifier/.death-notifier.db.log www:www 600 7 * $W0D23 JpE ``` ### Initialize diff --git a/composer.json b/composer.json index ce61638..46ed1cc 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "fwdekker/death-notifier", "description": "Get notified when a famous person dies.", - "version": "1.0.1", "_comment_version": "Also update version in `package.json`!", + "version": "1.1.0", "_comment_version": "Also update version in `package.json`!", "type": "project", "license": "MIT", "homepage": "https://git.fwdekker.com/tools/death-notifier", diff --git a/composer.lock b/composer.lock index 0815a60bcbd5236f64d002ab815c762a63ad218b..790ac293406fb7251e59200c6e7a9379cd84a363 100644 GIT binary patch delta 51 zcmbRBfMwPLmJPy;3dyOaDMo2VM&^mB=4r|1rp6|QX-3H=X=z4D1}UbNCe6l-+l?6+ HpX&htw383K delta 51 zcmbRBfMwPLmJPy;3dV^>M#&Z_X=$kj$>ye(W=V#|$p*;=sYc0ZW%5DWkS diff --git a/package-lock.json b/package-lock.json index 98d9124aad83be9d37153572193d3d323d159358..d09f3cfd6e66047411ae294200d99b5fbe9b4d87 100644 GIT binary patch delta 34 ocmaEIf%nM;-U&w2dz~1$Cff9XXyL}&t+yFlZ!>MZ&D@y|01uWAD*ylh delta 34 ocmaEIf%nM;-U&w2<@6Z2Cff9XXyL}&t+yFlZ!>MZ&D@y|0QxZwB>(^b diff --git a/package.json b/package.json index 6e1ad43..a3b76bf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "death-notifier", - "version": "1.0.1", "_comment_version": "Also update version in `composer.json`!", + "version": "1.1.0", "_comment_version": "Also update version in `composer.json`!", "description": "Get notified when a famous person dies.", "author": "Florine W. Dekker", "browser": "dist/bundle.js", diff --git a/src/main/api.php b/src/main/api.php index f314c1f..3eaded0 100644 --- a/src/main/api.php +++ b/src/main/api.php @@ -36,7 +36,7 @@ use com\fwdekker\deathnotifier\Util; require_once __DIR__ . "/.vendor/autoload.php"; -$logger = LoggerUtil::with_name(); +$logger = LoggerUtil::with_name(); // This also registers error handler // Wrap everything in try-catch to always return *something* to user diff --git a/src/main/config.default.ini.php b/src/main/config.default.ini.php index c33641e..fb682fc 100644 --- a/src/main/config.default.ini.php +++ b/src/main/config.default.ini.php @@ -5,13 +5,19 @@ cli_password = REPLACE THIS WITH A SECRET VALUE [database] -# Relative path to SQLite database. +# File to store SQLite database in. filename = .death-notifier.db [logger] -# File to store logs in. -file = .death-notifier.log -# Log level. See https://seldaek.github.io/monolog/doc/01-usage.html#log-levels +# File to store general logs in. +filename = .death-notifier.log +# Log level for general log events. See https://seldaek.github.io/monolog/doc/01-usage.html#log-levels +level = 250 + +[logger_db] +# File to store database logs in. +filename = .death-notifier.db.log +# Log level for database log events. See https://seldaek.github.io/monolog/doc/01-usage.html#log-levels level = 250 [mail] diff --git a/src/main/php/com/fwdekker/deathnotifier/Database.php b/src/main/php/com/fwdekker/deathnotifier/Database.php index 307e6b2..6d0feca 100644 --- a/src/main/php/com/fwdekker/deathnotifier/Database.php +++ b/src/main/php/com/fwdekker/deathnotifier/Database.php @@ -24,7 +24,7 @@ class Database /** * @var Logger the logger to use for logging */ - private readonly Logger $logger; + private readonly Logger $db_logger; /** * @var PDO the PDO object that connects to the database @@ -39,7 +39,7 @@ class Database */ public function __construct(string $filename) { - $this->logger = LoggerUtil::with_name($this::class); + $this->db_logger = LoggerUtil::db_with_name($this::class); $this->conn = new PDO("sqlite:$filename", options: array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)); $this->conn->exec("PRAGMA foreign_keys = ON;"); @@ -64,7 +64,7 @@ class Database if ($stmt->fetch()[0] !== 0) return; - $this->logger->notice("Database does not exist. Installing new database."); + $this->db_logger->notice("Database does not exist. Installing new database."); // Create `meta` table $this->conn->exec("CREATE TABLE meta(k TEXT NOT NULL UNIQUE PRIMARY KEY, v TEXT);"); @@ -77,7 +77,7 @@ class Database $user_list->install(); $tracking_list->install(); - $this->logger->notice("Installation complete."); + $this->db_logger->notice("Installation complete."); }); } @@ -96,7 +96,7 @@ class Database if (Comparator::greaterThanOrEqualTo($db_version, Database::LATEST_VERSION)) return; - $this->logger->notice("Current db is v$db_version. Will migrate to v" . Database::LATEST_VERSION . "."); + $this->db_logger->notice("Current db is v$db_version. Will migrate to v" . Database::LATEST_VERSION . "."); // Get current version $stmt = $this->conn->prepare("SELECT v FROM meta WHERE k='version';"); @@ -115,7 +115,7 @@ class Database $stmt->bindValue(":version", Database::LATEST_VERSION); $stmt->execute(); - $this->logger->notice("Completed migration to v" . Database::LATEST_VERSION . "."); + $this->db_logger->notice("Completed migration to v" . Database::LATEST_VERSION . "."); }); } @@ -127,7 +127,7 @@ class Database */ private function migrate_0_5_0(): void { - $this->logger->notice("Migrating to v0.5.0."); + $this->db_logger->notice("Migrating to v0.5.0."); $this->conn->exec("ALTER TABLE users ADD COLUMN email_notifications_enabled INT NOT NULL DEFAULT(1);"); @@ -141,7 +141,7 @@ class Database */ private function migrate_0_8_0(): void { - $this->logger->notice("Migrating to v0.8.0."); + $this->db_logger->notice("Migrating to v0.8.0."); $this->conn->exec("CREATE TABLE new_email_tasks(type TEXT NOT NULL, recipient TEXT NOT NULL, @@ -163,7 +163,7 @@ class Database */ private function migrate_0_10_0(): void { - $this->logger->notice("Migrating to v0.10.0."); + $this->db_logger->notice("Migrating to v0.10.0."); $this->conn->exec("CREATE TABLE new_email_tasks(type TEXT NOT NULL, recipient TEXT NOT NULL, @@ -188,7 +188,7 @@ class Database */ private function migrate_0_16_0(): void { - $this->logger->notice("Migrating to v0.16.0."); + $this->db_logger->notice("Migrating to v0.16.0."); $this->conn->exec("DROP TABLE email_tasks;"); $this->conn->exec("CREATE TABLE email_tasks(type_key TEXT NOT NULL, @@ -206,7 +206,7 @@ class Database */ private function migrate_0_18_0(): void { - $this->logger->notice("Migrating to v0.18.0."); + $this->db_logger->notice("Migrating to v0.18.0."); $this->conn->exec("CREATE TABLE new_trackings(user_uuid TEXT NOT NULL, person_name TEXT NOT NULL, diff --git a/src/main/php/com/fwdekker/deathnotifier/LoggerUtil.php b/src/main/php/com/fwdekker/deathnotifier/LoggerUtil.php index fbb97e1..b90dc55 100644 --- a/src/main/php/com/fwdekker/deathnotifier/LoggerUtil.php +++ b/src/main/php/com/fwdekker/deathnotifier/LoggerUtil.php @@ -15,28 +15,49 @@ use Monolog\Logger; class LoggerUtil { /** - * @var Logger|null the main logger instance that other loggers are derived from, or `null` if the main logger has - * not been created yet + * @var Logger|null the logger instance for general log events not covered by other loggers */ - private static ?Logger $main_logger = null; + private static ?Logger $general_logger = null; + /** + * @var Logger|null the logger instance for database log events + */ + private static ?Logger $db_logger = null; /** - * Returns a logger with the given name. + * Returns a general logger with the given name. * - * @param string $name the name of the logger to return - * @return Logger a logger with the given name + * @param string $name the name of the general logger to return + * @return Logger a general logger with the given name */ - public static function with_name(string $name = "main"): Logger + public static function with_name(string $name = "general"): Logger { - if (self::$main_logger === null) { + if (self::$general_logger === null) { $config = Config::get("logger"); - self::$main_logger = new Logger("main"); - self::$main_logger->pushHandler(new StreamHandler($config["file"], $config["level"])); - ErrorHandler::register(self::$main_logger); + self::$general_logger = new Logger("general"); + self::$general_logger->pushHandler(new StreamHandler($config["filename"], $config["level"])); + ErrorHandler::register(self::$general_logger); } - return self::$main_logger->withName($name); + return self::$general_logger->withName($name); + } + + /** + * Returns a database logger with the given name. + * + * @param string $name the name of the database logger to return + * @return Logger a database logger with the given name + */ + public static function db_with_name(string $name = "database"): Logger + { + if (self::$db_logger === null) { + $config = Config::get("logger_db"); + + self::$db_logger = new Logger("general"); + self::$db_logger->pushHandler(new StreamHandler($config["filename"], $config["level"])); + } + + return self::$db_logger->withName($name); } } diff --git a/src/main/php/com/fwdekker/deathnotifier/tracking/UpdateTrackingsAction.php b/src/main/php/com/fwdekker/deathnotifier/tracking/UpdateTrackingsAction.php index 558b640..39b4936 100644 --- a/src/main/php/com/fwdekker/deathnotifier/tracking/UpdateTrackingsAction.php +++ b/src/main/php/com/fwdekker/deathnotifier/tracking/UpdateTrackingsAction.php @@ -31,6 +31,10 @@ class UpdateTrackingsAction extends Action * @var Logger the logger to log with */ private readonly Logger $logger; + /** + * @var Logger the database logger to log with + */ + private readonly Logger $db_logger; /** * @var TrackingList the list of trackings to update */ @@ -55,6 +59,7 @@ class UpdateTrackingsAction extends Action public function __construct(TrackingList $tracking_list, Wikipedia $wikipedia, EmailQueue $mailer) { $this->logger = LoggerUtil::with_name($this::class); + $this->db_logger = LoggerUtil::db_with_name($this::class); $this->tracking_list = $tracking_list; $this->wikipedia = $wikipedia; $this->mailer = $mailer; @@ -105,21 +110,20 @@ class UpdateTrackingsAction extends Action // Send mails, log events // TODO: Restrict number of notifications to 1 per hour (excluding "oops we're not sure" message) // TODO: Wait for some time after person has been marked as dead before sending the email - $logger = LoggerUtil::with_name($this::class); $emails = []; $person_names = $new_deletions + $new_undeletions + array_keys($new_status_changes); $trackers = $this->tracking_list->list_trackers($person_names); foreach ($new_deletions as $new_deletion) { - $logger->notice("Deleted article $new_deletion."); + $this->db_logger->notice("Deleted article $new_deletion."); foreach ($trackers[$new_deletion] as $user_email) $emails[] = new NotifyArticleDeletedEmail($user_email, $new_deletion); } foreach ($new_undeletions as $new_undeletion) { - $logger->notice("Undeleted article $new_undeletion."); + $this->db_logger->notice("Undeleted article $new_undeletion."); foreach ($trackers[$new_undeletion] as $user_email) $emails[] = new NotifyArticleUndeletedEmail($user_email, $new_undeletion); @@ -127,7 +131,7 @@ class UpdateTrackingsAction extends Action foreach ($new_status_changes as $person_name => $person_status) { if ($person_status === PersonStatus::Alive) - $logger->notice("Person $person_name is now alive again."); + $this->db_logger->notice("Person $person_name is now alive again."); foreach ($trackers[$person_name] as $user_email) $emails[] = new NotifyStatusChangedEmail($user_email, $person_name, $person_status->value); diff --git a/src/test/php/com/fwdekker/deathnotifier/ConfigTest.php b/src/test/php/com/fwdekker/deathnotifier/ConfigTest.php index 4013923..49df50a 100644 --- a/src/test/php/com/fwdekker/deathnotifier/ConfigTest.php +++ b/src/test/php/com/fwdekker/deathnotifier/ConfigTest.php @@ -1,6 +1,6 @@