Symfony - 记录到服务中的多个日志文件
Symfony - log to multiple log files in a service
我正在尝试将多个独白处理程序注入服务。现在我的 parent class 注入了一个记录器, children class 注入了另一个记录器。我的目标是能够将特定操作记录到特定日志文件中。
我的service.yaml:
App\Services\PrinterManager:
arguments: ['@doctrine.orm.entity_manager','@logger', '', '', '', '','']
tags:
- { name: monolog.logger, channel: printerface}
App\Services\Printer\Printer:
autowire: true
autoconfigure: false
public: false
parent: App\Services\PrinterManager
arguments:
index_2: '@logger'
index_3: '@oneup_flysystem.printer_invoice_filesystem'
index_4: '@oneup_flysystem.printerface_content_filesystem'
index_5: '@oneup_flysystem.sftp_filesystem'
index_6: '@App\Services\PrinterApiService'
tags:
- { name: monolog.logger, channel: printerlog}
我的monolog.yaml:
monolog:
handlers:
main:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
channels: ["!event, !printerface", "!printerlog"]
printerface:
type: stream
level: debug
channels: ["printerface"]
path: "%kernel.logs_dir%/printerface.log"
printerlog:
type: stream
level: debug
channels: ["printerlog"]
path: "%kernel.logs_dir%/printerlog.log"
但似乎当前的服务配置破坏了构造函数,我得到以下错误:
The argument must be an existing index or the name of a constructor's parameter.
有没有办法在一个服务中使用两个日志文件?
这是 Symfony 用于替换子服务中父参数的方法:
/**
* You should always use this method when overwriting existing arguments
* of the parent definition.
*
* If you directly call setArguments() keep in mind that you must follow
* certain conventions when you want to overwrite the arguments of the
* parent definition, otherwise your arguments will only be appended.
*
* @param int|string $index
* @param mixed $value
*
* @return self the current instance
*
* @throws InvalidArgumentException when $index isn't an integer
*/
public function replaceArgument($index, $value)
{
if (\is_int($index)) {
$this->arguments['index_'.$index] = $value;
} elseif (0 === strpos($index, '$')) {
$this->arguments[$index] = $value;
} else {
throw new InvalidArgumentException('The argument must be an existing index or the name of a constructor\'s parameter.');
}
return $this;
}
如您所见,索引必须与父构造函数中的参数变量名称相同,并带有前缀 $
或表示相关参数的整数。
所以我认为你必须如下定义你的子服务:
App\Services\Printer\Printer:
autowire: true
autoconfigure: false
public: false
parent: App\Services\PrinterManager
arguments:
2: '@logger'
3: '@oneup_flysystem.printer_invoice_filesystem'
4: '@oneup_flysystem.printerface_content_filesystem'
5: '@oneup_flysystem.sftp_filesystem'
6: '@App\Services\PrinterApiService'
tags:
- { name: monolog.logger, channel: printerlog}
更新:
我复现了你的问题,发现解决方法如下。使用此解决方案,Symfony 自动装配将适用于子服务。
App\Services\Printer\Printer:
autowire: true
autoconfigure: false
public: false
parent: App\Services\PrinterManager
arguments:
$arg2: '@logger'
$arg3: '@oneup_flysystem.printer_invoice_filesystem'
$arg4: '@oneup_flysystem.printerface_content_filesystem'
$arg5: '@oneup_flysystem.sftp_filesystem'
$arg6: '@App\Services\PrinterApiService'
tags:
- { name: monolog.logger, channel: printerlog}
$arg2
、$arg3
、$arg4
、$arg5
和 $arg6
必须替换为 class 构造函数的参数名称。
我还没有用 parent/child class 完成它,但是我使用的是一些更简单的命名参数,这就是我所拥有的(使用三个不同的记录器):
# App/Subscribers/WebhookLoggingListener.php file
public function __construct(
LoggerInterface $logger,
LoggerInterface $mailgunLog,
LoggerInterface $dripLog) {
}
# services.yml
App\Subscribers\WebhookLoggingListener:
arguments:
$logger: "@logger"
$mailgunLog: "@monolog.logger.mailgun"
$dripLog: "@monolog.logger.drip"
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
如果我在别处使用其他记录器,我也可以将它们绑定到特定的变量名:
services:
_defaults:
# ... other config
bind:
$dripLog: "@?monolog.logger.drip"
我正在尝试将多个独白处理程序注入服务。现在我的 parent class 注入了一个记录器, children class 注入了另一个记录器。我的目标是能够将特定操作记录到特定日志文件中。
我的service.yaml:
App\Services\PrinterManager:
arguments: ['@doctrine.orm.entity_manager','@logger', '', '', '', '','']
tags:
- { name: monolog.logger, channel: printerface}
App\Services\Printer\Printer:
autowire: true
autoconfigure: false
public: false
parent: App\Services\PrinterManager
arguments:
index_2: '@logger'
index_3: '@oneup_flysystem.printer_invoice_filesystem'
index_4: '@oneup_flysystem.printerface_content_filesystem'
index_5: '@oneup_flysystem.sftp_filesystem'
index_6: '@App\Services\PrinterApiService'
tags:
- { name: monolog.logger, channel: printerlog}
我的monolog.yaml:
monolog:
handlers:
main:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
channels: ["!event, !printerface", "!printerlog"]
printerface:
type: stream
level: debug
channels: ["printerface"]
path: "%kernel.logs_dir%/printerface.log"
printerlog:
type: stream
level: debug
channels: ["printerlog"]
path: "%kernel.logs_dir%/printerlog.log"
但似乎当前的服务配置破坏了构造函数,我得到以下错误:
The argument must be an existing index or the name of a constructor's parameter.
有没有办法在一个服务中使用两个日志文件?
这是 Symfony 用于替换子服务中父参数的方法:
/**
* You should always use this method when overwriting existing arguments
* of the parent definition.
*
* If you directly call setArguments() keep in mind that you must follow
* certain conventions when you want to overwrite the arguments of the
* parent definition, otherwise your arguments will only be appended.
*
* @param int|string $index
* @param mixed $value
*
* @return self the current instance
*
* @throws InvalidArgumentException when $index isn't an integer
*/
public function replaceArgument($index, $value)
{
if (\is_int($index)) {
$this->arguments['index_'.$index] = $value;
} elseif (0 === strpos($index, '$')) {
$this->arguments[$index] = $value;
} else {
throw new InvalidArgumentException('The argument must be an existing index or the name of a constructor\'s parameter.');
}
return $this;
}
如您所见,索引必须与父构造函数中的参数变量名称相同,并带有前缀 $
或表示相关参数的整数。
所以我认为你必须如下定义你的子服务:
App\Services\Printer\Printer:
autowire: true
autoconfigure: false
public: false
parent: App\Services\PrinterManager
arguments:
2: '@logger'
3: '@oneup_flysystem.printer_invoice_filesystem'
4: '@oneup_flysystem.printerface_content_filesystem'
5: '@oneup_flysystem.sftp_filesystem'
6: '@App\Services\PrinterApiService'
tags:
- { name: monolog.logger, channel: printerlog}
更新:
我复现了你的问题,发现解决方法如下。使用此解决方案,Symfony 自动装配将适用于子服务。
App\Services\Printer\Printer:
autowire: true
autoconfigure: false
public: false
parent: App\Services\PrinterManager
arguments:
$arg2: '@logger'
$arg3: '@oneup_flysystem.printer_invoice_filesystem'
$arg4: '@oneup_flysystem.printerface_content_filesystem'
$arg5: '@oneup_flysystem.sftp_filesystem'
$arg6: '@App\Services\PrinterApiService'
tags:
- { name: monolog.logger, channel: printerlog}
$arg2
、$arg3
、$arg4
、$arg5
和 $arg6
必须替换为 class 构造函数的参数名称。
我还没有用 parent/child class 完成它,但是我使用的是一些更简单的命名参数,这就是我所拥有的(使用三个不同的记录器):
# App/Subscribers/WebhookLoggingListener.php file
public function __construct(
LoggerInterface $logger,
LoggerInterface $mailgunLog,
LoggerInterface $dripLog) {
}
# services.yml
App\Subscribers\WebhookLoggingListener:
arguments:
$logger: "@logger"
$mailgunLog: "@monolog.logger.mailgun"
$dripLog: "@monolog.logger.drip"
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
如果我在别处使用其他记录器,我也可以将它们绑定到特定的变量名:
services:
_defaults:
# ... other config
bind:
$dripLog: "@?monolog.logger.drip"