WCF logging, set max file size? - c#

Im using Microsoft Service Configuration Editor to setup diagnostics(WCF logging) and I can´t find any way to set the max file size?
I have found the MaxSizeOfMessageToLog but that do nothing about the file size?
Edit 1: According to this : http://msdn.microsoft.com/en-us/library/aa395205.aspx
There should be a maxFileSizeKB at the sharedListeners level but when hitting space in the add tag I do not get the possibility to type maxFileSizeKB?
Edit 2: When adding the maxFileSizeKB the serivce will not start anymore, instead I will get the following excetion :
'maxFileSizeKB' is not a valid configuration attribute for type 'System.Diagnostics.XmlWriterTraceListener'.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Configuration.ConfigurationErrorsException: 'maxFileSizeKB' is not a valid configuration attribute for type 'System.Diagnostics.XmlWriterTraceListener'.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Edit 3 :
I had to download the Circular TraceListener sample and include it in my project, there is no built in fileSize limiter.
My config looks like this now :
<system.diagnostics>
<sources>
<source name="System.ServiceModel.MessageLogging" switchValue="Warning, ActivityTracing">
<listeners>
<add name="ServiceModelMessageLoggingListener"/>
</listeners>
</source>
<source name="System.ServiceModel" switchValue="Warning,ActivityTracing"
propagateActivity="false">
<listeners>
<add name="ServiceModelTraceListener"/>
</listeners>
</source>
</sources>
<sharedListeners>
<add initializeData="C:\My\MyRelease 0.31\Host\My.Host.Dev\web_messages.svclog"
type="Microsoft.Samples.ServiceModel.CircularTraceListener,CircularTraceListener"
name="ServiceModelMessageLoggingListener" traceOutputOptions="Timestamp" maxFileSizeKB="1024">
<filter type="" />
</add>
<add initializeData="C:\My\MyRelease 0.31\Host\My.Host.Dev\web_tracelog.svclog"
type="Microsoft.Samples.ServiceModel.CircularTraceListener,CircularTraceListener"
name="ServiceModelTraceListener" traceOutputOptions="Timestamp" maxFileSizeKB="1024">
<filter type="" />
</add>
</sharedListeners>
This is limiting the message log file but not the trace log file?

It's because the link your gave use a custom trace listener ("Microsoft.ServiceModel.Samples.CircularTraceListener"), which have a "maxFileSizeKB" property.
There is no built-in functionnality to limit/roll svclog files, so you really need to use a custom trace listener.
You can use the sample used in your link (read at the end of the article how to download the code). Or here is another one that can be usefull.

Just want to add to #Fabske answer that inorder for this to work
1) Download WCF samples:
http://go.microsoft.com/fwlink/?LinkId=150780
2) Open
:\WF_WCF_Samples\WCF\Basic\Management\CircularTracing
3) Build the solution and grab the CircularTraceListener.dll
4) Add that dll to your project references
5) Update your configuration as shown http://msdn.microsoft.com/en-us/library/aa395205(v=vs.100).aspx

Related

Trace listener, how to output to different files based on event type c#

I would like to create two listeners, one for Data and one for errors. Each one outputs to different file. I would like to to decide which listener listens in my program
so what i would like:
<system.diagnostics>
<trace autoflush="true" indentsize="4">
<listeners>
<clear/>
<add name="AppListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="Output/logs.log"/>
<add name="ErrorListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="errors.log"/>
</listeners>
</trace>
In the program i would then like to make a call as such:
Trace.Writeline("AppListener", "Info: this is information");
Is this possible or something similar ?
Not really. The entries in the <listeners> list are all invoked and you don't have control over that from the tracing side. You can create an instance of System.Diagnostics.TextWriterTraceListener yourself in code, and use that directly instead. Depending on what you are trying to achieve exactly, you might find it useful to apply specific filters to the listeners in the <listeners> collection, which would allow them to act on different traces.

What does the autoflush attribute in trace element do

I have the following code in my web.config file:
<system.diagnostics>
<trace autoflush="false" indentsize="4">
<listeners>
<add name="myListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="TextWriterOutput.log" />
<remove name="Default" />
</listeners>
</trace>
</system.diagnostics>
and somewhere in my code behind:
System.Diagnostics.Trace.WriteLine("From the trace");
After running the application, TextWriterOutput.log file was created successfully, but blank. However, after changing the autoflush attribute to true the trace wrote to TextWriterOutput.log.
I also noticed that I can make the trace write to TextWriteOutput.log by using
System.Diagnostics.Trace.Flush();
instead of modifying the autoflush attribute to true.
I read about it in
https://msdn.microsoft.com/en-us/library/system.diagnostics.trace.flush(v=vs.110).aspx
but it didn't make sense to me. Why the trace cannot write immediately to the output file? Can anyone explain in simple words why?
The Flush method forces the output to be written to the file. Setting the autoflush attribute to true causes Trace to always be written immediately to the file, instead of being buffered.

