laravel 小技巧:为日志组件的非默认通道注册全局上下文 context

在使用 laravel 的日志组件(Facade门面模式)时,我们可以通过 withContext 方法为请求周期注册全局的上下文信息,用来做 RequestID/TraceId 类的请求链路追踪,非常的方便。但在 10- 以下的版本中,withContext 只能为默认日志通道注入全局上下文,在非默认通道的场景,比如 cli 下, 就无法优雅的实现了。

但如果你了解 ServiceServiceProviderFacade 三者之间的关系,那可以参考如下两类方法来优雅的实现非默认日志通道下注册全局 context 的方法:

门面 \Illuminate\Support\Facades\Log 代理的日志服务
实为 \Illuminate\Log\LogServiceProviderapp 容器中注册的
标识名为 log\Illuminate\Log\LogManager 日志服务的实例。

只要理解这三者的关系,我们就可以为Log门面重新注册。

方法一、非默认通道的日志Facade

\App\Supports\Facades\LogCli 代理一个非默认通道日志服务的实例即可,比如 log-cli

\App\Providers\AppServiceProvider 中注册 log-cli 的实例到 app 容器中

app->singleton('log-cli', function () {
            return (new LogManager($this->app))->channel('cli');
        });
    }
}

如此后,我们就可以在使用 LogCli::withContext 注册运行周期内的全局上下文参数了。

LogCli::withContext(['traceId' => "traceId will record in all log"]);
// 以下日志都会携带上 traceId 参数
LogCli::info("this is info");
LogCli::warning("this is warning");
LogCli::error("this is error");

方法二、自适应日志Facade

听起来是不是很高大上很优雅?其实就是仍使用 laravelLog FacadeFacade 只是个代理,将 实例 的诸多 方法静态 的风格 暴露 出来 方便调用。何谓自适应呢?让 Log Facadehttp 下使用 default 通道,在 cli 下使用 cli 通道,使用者无需刻意的去指定。
实现起来也很简单,根据运行时环境来判断,决定 log 代理哪个通道的日志服务。

app->singleton('log', function () {
                return (new LogManager($this->app))->channel('cli');
            });
        }
    }
}

这样在 http 模式下自动使用 default 通道,console 模式下自动使用 cli 通道。

Log::withContext(['traceId' => "traceId will record in all log"]);
// 以下日志都会携带上 traceId 参数
Log::info("this is info");
Log::warning("this is warning");
Log::error("this is error");

你可能感兴趣的:(laravel 小技巧:为日志组件的非默认通道注册全局上下文 context)