Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
72.73% covered (warning)
72.73%
16 / 22
0.00% covered (danger)
0.00%
0 / 1
CRAP
0.00% covered (danger)
0.00%
0 / 1
DatabaseLog
72.73% covered (warning)
72.73%
16 / 22
0.00% covered (danger)
0.00%
0 / 1
3.18
0.00% covered (danger)
0.00%
0 / 1
 log
72.73% covered (warning)
72.73%
16 / 22
0.00% covered (danger)
0.00%
0 / 1
3.18
1<?php
2declare(strict_types=1);
3
4namespace App\Log\Engine;
5
6use Cake\Log\Engine\BaseLog;
7use Cake\ORM\TableRegistry;
8use Exception;
9use Stringable;
10
11/**
12 * DatabaseLog
13 *
14 * A logging engine that writes log messages to a database table.
15 * This class extends the BaseLog class and implements the log method
16 * to save log entries into the 'SystemLogs' table.
17 */
18class DatabaseLog extends BaseLog
19{
20    /**
21     * Logs a message to the database and falls back to file logging on failure.
22     *
23     * This method attempts to log a message with a specified level and context to the 'SystemLogs' database table.
24     * If the database logging fails, it logs the error details to a file. Additionally, any exceptions encountered
25     * during the logging process are also logged to a file.
26     *
27     * @param mixed $level The severity level of the log message. This can be any type that represents the log level.
28     * @param \Stringable|string $message The log message to be recorded. This can be a string or an object that implements
29     *                                   the Stringable interface.
30     * @param array $context An array of additional context information to include with the log message. The context
31     *                       can contain any additional data that should be logged alongside the message. The 'group_name'
32     *                       key is used to categorize the log entry, defaulting to 'general' if not provided.
33     * @return void
34     * @throws \Exception If an error occurs while attempting to log the message to the database, the exception is caught
35     *                    and its message is logged to a file.
36     */
37    public function log(mixed $level, string|Stringable $message, array $context = []): void
38    {
39        $group = $context['group_name'] ?? 'general';
40
41        $data = [
42            'level' => $level,
43            'message' => $message,
44            'context' => json_encode($context),
45            'created' => date('Y-m-d H:i:s'),
46            'group_name' => $group,
47        ];
48
49        try {
50            $logsTable = TableRegistry::getTableLocator()->get('SystemLogs');
51            $logEntry = $logsTable->newEntity($data);
52            if (!$logsTable->save($logEntry)) {
53                // Log the error to a file if database logging fails
54                file_put_contents(
55                    LOGS . 'database_log_errors.log',
56                    date('Y-m-d H:i:s') . ': Failed to save log entry: ' . json_encode($logEntry->getErrors()) . "\n",
57                    FILE_APPEND,
58                );
59            }
60        } catch (Exception $e) {
61            // Log any exceptions to a file
62            file_put_contents(
63                LOGS . 'database_log_errors.log',
64                date('Y-m-d H:i:s') . ': Exception occurred while logging: ' . $e->getMessage() . "\n",
65                FILE_APPEND,
66            );
67        }
68    }
69}