mirror of
https://gitee.com/ctexthuang/hyperf_rbac_framework_server_ctexthuang.git
synced 2025-12-25 11:22:10 +08:00
Compare commits
2 Commits
48ad2ebd1b
...
cf5d5059d7
| Author | SHA1 | Date | |
|---|---|---|---|
| cf5d5059d7 | |||
| 0db9995c19 |
16
README.md
16
README.md
@@ -84,4 +84,18 @@ php bin/hyperf.php gen:event TestEvent
|
||||
- `workflow` 工作流改进
|
||||
- `mod` 不确定分类的修改
|
||||
- `wip` 开发中
|
||||
- `types` 类型
|
||||
- `types` 类型
|
||||
|
||||
## cache
|
||||
不允许使用序列化,为跨语言做准备
|
||||
|
||||
## 日志(合理安排)
|
||||
| 分组名称 | 用途 | 日志级别 | 保留天数 | 备注 |
|
||||
|---------|---------|------------|------|----------|
|
||||
| app | 应用业务日志 | DEBUG/INFO | 7 | 主要业务逻辑日志 |
|
||||
| error | 错误日志 | ERROR | 30 | 只记录错误 |
|
||||
| cache | CACHE日志 | DEBUG | 3 | 开发调试用 |
|
||||
| request | 请求访问日志 | INFO | 15 | 记录所有请求 |
|
||||
| cron | 定时任务日志 | INFO | 30 | 定时任务执行记录 |
|
||||
| payment | 支付相关日志 | INFO | 90 | 重要财务数据 |
|
||||
| audit | 审计日志 | INFO | 365 | 重要操作记录 |
|
||||
175
app/Cache/Redis/BaseScript.php
Normal file
175
app/Cache/Redis/BaseScript.php
Normal file
@@ -0,0 +1,175 @@
|
||||
<?php
|
||||
|
||||
namespace App\Cache\Redis;
|
||||
|
||||
|
||||
use App\Lib\Log\Logger;
|
||||
use Hyperf\Contract\ConfigInterface;
|
||||
use Hyperf\Redis\Redis;
|
||||
use Exception;
|
||||
use Throwable;
|
||||
|
||||
abstract class BaseScript
|
||||
{
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
protected ?string $sha1 = null;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected bool $debugMode;
|
||||
|
||||
/**
|
||||
* @var Redis
|
||||
*/
|
||||
protected Redis $redis;
|
||||
|
||||
/**
|
||||
* @var ConfigInterface
|
||||
*/
|
||||
protected ConfigInterface $config;
|
||||
|
||||
protected Logger $logger;
|
||||
|
||||
/**
|
||||
* @param Redis $redis
|
||||
* @param ConfigInterface $config
|
||||
* @param Logger $logger
|
||||
*/
|
||||
public function __construct(
|
||||
Redis $redis,
|
||||
ConfigInterface $config,
|
||||
Logger $logger
|
||||
)
|
||||
{
|
||||
$this->redis = $redis;
|
||||
$this->debugMode = $config->get('app_debug',false);
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取脚本名称(对应lua文件名)
|
||||
* @return string
|
||||
*/
|
||||
abstract public function getName(): string;
|
||||
|
||||
/**
|
||||
* @param array $keys
|
||||
* @param array $args
|
||||
* @param int|null $numKeys
|
||||
* @return mixed
|
||||
*/
|
||||
protected function run(
|
||||
array $keys,
|
||||
array $args,
|
||||
?int $numKeys = null
|
||||
): mixed
|
||||
{
|
||||
$numKeys = $numKeys ?? count($keys);
|
||||
|
||||
try {
|
||||
$script = $this->getScriptContent();
|
||||
// $this->logExecution($keys, $args, true);
|
||||
return $this->execute($script, $keys, $args, $numKeys);
|
||||
} catch (Exception|Throwable $e) {
|
||||
$this->logExecution($keys, $args, false, $e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function getScriptContent(): string
|
||||
{
|
||||
$path = __DIR__.'/Script/'.$this->getName().'.lua';
|
||||
// $path = __DIR__.'/Lua/'.$this->getName().'.lua';
|
||||
|
||||
if (!file_exists($path)) throw new Exception('lua文件不存在');
|
||||
|
||||
$content = file_get_contents($path);
|
||||
if ($content === false) throw new Exception('lua文件读取失败');
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $script
|
||||
* @param array $keys
|
||||
* @param array $args
|
||||
* @param int $numKeys
|
||||
* @return mixed
|
||||
*/
|
||||
protected function execute(
|
||||
string $script,
|
||||
array $keys,
|
||||
array $args,
|
||||
int $numKeys
|
||||
): mixed
|
||||
{
|
||||
if (
|
||||
!$this->debugMode &&
|
||||
$this->sha1
|
||||
)
|
||||
{
|
||||
try {
|
||||
return $this->redis->evalsha(
|
||||
$this->sha1,
|
||||
array_merge($keys, $args),
|
||||
$numKeys
|
||||
);
|
||||
} catch (Throwable $e)
|
||||
{
|
||||
// SHA1 不存在时回避
|
||||
$this->sha1 = null;
|
||||
}
|
||||
}
|
||||
|
||||
$result = $this->redis->eval(
|
||||
$script,
|
||||
array_merge($keys, $args),
|
||||
$numKeys
|
||||
);
|
||||
$this->sha1 = sha1($script);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $keys
|
||||
* @param array $args
|
||||
* @param bool $success
|
||||
* @param Throwable|null $e
|
||||
* @return void
|
||||
*/
|
||||
protected function logExecution(
|
||||
array $keys,
|
||||
array $args,
|
||||
bool $success,
|
||||
?Throwable $e = null,
|
||||
): void
|
||||
{
|
||||
$context = [
|
||||
'script' => $this->getName(),
|
||||
'keys' => $keys,
|
||||
'args' => $args,
|
||||
'success' => $success,
|
||||
'error' => $e?->getMessage(),
|
||||
'line' => $e?->getLine(),
|
||||
'trace' => $e?->getTraceAsString()
|
||||
];
|
||||
|
||||
$logStrategy = match(true) {
|
||||
!$success => $this->logger->cache()->error(...),
|
||||
$this->debugMode => $this->logger->cache()->debug(...),
|
||||
default => fn() => null // 不记录
|
||||
};
|
||||
|
||||
if (!$logStrategy) return;
|
||||
|
||||
$logStrategy('Redis Lua execution', $context);
|
||||
}
|
||||
}
|
||||
30
app/Cache/Redis/Lua/RateLimit.php
Normal file
30
app/Cache/Redis/Lua/RateLimit.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Cache\Redis\Lua;
|
||||
|
||||
use App\Cache\Redis\BaseScript;
|
||||
|
||||
class RateLimit extends BaseScript
|
||||
{
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'rate_limit';
|
||||
}
|
||||
|
||||
/**
|
||||
* 限流
|
||||
* @param string $key
|
||||
* @param int $limit
|
||||
* @param int $window
|
||||
* @return array
|
||||
*/
|
||||
public function check(string $key, int $limit, int $window): array
|
||||
{
|
||||
$result = $this->run([$key], [$limit, $window]);
|
||||
if (!$result) return [];
|
||||
return [(bool)$result[0], (int)$result[1]];
|
||||
}
|
||||
}
|
||||
82
app/Cache/Redis/RedisCache.php
Normal file
82
app/Cache/Redis/RedisCache.php
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
namespace App\Cache\Redis;
|
||||
|
||||
use App\Lib\Log\Logger;
|
||||
use Hyperf\Contract\ConfigInterface;
|
||||
use Hyperf\Redis\RedisFactory;
|
||||
use Hyperf\Redis\RedisProxy;
|
||||
|
||||
/**
|
||||
* @mixin RedisProxy
|
||||
*/
|
||||
class RedisCache
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private string $poolName = 'default';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private array $luaHandlers = [];
|
||||
|
||||
/**
|
||||
* @param RedisFactory $redisFactory
|
||||
* @param ConfigInterface $config
|
||||
* @param Logger $logger
|
||||
*/
|
||||
public function __construct(
|
||||
protected readonly RedisFactory $redisFactory,
|
||||
protected readonly ConfigInterface $config,
|
||||
protected readonly Logger $logger
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @param string $poolName
|
||||
* @return $this
|
||||
*/
|
||||
public function with(string $poolName = 'default'): self
|
||||
{
|
||||
$new = clone $this;
|
||||
$new->poolName = $poolName;
|
||||
return $new;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return RedisProxy
|
||||
*/
|
||||
public function client(): RedisProxy
|
||||
{
|
||||
return $this->redisFactory->get($this->poolName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $scriptClass
|
||||
* @return mixed
|
||||
*/
|
||||
public function lua(string $scriptClass): mixed
|
||||
{
|
||||
$poolName = $this->poolName ?? 'default';
|
||||
$key = $poolName . ':' . $scriptClass;
|
||||
|
||||
if (!isset($this->luaHandlers[$key])) {
|
||||
$this->luaHandlers[$key] = new $scriptClass(
|
||||
$this->client(),
|
||||
$this->config,
|
||||
$this->logger
|
||||
);
|
||||
}
|
||||
|
||||
return $this->luaHandlers[$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* 魔术方法代理原生 Redis 命令 (默认连接池)
|
||||
*/
|
||||
public function __call(string $method, array $arguments)
|
||||
{
|
||||
return $this->client()->{$method}(...$arguments);
|
||||
}
|
||||
}
|
||||
15
app/Cache/Redis/RedisKey.php
Normal file
15
app/Cache/Redis/RedisKey.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Cache\Redis;
|
||||
|
||||
class RedisKey
|
||||
{
|
||||
/**
|
||||
* @param int $id
|
||||
* @return string
|
||||
*/
|
||||
public static function getAdminUserInfoKey(int $id): string
|
||||
{
|
||||
return 'admin_user:'.$id;
|
||||
}
|
||||
}
|
||||
31
app/Cache/Redis/RedisProxyWrapper.php
Normal file
31
app/Cache/Redis/RedisProxyWrapper.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Cache\Redis;
|
||||
|
||||
use Hyperf\Redis\RedisProxy;
|
||||
|
||||
class RedisProxyWrapper
|
||||
{
|
||||
public function __construct(
|
||||
protected readonly RedisProxy $redisProxy,
|
||||
protected string $poolName
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @param array $arguments
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call(string $method, array $arguments)
|
||||
{
|
||||
return $this->redisProxy->{$method}(...$arguments);
|
||||
}
|
||||
|
||||
public function lua(string $scriptClass)
|
||||
{
|
||||
// 这里实现你的 Lua 脚本逻辑
|
||||
$key = $this->poolName . ':' . $scriptClass;
|
||||
// 实际实现根据你的需求
|
||||
return $this->redisProxy->eval($scriptClass, 0);
|
||||
}
|
||||
}
|
||||
18
app/Cache/Redis/Script/rate_limit.lua
Normal file
18
app/Cache/Redis/Script/rate_limit.lua
Normal file
@@ -0,0 +1,18 @@
|
||||
-- app/Cache/Redis/Script/rate_limit.lua
|
||||
local key = KEYS[1]
|
||||
local limit = tonumber(ARGV[1])
|
||||
local window = tonumber(ARGV[2])
|
||||
local current = redis.call('GET', key)
|
||||
local remaining = 0
|
||||
if current then
|
||||
remaining = tonumber(current) - 1
|
||||
if remaining >= 0 then
|
||||
redis.call('DECR', key)
|
||||
else
|
||||
remaining = -1
|
||||
end
|
||||
else
|
||||
remaining = limit - 1
|
||||
redis.call('SET', key, remaining, 'EX', window)
|
||||
end
|
||||
return {remaining >= 0, remaining}
|
||||
91
app/Lib/Log/Logger.php
Normal file
91
app/Lib/Log/Logger.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
namespace App\Lib\Log;
|
||||
|
||||
use Hyperf\Logger\LoggerFactory;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* Log类分组调用
|
||||
* config/autoload/logger.php 在前面的配置文件中添加分组 在这个文件中添加方法(也可以直接调用 channel('分组名称'))
|
||||
*/
|
||||
class Logger
|
||||
{
|
||||
/**
|
||||
* @var LoggerFactory
|
||||
*/
|
||||
protected LoggerFactory $loggerFactory;
|
||||
|
||||
/**
|
||||
* @param LoggerFactory $loggerFactory
|
||||
*/
|
||||
public function __construct(LoggerFactory $loggerFactory)
|
||||
{
|
||||
$this->loggerFactory = $loggerFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LoggerInterface
|
||||
*/
|
||||
public function default(): LoggerInterface
|
||||
{
|
||||
return $this->loggerFactory->get('default','default');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LoggerInterface
|
||||
*/
|
||||
public function error(): LoggerInterface
|
||||
{
|
||||
return $this->loggerFactory->get('error','error');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LoggerInterface
|
||||
*/
|
||||
public function request(): LoggerInterface
|
||||
{
|
||||
return $this->loggerFactory->get('request','request');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LoggerInterface
|
||||
*/
|
||||
public function cron(): LoggerInterface
|
||||
{
|
||||
return $this->loggerFactory->get('cron','cron');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LoggerInterface
|
||||
*/
|
||||
public function payment(): LoggerInterface
|
||||
{
|
||||
return $this->loggerFactory->get('payment','payment');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LoggerInterface
|
||||
*/
|
||||
public function audit(): LoggerInterface
|
||||
{
|
||||
return $this->loggerFactory->get('audit','audit');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LoggerInterface
|
||||
*/
|
||||
public function cache(): LoggerInterface
|
||||
{
|
||||
return $this->loggerFactory->get('cache','cache');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $channel
|
||||
* @return LoggerInterface
|
||||
*/
|
||||
public function channel(string $channel): LoggerInterface
|
||||
{
|
||||
return $this->loggerFactory->get($channel, $channel);
|
||||
}
|
||||
}
|
||||
@@ -31,4 +31,13 @@ final class AdminUserRepository extends BaseRepository
|
||||
->where('username', $username)
|
||||
->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $id
|
||||
* @return array|null
|
||||
*/
|
||||
public function findById(mixed $id): ?array
|
||||
{
|
||||
return $this->getQuery()->whereKey($id)->first()?->toArray() ?? null;
|
||||
}
|
||||
}
|
||||
@@ -10,15 +10,20 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Service\Admin\AdminUser;
|
||||
|
||||
use App\Cache\Redis\Lua\RateLimit;
|
||||
use App\Cache\Redis\RedisCache;
|
||||
use App\Lib\Jwt\RequestScopedTokenTrait;
|
||||
use App\Repository\AdminUserRepository;
|
||||
use App\Service\Admin\BaseAdminService;
|
||||
use App\Service\BaseTokenService;
|
||||
use App\Trait\AdminUserTrait;
|
||||
use Hyperf\Collection\Arr;
|
||||
use Hyperf\Di\Annotation\Inject;
|
||||
use Lcobucci\JWT\Token\RegisteredClaims;
|
||||
|
||||
class UserService extends BaseAdminService
|
||||
{
|
||||
use RequestScopedTokenTrait;
|
||||
use AdminUserTrait;
|
||||
|
||||
/**
|
||||
* @var BaseTokenService
|
||||
@@ -26,13 +31,26 @@ class UserService extends BaseAdminService
|
||||
#[Inject]
|
||||
protected BaseTokenService $tokenService;
|
||||
|
||||
#[Inject]
|
||||
protected RedisCache $redisCache;
|
||||
|
||||
public function handle(): array
|
||||
{
|
||||
var_dump($this->getToken()->claims()->all());
|
||||
var_dump($this->getToken()->claims()->get(RegisteredClaims::ID));
|
||||
var_dump($this->getToken()->claims()->get(RegisteredClaims::AUDIENCE));
|
||||
$this->redisCache->with()->set('123',1);
|
||||
$this->redisCache->with()->lua(RateLimit::class)->check('user:123', 10, 60);
|
||||
|
||||
return $this->adminReturn->success(
|
||||
'success',
|
||||
Arr::only(
|
||||
$this->getAdminUserInfo($this->adminId) ?: [],
|
||||
['username', 'nickname', 'avatar', 'signed', 'backend_setting', 'phone', 'email']
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private function user()
|
||||
{
|
||||
|
||||
return $this->adminReturn->success();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -10,13 +10,16 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Service\Admin;
|
||||
|
||||
use App\Lib\Jwt\RequestScopedTokenTrait;
|
||||
use App\Lib\Return\AdminReturn;
|
||||
use Hyperf\Context\Context;
|
||||
use Hyperf\Di\Annotation\Inject;
|
||||
use Hyperf\HttpServer\Contract\RequestInterface;
|
||||
use Lcobucci\JWT\Token\RegisteredClaims;
|
||||
|
||||
abstract class BaseAdminService
|
||||
{
|
||||
use RequestScopedTokenTrait;
|
||||
|
||||
/**
|
||||
* 请求对象注入
|
||||
* @var RequestInterface
|
||||
@@ -42,7 +45,7 @@ abstract class BaseAdminService
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->adminId = Context::get('admin_id',0);
|
||||
$this->adminId = (int) $this->getToken()?->claims()?->get(RegisteredClaims::ID) ?? 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,8 +19,6 @@ use Lcobucci\JWT\UnencryptedToken;
|
||||
|
||||
class RefreshService extends BaseAdminService
|
||||
{
|
||||
use RequestScopedTokenTrait;
|
||||
|
||||
/**
|
||||
* @var BaseTokenService
|
||||
*/
|
||||
|
||||
50
app/Trait/AdminUserTrait.php
Normal file
50
app/Trait/AdminUserTrait.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace App\Trait;
|
||||
|
||||
use App\Cache\Redis\RedisCache;
|
||||
use App\Cache\Redis\RedisKey;
|
||||
use App\Repository\AdminUserRepository;
|
||||
use Hyperf\Context\Context;
|
||||
use Hyperf\Di\Annotation\Inject;
|
||||
|
||||
trait AdminUserTrait
|
||||
{
|
||||
/**
|
||||
* @var RedisCache
|
||||
*/
|
||||
#[Inject]
|
||||
protected RedisCache $redis;
|
||||
|
||||
/**
|
||||
* @var AdminUserRepository
|
||||
*/
|
||||
#[Inject]
|
||||
protected AdminUserRepository $adminUserRepository;
|
||||
|
||||
/**
|
||||
* @param int $adminId
|
||||
* @return array|null
|
||||
*/
|
||||
public function getAdminUserInfo(int $adminId): array|null
|
||||
{
|
||||
$key = RedisKey::getAdminUserInfoKey($adminId);
|
||||
if (Context::has($key)) {
|
||||
return Context::get($key,false);
|
||||
}
|
||||
|
||||
if ($this->redis->with()->exists($key)) {
|
||||
$userInfo = $this->redis->with()->get($key);
|
||||
Context::set($key,$userInfo);
|
||||
return json_decode($userInfo,true);
|
||||
}
|
||||
|
||||
$userInfo = $this->adminUserRepository->findById($adminId);
|
||||
if (!$userInfo) return null;
|
||||
|
||||
Context::set($key, $userInfo);
|
||||
$this->redis->with()->set($key, json_encode($userInfo), 3600);
|
||||
|
||||
return $userInfo;
|
||||
}
|
||||
}
|
||||
@@ -39,9 +39,9 @@ return [
|
||||
// jwt 签名key
|
||||
'key' => InMemory::base64Encoded(env('JWT_SECRET')),
|
||||
// token过期时间,单位为秒
|
||||
'ttl' => (int) env('ADMIN_JWT_TTL', 3),
|
||||
'ttl' => (int) env('ADMIN_JWT_TTL', 3600),
|
||||
// 刷新token过期时间,单位为秒
|
||||
'refresh_ttl' => (int) env('ADMIN_JWT_REFRESH_TTL', 10),
|
||||
'refresh_ttl' => (int) env('ADMIN_JWT_REFRESH_TTL', 7200),
|
||||
'claims' => [
|
||||
// 默认的jwt claims
|
||||
RegisteredClaims::ISSUER => (string) env('APP_NAME') .'_admin',
|
||||
|
||||
@@ -9,17 +9,22 @@ declare(strict_types=1);
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
use Monolog\Formatter\LineFormatter;
|
||||
use Monolog\Handler\RotatingFileHandler;
|
||||
use Monolog\Handler\StreamHandler;
|
||||
|
||||
return [
|
||||
'default' => [
|
||||
'handler' => [
|
||||
'class' => Monolog\Handler\StreamHandler::class,
|
||||
'class' => StreamHandler::class,
|
||||
'constructor' => [
|
||||
'stream' => BASE_PATH . '/runtime/logs/hyperf.log',
|
||||
'level' => Monolog\Logger::DEBUG,
|
||||
],
|
||||
],
|
||||
'formatter' => [
|
||||
'class' => Monolog\Formatter\LineFormatter::class,
|
||||
'class' => LineFormatter::class,
|
||||
'constructor' => [
|
||||
'format' => null,
|
||||
'dateFormat' => 'Y-m-d H:i:s',
|
||||
@@ -27,4 +32,93 @@ return [
|
||||
],
|
||||
],
|
||||
],
|
||||
'app' => [
|
||||
'handler' => [
|
||||
'class' => RotatingFileHandler::class,
|
||||
'constructor' => [
|
||||
'filename' => BASE_PATH . '/runtime/logs/app/app.log',
|
||||
'level' => Monolog\Logger::DEBUG,
|
||||
'maxFiles' => 7,
|
||||
],
|
||||
],
|
||||
'formatter' => [
|
||||
'class' => LineFormatter::class,
|
||||
'constructor' => [
|
||||
'format' => "[%datetime%] %level_name% [%channel%]: %message% %context%\n",
|
||||
'dateFormat' => 'Y-m-d H:i:s',
|
||||
],
|
||||
],
|
||||
],
|
||||
'error' => [
|
||||
'handler' => [
|
||||
'class' => RotatingFileHandler::class,
|
||||
'constructor' => [
|
||||
'filename' => BASE_PATH . '/runtime/logs/error/error.log',
|
||||
'level' => Monolog\Logger::ERROR,
|
||||
'maxFiles' => 30,
|
||||
],
|
||||
// 可以添加邮件通知handler
|
||||
// [
|
||||
// 'class' => \Monolog\Handler\NativeMailerHandler::class,
|
||||
// 'constructor' => [
|
||||
// 'to' => 'admin@example.com',
|
||||
// 'subject' => 'Application Error',
|
||||
// 'from' => 'error@example.com',
|
||||
// 'level' => Monolog\Logger::ERROR,
|
||||
// ],
|
||||
// ],
|
||||
],
|
||||
],
|
||||
'request' => [
|
||||
'handler' => [
|
||||
'class' => RotatingFileHandler::class,
|
||||
'constructor' => [
|
||||
'filename' => BASE_PATH . '/runtime/logs/request/request.log',
|
||||
'level' => Monolog\Logger::INFO,
|
||||
'maxFiles' => 15,
|
||||
],
|
||||
],
|
||||
],
|
||||
'cron' => [
|
||||
'handler' => [
|
||||
[
|
||||
'class' => RotatingFileHandler::class,
|
||||
'constructor' => [
|
||||
'filename' => BASE_PATH . '/runtime/logs/crontab/cron.log',
|
||||
'level' => Monolog\Logger::INFO,
|
||||
'maxFiles' => 30,
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
'payment' => [
|
||||
'handler' => [
|
||||
'class' => RotatingFileHandler::class,
|
||||
'constructor' => [
|
||||
'filename' => BASE_PATH . '/runtime/logs/payment/payment.log',
|
||||
'level' => Monolog\Logger::INFO,
|
||||
'maxFiles' => 90,
|
||||
],
|
||||
],
|
||||
],
|
||||
'audit' => [
|
||||
'handler' => [
|
||||
'class' => RotatingFileHandler::class,
|
||||
'constructor' => [
|
||||
'filename' => BASE_PATH . '/runtime/logs/audit.log',
|
||||
'level' => Monolog\Logger::INFO,
|
||||
'maxFiles' => 365,
|
||||
],
|
||||
],
|
||||
],
|
||||
'cache' => [
|
||||
'handler' => [
|
||||
'class' => RotatingFileHandler::class,
|
||||
'constructor' => [
|
||||
'filename' => BASE_PATH . '/runtime/logs/cache/cache.log',
|
||||
'level' => Monolog\Logger::DEBUG,
|
||||
'maxFiles' => 3,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user