如何 cakephp 3.6 数据库和文件日志
how to cakephp 3.6 database and file logs
如何在 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);
}
}
我现在需要的是做数据库日志
我在网上看到过例子,但是它使用了插件,我不想那样做。
我想要的是为日志创建自定义 table(result_log)。
有可能吗?
有人可以分享他的想法或者 link 我可以分享一些创建数据库日志的指南吗?
您可以创建自己的日志适配器,然后使用它来代替 CakePHP 提供的日志适配器。
如果您想将日志写入数据库,请创建一个 table,烘焙一个模型并在您的日志适配器中使用它,就像您保存 "normal" 实体一样。然后您也可以将其保存到文件中。
有关创建日志适配器的更多信息可以在文档中找到:Creating Log Adapters
您还可以检查它是如何在其中一个插件中制作的,例如在 dereuromark/CakePHP-DatabaseLog
什么 是 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
的数据库 table,您可以尝试使用
烘焙模型
bin/cake bake model ResultLog
(蛋糕的方式是调用 table ResultLogs
- 复数形式,但如果需要的话,可以通过一些配置将其设为单数形式)。
祝你好运!
如何在 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);
}
}
我现在需要的是做数据库日志
我在网上看到过例子,但是它使用了插件,我不想那样做。
我想要的是为日志创建自定义 table(result_log)。
有可能吗?
有人可以分享他的想法或者 link 我可以分享一些创建数据库日志的指南吗?
您可以创建自己的日志适配器,然后使用它来代替 CakePHP 提供的日志适配器。
如果您想将日志写入数据库,请创建一个 table,烘焙一个模型并在您的日志适配器中使用它,就像您保存 "normal" 实体一样。然后您也可以将其保存到文件中。
有关创建日志适配器的更多信息可以在文档中找到:Creating Log Adapters
您还可以检查它是如何在其中一个插件中制作的,例如在 dereuromark/CakePHP-DatabaseLog
什么
我写这篇文章是因为您有自己的日志记录实现,它不遵循 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
的数据库 table,您可以尝试使用
bin/cake bake model ResultLog
(蛋糕的方式是调用 table ResultLogs
- 复数形式,但如果需要的话,可以通过一些配置将其设为单数形式)。
祝你好运!