From 7c31c6123817aa68a4da08c9489e0daebd3227b7 Mon Sep 17 00:00:00 2001 From: Sahil Sharma Date: Mon, 9 Dec 2024 15:31:33 +1100 Subject: [PATCH] Created new drush command for audit trail logs cleaup (#534) * Created new drush command for audit trail logs cleaup * CR changes to add yes option * Removed default yes option and use custom option * Drush service file to register custom cmd * Test failed fixes * Build fixes * Build Fix * Fix build issue * Fix build --------- Co-authored-by: Sahil Sharma Co-authored-by: Sahil Sharma Co-authored-by: sharmasahil --- drush.services.yml | 6 ++ src/Command/AuditLogCleanupCommand.php | 106 +++++++++++++++++++++++++ src/Form/AuditTrailSettingsForm.php | 62 +++++++++++++++ tide_core.links.menu.yml | 6 ++ tide_core.routing.yml | 8 ++ 5 files changed, 188 insertions(+) create mode 100644 drush.services.yml create mode 100755 src/Command/AuditLogCleanupCommand.php create mode 100644 src/Form/AuditTrailSettingsForm.php diff --git a/drush.services.yml b/drush.services.yml new file mode 100644 index 000000000..f7fa3f647 --- /dev/null +++ b/drush.services.yml @@ -0,0 +1,6 @@ +services: + drush.command.tide_core: + class: Drupal\tide_core\Command\AuditLogCleanupCommand + arguments: ['@config.factory'] + tags: + - { name: drush.command } \ No newline at end of file diff --git a/src/Command/AuditLogCleanupCommand.php b/src/Command/AuditLogCleanupCommand.php new file mode 100755 index 000000000..d693d00bd --- /dev/null +++ b/src/Command/AuditLogCleanupCommand.php @@ -0,0 +1,106 @@ +configFactory = $config_factory; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('config.factory') + ); + } + + /** + * Removes log entries older than the configured retention period. + * + * @command tide_core:auditlog-cleanup + * @aliases tcl + * @description Cleans up audittrail logs older than the configured retention period. + * + * @option force-cleanup Skip confirmation and run the cleanup immediately. + */ + public function cleanupLogs($options = ['force-cleanup' => FALSE]) { + // Check if the user passed the --force-cleanup option. + if (!$options['force-cleanup']) { + // If the force-cleanup flag isn't passed, ask for confirmation. + $confirmation = $this->confirmCleanup(); + if (!$confirmation) { + $this->output()->writeln('Cleanup operation cancelled.'); + return; + } + } + + $config = $this->configFactory->get('tide_core.settings'); + define('DEFAULT_LOG_RETENTION_DAYS', 30); + $log_retention_days = $config->get('log_retention_days') ?: DEFAULT_LOG_RETENTION_DAYS; + // Get current date and time. + $current_time = new DateTime(); + $current_time->sub(new DateInterval("P{$log_retention_days}D")); + $threshold_timestamp = $current_time->getTimestamp(); + // Connect to the database. + $database = Database::getConnection(); + $deleted = $database->delete('admin_audit_trail') + ->condition('created', $threshold_timestamp, '<') + ->execute(); + + // Output the result. + $this->output()->writeln("Deleted $deleted log entries older than $log_retention_days days."); + // Run a database optimization command to recover space. + $this->optimizeDatabase(); + } + + /** + * Ask for confirmation before proceeding with the cleanup. + * + * @return bool + * TRUE if the user confirms, FALSE if the user cancels. + */ + private function confirmCleanup() { + $question = 'Are you sure you want to delete log entries older than the configured retention period? (y/n): '; + $confirmation = $this->io()->ask($question, 'n'); + $confirmation = strtolower($confirmation); + // Return TRUE if the user answers 'y' or 'yes'. + return in_array($confirmation, ['y', 'yes']); + } + + /** + * Run database optimization (optional). + * + * @return void + * TRUE write the message. + */ + private function optimizeDatabase() { + $database = Database::getConnection(); + $database->query('OPTIMIZE TABLE {admin_audit_trail}'); + $this->output()->writeln("Database optimized to recover space."); + } + +} diff --git a/src/Form/AuditTrailSettingsForm.php b/src/Form/AuditTrailSettingsForm.php new file mode 100644 index 000000000..79d5679c5 --- /dev/null +++ b/src/Form/AuditTrailSettingsForm.php @@ -0,0 +1,62 @@ +config('tide_core.settings'); + + // Add a text field to specify the number of days for log retention. + $form['log_retention_days'] = [ + '#type' => 'number', + '#title' => $this->t('Log retention days'), + '#description' => $this->t('Enter the number of days after which logs should be deleted.'), + // Default to 30 if not set. + '#default_value' => $config->get('log_retention_days', 30), + '#min' => 1, + '#required' => TRUE, + ]; + + return parent::buildForm($form, $form_state); + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + $this->config('tide_core.settings') + ->set('log_retention_days', $form_state->getValue('log_retention_days')) + ->save(); + + $this->messenger()->addMessage($this->t('The log retention days have been updated.')); + parent::submitForm($form, $form_state); + } + +} diff --git a/tide_core.links.menu.yml b/tide_core.links.menu.yml index 3379177e4..766f1b9f0 100644 --- a/tide_core.links.menu.yml +++ b/tide_core.links.menu.yml @@ -4,3 +4,9 @@ tide_core.moderated_content: parent: system.admin_content route_name: content_moderation.admin_moderated_content weight: 100 + +audit_trail_settings.admin: + title: 'Audit Trail Settings' + description: 'Change audit trail log clean time' + parent: admin_audit_trail.report_form + route_name: audit_trail_settings.admin \ No newline at end of file diff --git a/tide_core.routing.yml b/tide_core.routing.yml index 785595880..3e98bb11d 100644 --- a/tide_core.routing.yml +++ b/tide_core.routing.yml @@ -36,3 +36,11 @@ tide_core.package_version: methods: ['GET'] requirements: _access: 'TRUE' + +audit_trail_settings.admin: + path: '/admin/reports/audit-trail/audit-trail-settings' + defaults: + _form: '\Drupal\tide_core\Form\AuditTrailSettingsForm' + _title: 'Audit Trail Settings' + requirements: + _permission: "access admin audit trail"