使用 SeriLog 和 PowerShell 实现 Hello World

Eri*_*ger 2 .net powershell serilog serilog-exceptions

我想了解如何在 PS 中使用 SeriLog。

这是一个有效的代码示例:

$SeriLog = Add-Type -Path "C:\Program Files\PackageManagement\Serilog.2.10.0\lib\net46\Serilog.dll" -PassThru 
$SeriLog_Sink_Console = Add-Type -Path "C:\Program Files\PackageManagement\Serilog.Sinks.Console.3.1.1\lib\net45\Serilog.Sinks.Console.dll" -PassThru

$SeriLog_Config = New-Object Serilog.LoggerConfiguration
$SeriLog_Config = [Serilog.Configuration.LoggerSinkConfiguration]$SeriLog_Config_Sink = $SeriLog_Config.WriteTo
[Serilog.Log]::Logger = [Serilog.ConsoleLoggerConfigurationExtensions]::Console($SeriLog_Config_Sink).CreateLogger()
[Serilog.Log]::Information("Logging started")
Run Code Online (Sandbox Code Playgroud)

根据 dotnet SeriLogs 网站上列出的示例,我不明白的是为什么我的所有接收器都丢失了。

例子:

$SeriLog = Add-Type -Path "C:\Program Files\PackageManagement\Serilog.2.10.0\lib\net46\Serilog.dll" -PassThru 
$SeriLog_Sink_Console = Add-Type -Path "C:\Program Files\PackageManagement\Serilog.Sinks.Console.3.1.1\lib\net45\Serilog.Sinks.Console.dll" -PassThru

$SeriLog_Config = New-Object Serilog.LoggerConfiguration
$SeriLog_Config.WriteTo.Console()
Run Code Online (Sandbox Code Playgroud)

我得到的错误是:

InvalidOperation:方法调用失败,因为 [Serilog.Configuration.LoggerSinkConfiguration] 不包含名为“Console”的方法。

这在某种程度上是有道理的,因为我可以看到它丢失了,但我不明白为什么?我已经导入了两个 DLL。我想对我来说,在理解如何在 PS 中使用 DLL 方面我还是个新手。我的运气要好得多,并且使用 Log4Net 拥有一个可靠工作的模块,但我正在尝试迁移到更现代的东西,并且我正在绞尽脑汁试图了解如何集成各种接收器,如果公共示例dotnet 不翻译为 PS。

JFYI,我正在使用 PS 7.1,以防万一。

Cai*_*ete 5

水槽没有丢失,并且您正在正确加载组件。事实是,Serilog 接收器遵循一种约定,该约定利用了 C# 语言的一项称为“扩展方法”的功能,而该功能在 PowerShell 中不可用。

如果您查看Console sink 的源代码,您会发现配置它的方法是一个静态方法,它使用特殊关键字this接收 Serilog 配置作为第一个参数:

public static class ConsoleLoggerConfigurationExtensions
{
    public static LoggerConfiguration Console(
        this LoggerSinkConfiguration sinkConfiguration, ...)
    {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

类型之前的特殊关键字thisLoggerSinkConfiguration告诉 C# 编译器可以调用该方法,就好像它是 的实例方法一样LoggerSinkConfiguration

WriteTo的属性LoggerConfiguration是类型,LoggerSinkConfiguration这就是为什么你可以写:

var config = new LoggerConfiguration();
config.WriteTo.Console();
Run Code Online (Sandbox Code Playgroud)

这只是语法糖。编译器会将调用转换为如下形式:

var config = new LoggerConfiguration();
ConsoleLoggerConfigurationExtensions.Console(config.WriteTo);
Run Code Online (Sandbox Code Playgroud)

这正是您需要在 PowerShell 中执行的操作:

$config = New-Object Serilog.LoggerConfiguration
[Serilog.ConsoleLoggerConfigurationExtensions]::Console($config.WriteTo) | out-null
Run Code Online (Sandbox Code Playgroud)

因此,为了在 PowerShell 中使用 Serilog 接收器,您必须找出包含配置扩展方法的类的名称(因每个接收器而异),并将它们作为静态方法调用。

该模式与上面第一个代码块中的模式相同:

$serilog = Add-Type -Path "C:\path-to\Serilog.dll" -PassThru 
$serilogSinksConsole = Add-Type -Path "C:\path-to\Serilog.Sinks.Console.dll" -PassThru
# ... (add more sink assemblies)

$config = New-Object Serilog.LoggerConfiguration
[Serilog.ConsoleLoggerConfigurationExtensions]::Console($config.WriteTo) | out-null
# ... (configure more sinks)

# (create the logger with all the different sinks configured above)
[Serilog.Log]::Logger = $config.CreateLogger()

[Serilog.Log]::Information("Logging started") 
Run Code Online (Sandbox Code Playgroud)

找出配置每个接收器所需的类名称的最佳方法是查看要使用的接收器的源代码。他们通常遵循约定,<SinkName>LoggerConfigurationExtensions但不能保证这一点。

主要的 Serilog 组织中,您可以找到官方接收器的源代码,对于其他社区提供的接收器,您可以访问每个接收器的单独源代码存储库。