I have a working WCF service that I wanted to hook into so I can look at the logs. So, I added a .config file, and now my service will not start at all.
In my code I do the following:
private ServiceHost _myHost;
....
_myHost= new ServiceHost(typeof (MyType), new Uri(baseUri));
_myHost.AddServiceEndpoint(typeof (myInterface), new NetNamedPipeBinding(), hostName);
_myHost.Open();
And, as mentioned, this works when I do not have a .config file. However, to view the logs I have to add a .config file that looks like this:
<system.diagnostics>
<sources>
<source propagateActivity="true" name="System.ServiceModel" switchValue="Verbose,ActivityTracing">
<listeners>
<add type="System.Diagnostics.DefaultTraceListener" name="Default">
<filter type="" />
</add>
<add initializeData="c:\logs\Traces.svclog" type="System.Diagnostics.XmlWriterTraceListener"
name="traceListener" traceOutputOptions="LogicalOperationStack, DateTime, Timestamp, ProcessId, ThreadId, Callstack">
<filter type="" />
</add>
</listeners>
</source>
</sources>
</system.diagnostics>
<system.serviceModel>
<diagnostics>
<messageLogging logMalformedMessages="true" logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="true" />
<endToEndTracing activityTracing="true" messageFlowTracing="true" />
</diagnostics>
</system.serviceModel>
The error I now get in the logger is Failed to open System.ServiceModel.ServiceHost and it occurs at the instance creation of my ServiceHost. So, why does adding a logging config make any difference?
UPDATE
The logger is the ServiceTraceViewer, that is where I am seeing the error once I throw in the config. So, the logging is working, it is just breaking the functionality of the code. I read somewhere that if I use a .config that I MUST have an endpoint in the config. Is that true, and if so, is there a workaround to this since I am doing that via code
Related
I have successfully configured logging in the App.config file of an application. The relevant parts are as follows.
<system.diagnostics>
<sources>
<source name="System.Net.Http">
<listeners>
<add name="PushTraceListener" />
</listeners>
</source>
</sources>
<switches>
<add name="System.Net.Http" value="Verbose"/>
</switches>
<sharedListeners>
<add name="PushTraceListener"
type="PushCore.Logging.LoggingTraceListener, PushCore" />
</sharedListeners>
</system.diagnostics>
<system.serviceModel>
<diagnostics>
<messageLogging logEntireMessage="true"
logMalformedMessages="false"
logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="true"
maxMessagesToLog="3000"
maxSizeOfMessageToLog="2000"/>
</diagnostics>
</system.serviceModel>
While this works fine, I seem unable to do the same in the application code, which I tried as follows.
var LoggingTraceListener = new LoggingTraceListener
{ Name = "PushTraceListener", Filter = new LoggingTraceFilter() };
Trace.AutoFlush = true;
var TraceSourceNames = new string[] { "System.Net.Http" };
foreach (var TraceSourceName in TraceSourceNames)
{
var TraceSource = new TraceSource(TraceSourceName, SourceLevels.Verbose);
TraceSource.Switch = new SourceSwitch(TraceSourceName, "Verbose");
TraceSource.Listeners.Add(LoggingTraceListener);
}
Trace.Listeners.Add(LoggingTraceListener);
The TraceListener itself seems to behave as expected, as it recieves messages written via Trace, but apparently not from the instantiated TraceSource instance. I somehow believe that instantiation of the TraceSource is not desired here, but instead an existing trace source would have to be used. However, I don't know how to do that.
Is it possible to achieve loggig as desired in the first place? If so, how?
A justified question would be why I would like to do access in code instead of using App.config if the configuration works fine. The reason is that App.config can only be used for an actual application but not for a Windows service.
Any suggestions?
I'm logging messages for WCF web service using System.Diagnostics System.ServiceModel.MessageLogging with configuration below. And I extended
TraceListener class as:
public class FormattedTraceListener : TraceListener
{
static readonly Logger logger = new Logger();
public FormattedTraceListener()
: base(string.Empty)
{
}
public override void TraceData(TraceEventCache eventCache,String source,TraceEventType eventType,**Int32 id,**Object data)
{
//....
<system.diagnostics>
<sources>
<source name="System.ServiceModel.MessageLogging" >
<listeners>
<add name="pretty" />
<remove name="Default"/>
</listeners>
</source>
</sources>
<sharedListeners>
<add name="pretty" lockItem="true" type="LoggingTest.FormattedXmlWriterTraceListener,LoggingTest" />
</sharedListeners>
<trace autoflush="true" indentsize="4">
</trace>
</system.diagnostics>
....
<diagnostics >
<messageLogging
logEntireMessage="true"
logMalformedMessages="false"
logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="false"
maxMessagesToLog="-1"
maxSizeOfMessageToLog="134217728">
<filters >
<add xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">/s:Envelope</add>
<add xmlns:s="http://www.w3.org/2003/05/soap-envelope">/s:Envelope</add>
</filters>
</messageLogging>
<endToEndTracing propagateActivity="true" activityTracing="true" messageFlowTracing="true" />
</diagnostics>
</system.serviceModel>
TraceData method fired twice (for request and response) for each service call.
However, when method is hit, the id parameter is always 0.
I need a unique id in logging text to match request and response log. How can I specify that?
Your approach is not right. The TraceData(int id) field is not a unique id for the WCF request. It's the application defined code for the event type.
Just use the standard WCF trace classes and view correlated traces. If I understand what you are trying to accomplish in matching up request to response, the default behavior already meets your requirements.
I want to add a trace file in my windows service but the file is never created. Is this only meant for web applications?
<?xml version="1.0"?>
<configuration>
<startup>
<system.diagnostics>
<trace autoflush="true" indentsize="4">
<listeners>
<add name="myListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="C:\Logs\application.log" />
<remove name="Default" />
</listeners>
</trace>
</system.diagnostics>
</startup>
</configuration>
In code
Trace.WriteLine("Application started.", "App");
The config file you show is invalid. Under the startup element only settings for the runtime are allowed.
The system.diagnostics goes directly under the <config> element, like so:
<?xml version="1.0"?>
<configuration>
<system.diagnostics>
<trace autoflush="true" indentsize="4">
<listeners>
<add name="myListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="C:\Logs\application.log" />
<remove name="Default" />
</listeners>
</trace>
</system.diagnostics>
</configuration>
Depending on the security context for your service you might have to set permissions on the folder where you want to log, in your case c:\logs. The Tracing will silently fail if it can't write to that log file.
I have a certain framework of code, and I have a TraceListener defined for two reasons:
Back-compatibility with a lot of the old logging that was done via Trace.Write until we update it, and
It's nice to be able to instrument the other assemblies our code references if we need to.
However, I have one assembly (not ours) that logs a lot of pointless data that doesn't help us debug anything. How can I turn off tracing for this one assembly (or, alternately, the facade project we built around it), while leaving it on for the rest of the application?
I've tried various flavors of configuration in our facade project, usually looking like the following, to no avail. I've tried adding <remove> elements that match the <add> elements which setup the logging in the first place, tried <clear>ing them, setting <trace enabled="false"> and at least three other attempts. Thanks for any help you can provide!
<system.diagnostics>
<trace autoflush="true" indentsize="4">
<listeners>
<clear/>
</listeners>
</trace>
<switches>
</switches>
</system.diagnostics>
You can write your own trace filter, for use with your TraceListener. Inside this filter you can look for your assembly in stackTrace and turn off event tracing.
In my case I wrote filter (see: DotNetOpenAuthFilter) based on EventTypeFilter, which filters events only from the DotNetOpenAuth library.
Then connect the filter to the listener in the web.config:
<configuration>
<system.diagnostics>
<trace>
<listeners>
<add name="console" type="System.Diagnostics.ConsoleTraceListener" >
<filter type="Common.Log.DotNetOpenAuthFilter, Common" initializeData="Warning" />
</add>
</listeners>
</trace>
</system.diagnostics>
</configuration>
Use TraceSource.
Initialize it in your trace source.
TraceSource logger = new TraceSource("Class1");
Call it from critical points in code:
logger.TraceInformation("Hello from Class1");
Be sure to edit your application configuration:
<system.diagnostics>
<trace autoflush="true"/>
<sources>
<source name="Class1" switchName="Class1Switch" switchType="System.Diagnostics.SourceSwitch">
<listeners>
<add name="console"></add>
<add name="csv" />
<!-- or you can add your own listener here -->
</listeners>
</source>
</sources>
<switches>
<add name="Class1Switch" value="Information" />
</switches>
<sharedListeners>
<add name="console" type="System.Diagnostics.ConsoleTraceListener" />
<add name="csv" type="System.Diagnostics.DelimitedListTraceListener"
delimiter="|" initializeData="d:\data\tracing\trace.log"
traceOutputOptions="Timestamp, ThreadId, LogicalOperationStack, DateTime, ProcessId">
</add>
</sharedListeners>
</system.diagnostics>
If say, you want to only log errors, change the switch:
<add name="Class1Switch" value="Error" />
To switch it completely off:
<add name="Class1Switch" value="Off" />
I've got a WCF client communicating with a WCF service using [DataContract] types, and I'm getting a serialization error:
The formatter threw an exception while trying to deserialize the message: There was an error
while trying to deserialize parameter http://www.example.com/2007/09/Example:ExampleResult.
The InnerException message was 'Deserialized object with reference id 'i3' not found in
stream.'. Please see InnerException for more details.
Normally, I'd simply crank up the tracing and see exactly what happened, but in this case, I can't get the offending (response) message to appear in the log.
My configuration looks like this:
<system.serviceModel>
... (more stuff)
<diagnostics>
<messageLogging logEntireMessage="true" logMalformedMessages="true"
logMessagesAtServiceLevel="false" logMessagesAtTransportLevel="true"
maxMessagesToLog="10000" maxSizeOfMessageToLog="81920000" />
</diagnostics>
</system.serviceModel>
<system.diagnostics>
<trace autoflush="true" />
<sources>
<source name="System.ServiceModel" switchValue="Information, ActivityTracing"
propagateActivity="true">
<listeners>
<add name="wcf_listener" />
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="wcf_listener" />
</listeners>
</source>
</sources>
<sharedListeners>
<add name="wcf_listener" initializeData="tracelog.svclog"
type="System.Diagnostics.XmlWriterTraceListener" />
</sharedListeners>
</system.diagnostics>
In the resulting log file, I get the outbound message logged, and then the exception logged. I never see the incoming message. What am I doing wrong here?
It seems that the problem related to your flooded data between the service and the client.
Please refer to my post here