feat : Decorator Container
This commit is contained in:
@@ -20,12 +20,16 @@ class DecoratorController extends AbstractController
|
||||
* @return array
|
||||
*/
|
||||
#[RequestMapping(path: 'basic', methods: 'GET')]
|
||||
public function basic()
|
||||
public function basic(): array
|
||||
{
|
||||
return (new BasicService)->handle();
|
||||
}
|
||||
|
||||
public function container()
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
#[RequestMapping(path: 'container', methods: 'GET')]
|
||||
public function container(): array
|
||||
{
|
||||
return (new ContainerService)->handle();
|
||||
}
|
||||
|
||||
16
app/Interface/Test/Decorator/LoggerInterface.php
Normal file
16
app/Interface/Test/Decorator/LoggerInterface.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Interface\Test\Decorator;
|
||||
|
||||
interface LoggerInterface
|
||||
{
|
||||
/**
|
||||
* 定义日志接口
|
||||
* @param string $msg
|
||||
* @return void
|
||||
*/
|
||||
public function log(string $msg): void;
|
||||
public function debug(string $msg): void;
|
||||
public function error(string $msg): void;
|
||||
public function warning(string $msg): void;
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
/**
|
||||
* This service file is part of item.
|
||||
*
|
||||
* @author ctexthuang
|
||||
* @contact ctexthuang@qq.com
|
||||
* @web_site https://ctexthuang.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service\Test\Decorator\Container;
|
||||
|
||||
use App\Interface\Test\Decorator\LoggerInterface;
|
||||
use Hyperf\Di\Annotation\Inject;
|
||||
|
||||
abstract class AbstractLoggerDecorator implements LoggerInterface
|
||||
{
|
||||
/**
|
||||
* 注入日志接口
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
protected LoggerInterface $logger;
|
||||
|
||||
/**
|
||||
* 注入
|
||||
* @param LoggerInterface $logger
|
||||
*/
|
||||
public function __construct(LoggerInterface $logger)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* 抽象复用
|
||||
* @param string $msg
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function decorateMessage(string $msg): string;
|
||||
|
||||
/**
|
||||
* @param string $msg
|
||||
* @return void
|
||||
*/
|
||||
public function debug(string $msg): void
|
||||
{
|
||||
$this->logger->debug($this->decorateMessage($msg));
|
||||
}
|
||||
|
||||
/**
|
||||
* error 级别日志
|
||||
* @param string $msg
|
||||
* @return void
|
||||
*/
|
||||
public function error(string $msg): void
|
||||
{
|
||||
$this->logger->error($this->decorateMessage($msg));
|
||||
}
|
||||
|
||||
/**
|
||||
* warning 级别日志
|
||||
* @param string $msg
|
||||
* @return void
|
||||
*/
|
||||
public function warning(string $msg): void
|
||||
{
|
||||
$this->logger->warning($this->decorateMessage($msg));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* info 级别日志
|
||||
* @param string $msg
|
||||
* @return void
|
||||
*/
|
||||
public function log(string $msg): void
|
||||
{
|
||||
$this->logger->log($this->decorateMessage($msg));
|
||||
}
|
||||
}
|
||||
72
app/Service/Test/Decorator/Container/BasicFileLogger.php
Normal file
72
app/Service/Test/Decorator/Container/BasicFileLogger.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/**
|
||||
* This service file is part of item.
|
||||
*
|
||||
* @author ctexthuang
|
||||
* @contact ctexthuang@qq.com
|
||||
* @web_site https://ctexthuang.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service\Test\Decorator\Container;
|
||||
|
||||
use App\Interface\Test\Decorator\LoggerInterface;
|
||||
use Psr\Log\LoggerInterface as PsrLoggerInterface;
|
||||
use Hyperf\Logger\LoggerFactory as HyperfLoggerFactory;
|
||||
|
||||
class BasicFileLogger implements LoggerInterface
|
||||
{
|
||||
/**
|
||||
* @var PsrLoggerInterface
|
||||
*/
|
||||
private PsrLoggerInterface $logger;
|
||||
|
||||
/**
|
||||
* @param HyperfLoggerFactory $loggerFactory
|
||||
*/
|
||||
public function __construct(HyperfLoggerFactory $loggerFactory)
|
||||
{
|
||||
$this->logger = $loggerFactory->get('app','app');
|
||||
}
|
||||
|
||||
/**
|
||||
* info 级别日志
|
||||
* @param string $msg
|
||||
* @return void
|
||||
*/
|
||||
public function log(string $msg): void
|
||||
{
|
||||
$this->logger->info($msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* debug 级别日志
|
||||
* @param string $msg
|
||||
* @return void
|
||||
*/
|
||||
public function debug(string $msg): void
|
||||
{
|
||||
$this->logger->debug($msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* error 级别日志
|
||||
* @param string $msg
|
||||
* @return void
|
||||
*/
|
||||
public function error(string $msg): void
|
||||
{
|
||||
$this->logger->error($msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* warning 级别日志
|
||||
* @param string $msg
|
||||
* @return void
|
||||
*/
|
||||
public function warning(string $msg): void
|
||||
{
|
||||
$this->logger->warning($msg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/**
|
||||
* This service file is part of item.
|
||||
*
|
||||
* @author ctexthuang
|
||||
* @contact ctexthuang@qq.com
|
||||
* @web_site https://ctexthuang.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service\Test\Decorator\Container;
|
||||
|
||||
use App\Interface\Test\Decorator\LoggerInterface;
|
||||
|
||||
class CriticalLoggerDecorator extends AbstractLoggerDecorator
|
||||
{
|
||||
/**
|
||||
* 注入日志接口
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
protected LoggerInterface $logger;
|
||||
|
||||
/**
|
||||
* @param LoggerInterface $logger
|
||||
*/
|
||||
public function __construct(LoggerInterface $logger)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $msg
|
||||
* @return string
|
||||
*/
|
||||
protected function decorateMessage(string $msg): string
|
||||
{
|
||||
return $msg; //默认严重级别的不装饰
|
||||
}
|
||||
|
||||
/**
|
||||
* 重写 只有当 error 级别日志写入才生效
|
||||
* @param string $msg
|
||||
* @return void
|
||||
*/
|
||||
public function error(string $msg): void
|
||||
{
|
||||
$this->logger->error("[CRITICAL] " . $msg);
|
||||
}
|
||||
}
|
||||
52
app/Service/Test/Decorator/Container/IpLoggerDecorator.php
Normal file
52
app/Service/Test/Decorator/Container/IpLoggerDecorator.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/**
|
||||
* This service file is part of item.
|
||||
*
|
||||
* @author ctexthuang
|
||||
* @contact ctexthuang@qq.com
|
||||
* @web_site https://ctexthuang.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service\Test\Decorator\Container;
|
||||
|
||||
use App\Interface\Test\Decorator\LoggerInterface;
|
||||
use Hyperf\Di\Annotation\Inject;
|
||||
use Hyperf\HttpServer\Contract\RequestInterface;
|
||||
|
||||
class IpLoggerDecorator extends AbstractLoggerDecorator
|
||||
{
|
||||
/**
|
||||
* 注入请求接口
|
||||
* @var RequestInterface
|
||||
*/
|
||||
protected RequestInterface $request;
|
||||
|
||||
/**
|
||||
* 注入日志接口
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
protected LoggerInterface $logger;
|
||||
|
||||
/**
|
||||
* @param LoggerInterface $logger
|
||||
* @param RequestInterface $request
|
||||
*/
|
||||
public function __construct(LoggerInterface $logger,RequestInterface $request)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* ip装饰
|
||||
* @param string $msg
|
||||
* @return string
|
||||
*/
|
||||
protected function decorateMessage(string $msg): string
|
||||
{
|
||||
$ip = $this->request->getServerParams()['remote_addr'] ?? 'unknown';
|
||||
return "[IP: {$ip}] " . $msg;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* This service file is part of item.
|
||||
*
|
||||
* @author ctexthuang
|
||||
* @contact ctexthuang@qq.com
|
||||
* @web_site https://ctexthuang.com
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service\Test\Decorator\Container;
|
||||
|
||||
use App\Interface\Test\Decorator\LoggerInterface;
|
||||
|
||||
class TimestampLoggerDecorator extends AbstractLoggerDecorator
|
||||
{
|
||||
/**
|
||||
* 注入日志接口
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
protected LoggerInterface $logger;
|
||||
|
||||
/**
|
||||
* 这里不能注解注入 会导致重复
|
||||
* @param LoggerInterface $logger
|
||||
*/
|
||||
public function __construct(LoggerInterface $logger)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
}
|
||||
|
||||
/**
|
||||
* 复用日期
|
||||
* @param string $msg
|
||||
* @return string
|
||||
*/
|
||||
protected function decorateMessage(string $msg): string
|
||||
{
|
||||
return '[' . date('Y-m-d H:i:s') . '] ' . $msg;
|
||||
}
|
||||
}
|
||||
@@ -11,12 +11,41 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Service\Test\Decorator;
|
||||
|
||||
use App\Interface\Test\Decorator\LoggerInterface;
|
||||
use App\Service\Test\TestBaseService;
|
||||
use Hyperf\Di\Annotation\Inject;
|
||||
|
||||
class ContainerService extends TestBaseService
|
||||
{
|
||||
public function handle()
|
||||
/**
|
||||
* 注解注入日志接口
|
||||
* @var LoggerInterface $logger
|
||||
*/
|
||||
#[Inject]
|
||||
protected LoggerInterface $logger;
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function handle(): array
|
||||
{
|
||||
return $this->return->success();
|
||||
$this->logger->log('装饰器 [info] 级别日志');
|
||||
$this->logger->warning('装饰器 [warning] 级别日志');
|
||||
$this->logger->debug('!!装饰器 [debug] 级别日志');
|
||||
$this->logger->error('!!!装饰器 [error] 级别日志');
|
||||
|
||||
return $this->return->success('完成逻辑');
|
||||
}
|
||||
|
||||
/**
|
||||
* 封装Log vs 装饰器
|
||||
*
|
||||
* ---------- 封装Log -----------
|
||||
* 封装Log因为无需额外调用栈无装饰器的额外内存占用
|
||||
*
|
||||
* ---------- 装饰器 -----------
|
||||
* 灵活扩展(比如增加一个 traceId 新增装饰器就好) 可以扩展功能 比如时间戳 比如客户端IP 最重要的错误日志告警-写入后调用报警API-比如企业微信机器人等等
|
||||
*
|
||||
* 优化方案 : 装饰器+异步写入(终极方案)todo 研究方向
|
||||
*/
|
||||
}
|
||||
@@ -13,24 +13,24 @@
|
||||
"license": "Apache-2.0",
|
||||
"require": {
|
||||
"php": ">=8.1",
|
||||
"hyperf/amqp": "~3.1.0",
|
||||
"hyperf/async-queue": "~3.1.0",
|
||||
"hyperf/cache": "~3.1.0",
|
||||
"hyperf/command": "~3.1.0",
|
||||
"hyperf/config": "~3.1.0",
|
||||
"hyperf/constants": "~3.1.0",
|
||||
"hyperf/database": "~3.1.0",
|
||||
"hyperf/db-connection": "~3.1.0",
|
||||
"hyperf/elasticsearch": "~3.1.0",
|
||||
"hyperf/engine": "^2.10",
|
||||
"hyperf/framework": "~3.1.0",
|
||||
"hyperf/guzzle": "~3.1.0",
|
||||
"hyperf/http-server": "~3.1.0",
|
||||
"hyperf/logger": "~3.1.0",
|
||||
"hyperf/logger": "^3.1",
|
||||
"hyperf/memory": "~3.1.0",
|
||||
"hyperf/process": "~3.1.0",
|
||||
"hyperf/database": "~3.1.0",
|
||||
"hyperf/redis": "~3.1.0",
|
||||
"hyperf/constants": "~3.1.0",
|
||||
"hyperf/async-queue": "~3.1.0",
|
||||
"hyperf/amqp": "~3.1.0",
|
||||
"hyperf/model-cache": "~3.1.0",
|
||||
"hyperf/elasticsearch": "~3.1.0",
|
||||
"hyperf/process": "~3.1.0",
|
||||
"hyperf/redis": "~3.1.0",
|
||||
"hyperf/tracer": "~3.1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
|
||||
2
composer.lock
generated
2
composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "88f2a4d4a4e81dc7d415bcdf39930654",
|
||||
"content-hash": "4ac3b7f3d4fc837bc272d5727a863971",
|
||||
"packages": [
|
||||
{
|
||||
"name": "carbonphp/carbon-doctrine-types",
|
||||
|
||||
@@ -11,10 +11,23 @@ declare(strict_types=1);
|
||||
*/
|
||||
|
||||
use App\Interface\Test\Adapter\CacheInterface;
|
||||
use App\Interface\Test\Decorator\LoggerInterface;
|
||||
use App\Service\Test\Adapter\Cache\FileCacheAdapter;
|
||||
use App\Service\Test\Adapter\Cache\RedisCacheService;
|
||||
use App\Service\Test\Decorator\Container\BasicFileLogger;
|
||||
use App\Service\Test\Decorator\Container\CriticalLoggerDecorator;
|
||||
use App\Service\Test\Decorator\Container\IpLoggerDecorator;
|
||||
use App\Service\Test\Decorator\Container\TimestampLoggerDecorator;
|
||||
use Hyperf\Logger\LoggerFactory;
|
||||
use function Hyperf\Support\make;
|
||||
|
||||
return [
|
||||
CacheInterface::class => RedisCacheService::class,
|
||||
// CacheInterface::class => FileCacheAdapter::class,
|
||||
LoggerInterface::class => function () {
|
||||
$logger = make(BasicFileLogger::class);
|
||||
$logger = make(TimestampLoggerDecorator::class, ['logger' => $logger]);
|
||||
$logger = make(IpLoggerDecorator::class, ['logger' => $logger]);
|
||||
return make(CriticalLoggerDecorator::class, ['logger' => $logger]);
|
||||
},
|
||||
];
|
||||
|
||||
@@ -27,4 +27,22 @@ return [
|
||||
],
|
||||
],
|
||||
],
|
||||
'app' => [
|
||||
'handler' => [
|
||||
'class' => Monolog\Handler\RotatingFileHandler::class,
|
||||
'constructor' => [
|
||||
'filename' => BASE_PATH . '/runtime/logs/app/hyperf.log',
|
||||
'level' => Monolog\Logger::DEBUG,
|
||||
],
|
||||
],
|
||||
'formatter' => [
|
||||
'class' => Monolog\Formatter\LineFormatter::class,
|
||||
'constructor' => [
|
||||
'format' => null,
|
||||
'dateFormat' => null,
|
||||
'allowInlineLineBreaks' => true,
|
||||
'ignoreEmptyContextAndExtra' => true,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
@@ -16,3 +16,8 @@ Content-Type: application/x-www-form-urlencoded
|
||||
### Decorator basic test
|
||||
GET {{host}}/decorator/test/basic
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
|
||||
### Decorator container test
|
||||
GET {{host}}/decorator/test/container
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Reference in New Issue
Block a user