简体   繁体   English

C#在运行时启用/禁用网络跟踪?

[英]C# enable/disable network tracing at runtime?

In the examples I can find the tracing is enabled via config file, for example 在示例中,我可以发现通过配置文件启用了跟踪,例如

    <?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
  <system.diagnostics>
    <sources>
      <source name="System.Net" tracemode="includehex" maxdatasize="1024">
        <listeners>
          <add name="System.Net"/>
        </listeners>
      </source>
    </sources>
    <switches>
      <add name="System.Net" value="Verbose"/>
    </switches>
    <sharedListeners>
      <add name="System.Net"
        type="System.Diagnostics.TextWriterTraceListener"
        initializeData="network.log"
      />
    </sharedListeners>
    <trace autoflush="true" indentsize="4" />    
  </system.diagnostics>
</configuration>

But I don't want config file to be shipped with my dll. 但是我不希望dll附带配置文件。 Moreover I need to be able to enable/disable tracing and change log name "on the fly" in my code. 此外,我需要能够启用/禁用跟踪并在代码中“即时”更改日志名称。 What I came up with: 我想到的是:

FileStream stream = new FileStream("D:\\network1.log", FileMode.OpenOrCreate);
TextWriterTraceListener listener = new TextWriterTraceListener(stream);
Trace.Listeners.Add(listener);
Trace.AutoFlush = true;

TraceSwitch ts = new TraceSwitch("System.Net", ".Net");
ts.Level = TraceLevel.Verbose;

and it is not logging anything, and I don't know where to add the switch, and if that is correct at all. 而且它没有记录任何内容,而且我也不知道将开关添加到何处,如果这是正确的话。 The listener works but it don't fetch any data. 侦听器可以工作,但不会获取任何数据。

I've been reading msdn and this blog post http://www.codeguru.com/csharp/.net/article.php/c19405/Tracing-in-NET-and-Implementing-Your-Own-Trace-Listeners.htm and from the way I understand it, once added to the Trace.Listeners a listener should log all thace info in the current exe, but that's obvioustly not the case. 我正在阅读msdn和此博客文章http://www.codeguru.com/csharp/.net/article.php/c19405/Tracing-in-NET-and-Implementing-Your-Own-Trace-Listeners.htm从我的理解来看,一旦添加到Trace.Listeners ,侦听器应将所有thace信息记录在当前exe中,但事实并非如此。

So how to achieve that? 那么如何实现呢?

Edit: I've managed to hack around this limitation by dissasembling the TextWriterTraceListener and implementing my own TraceListener with the dissasembled code, adding if staatements in Write and WriteLine methods that check some static fields of another class, and adding my type in the config. 编辑:我已经设法通过拆解TextWriterTraceListener并用反汇编的代码实现我自己的TraceListener来解决这个限制,并在Write和WriteLine方法中添加是否检查了另一个类的某些静态字段的变量,并在配置中添加了我的类型。

You can't enable the tracing of System.Net from code, at least not in a supported way. 您不能通过代码启用System.Net的跟踪,至少不能以受支持的方式启用。

First let me point out that you mixed up a TraceSwitch and a TraceSource . 首先让我指出,您混合使用了TraceSwitchTraceSource The TraceSource is the one that gets used to trace messages to. TraceSource是用于跟踪邮件的源。 The TraceSwitch only controls what gets logged. TraceSwitch仅控制要记录的内容。

When you instantiate a TraceSource it initializes itself by checking the <sources> collection of the system.diagnostics setting for a <source> with the same name. 实例化TraceSource它会通过检查system.diagnostics设置的<sources>集合以查找具有相同名称的<source>来初始化自身。 When there is one, the instance is build-up with the settings provided. 如果有一个实例,则使用提供的设置构建实例。 Your program will then use that specific TraceSource instance to log its data by calling TraceEvent or any of the other methods. 然后,您的程序将使用特定的TraceSource实例通过调用TraceEvent或任何其他方法来记录其数据。
If there is no config found, the TraceSource is configured with the DefaultTraceListener with the SwitchLevel set to Off. 如果没有找到配置,则使用DefaultTraceListener和SwitchLevel设置为Off来配置TraceSource

What I described above is also done by the internal System.Net.Logging class in its InitializeLogging method. 我上面描述的内容也由内部System.Net.Logging类的InitializeLogging方法完成。 It creates its own instance of a TraceSource for System.Net that once created, either is configured as defined in the config file or with the Defaults. 它为System.Net创建自己的TraceSource实例,该实例一旦创建,就可以按照配置文件中的定义进行配置,也可以使用默认值进行配置。 All the logging that is done by the classes in the System.Net namespace use that private/internal TraceSource . System.Net命名空间中的类完成的所有日志记录都使用该私有/内部TraceSource

There is no public interface that allows you to insert or intercept TraceSource construction so you can't control which listener to connect or set Switch levels on a shared/singleton like TraceSource. 没有公共接口允许您插入或拦截TraceSource构造,因此您无法控制连接或设置共享级别(如TraceSource)上的Switch级别的侦听器。 Nor is there an option to get to the internal System.Diagnostics.DiagnosticsConfiguration class instance. 也没有选择进入内部System.Diagnostics.DiagnosticsConfiguration类实例的选项。
I did venture a bit in System.Configuration.Internal but I gave-up on that. 我确实尝试过System.Configuration.Internal,但是我放弃了。

If you do fancy reflection you can grab the internal static type System.Net.Logging and get a reference to the TraceSource from the static property Web . 如果进行奇特的反射,则可以获取内部静态类型System.Net.Logging并从静态属性Web获取对TraceSource的引用。 Once you have the reference, I imagine you can set the listeners and switchlevel. 获得参考之后,我想您可以设置侦听器和开关级别。 That is an internal implementation detail and might change without notice so I don't recommend this. 这是内部实现的详细信息,可能会更改,恕不另行通知,因此我不建议您这样做。

To get control over logging, create overloads for the classes in System.Net and add your own TraceSource instance and log info to that instance. 若要控制日志记录,请为System.Net的类创建重载,然后添加您自己的TraceSource实例并将信息记录到该实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM