Reputation: 43
What I'm trying to accomplish is setting a TraceListener for a TraceSource in a referenced .dll using only the config file.
Specifically I have solution Robot which has an app.config that looks like this:
<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/
and a ExtendedSource (from the Ukadc.Diagnostics.dll) initialized like this:
public static ExtendedSource robotSourceEx = new ExtendedSource( "RobotModel", SourceLevels.All );
Then I export the .dll and import it to the UI component and have a similar 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>
When I run the UI component I get an empty console (Console.WriteLine and the trace information is missing), but if i comment out the TraceListener for the RobotModel, then the console has the example trace messages (as well as the Console.WriteLine message).
Note: the gui is a Winforms/Windows Application while the Robot class is a console application. I don't think this would make a huge difference but maybe its noteworthy. I do manually allocate a console on the Windows Application so that I can ensure the trace works before routing it to a File.
Upvotes: 0
Views: 480
Reputation: 111
To Setup TraceListener to a TraceSource defined in assembly as well as application using just config file we can use sharedListeners as shown below:
Application code:
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 Code:
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>
This will create a TraceSourceTest.log file in the directory from where app is running with below logs:
TraceSourceTest Information: 101 : Hello World
TestLibrary Information: 101 : Add 5 and 10
TestLibrary Information: 102 : Result 15
and Console would be printing below output:
Hello World!
15
Upvotes: 0
Reputation: 43
To answer my own questions:
In terms of what was causing my problem it seems it had something to do with when I allocated the console in the WinForms. After changing the location of where I called AllocConsole the cmd window showed the trace information for both sources.
For posterity here is the code I used to test this:
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;
}
}
Then exported this as an assembly imported it to a 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();
}
}
}
And the app config which I used:
<?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>
Upvotes: 0