как создать базу данных и файлы журнала CakePHP 3.6 - PullRequest
0 голосов
/ 07 мая 2018

Как я могу объединить базы данных и журналы файлов в cakephp 3.6?

функция для файла журнала уже существует, и вот она (ProjectLog.php):

<?php

namespace Project\Util;

use Monolog\Formatter\LineFormatter;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;

class ProjectLog
{
    /** @var Logger $logger */
    private static $logger;

    /** @var string $filePath */
    private static $filePath;

    /** @var string $key */
    private static $key;

    /**
     * @return string
     */
    public static function getFilePath(): string
    {
        return self::$filePath;
    }

    /**
     * @param string $name
     * @param string $category
     * @param string $client
     * @param string $mall
     * @param bool|null $stdoutFlag
     * @throws \Exception
     */
    public static function setConfig(
        string $name,
        string $category = 'client',
        string $client = 'etc',
        string $mall = 'etc',
        ?bool $stdoutFlag = false
    ) {
        if (empty($name) || empty($category) || empty($client) || empty($mall)) {
            $message = "Logger setting value is incomplete. name:{$name}, category:{$category}, client:{$client}, mall:{$mall}";
            throw new \Exception($message);
        }

        $dir = LOGS . $category . DS . $client . DS . $mall;
        if (!is_dir($dir)) {
            if (!mkdir($dir, 0777, true)) {
                throw new \Exception("Log directory creation failed. dir:{$dir}");
            }
        }

        self::$filePath = $dir . DS . $name . '_' . date('Ymd') . '.log';

        // monolog
        self::$key = self::$key ?? uniqid(mt_rand(10000000, 99999999)); // It looks like a key to be output to a log file. A different number for each process is numbered
        self::$logger = new Logger(self::$key);
        $logLevel = constant('Monolog\Logger::' . OUTPUT_LOG_LEVEL[KEY_ENVIRONMENT]);
        $stream = new StreamHandler(self::$filePath, $logLevel);
        $stream->setFormatter(new LineFormatter(null, null, true, true)); // Set monolog setting to have line feed
        self::$logger->pushHandler($stream);
        if ($stdoutFlag === true) {
            $stream = new StreamHandler("php://stdout", $logLevel);
            $stream->setFormatter(new LineFormatter(null, null, true, true)); // Set monolog setting to have line feed
            self::$logger->pushHandler($stream);
        }
    }

    /**
     * Grant user name to log
     *
     * @param string $userName
     */
    public static function addUserNameProcessor(string $userName): void
    {
        $handlers = self::$logger->getHandlers();

        foreach ($handlers as $handler) {
            $format = "[%extra.user_name%] [%datetime%] %channel%.%level_name%: %message% %context%\n";
            $handler->setFormatter(new LineFormatter($format, null, true, true)); // Set monolog setting to have line feed
        }

        self::$logger->pushProcessor(function ($record) use ($userName) {
            $record['extra']['user_name'] = $userName;
            return $record;
        });
    }

    /**
     * @param string $message
     * @param mixed $param
     */
    public static function emergency(string $message, $param = null): void
    {
        self::write(Logger::EMERGENCY, $message, $param);
    }

    /**
     * @param string $message
     * @param mixed $param
     */
    public static function critical(string $message, $param = null): void
    {
        self::write(Logger::CRITICAL, $message, $param);
    }

    /**
     * @param string $message
     * @param mixed $param
     */
    public static function alert(string $message, $param = null): void
    {
        self::write(Logger::ALERT, $message, $param);
    }

    /**
     * @param string $message
     * @param mixed $param
     */
    public static function error(string $message, $param = null): void
    {
        self::write(Logger::ERROR, $message, $param);
    }

    /**
     * @param string $message
     * @param mixed $param
     */
    public static function warning(string $message, $param = null): void
    {
        self::write(Logger::WARNING, $message, $param);
    }

    /**
     * @param string $message
     * @param mixed $param
     */
    public static function notice(string $message, $param = null): void
    {
        self::write(Logger::NOTICE, $message, $param);
    }

    /**
     * @param string $message
     * @param mixed $param
     */
    public static function info(string $message, $param = null): void
    {
        self::write(Logger::INFO, $message, $param);
    }

    /**
     * @param string $message
     * @param mixed $param
     */
    public static function debug(string $message, $param = null): void
    {
        self::write(Logger::DEBUG, $message, $param);
    }

    /**
     * @param int $level
     * @param string $message
     * @param null|array $param
     * @throws \LogicException
     */
    private static function write(int $level, string $message, $param = null): void
    {
        if (!self::$logger) {
            throw new \LogicException('Logger is not set.');
        }

        // Adjust so that $param can be passed to monolog if it is not an array
        if (is_null($param)) {
            $param = [];
        } elseif (is_object($param)) {
            $param = (array)$param;
        } elseif (!is_array($param)) {
            $param = [$param];
        }

        // Caller file and number of lines
        $backtrace = debug_backtrace();
        $file = $backtrace[1]['file'];
        $line = $backtrace[1]['line'];
        $context = ['file' => $file, 'line' => $line, 'param' => $param];

        self::$logger->addRecord($level, $message, $context);
    }
}

Теперь мне нужно сделать журнал базы данных.

Я видел примеры в Интернете, но он использует плагины, и я не хочу этого делать.

Я хочу создать собственную таблицу для журналов (result_log).

Возможно ли это?

Может ли кто-нибудь поделиться своей идеей или связать меня с некоторыми руководствами по созданию журнала базы данных?

Ответы [ 2 ]

0 голосов
/ 07 мая 2018

Что Сжимон сказал - это способ Cake сделать это, и я согласен с их ответом.

Я пишу это, потому что у вас есть собственная реализация ведения журнала, которая не соответствует конфигурации ведения журнала CakePHP.

В вашем случае, вероятно, самый простой способ сделать это - изменить вашу static::write() функцию и добавить некоторый код в конце, чтобы также сохранить журналы в базе данных.

Нечто подобное:

$ResultLog = TableRegistry::get('ResultLog');

$data = []; //add here data relevant to your logs and the db structure you are using

$logEntry = $ResultLogs->newEntity($data);

if(!($ResultLog->save($logEntry)){
    throw new \LogicException('Could not store the log into the DB.');
}

Прежде чем вызвать ResultLog, вам нужно иметь Model \ Table, которая называется так. Если у вас уже есть таблица базы данных с именем result_log, вы можете попытаться испечь модель с помощью

bin/cake bake model ResultLog

(проще всего было бы назвать таблицу ResultLogs - форма множественного числа, но с небольшим количеством конфигурации вы можете иметь ее в единственном числе, если вы этого хотите).

Удачи!

0 голосов
/ 07 мая 2018

Вы можете создать свой собственный адаптер журнала, а затем использовать его вместо того, который предоставлен CakePHP.

Если вы хотите записать свои журналы в БД, создайте таблицу, запекайте модель и используйте ее в своем адаптере журналов так же, как вы сохранили бы «нормальную» сущность. Затем вы можете сохранить его также в файл.

Более подробную информацию о создании адаптеров журнала можно найти в документации: Создание адаптеров журнала

Вы также можете проверить, как это было сделано в одном из плагинов, например, в dereuromark / CakePHP-DatabaseLog

...