feat : Decorator Container
This commit is contained in:
@@ -20,12 +20,16 @@ class DecoratorController extends AbstractController
|
|||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
#[RequestMapping(path: 'basic', methods: 'GET')]
|
#[RequestMapping(path: 'basic', methods: 'GET')]
|
||||||
public function basic()
|
public function basic(): array
|
||||||
{
|
{
|
||||||
return (new BasicService)->handle();
|
return (new BasicService)->handle();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function container()
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
#[RequestMapping(path: 'container', methods: 'GET')]
|
||||||
|
public function container(): array
|
||||||
{
|
{
|
||||||
return (new ContainerService)->handle();
|
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;
|
namespace App\Service\Test\Decorator;
|
||||||
|
|
||||||
|
use App\Interface\Test\Decorator\LoggerInterface;
|
||||||
use App\Service\Test\TestBaseService;
|
use App\Service\Test\TestBaseService;
|
||||||
|
use Hyperf\Di\Annotation\Inject;
|
||||||
|
|
||||||
class ContainerService extends TestBaseService
|
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",
|
"license": "Apache-2.0",
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=8.1",
|
"php": ">=8.1",
|
||||||
|
"hyperf/amqp": "~3.1.0",
|
||||||
|
"hyperf/async-queue": "~3.1.0",
|
||||||
"hyperf/cache": "~3.1.0",
|
"hyperf/cache": "~3.1.0",
|
||||||
"hyperf/command": "~3.1.0",
|
"hyperf/command": "~3.1.0",
|
||||||
"hyperf/config": "~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/db-connection": "~3.1.0",
|
||||||
|
"hyperf/elasticsearch": "~3.1.0",
|
||||||
"hyperf/engine": "^2.10",
|
"hyperf/engine": "^2.10",
|
||||||
"hyperf/framework": "~3.1.0",
|
"hyperf/framework": "~3.1.0",
|
||||||
"hyperf/guzzle": "~3.1.0",
|
"hyperf/guzzle": "~3.1.0",
|
||||||
"hyperf/http-server": "~3.1.0",
|
"hyperf/http-server": "~3.1.0",
|
||||||
"hyperf/logger": "~3.1.0",
|
"hyperf/logger": "^3.1",
|
||||||
"hyperf/memory": "~3.1.0",
|
"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/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"
|
"hyperf/tracer": "~3.1.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"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",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "88f2a4d4a4e81dc7d415bcdf39930654",
|
"content-hash": "4ac3b7f3d4fc837bc272d5727a863971",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "carbonphp/carbon-doctrine-types",
|
"name": "carbonphp/carbon-doctrine-types",
|
||||||
|
|||||||
@@ -11,10 +11,23 @@ declare(strict_types=1);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use App\Interface\Test\Adapter\CacheInterface;
|
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\FileCacheAdapter;
|
||||||
use App\Service\Test\Adapter\Cache\RedisCacheService;
|
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 [
|
return [
|
||||||
CacheInterface::class => RedisCacheService::class,
|
CacheInterface::class => RedisCacheService::class,
|
||||||
// CacheInterface::class => FileCacheAdapter::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
|
### Decorator basic test
|
||||||
GET {{host}}/decorator/test/basic
|
GET {{host}}/decorator/test/basic
|
||||||
Content-Type: application/x-www-form-urlencoded
|
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