1

Most TraceSource tracing examples show how it is done via configuration. I am trying to achieve this via code.

I have a simple assembly as follows:

using System;
using System.Diagnostics;
using System.Threading;

namespace TracingLib
{
    public class AppTracer
    {
        public event EventHandler AppStarted;
        public event EventHandler AppStopped;
        private bool CancelRequested = false;
        public void Start()
        {
            Thread thread = new Thread(new ThreadStart(() =>
            {
                if(AppStarted != null) AppStarted(this, new EventArgs());

                TraceSource ts = new TraceSource("ThreadSource");

                ts.TraceInformation("Thread Begins");
                //ts.Flush();
                int i = 0;
                while (!CancelRequested)
                {

                    ts.TraceInformation("i: {0}", i++);
                    //ts.Flush();
                    Debug.Print("i : {0}", i);
                    Thread.Sleep(5000);
                }

                if (AppStopped != null) AppStopped(this, new EventArgs());
            }));
            thread.Start();
        }

        public void Stop()
        {
            CancelRequested = true;
        }
    }
}

I am consuming this in a console application.

using System;
using System.Threading;
using TracingLib;

namespace caTracingLibImplementation
{
    class Program
    {
        static void Main(string[] args)
        {
            AppTracer tracer = new AppTracer();
            ManualResetEvent waiter = new ManualResetEvent(false);
            tracer.AppStopped += (sender, e) =>
            {
                waiter.Set();
            };

            TraceSource ts = new TraceSource("ThreadSource");            
            ts.Listeners.Add(new ConsoleTraceListener());
            var sw = new SourceSwitch("foo");
            sw.Level = SourceLevels.Warning;
            ts.Switch = sw;
            tracer.Start();
            Console.WriteLine("AppTracer started...");
            Thread.Sleep(10000);
            tracer.Stop();
            Console.WriteLine("AppTracer stopped...");
            Console.WriteLine("Waiting to stop...");
            waiter.WaitOne();
            Console.WriteLine("End of program");
        }
    }
}

If I try to enable tracing via the console application I cannot see the trace messages.

deostroll
  • 11,661
  • 21
  • 90
  • 161
  • Once you get a reference to the internal tracesources list (1 per AppDomain) you can do anything you want to it (that would normally be done on startup via config), this code illustrates the technique, I'll see if I can create a woking example: https://stackoverflow.com/questions/23664573/tracesource-and-tracelistener-quietly-fail-to-do-anything/23664574#23664574 – MatthewMartin Mar 22 '15 at 01:16

2 Answers2

1

Firstly, You need to supply TraceListeners to the TraceSource defined in AppTracer.

This code would work using configuration files would work because the .NET framework keeps a single instance of each listener obtained from the configuration file and assigns them to each TraceSource based on the initial string parameter.

If the string parameter for the TraceSource is not defined in app.config then there will be no listeners saved in global state. Therefore each instance of a TraceSource must have all the listeners supplied to it.

TraceSource.Initialize() Source

Secondly, the switch: sw.Level = SourceLevels.Warning; will disable any statements logged with: ts.TraceInformation()

user1112560
  • 185
  • 1
  • 8
  • exactly "what" is reading the configuration file for the enabling the tracing via tracesource? – deostroll Mar 22 '15 at 03:24
  • 1
    You'd be best to read through the linked source for the most complete explanation. sourceElement.Listeners is where the magic happens. – user1112560 Mar 23 '15 at 01:46
  • I guess the only option I am left with is to expose the TraceSource object from AppTracer and add listeners to it from the executing assembly... – deostroll Mar 23 '15 at 05:10
0

If you are configuring your TraceSource at run time then I think the most appropriate solution for your code is to:

  1. Inject that dynamic TraceSource into the constructor of AppTracer.
  2. OR pass the TraceSource in through Start().

I would lean toward #1 over #2.

As user1112560 mentions, you will not see TraceInformation output if your switch level is set to Warning. The precedence is Off, Error, Warning, Information, Verbose. See MSDN Trace Switches.

Jeremy
  • 587
  • 6
  • 12