Trying to get to the bottom of a Windows Workflow 4.5 issue

The error I am getting is
"The WorkflowApplication has been aborted because a Load or
LoadRunnableInstance operation threw an exception. Create a new
WorkflowApplication object to try loading another workflow instance."
I am using "workflowapplication" to run the workflow. The workflow instance I'm trying to load (there are a few of them) were created sometime ago and were persisted into the database.
Is there a way to find the exception that was actually thrown during Load or LoadRunnableInstance operation? I caught this error in the "aborted" event on the workflowapplication object, but it does not tell me the error that was thrown during load.
New addition
I stuck the following code in my web.config to get more details about the above exception:
<system.diagnostics>
<sources>
<source name="System.Activities.DurableInstancing" switchValue="Verbose">
<listeners>
<add name="textListener" />
<remove name="Default" />
</listeners>
</source>
</sources>
<sharedListeners>
<add name="textListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="c:\Log\persistenceproblem.txt" traceOutputOptions="ProcessId, DateTime" />
</sharedListeners>
<trace autoflush="true" indentsize="4">
<listeners>
<add name="textListener" />
</listeners>
</trace>
</system.diagnostics>
This pointed me to the exception
System.Activities.DurableInstancing Warning: 131075 : http://msdn.microsoft.com/en-US/library/System.ServiceModel.Diagnostics.ThrowingException.aspxThrowing an exception. Source: System.Activities.DurableInstancing 4.0.0.0. Exception details: System.Runtime.DurableInstancing.InstancePersistenceCommandException: The execution of the InstancePersistenceCommand named {urn:schemas-microsoft-com:System.Activities.Persistence/command}LoadWorkflow was interrupted by an error. ---> System.Runtime.Serialization.SerializationException: The deserializer cannot load the type to deserialize because type 'System.Data.Entity.DynamicProxies.VacancyQuestionFormA_0A0432BFEF4023483E1B33251D8373454EAC6EDF2B2C6F312A4F606F45AF30E8' could not be found in assembly 'EntityFrameworkDynamicProxies-ConnectCore, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Check that the type being serialized has the same contract as the type being deserialized and the same assembly is used.
So now my issues is how to deal with Dynamic proxies that are being serialized. From what I've read, these are on demand so won't be guaranteed to be in the Dlls especially as we have multiple developers.
We already have clients that will have instances of the workflow with serialized Proxy classes.
My question now becomes:
Is there a built in way for Windows Workflow to deal with Serialized Proxy classes more eloquently?

Cannot get WPF binding error trace information to write to log file configured in code

I'm trying to debug what I believe is a WPF binding issue that is only happening on one machine in production -- I cannot repro on a developer machine. In order to do this, I've been trying to get the binding trace information to output to a log file. Following answers like this one, I've been able to get it to output to a hard-coded location by configuring it in App.config:
<system.diagnostics>
<sources>
<source name="System.Windows.Data" switchName="SourceSwitch" >
<listeners>
<add name="textListener" />
</listeners>
</source>
</sources>
<switches>
<add name="SourceSwitch" value="All" />
</switches>
<sharedListeners>
<add name="textListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="c:\BindingErrors.log" />
</sharedListeners>
<trace autoflush="true" indentsize="4"/>
</system.diagnostics>
This works fine on my machine where I have administrative rights to the c:\ drive. The problem is I want to write the log somewhere the user has rights to, e.g. their TEMP folder. So I want to do something like this, using the %TEMP% environmental variable:
initializeData="%TEMP%\BindingErrors.log"
This isn't working, though, and I guess it won't work -- see this answer; so, following the advice in that answer, I've attempted to configure the output via code instead of App.config. Here's what I've tried so far:
var listener = new
TextWriterTraceListener(Environment.ExpandEnvironmentVariables(
#"%TEMP%\BindingErrors.log"), "myListener");
Trace.Listeners.Add(listener);
Trace.WriteLine("foo"); // just to see if it works at all.
Trace.Flush();
But this only writes foo to the log file in the %TEMP% folder. It doesn't write the binding errors. I've tried to replicate what the App.config had, but there's no Sources collection, so when I instantiate a TraceSource, like this:
var source = new TraceSource("mySource", SourceLevels.Information);
I don't know what to do with it, and there's no Listeners collection to which I can add my listener instance.
MSDN doesn't seem to bring it all together for me, or I'm missing some critical details. Can someone please help me figure out what I'm doing wrong?
…there's no Listeners collection to which I can add my listener instance.
Actually, there is: PresentationTraceSources.DataBindingSource.Listeners
The property returns the TraceSource object that is used when data binding messages are output. You can add any listener to that source, such as a TextWriterTraceListener you've created in code-behind by expanding the %TEMP% environment variable and using that as the directory for your output file.
Note that the programmatic approach requires recompiling to change the output location, or the addition of some other configuration value that can be read at run-time. A different technique allows you to specify the entire configuration in the app.config file, by implementing a custom TraceListener that knows how to expand environment variables.
For example:
namespace TestSO39836570TraceListenerBindingErrors
{
class EnvironmentAwareTextWriterTraceListener : TextWriterTraceListener
{
public EnvironmentAwareTextWriterTraceListener(string path)
: base(Environment.ExpandEnvironmentVariables(path))
{ }
public EnvironmentAwareTextWriterTraceListener(string path, string name)
: base(Environment.ExpandEnvironmentVariables(path), name)
{ }
}
}
Then in the app.config file, you can specify the listener:
<system.diagnostics>
<sources>
<source name="System.Windows.Data" switchName="SourceSwitch">
<listeners>
<add name="textListener"/>
</listeners>
</source>
</sources>
<switches>
<add name="SourceSwitch" value="All"/>
</switches>
<sharedListeners>
<add name="textListener"
type="TestSO39836570TraceListenerBindingErrors.EnvironmentAwareTextWriterTraceListener, TestSO39836570TraceListenerBindingErrors"
initializeData="%temp%\BindingErrors.log"/>
</sharedListeners>
<trace autoflush="true" indentsize="4"/>
</system.diagnostics>
Note that when specifying a custom TraceListener type that is found in your own program assembly, you need to specify the assembly name in the type attribute, by following the fully-qualified type name with a comma and then the assembly name (in the example above, the type's namespace is identical to the assembly name, per the defaults for a project created in Visual Studio).
You may of course opt for shorter namespace and type names than the ones I've used here. :)

How to filter trace listened by event id?

I'm using next method to add a trace record:
TraceSource.TraceEvent(TraceEventType, Int32, String)
where Int32 represents event id.
So how to filter in TraceSwitch to listen only by specified event id? Ir this is impossible?
<system.diagnostics>
<sources>
<source name="MyTraceSource" switchName="sourceSwitch" switchType="System.Diagnostics.SourceSwitch>"
<listeners>
<add name="console" type="System.Diagnostics.ConsoleTraceListener" />
</listeners>
</source>
</sources>
<switches>
<add name="sourceSwitch" value="?" />
</switches>
</system.diagnostics>
It's possible but you need to write a custom TraceFilter and override the ShouldTrace method. The id is passed to it, but no out-of-the-box filter supports it.
Then, you can declare it like this in a .config file:
<source name="MyTraceSource" switchName="sourceSwitch" switchType="System.Diagnostics.SourceSwitch">
<listeners>
<add name="console" type="System.Diagnostics.ConsoleTraceListener">
<filter type="YourNamespace.YourFilter, YourAssembly, ..." />
</add>
</listeners>
</source>
You can try Ukadc.Diagnostics from codeplex. This project provides some useful extensions for System.Diagnostics. The coolest thing, in my opinion, that they provide is a token based system that can be used to define log/trace output format similar to what you can achieve with log4net and NLog. It is a configuration-only dependency. That is, if you code is already using TraceSources, you only have to put Ukadc.Diagnostics on your machine and have your app.config point to their TraceListeners, PropertyTokens, etc.
You still instrument your code using System.Diagnostics.TraceSource objects.
To your point, using Ukadc.Diagnostics you can filter based on most property tokens (including EventId).
Note that the token system can only be used (as far as I know) with the corresponding TraceListeners provided in Ukadc.Diagnostics (or any TraceListener that you write based on their base TraceListener class).
I have not used this project in production, but I have fooled around with it quite a bit and have been quite impressed. It works well and is easy to extend.

Categories