Loading configuration for System.Diagnostics.TraceSource from an xml file - c#

In log4net, it is possible to choose between loading the configuration from the app.config, or from an arbitrary xml file.
Is it possible to load the configuration for System.Diagnostics.TraceSource from an arbitrary xml file?

System.Diagnostics classes look only at application configuration file. E.g. remarks section of SourceSwitch says:
To configure a SourceSwitch, edit the configuration file that
corresponds to the name of your application.
If you will look into code, you'll see that internally these classes use static DiagnosticConfiguration class which simply gets system.diagonostics configuration section from current app.config
BUT you can move system.diagonostics configuratin section to separate xml file. Just specify name of file where section will be defined:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.diagnostics configSource="diagnostics.xml"/>
</configuration>
diagnostics.xml
<system.diagnostics>
<sources>
<source name="foo" switchName="bar"
switchType="System.Diagnostics.SourceSwitch">
<listeners>
<add name="console"/>
</listeners>
</source>
</sources>
<switches>
<add name="bar" value="Warning"/>
</switches>
<sharedListeners>
<add name="console"
type="System.Diagnostics.ConsoleTraceListener" initializeData="false"/>
</sharedListeners>
<trace autoflush="true" indentsize="4">
<listeners>
<add name="console"/>
</listeners>
</trace>
</system.diagnostics>

Related

Write Trace Logs to text file in ASP.NET Core

I have an application written in .NetFramework 4.5 and the trace logs are added in the simplest possible way:
System.Diagnostics.Trace.WriteLine("Method in: ");
//
//
//
System.Diagnostics.Trace.WriteLine("Method out: ");
We use to write the trace logs into a text file using the <configuration /> tag in web.config.
<configuration>
<system.diagnostics>
<trace autoflush="true" indentsize="4">
<listeners>
<add name="app-logger" type="System.Diagnostics.TextWriterTraceListener"
initializeData="logfile.txt" />
<remove name="Default" />
</listeners>
</trace>
</system.diagnostics>
</configuration>
I'm trying to implement the same functionality in .NetCore 3.1 but where should I place the <configuration /> tag?
You can use Serilog for logging into Text file.
https://nblumhardt.com/2016/10/aspnet-core-file-logger/

Diagnostic Logging

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>

Adding a custom path for a Tracesource TextWriterTraceListener output in config

So I'm using Tracesource to log some errors and wan't to create a log file in a users local windows document structure ( something like System.Environment.SpecialFolder.LocalApplicationData ).
However I have no idea if I can do anything like that inside a config file.
<system.diagnostics>
<trace autoflush="true"/>
<sources>
<source name="MainSource"
switchName="MainSwitch"
switchType="System.Diagnostics.SourceSwitch" >
<listeners>
<add name="LogFileListener" />
</listeners>
</source>
</sources>
<sharedListeners>
<add name="LogFileListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="This is the place the output file goes to"
traceOutputOptions="ProcessId, DateTime, Callstack" />
</sharedListeners>
<switches>
<add name="MainSwitch" value="Verbose" />
</switches>
</system.diagnostics>
initializeData is I think a parameter to the constructor and is where I would have to put a custom path.
The path to the logfile in the config file is absolute and cannot be assumed by any special variables.
However, you could create it dynamically and this should solve your issue
How to: Create and Initialize Trace Sources
Below is sample code I was using for my options. It could help you understand the schema.
Configuration exeConfiguration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
ConfigurationSection diagnosticsSection = exeConfiguration.GetSection("system.diagnostics");
ConfigurationElementCollection switches = diagnosticsSection.ElementInformation
.Properties["switches"]
.Value as ConfigurationElementCollection;
foreach (ConfigurationElement switchElement in switches)
{
Debug.WriteLine("switch: name=" +
switchElement.ElementInformation.Properties["name"].Value +
" value=" +
switchElement.ElementInformation.Properties["value"].Value);
}

Auto-load trace listener to all new trace sources

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 to get Tracelistnername from app.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.diagnostics>
<trace autoflush="true" indentsize="4">
<listeners>
<add name="mylistener" type="System.Diagnostics.TextWriterTraceListener" initializeData="C:\application.txt" />
<add name="mylistener2" type="System.Diagnostics.TextWriterTraceListener" initializeData="C:\application2.txt" />
<remove name="mylistener"/>
<remove name="mylistener2"/>
</listeners>
</trace>
I have the above app.config file.I want to get name from <remove> tag.Can somebody help me to get the remove tag name from codebehind.
You can access the name of the current listeners using the following snippet:
foreach (TraceListener listener in System.Diagnostics.Trace.Listeners)
{
Console.WriteLine(listener.Name);
}
But there is no way to get the names of listeners removed immediately. Your app.config registers two listeners and immediately removes it, what doesn't make sense (to me).

Categories

Resources