为配置中的程序集中定义的跟踪源设置跟踪列表器

时间:2018-07-18 13:38:49

标签: logging system.diagnostics tracelistener tracesource

我要完成的工作是仅使用配置文件在引用的.dll中为TraceSource设置TraceListener。

具体来说,我有解决方案机器人,该机器人的app.config如下所示:

<system.diagnostics>
<sources>
  <source name="RobotModel" switchValue="All">
    <listeners>
      <add name="RobotModelConsole" type="Ukadc.Diagnostics.Listeners.ConsoleTraceListener, Ukadc.Diagnostics" initializeData="{DateTime}::{EventType}::{Message}"/>
    </listeners>
  </source>
</sources/

和一个ExtendedSource(来自Ukadc.Diagnostics.dll)初始化如下:

public static ExtendedSource robotSourceEx = new ExtendedSource( "RobotModel", SourceLevels.All );

然后我导出.dll并将其导入到UI组件,并具有类似的app.config:

 <system.diagnostics>
<sources>

  <source name="Temp" switchValue="All">
    <listeners>
      <!--<add name="console1" type="System.Diagnostics.ConsoleTraceListener" /> -->
      <add name="console" type="Ukadc.Diagnostics.Listeners.ConsoleTraceListener, Ukadc.Diagnostics" initializeData="{DateTime}::{EventType}::{Message}" />
    </listeners>
  </source>

  <source name="RobotModel" switchValue="All">
    <listeners>
      <add name="console1" type="Ukadc.Diagnostics.Listeners.ConsoleTraceListener, Ukadc.Diagnostics" initializeData="{DateTime}::{EventType}::{Message}" />
    </listeners>
  </source>

</sources>

当我运行UI组件时,我得到一个空的控制台(Console.WriteLine,并且缺少跟踪信息),但是如果我注释掉了RobotModel的TraceListener,则该控制台将包含示例跟踪消息(以及Console.WriteLine消息)。

  1. 我是否需要为RobotModel TraceListener指定.dll或命名空间
  2. 我知道我可以动态地执行此操作,因为我有一个winform组件TraceListener来获取跟踪消息,但希望在所有可能的情况下都可以从app.config进行配置

注意:gui是Winforms / Windows应用程序,而Robot类是控制台应用程序。我不认为这会带来巨大的变化,但也许值得注意。我确实在Windows应用程序上手动分配了一个控制台,以便可以在将跟踪路由到文件之前确保跟踪正常工作。

2 个答案:

答案 0 :(得分:0)

要回答我自己的问题:

  1. 否,在程序集中引用TraceSource时不需要指定.dll或名称空间,您只需要知道源名称即可
  2. 是的,可以通过如下所示的app config严格执行此操作

就造成我问题的原因而言,似乎与在WinForms中分配控制台有关。更改了我称为AllocConsole的位置后,cmd窗口将显示两个源的跟踪信息。

为了后代,这是我用来测试的代码:

public class Person {
    public int Age { get; set; }
    public string Name { get; set; }
    public static TraceSource source = new TraceSource( "[Source]" );
    public static ExtendedSource exSource = new ExtendedSource( "[SourceEx]" );
    public Person ( int age, string name ) {
        source.TraceInformation( "Creating a person named: {0}", name );
        exSource.TraceInformation( "{0} is alive!", name );
        Age = age;
        Name = name;
    }

    public int DateOfBirth () {
        return 2018 - Age;
    }
}

然后将其导出为程序集,将其导入到winform:

namespace TestForm {
public partial class Form1 : Form {
    public static TraceSource source = new TraceSource( "[FormSource]" );
    public static ExtendedSource exSource = new ExtendedSource( "[FormSourceEx]", SourceLevels.All);
    public static int age;
    private int count = 0;

    [DllImport( "kernel32.dll", SetLastError = true )]
    [return: MarshalAs( UnmanagedType.Bool )]
    static extern bool AllocConsole ();

