在不创建 .config 文件的情况下在 PowerShell 中进行 .NET 跟踪
.NET tracing in PowerShell without creating .config file
我知道我可以启用 .NET tracing by adding <system.diagnostics>
element to App config (powershell.exe.config
) in PowerShell installation folder. This is covered in System.Net tracing in PowerShell。
其实我也想登录System.Net
tracing source (e.g. FtpWebRequest
)。
但是有没有办法在本地启用跟踪?就像代码本身一样?或者可能使用一些命令行开关?或者我是否可以至少将 App 配置文件放在 local 文件夹中,而不必修改系统范围的设置?
是的,您可以在代码中编写跟踪。
Trace.Write("Hello world");
如果您想要更高级的东西,请尝试 Log4Net,它会生成一个配置文件。
仅在代码中(因此在 Powershell 中)启用默认跟踪源(Trace.Information
等)相对容易。
对 System.Net
跟踪源执行此操作更为复杂,因为它们不可公开访问。
我之前在 C# 中看到过,调用 System.Net
方法,例如Dns.Resolve
是创建 TraceSource
所必需的,但这在 Powershell 中似乎不需要。
所以这不是一个很好的解决方案......但这取决于我猜你的替代方案是什么:
$id = [Environment]::TickCount;
$fileName = "${PSScriptRoot}\Powershell_log_${id}.txt"
$listener1 = [System.Diagnostics.TextWriterTraceListener]::New($fileName, "text_listener")
$listener2 = [System.Diagnostics.ConsoleTraceListener]::New()
$listener2.Name = "console_listener"
[System.Diagnostics.Trace]::AutoFlush = $true
[System.Diagnostics.Trace]::Listeners.Add($listener1) | out-null
[System.Diagnostics.Trace]::Listeners.Add($listener2) | out-null
# Use reflection to enable and hook up the TraceSource
$logging = [System.Net.Sockets.Socket].Assembly.GetType("System.Net.Logging")
$flags = [System.Reflection.BindingFlags]::NonPublic -bor [System.Reflection.BindingFlags]::Static
$logging.GetField("s_LoggingEnabled", $flags).SetValue($null, $true)
$webTracing = $logging.GetProperty("Web", $flags);
$webTraceSource = [System.Diagnostics.Tracesource]$webTracing.GetValue($null, $null);
$webTraceSource.Switch.Level = [System.Diagnostics.SourceLevels]::Information
$webTracesource.Listeners.Add($listener1) | out-null
$webTracesource.Listeners.Add($listener2) | out-null
[System.Diagnostics.Trace]::TraceInformation("About to do net stuff");
[System.Net.FtpWebRequest]::Create("ftp://www.google.com") | out-null
[System.Diagnostics.Trace]::TraceInformation("Finished doing net stuff");
#get rid of the listeners
[System.Diagnostics.Trace]::Listeners.Clear();
$webTraceSource.Listeners.Clear();
$listener1.Dispose();
$listener2.Dispose();
我知道我可以启用 .NET tracing by adding <system.diagnostics>
element to App config (powershell.exe.config
) in PowerShell installation folder. This is covered in System.Net tracing in PowerShell。
其实我也想登录System.Net
tracing source (e.g. FtpWebRequest
)。
但是有没有办法在本地启用跟踪?就像代码本身一样?或者可能使用一些命令行开关?或者我是否可以至少将 App 配置文件放在 local 文件夹中,而不必修改系统范围的设置?
是的,您可以在代码中编写跟踪。
Trace.Write("Hello world");
如果您想要更高级的东西,请尝试 Log4Net,它会生成一个配置文件。
仅在代码中(因此在 Powershell 中)启用默认跟踪源(Trace.Information
等)相对容易。
对 System.Net
跟踪源执行此操作更为复杂,因为它们不可公开访问。
我之前在 C# 中看到过,调用 System.Net
方法,例如Dns.Resolve
是创建 TraceSource
所必需的,但这在 Powershell 中似乎不需要。
所以这不是一个很好的解决方案......但这取决于我猜你的替代方案是什么:
$id = [Environment]::TickCount;
$fileName = "${PSScriptRoot}\Powershell_log_${id}.txt"
$listener1 = [System.Diagnostics.TextWriterTraceListener]::New($fileName, "text_listener")
$listener2 = [System.Diagnostics.ConsoleTraceListener]::New()
$listener2.Name = "console_listener"
[System.Diagnostics.Trace]::AutoFlush = $true
[System.Diagnostics.Trace]::Listeners.Add($listener1) | out-null
[System.Diagnostics.Trace]::Listeners.Add($listener2) | out-null
# Use reflection to enable and hook up the TraceSource
$logging = [System.Net.Sockets.Socket].Assembly.GetType("System.Net.Logging")
$flags = [System.Reflection.BindingFlags]::NonPublic -bor [System.Reflection.BindingFlags]::Static
$logging.GetField("s_LoggingEnabled", $flags).SetValue($null, $true)
$webTracing = $logging.GetProperty("Web", $flags);
$webTraceSource = [System.Diagnostics.Tracesource]$webTracing.GetValue($null, $null);
$webTraceSource.Switch.Level = [System.Diagnostics.SourceLevels]::Information
$webTracesource.Listeners.Add($listener1) | out-null
$webTracesource.Listeners.Add($listener2) | out-null
[System.Diagnostics.Trace]::TraceInformation("About to do net stuff");
[System.Net.FtpWebRequest]::Create("ftp://www.google.com") | out-null
[System.Diagnostics.Trace]::TraceInformation("Finished doing net stuff");
#get rid of the listeners
[System.Diagnostics.Trace]::Listeners.Clear();
$webTraceSource.Listeners.Clear();
$listener1.Dispose();
$listener2.Dispose();