在 Symfony 4 中,自定义服务应通过构造函数注入 LoggerInterface 实现日志功能,确保启用 autowire 和自动注册;可选指定独立 channel(如 my_service)并在 services.yaml 中绑定对应 logger 服务。

在 Symfony 4 中,自定义服务要使用日志功能,最标准的方式是通过构造函数注入 LoggerInterface,而不是手动从容器中获取 logger 服务。这符合依赖注入原则,也便于测试和维护。
确保服务自动注册并启用 autowire
Symfony 4 默认开启 autowire 和 autoconfigure,只要你的服务类位于 src/ 下且未被显式禁用,就会自动注册。检查 config/services.yaml 中是否包含:
# config/services.yaml
services:
# 默认规则:自动加载 src/ 下所有类,启用 autowire & autoconfigure
App\:
resource: '../src/*'
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
<pre class="brush:php;toolbar:false;">App\Controller\:
resource: '../src/Controller/'
tags: ['controller.service_arguments']在自定义服务中声明 LoggerInterface 依赖
直接在构造函数中声明类型提示即可,Symfony 会自动注入默认的 logger(即 monolog.logger,通常对应 app channel):
例如:
// src/Service/MyCustomService.php
namespace App\Service;
<p>use Psr\Log\LoggerInterface;</p><p>class MyCustomService
{
private $logger;</p><pre class="brush:php;toolbar:false;">public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
public function doSomething()
{
$this->logger->info('执行了自定义逻辑');
$this->logger->error('发生了一个错误', ['context' => '详情']);
}}
指定特定日志 channel(可选)
如果你希望该服务使用独立的日志 channel(比如 my_service),需两步操作:
- 在
config/packages/dev/monolog.yaml(或对应环境配置)中定义 channel:
monolog:
channels: ['my_service']
- 在服务定义中绑定接口到具体 channel 的 logger 服务(推荐在
services.yaml中):
# config/services.yaml
services:
App\Service\MyCustomService:
arguments:
$logger: '@monolog.logger.my_service'
这样,MyCustomService 构造函数中的 LoggerInterface 参数就会注入 monolog.logger.my_service 实例,日志将写入独立的 channel。
避免手动从容器获取 logger
不要在服务中写类似 $this->container->get('logger') 或 $this->get('logger') —— 这属于服务定位反模式,破坏可测性,且在无容器环境中(如单元测试)会报错。始终优先使用构造函数注入。


