    public Form1 () {
        InitializeComponent();
    }

    private void button1_Click ( object sender, EventArgs e ) {
        source.TraceInformation( "Button Clicked" );
        exSource.TraceInformation( "Click count: {0}" ,count++ );
        Person p = new Person( age++, "Jordo" );
    }

    private void Form1_Load ( object sender, EventArgs e ) {
        AllocConsole();
    }
}
}

以及我使用的应用配置:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.diagnostics>
<sources>
  <source name="[Source]" switchValue="All">
    <listeners>
      <add name="console" type="Ukadc.Diagnostics.Listeners.ConsoleTraceListener, Ukadc.Diagnostics" initializeData="{Source}::{Hour}:{Minute}:{Second}:{Millisecond}::{EventType}::{Message}" />
    </listeners>
  </source>
  <source name="[SourceEx]" switchValue="All">
    <listeners>
      <add name="console" type="Ukadc.Diagnostics.Listeners.ConsoleTraceListener, Ukadc.Diagnostics" initializeData="{Source}::{Hour}:{Minute}:{Second}:{Millisecond}::{EventType}::{Message}" />
    </listeners>
  </source>
  <source name="[FormSource]" switchValue="All">
    <listeners>
      <add name="console1" type="Ukadc.Diagnostics.Listeners.ConsoleTraceListener, Ukadc.Diagnostics" initializeData="{Source}::{Hour}:{Minute}:{Second}:{Millisecond}::{EventType}::{Message}" />
    </listeners>
  </source>
  <source name="[FormSourceEx]" switchValue="All">
    <listeners>
      <add name="console2" type="Ukadc.Diagnostics.Listeners.ConsoleTraceListener, Ukadc.Diagnostics" initializeData="{Source}::{Hour}:{Minute}:{Second}:{Millisecond}::{EventType}::{Message}" />
    </listeners>
  </source>
</sources>
</system.diagnostics>
<startup> 
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>

答案 1 :(得分:0)

要仅使用配置文件将TraceListener设置为程序集和应用程序中定义的TraceSource,我们可以使用sharedListeners,如下所示:

应用代码:

using System;
using System.Diagnostics;
using TestLibrary;

namespace TraceSourceTest
{
    class Program
    {
        static TraceSource source = new TraceSource("TraceSourceTest");
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            source.TraceEvent(TraceEventType.Information, 101, "Hello World");
            Class1 test = new Class1();
            Console.WriteLine(test.add(5, 10));
            Console.ReadKey();
        }
    }
}

TestLibrary代码:

using System.Diagnostics;
namespace TestLibrary
{
    public class Class1
    {
        static TraceSource source = new TraceSource("TestLibrary");
        public int add(int a, int b)
        {
            source.TraceEvent(TraceEventType.Information, 101, "Add " + a + " and " + b);
            source.TraceEvent(TraceEventType.Information, 102, "Result " + (a + b));
            return a + b;
        }
    }
}

Appexe.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
    </startup>
    <system.diagnostics>    
        <trace autoflush="true" indentsize="4" />
        <sources>
            <source name ="TestLibrary" switchValue="All">
                <listeners>    
                    <add name="testListener" />    
                </listeners>
            </source>
            <source name ="TraceSourceTest" switchValue="All">
                <listeners>    
                    <add name="testListener" />
                </listeners>
            </source>
        </sources>
        <sharedListeners>
            <add name="testListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="TraceSourceTest.log">
                <filter initializeData="All" type="System.Diagnostics.EventTypeFilter"/>
            </add>
        </sharedListeners>
    </system.diagnostics>
</configuration>

这将在运行应用程序的目录中创建以下目录的TraceSourceTest.log文件:

TraceSourceTest Information: 101 : Hello World
TestLibrary Information: 101 : Add 5 and 10
TestLibrary Information: 102 : Result 15

并且控制台将在输出下面打印:

Hello World!
15