Here is the code
class Program
{
public static TraceSource TS = new TraceSource("myTraceSrc", SourceLevels.All);
static void Main(string[] args)
{
TS.TraceInformation("Hello Trace from Main");
}
}
here is the config file
<system.diagnostics>
<sources>
<source name="myTraceSrc" switchName="switch1">
<listeners>
<add type="System.Diagnostics.TextWriterTraceListener" name="myLocalListener" initializeData="c:\Test.Log" />
<add name="consoleListener" />
</listeners>
</source>
</sources>
<sharedListeners>
<add type="System.Diagnostics.ConsoleTraceListener" name="consoleListener" traceOutputOptions="None" />
</sharedListeners>
<switches>
<add name="switch1" value="all" />
</switches>
</system.diagnostics>
Message is displayed on the console but nothing goes in file. What am I doing wrong?
Have you tried calling TraceSource.Flush?
Try creating the TextWriterTraceListener manually like it is described here.
Related
Apologies if this has been asked before.
I have recently enabled the diagnostics messagelogging on our C# solution. However, the example I got from the web, the standard, has, I think, too many events being logged.
Can I adjust this messagelogger to log just the critical errors experienced in the system? I am still new at this message logging, so if I knew what to do, I wouldn't be asking you guys.
My current setup:
<system.serviceModel>
<diagnostics>
<!-- Enable Message Logging here. -->
<!-- log all messages received or sent at the transport or service model levels >-->
<messageLogging logEntireMessage="true" maxMessagesToLog="300" logMessagesAtServiceLevel="true" logMalformedMessages="true" logMessagesAtTransportLevel="true" />
</diagnostics>
<system.diagnostics>
<sources>
<source name="System.ServiceModel" switchValue="Information,ActivityTracing" propagateActivity="true">
<listeners>
<add name="xml" />
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="xml" />
</listeners>
</source>
</sources>
<sharedListeners>
<add initializeData="C:\logs\Diagnostics.svclog" type="System.Diagnostics.XmlWriterTraceListener" name="xml" />
</sharedListeners>
<trace autoflush="true" />
All this is of course in my App.config. I only use it here, and not in my code or anywhere else. It works, but to me, there is too much info being saved. Could I just save the major/critical errors?
C# project, Visual Studio 2015, Windows 10. If you need more, please ask.
Within you <source> node change the value of the attribute switchValue to Critical, Error then this should only log those events. Information is an event that generally occurs everywhere on tracing.
You can maybe also look here to gain further information about the logging: From zero to logging
The problem with excessive logs in your setup occurs in the System.ServiceModel.MessageLogging listener; you're telling the ServiceModel to log all service messages, which is fine. However, if you only want to log error messages for both ServiceModel and ServiceModel.MessageLogging you'll need to create a filter for your sharedListener.
The following diagnostics configuration works quite nicely:
<system.diagnostics>
<sources>
<source name="System.ServiceModel">
<listeners>
<add name="xml" />
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="xml" />
</listeners>
</source>
</sources>
<switches>
<add name="System.ServiceModel" value="Critical, Error"/>
</switches>
<sharedListeners>
<add initializeData="Diagnostics.svclog" type="System.Diagnostics.XmlWriterTraceListener" name="xml">
<filter type="System.Diagnostics.EventTypeFilter" initializeData="Critical, Error"/>
</add>
</sharedListeners>
<trace autoflush="true" />
The <filter /> element tells the listener to only write logs with an EventType of Critical or Error. The assumption here is that if a message is problematic, it would be flagged with an Error event type.
Additionally, you could create a rolling or daily XmlWriterTraceListener to start a new log by file size or each day respectively.
Simply change the sharedListener type:
<add initializeData="Diagnostics.svclog"
type="My.Namespace.MyXmlWriterTraceListener, MyAssembly"
name="xml">
...
</add>
I am converting some code to use Microsoft tracing. What I'd like is to define all the listeners in one project and then use them from other assemblies, without having to explicitly load them there.
To clarify, this is what I'm doing now:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add name="myListener" type="ConsoleApplication4.LogListener, ConsoleApplication4"/>
<remove name="Default" />
</listeners>
</trace>
</system.diagnostics>
</configuration>
And in the C# code:
var b = Trace.Listeners;
TraceSource tr = new TraceSource("Blah", SourceLevels.All);
tr.Listeners.Add(b["myListener"]);
tr.TraceEvent(TraceEventType.Warning, 5, "Hello");
What I would like is for myListener to be automatically added to any new trace source I create without having to look it up the way I'm doing now. Is this possible?
Define the trace source along with its listeners in config:
<system.diagnostics>
<sources>
<source name="Blah" switchValue="Warning">
<listeners>
<add name="myListener" />
</listeners>
</source>
</sources>
<!-- Note these are in sharedListeners rather than trace -->
<sharedListeners>
<add name="myListener" ... />
</sharedListeners>
<!-- Autoflush still works as expected -->
<trace autoflush="true" />
</system.diagnostics>
Then construct the TraceSource in code the way you already are (its trace level will be overridden by the switchValue in config), don't add any listeners to it and log to it as normal.
How can one add a footer to a trace listener which is defined in the app.config:
<system.diagnostics>
<switches>
<!-- Set loglevel for diagnostic messages
(0=none, 1=errors, 2=warnings, 3=info, 4=verbose) -->
<add name="logLevel" value="4" />
</switches>
<trace autoflush="true" indentsize="4">
<listeners>
<add name="FileListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="Logs\QFXLog.txt" />
<remove name="Default" />
</listeners>
</trace>
I want to write an end footer when this listener is closed.
What entries are to be defined in the config(if any?) and where must one define the footer string in code?
Thanks,
Juergen
I don't know of any way to handle this directly in the app.config file, but you could implement a class which inherits TextWriterTraceListener and then override its Close method:
namespace MyNamespace
{
public class FormattedTextTracer : TextWriterTraceListener
{
public override void Close()
{
// Write footer
Writer.WriteLine("==== Footer ====");
Writer.Flush();
base.Close();
}
}
}
And in the app.config file, replace the listener type with your class:
<listeners>
<add name="FileListener"
type="MyNamespace.FormattedTextTracer, MyNamespace"
initializeData="Logs\QFXLog.txt" />
<remove name="Default" />
</listeners>
Here is my code
public static TraceSource TS = new TraceSource("myTraceSrc", SourceLevels.All);
static void Main(string[] args)
{
TS.TraceInformation("Hello Information Trace from Main");
TS.TraceEvent(System.Diagnostics.TraceEventType.Error, 1, "Hello Error Trace from Main");
}
here is config file
<system.diagnostics>
<trace autoflush="true" />
<sources>
<source name="myTraceSrc" switchName="switch1" >
<listeners>
<add type="System.Diagnostics.TextWriterTraceListener" name="myLocalListener" initializeData="c:\WasteBin\Test.Log" />
<add name="consoleListener" />
</listeners>
</source>
</sources>
<sharedListeners>
<add type="System.Diagnostics.ConsoleTraceListener" name="consoleListener" traceOutputOptions="None" />
<add type="System.Diagnostics.EventTypeFilter" name="EventListener" traceOutputOptions="None" />
</sharedListeners>
<switches>
<add name="switch1" value="all" />
</switches>
</system.diagnostics>
I want all my messages to go to console and text file but only error should go to events log. How can I set it up using configuration settings?
Try to use logging libraries (Nlog, log4net) for your tasks. They have message filtering and routing.
I'm new with TraceSource so I'm doing some investigation into how it can/ can't be used (basically pros and cons).
Something I do like is that I can get dumps from within the .NET framework itself, so I've made a little app to test that and using my own custom source together (as that's how I'd expect it to be used), like so:
class Program
{
static void Main(string[] args)
{
SmtpClient smtp = new SmtpClient();
var mm = new MailMessage();
mm.To.Add("me#my-site.com");
mm.Subject = "Trace Testing";
smtp.Send(mm);
var ts = new TraceSource("MyCustomTracer");
ts.TraceEvent(TraceEventType.Error, 0, "This is an error");
ts.TraceEvent(TraceEventType.Information, 0, "Just debugging now");
}
}
I've then added some listeners into the App.config like this:
<system.diagnostics>
<trace autoflush="true" />
<sources>
<source name="MyCustomTracer"
switchValue="Information, ActivityTracing">
<listeners>
<add name="sdt"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData= "traceOutput.log" />
</listeners>
</source>
<source name="System.Net"
switchValue="Information, ActivityTracing, Critical">
<listeners>
<add name="sdt"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData= "traceOutput.log" />
</listeners>
</source>
</sources>
</system.diagnostics>
But for some reason when I run the app the 2 events I'm logging via MyCustomTracer aren't going into the log file unless I comment out the SmtpClient stuff (ie - only have my custom tracer used).
I would have expected that multiple TraceSources can be used in the manner in which I'm trying to use them, I'm just not sure what's going wrong.
Found the problem, a complete noob mistake, both my TraceSource items have a Listener which is writing to the same file. Although I'm not sure exactly the error, but it'd be some kind of clash when writing.
If you want to have multiple sources using the same listener you need to use the <sharedListeners /> like this:
<system.diagnostics>
<trace autoflush="true" />
<sources>
<source name="MyCustomTracer"
switchValue="Information, ActivityTracing">
<listeners>
<add name="sdt" />
</listeners>
</source>
<source name="System.Net"
switchValue="Information, ActivityTracing, Critical">
<listeners>
<add name="sdt" />
</listeners>
</source>
</sources>
<sharedListeners>
<add name="sdt"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData= "traceOutput.log" />
</sharedListeners>
</system.diagnostics>