在c#代码中删除跟踪源的侦听器/禁用日志

时间:2013-06-07 08:36:12

标签: c# logging tracelistener

为了禁用FirebirdSQL日志记录,我需要将以下代码(See here)添加到app.config:

<system.diagnostics>
    <sources>
      <source name="FirebirdSql.Data.FirebirdClient" switchValue="Off">
        <listeners>
          <clear />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>

这成功,即没有记录任何内容。 现在我已经用C#代码做了这个,但是尽管我的代码仍然记录了所有内容:

TraceSource ts = new TraceSource("FirebirdSql.Data.FirebirdClient");
ts.Switch = new SourceSwitch("sourceSwitch", "Off");
var listeners = ts.Listeners;
listeners.Clear();
ts.Switch.Level = SourceLevels.Off;

我添加到执行SQL语句的程序集中。

我错过了什么?

1 个答案:

答案 0 :(得分:1)

这会禁用所有跟踪源,无论它们是如何注册的(在代码或配置中)。

创建TraceSource(在代码或配置中)时,会将其添加到静态列表中。没有公共API可以获得该列表。但这个“私人”关键词是较小的开发者服从的标志,而不是我们。所以我们只是将它踢下来并参考我们理所当然的变量。然后我们可以添加/删除侦听器,关闭跟踪标志 - 有多种方法可以禁用跟踪。

此示例将在单个方法中起作用,但即使您没有像此示例那样对TraceSource的引用,该技术也将/应该工作。

TraceSource source = new TraceSource("foo");
SourceSwitch onOff = new SourceSwitch("onOff", "Verbose");

onOff.Level = SourceLevels.Verbose;

ConsoleTraceListener console = new ConsoleTraceListener();

source.Switch = onOff;
bool alreadyDone = false;
foreach (var listener in source.Listeners)
{
    if (typeof(ConsoleTraceListener) == listener.GetType())
    {
        alreadyDone = true;
    }
}
if (!alreadyDone)
{
    source.Listeners.Add(console);
}

source.TraceInformation("Hellow World! The trace is on!");

List<WeakReference>  traceSources = 
           (List<WeakReference>)typeof(TraceSource)
               .GetField("tracesources", BindingFlags.NonPublic | BindingFlags.Static)
               .GetValue(source);

foreach (WeakReference weakReference in traceSources)
{
    TraceSource target = (TraceSource)weakReference.Target;
    source.TraceInformation(
          "Somebody, in code or config, registered this trace source " + target.Name);
    target.Listeners.Clear();
}
source.TraceInformation(
       "Can you still see this? (No you can't, I cleared all the listeners)");