tags:

views:

460

answers:

3

I would like my application to write out different trace files named like MachineName_UserName_yyyymmdd_hhmmss.txt where the username is the currently logged in user and the time is the start time of the application. The .Net listener TextWriterTraceListener only seems to support a hard coded file name specified in the config file. Is there a way to do this without writing a custom trace listener.

Assuming I have to write a custom trace listener, I have implemented a tracelistener like this:

Imports System.Diagnostics

Public Class MyCustomTraceListener
    Inherits TextWriterTraceListener

    Public Sub New()
        'Need to do it this way as the Base constructor call has to be the first statement
        MyBase.New(String.Format("AppNameTraceFile_{0}_{1}_{2}{3}{4}-{5}{6}{7}.txt", _
                                                       Environment.MachineName, _
                                                       Environment.UserName, _
                                                       DateTime.Now.ToString("yyyy"), _
                                                       DateTime.Now.ToString("MM"), _
                                                       DateTime.Now.ToString("dd"), _
                                                       DateTime.Now.ToString("HH"), _
                                                       DateTime.Now.ToString("mm"), _
                                                       DateTime.Now.ToString("ss")))
        Me.IndentSize = 4
    End Sub

End Class

In the config file, I have configured the trace source like this:

  <system.diagnostics>
    <trace autoflush="true"/>
    <sources>
      <source name="MyTraceSource"
              switchName="mySwitch"
              switchType="System.Diagnostics.SourceSwitch" >
        <listeners>
          <clear/>
          <add name="MyTraceListener"
            type="MyNameSpace.MyCustomTraceListener"
            traceOutputOptions="ProcessId, DateTime, Callstack" />
        </listeners>
      </source>
    </sources>
    <switches>
      <add name="mySwitch" value="Warning" />
    </switches>
  </system.diagnostics>

I am creating the trace source like so:

Dim tsTraceSource As TraceSource = New TraceSource("MyTraceSource")
tsTraceSource.TraceEvent(TraceEventType.Warning, 0, "warning message")

However, at startup, I keep getting an error that the type "MyNameSpace.MycustomTraceListener" could not be found.

Does anyone see what the problem is here ?

Thanks.

A: 

Don't you need to inform your type assembly?

<add name="MyTraceListener"
     type="MyNameSpace.MyCustomTraceListener, MyAssembly"
     traceOutputOptions="ProcessId, DateTime, Callstack" />
Rubens Farias
This works. Thank you.
DevByDefault
A: 

Another approach which avoids the need for a derived class entirely:

Create a base class TextWriterTraceListener in your config xml, and then on startup, you can enumerate the Listeners collection to find it (there will usually be a DefaultTraceListener and a TextWriterTraceListener), then just set its logging stream to a new stream.

Jason Williams
This approach works too. Thanks.
DevByDefault
A: 

What about setting up your TraceListener in code? If you still want certain parameters, e.g. log path, to be in the app.config, define them in the appSettings section and read them when you create your listener.

' VB
Dim traceLog As New FileStream(traceFile, FileMode.OpenOrCreate)
Dim traceListener As New TextWriterTraceListener(traceLog)
Trace.Listeners.Add(traceListener)

// C#
FileStream traceLog = new FileStream(traceFile, FileMode.OpenOrCreate);
TextWriterTraceListener traceListener = new TextWriterTraceListener(traceLog);
Trace.Listeners.Add(traceListener);

Every element in the config corresponds to the API, so you'll be able to do everything you need.

traceListener.TraceOutputOptions |= TraceOptions.Callstack | TraceOptions.DateTime | TraceOptions.ProcessId;
AndyM
Yes this would work, but I would rather go with all the configuration capabilities provided through the config file rather than home bake the appsettings to mimic the same settings and then set them programatically. Config file is definitely more 'the standard' way of doing it. But, I do agree this is a workable option. Thanks.
DevByDefault