mirror of
https://gitee.com/hyperf/hyperf.git
synced 2024-11-30 02:37:58 +08:00
Merge pull request #415 from limingxinleo/1.0-logger
Added handlers config for logger.
This commit is contained in:
commit
3ee382a896
@ -3,6 +3,7 @@
|
||||
## Added
|
||||
|
||||
- [#405](https://github.com/hyperf-cloud/hyperf/pull/405) Added Context::override() method.
|
||||
- [#415](https://github.com/hyperf-cloud/hyperf/pull/415) Added handlers configuration for logger, now you could config multiple handlers to logger.
|
||||
|
||||
## Fixed
|
||||
- [#414](https://github.com/hyperf-cloud/hyperf/pull/414) Fixed WebSocketExceptionHandler typo
|
||||
|
@ -1,5 +1,15 @@
|
||||
<?php
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://doc.hyperf.io
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
# source: grpc.proto
|
||||
|
||||
namespace GPBMetadata;
|
||||
@ -8,22 +18,22 @@ class Grpc
|
||||
{
|
||||
public static $is_initialized = false;
|
||||
|
||||
public static function initOnce() {
|
||||
public static function initOnce()
|
||||
{
|
||||
$pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
|
||||
|
||||
if (static::$is_initialized == true) {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
$pool->internalAddGeneratedFile(hex2bin(
|
||||
"0aae010a0a677270632e70726f746f12046772706322200a04496e666f12" .
|
||||
"0a0a026964180120012805120c0a046e616d6518022001280922360a0955" .
|
||||
"7365725265706c79120f0a076d65737361676518012001280912180a0469" .
|
||||
"6e666f18022001280b320a2e677270632e496e666f32380a0c757365725f" .
|
||||
"7365727669636512280a0767657455736572120a2e677270632e496e666f" .
|
||||
"1a0f2e677270632e557365725265706c792200620670726f746f33"
|
||||
'0aae010a0a677270632e70726f746f12046772706322200a04496e666f12' .
|
||||
'0a0a026964180120012805120c0a046e616d6518022001280922360a0955' .
|
||||
'7365725265706c79120f0a076d65737361676518012001280912180a0469' .
|
||||
'6e666f18022001280b320a2e677270632e496e666f32380a0c757365725f' .
|
||||
'7365727669636512280a0767657455736572120a2e677270632e496e666f' .
|
||||
'1a0f2e677270632e557365725265706c792200620670726f746f33'
|
||||
));
|
||||
|
||||
static::$is_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,24 +1,33 @@
|
||||
<?php
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://doc.hyperf.io
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
# source: grpc.proto
|
||||
|
||||
namespace Grpc;
|
||||
|
||||
use Google\Protobuf\Internal\GPBType;
|
||||
use Google\Protobuf\Internal\RepeatedField;
|
||||
use Google\Protobuf\Internal\GPBUtil;
|
||||
|
||||
/**
|
||||
* Generated from protobuf message <code>grpc.Info</code>
|
||||
* Generated from protobuf message <code>grpc.Info</code>.
|
||||
*/
|
||||
class Info extends \Google\Protobuf\Internal\Message
|
||||
{
|
||||
/**
|
||||
* Generated from protobuf field <code>int32 id = 1;</code>
|
||||
* Generated from protobuf field <code>int32 id = 1;</code>.
|
||||
*/
|
||||
private $id = 0;
|
||||
|
||||
/**
|
||||
* Generated from protobuf field <code>string name = 2;</code>
|
||||
* Generated from protobuf field <code>string name = 2;</code>.
|
||||
*/
|
||||
private $name = '';
|
||||
|
||||
@ -26,19 +35,20 @@ class Info extends \Google\Protobuf\Internal\Message
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $data {
|
||||
* Optional. Data for populating the Message object.
|
||||
* Optional. Data for populating the Message object.
|
||||
*
|
||||
* @type int $id
|
||||
* @type string $name
|
||||
* @var int $id
|
||||
* @var string $name
|
||||
* }
|
||||
*/
|
||||
public function __construct($data = NULL) {
|
||||
public function __construct($data = null)
|
||||
{
|
||||
\GPBMetadata\Grpc::initOnce();
|
||||
parent::__construct($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generated from protobuf field <code>int32 id = 1;</code>
|
||||
* Generated from protobuf field <code>int32 id = 1;</code>.
|
||||
* @return int
|
||||
*/
|
||||
public function getId()
|
||||
@ -47,7 +57,7 @@ class Info extends \Google\Protobuf\Internal\Message
|
||||
}
|
||||
|
||||
/**
|
||||
* Generated from protobuf field <code>int32 id = 1;</code>
|
||||
* Generated from protobuf field <code>int32 id = 1;</code>.
|
||||
* @param int $var
|
||||
* @return $this
|
||||
*/
|
||||
@ -60,7 +70,7 @@ class Info extends \Google\Protobuf\Internal\Message
|
||||
}
|
||||
|
||||
/**
|
||||
* Generated from protobuf field <code>string name = 2;</code>
|
||||
* Generated from protobuf field <code>string name = 2;</code>.
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
@ -69,17 +79,15 @@ class Info extends \Google\Protobuf\Internal\Message
|
||||
}
|
||||
|
||||
/**
|
||||
* Generated from protobuf field <code>string name = 2;</code>
|
||||
* Generated from protobuf field <code>string name = 2;</code>.
|
||||
* @param string $var
|
||||
* @return $this
|
||||
*/
|
||||
public function setName($var)
|
||||
{
|
||||
GPBUtil::checkString($var, True);
|
||||
GPBUtil::checkString($var, true);
|
||||
$this->name = $var;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,44 +1,54 @@
|
||||
<?php
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://doc.hyperf.io
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
# source: grpc.proto
|
||||
|
||||
namespace Grpc;
|
||||
|
||||
use Google\Protobuf\Internal\GPBType;
|
||||
use Google\Protobuf\Internal\RepeatedField;
|
||||
use Google\Protobuf\Internal\GPBUtil;
|
||||
|
||||
/**
|
||||
* Generated from protobuf message <code>grpc.UserReply</code>
|
||||
* Generated from protobuf message <code>grpc.UserReply</code>.
|
||||
*/
|
||||
class UserReply extends \Google\Protobuf\Internal\Message
|
||||
{
|
||||
/**
|
||||
* Generated from protobuf field <code>string message = 1;</code>
|
||||
* Generated from protobuf field <code>string message = 1;</code>.
|
||||
*/
|
||||
private $message = '';
|
||||
|
||||
/**
|
||||
* Generated from protobuf field <code>.grpc.Info info = 2;</code>
|
||||
* Generated from protobuf field <code>.grpc.Info info = 2;</code>.
|
||||
*/
|
||||
private $info = null;
|
||||
private $info;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $data {
|
||||
* Optional. Data for populating the Message object.
|
||||
* Optional. Data for populating the Message object.
|
||||
*
|
||||
* @type string $message
|
||||
* @type \Grpc\Info $info
|
||||
* @var string $message
|
||||
* @var \Grpc\Info $info
|
||||
* }
|
||||
*/
|
||||
public function __construct($data = NULL) {
|
||||
public function __construct($data = null)
|
||||
{
|
||||
\GPBMetadata\Grpc::initOnce();
|
||||
parent::__construct($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generated from protobuf field <code>string message = 1;</code>
|
||||
* Generated from protobuf field <code>string message = 1;</code>.
|
||||
* @return string
|
||||
*/
|
||||
public function getMessage()
|
||||
@ -47,20 +57,20 @@ class UserReply extends \Google\Protobuf\Internal\Message
|
||||
}
|
||||
|
||||
/**
|
||||
* Generated from protobuf field <code>string message = 1;</code>
|
||||
* Generated from protobuf field <code>string message = 1;</code>.
|
||||
* @param string $var
|
||||
* @return $this
|
||||
*/
|
||||
public function setMessage($var)
|
||||
{
|
||||
GPBUtil::checkString($var, True);
|
||||
GPBUtil::checkString($var, true);
|
||||
$this->message = $var;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generated from protobuf field <code>.grpc.Info info = 2;</code>
|
||||
* Generated from protobuf field <code>.grpc.Info info = 2;</code>.
|
||||
* @return \Grpc\Info
|
||||
*/
|
||||
public function getInfo()
|
||||
@ -69,7 +79,7 @@ class UserReply extends \Google\Protobuf\Internal\Message
|
||||
}
|
||||
|
||||
/**
|
||||
* Generated from protobuf field <code>.grpc.Info info = 2;</code>
|
||||
* Generated from protobuf field <code>.grpc.Info info = 2;</code>.
|
||||
* @param \Grpc\Info $var
|
||||
* @return $this
|
||||
*/
|
||||
@ -80,6 +90,4 @@ class UserReply extends \Google\Protobuf\Internal\Message
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -26,10 +26,9 @@ class RequestTest extends TestCase
|
||||
public function testRequest()
|
||||
{
|
||||
$request = new Request($path = 'grpc.service/path', $info = new Info());
|
||||
$this->assertSame([
|
||||
'content-type' => 'application/grpc+proto',
|
||||
'user-agent' => 'grpc-php-hyperf/1.0 (hyperf-grpc-client/dev-master)',
|
||||
], $request->headers);
|
||||
$this->assertSame(2, count($request->headers));
|
||||
$this->assertSame('application/grpc+proto', $request->headers['content-type']);
|
||||
$this->assertRegExp('/^grpc-php-hyperf\/1.0 \(hyperf-grpc-client\/.*\)$/', $request->headers['user-agent']);
|
||||
$this->assertSame($path, $request->path);
|
||||
$this->assertSame(Parser::serializeMessage($info), $request->data);
|
||||
}
|
||||
@ -37,10 +36,9 @@ class RequestTest extends TestCase
|
||||
public function testGetDefaultHeaders()
|
||||
{
|
||||
$request = new Request($path = 'grpc.service/path', $info = new Info());
|
||||
$this->assertSame([
|
||||
'content-type' => 'application/grpc+proto',
|
||||
'user-agent' => 'grpc-php-hyperf/1.0 (hyperf-grpc-client/dev-master)',
|
||||
], $request->getDefaultHeaders());
|
||||
$this->assertSame(2, count($request->getDefaultHeaders()));
|
||||
$this->assertSame('application/grpc+proto', $request->getDefaultHeaders()['content-type']);
|
||||
$this->assertRegExp('/^grpc-php-hyperf\/1.0 \(hyperf-grpc-client\/.*\)$/', $request->getDefaultHeaders()['user-agent']);
|
||||
}
|
||||
|
||||
public function testUserDefinedHeaders()
|
||||
@ -49,10 +47,10 @@ class RequestTest extends TestCase
|
||||
'content-type' => 'application/grpc',
|
||||
'foo' => 'bar',
|
||||
]);
|
||||
$this->assertSame([
|
||||
'content-type' => 'application/grpc',
|
||||
'user-agent' => 'grpc-php-hyperf/1.0 (hyperf-grpc-client/dev-master)',
|
||||
'foo' => 'bar',
|
||||
], $request->headers);
|
||||
|
||||
$this->assertSame(3, count($request->headers));
|
||||
$this->assertSame('application/grpc', $request->headers['content-type']);
|
||||
$this->assertRegExp('/^grpc-php-hyperf\/1.0 \(hyperf-grpc-client\/.*\)$/', $request->headers['user-agent']);
|
||||
$this->assertSame('bar', $request->headers['foo']);
|
||||
}
|
||||
}
|
||||
|
@ -12,16 +12,18 @@ declare(strict_types=1);
|
||||
|
||||
return [
|
||||
'default' => [
|
||||
'handler' => [
|
||||
'class' => \Monolog\Handler\StreamHandler::class,
|
||||
'constructor' => [
|
||||
'stream' => BASE_PATH . '/runtime/logs/hyperf.log',
|
||||
'level' => \Monolog\Logger::DEBUG,
|
||||
'handlers' => [
|
||||
[
|
||||
'class' => Monolog\Handler\StreamHandler::class,
|
||||
'constructor' => [
|
||||
'stream' => BASE_PATH . '/runtime/logs/hyperf.log',
|
||||
'level' => Monolog\Logger::DEBUG,
|
||||
],
|
||||
'formatter' => [
|
||||
'class' => Monolog\Formatter\LineFormatter::class,
|
||||
'constructor' => [],
|
||||
],
|
||||
],
|
||||
],
|
||||
'formatter' => [
|
||||
'class' => \Monolog\Formatter\LineFormatter::class,
|
||||
'constructor' => [],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
@ -14,8 +14,11 @@ namespace Hyperf\Logger;
|
||||
|
||||
use Hyperf\Contract\ConfigInterface;
|
||||
use Hyperf\Logger\Exception\InvalidConfigException;
|
||||
use Hyperf\Utils\Arr;
|
||||
use Monolog\Formatter\FormatterInterface;
|
||||
use Monolog\Formatter\LineFormatter;
|
||||
use Monolog\Handler\HandlerInterface;
|
||||
use Monolog\Handler\StreamHandler;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
@ -50,11 +53,11 @@ class LoggerFactory
|
||||
}
|
||||
|
||||
$config = $config[$group];
|
||||
$handler = $this->handler($config);
|
||||
$handlers = $this->handlers($config);
|
||||
|
||||
return make(Logger::class, [
|
||||
'name' => $name,
|
||||
'handlers' => [$handler],
|
||||
'handlers' => $handlers,
|
||||
]);
|
||||
}
|
||||
|
||||
@ -67,16 +70,55 @@ class LoggerFactory
|
||||
return $this->loggers[$name] = $this->make($name, $group);
|
||||
}
|
||||
|
||||
protected function handler(array $config): HandlerInterface
|
||||
protected function getDefaultFormatterConfig($config)
|
||||
{
|
||||
$handlerClass = $config['handler']['class'];
|
||||
$handlerConstructor = $config['handler']['constructor'];
|
||||
$formatterClass = Arr::get($config, 'formatter.class', LineFormatter::class);
|
||||
$formatterConstructor = Arr::get($config, 'formatter.constructor', []);
|
||||
|
||||
return [
|
||||
'class' => $formatterClass,
|
||||
'constructor' => $formatterConstructor,
|
||||
];
|
||||
}
|
||||
|
||||
protected function getDefaultHandlerConfig($config)
|
||||
{
|
||||
$handlerClass = Arr::get($config, 'handler.class', StreamHandler::class);
|
||||
$handlerConstructor = Arr::get($config, 'handler.constructor', [
|
||||
'stream' => BASE_PATH . '/runtime/logs/hyperf.log',
|
||||
'level' => Logger::DEBUG,
|
||||
]);
|
||||
|
||||
return [
|
||||
'class' => $handlerClass,
|
||||
'constructor' => $handlerConstructor,
|
||||
];
|
||||
}
|
||||
|
||||
protected function handlers(array $config): array
|
||||
{
|
||||
$handlerConfigs = $config['handlers'] ?? [[]];
|
||||
$handlers = [];
|
||||
$defaultHandlerConfig = $this->getDefaultHandlerConfig($config);
|
||||
$defaultFormatterConfig = $this->getDefaultFormatterConfig($config);
|
||||
foreach ($handlerConfigs as $value) {
|
||||
$class = $value['class'] ?? $defaultHandlerConfig['class'];
|
||||
$constructor = $value['constructor'] ?? $defaultHandlerConfig['constructor'];
|
||||
$formatterConfig = $value['formatter'] ?? $defaultFormatterConfig;
|
||||
|
||||
$handlers[] = $this->handler($class, $constructor, $formatterConfig);
|
||||
}
|
||||
|
||||
return $handlers;
|
||||
}
|
||||
|
||||
protected function handler($class, $constructor, $formatterConfig): HandlerInterface
|
||||
{
|
||||
/** @var HandlerInterface $handler */
|
||||
$handler = make($handlerClass, $handlerConstructor);
|
||||
$handler = make($class, $constructor);
|
||||
|
||||
$formatterClass = $config['formatter']['class'];
|
||||
$formatterConstructor = $config['formatter']['constructor'];
|
||||
$formatterClass = $formatterConfig['class'];
|
||||
$formatterConstructor = $formatterConfig['constructor'];
|
||||
|
||||
/** @var FormatterInterface $formatter */
|
||||
$formatter = make($formatterClass, $formatterConstructor);
|
||||
|
@ -18,10 +18,13 @@ use Hyperf\Contract\StdoutLoggerInterface;
|
||||
use Hyperf\Logger\LoggerFactory;
|
||||
use Hyperf\Utils\ApplicationContext;
|
||||
use Mockery;
|
||||
use Monolog\Handler\StreamHandler;
|
||||
use Monolog\Handler\TestHandler;
|
||||
use Monolog\Logger;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use ReflectionClass;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
@ -47,17 +50,43 @@ class LoggerFactoryTest extends TestCase
|
||||
ApplicationContext::setContainer($container);
|
||||
$factory = $container->get(LoggerFactory::class);
|
||||
$logger = $factory->get('hyperf');
|
||||
$this->assertInstanceOf(StdoutLoggerInterface::class, $logger);
|
||||
$this->assertInstanceOf(LoggerInterface::class, $logger);
|
||||
$this->assertInstanceOf(Logger::class, $logger);
|
||||
$this->assertInstanceOf(\Hyperf\Logger\Logger::class, $logger);
|
||||
}
|
||||
|
||||
private function mockContainer()
|
||||
public function testHandlerConfig()
|
||||
{
|
||||
$container = $this->mockContainer();
|
||||
$factory = $container->get(LoggerFactory::class);
|
||||
$logger = $factory->get('hyperf', 'default');
|
||||
$this->assertInstanceOf(\Hyperf\Logger\Logger::class, $logger);
|
||||
$reflectionClass = new ReflectionClass($logger);
|
||||
$handlersProperty = $reflectionClass->getProperty('handlers');
|
||||
$handlersProperty->setAccessible(true);
|
||||
$handlers = $handlersProperty->getValue($logger);
|
||||
$this->assertCount(1, $handlers);
|
||||
$this->assertInstanceOf(StreamHandler::class, current($handlers));
|
||||
}
|
||||
|
||||
public function testHandlersConfig()
|
||||
{
|
||||
$container = $this->mockContainer();
|
||||
$factory = $container->get(LoggerFactory::class);
|
||||
$logger = $factory->get('hyperf', 'default-handlers');
|
||||
$this->assertInstanceOf(\Hyperf\Logger\Logger::class, $logger);
|
||||
$reflectionClass = new ReflectionClass($logger);
|
||||
$handlersProperty = $reflectionClass->getProperty('handlers');
|
||||
$handlersProperty->setAccessible(true);
|
||||
$handlers = $handlersProperty->getValue($logger);
|
||||
$this->assertCount(2, $handlers);
|
||||
$this->assertInstanceOf(StreamHandler::class, $handlers[0]);
|
||||
$this->assertInstanceOf(TestHandler::class, $handlers[1]);
|
||||
}
|
||||
|
||||
private function mockContainer(): ContainerInterface
|
||||
{
|
||||
$container = Mockery::mock(ContainerInterface::class);
|
||||
|
||||
$container->shouldReceive('get')->once()->with(ConfigInterface::class)->andReturn(new Config([
|
||||
$container->shouldReceive('get')->with(ConfigInterface::class)->andReturn(new Config([
|
||||
'logger' => [
|
||||
'default' => [
|
||||
'handler' => [
|
||||
@ -72,11 +101,31 @@ class LoggerFactoryTest extends TestCase
|
||||
'constructor' => [],
|
||||
],
|
||||
],
|
||||
'default-handlers' => [
|
||||
'handlers' => [
|
||||
[
|
||||
'class' => \Monolog\Handler\StreamHandler::class,
|
||||
'constructor' => [
|
||||
'stream' => BASE_PATH . '/runtime/logs/hyperf.log',
|
||||
'level' => \Monolog\Logger::DEBUG,
|
||||
],
|
||||
],
|
||||
[
|
||||
'class' => \Monolog\Handler\TestHandler::class,
|
||||
'constructor' => [
|
||||
'level' => \Monolog\Logger::DEBUG,
|
||||
],
|
||||
]
|
||||
],
|
||||
'formatter' => [
|
||||
'class' => \Monolog\Formatter\LineFormatter::class,
|
||||
'constructor' => [],
|
||||
],
|
||||
],
|
||||
],
|
||||
]));
|
||||
|
||||
$container->shouldReceive('get')
|
||||
->once()
|
||||
->with(LoggerFactory::class)
|
||||
->andReturn(new LoggerFactory($container));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user