TraceListener for Azure

Topics: Exception Handling Application Block, Logging Application Block
Mar 3, 2010 at 3:32 PM

I'm getting ready to write a custom traceListener for entLib logging to an Azure log or table.  Someone must have already done that.  And I'm reprehensibly lazy.  Any code out there for me?

Mar 4, 2010 at 6:52 AM

Hi,

I haven't tried ent lib logging to azure, but the concept is fairly simple. You must implement you custom trace listener (http://msdn.microsoft.com/en-us/library/cc511727.aspx) and in the trace data method, you should add a code that will log to azure, you can try the code that can be found here: http://blog.benday.com/archive/2008/11/07/23201.aspx which is using the RoleManager class.

Valiant Dudan
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com

Mar 4, 2010 at 2:57 PM

Thanks for the tip.  It looks pretty simple.  However, FYI, as of Azure SDK 1.1 RoleMananger, and the namespace it used to live in, have gone away and have been replaced by a TraceListener referenced in the config.  So you can write to the log using  System.Diagnostics.Trace.WriteError("my error message"), or various other Trace methods.  It took me quite a long time to figure this out yesterday, so hopefully this will save someone the effort.  There's a good doc at: 

http://nmackenzie.spaces.live.com/blog/cns!B863FF075995D18A!536.entry?wa=wsignin1.0&sa=230784924

 

Meanwhile, I'd hoped that I could just reference the Azure traceListener in the EntLib config, but I was not able to make that work.  So now I'll try a custom listener that just writes to System.Diagnostics.Trace.  I'll report my progress here.

Mar 4, 2010 at 3:20 PM

Success!  Just implement the custom listener as described in http://msdn.microsoft.com/en-us/library/dd139989.aspx and put the System.Dianostics.Trace.TraceError() calls in the overwritten Write and WriteLine methods.  Then configure appropriately.  I'm sure we could add some more sophisticated logging techniques but I'm satisfied with this for the moment.

 

Mar 23, 2010 at 11:48 PM

I'm trying something similar and can't seem to verify that my TraceData method is being called. Anyone got any advice?

Mar 24, 2010 at 9:34 AM

Hi bstineman,

Is there any exception thrown? I don’t know exactly where you are on this so it’ll be very helpful if you can post your custom trace listener code and config file if possible.  The link from the previous post http://msdn.microsoft.com/en-us/library/dd139989.aspx really had it all documented. If there is something that lacks in the document for me I think it’s probably on the part where you need to configure your configuration file, given that it never gone through to too much details on that.

If you’re running in debug mode you should be able to step into your CustomTraceListener code by having breakpoints. Also, try checking if there is any exception log in your Event Viewer that has been thrown by Application Logging Block. This is assuming that you have not modified the default properties of your Application Logging Block specifically the Logging Errors and Warnings in the Special Sources node that has a default TraceListener of Formatted EventLog TraceListener.

Anyways, here are some thoughts that I hope may help you;

  1. Make sure your Logging Application Block is configured properly in your configuration. See http://msdn.microsoft.com/en-us/library/dd203279.aspx for details.
  2. And make sure the correct Logging Category is getting called in your application code. See http://msdn.microsoft.com/en-us/library/dd203194.aspx for details.

HTH,

~ginkapitan

Mar 24, 2010 at 1:35 PM

Couple issues..

1) I'm actually wrapping a custom rotating flat file trace listener implementation that I can't debug into. However, if I put breakpoints in my tracedata, write, and writeline methods... they are never hit.

2) I'm running this in Azure, so there's no direct access to the Event Log. EntLib tries to use custom event sources which are prohibited by the Azure fabric because creating them requires update permission to the registry (Azure doesn't allow this)

I'm going to play around today and remove the wrapped listener and verify that mine is working properly. I suspect that configuration may indeed be part of the issue. EntLib's configuration block means that the listeners are loaded into a different list then default listeners. I can see the EntLib listener in Microsoft.Practices.EnterpriseLibrary.Logging.Logger.Writer.Sources where the default Azure Diagnostic listener appears in System.Diagnostics.Trace.Listeners.

If pulling the wrapped listener out doesn't teach me anything, I'm going to try and implement a basic non-EntLib listener to see if that works better. I'll be disappointed in this is the end approach I need to take though, as I'll have to refactor a significant amount of code to get this working again. :P 

Mar 24, 2010 at 3:05 PM

Found the issue. The listener I'm wrapping required a matching custom writer. Implemented that and it worked just fine. :)

Aug 25, 2010 at 2:43 AM

This proved to be seminal reading for me to understand how to get logging working in the Cloud.  Unfortunately I can't seem to get Logger.Write to write anything to development storage let alone deployed to the Cloud.  Most of the examples seem to use:

LogEntry log = new LogEntry();
            log.Message = TextBox1.Text;
            log.Categories.Add(Category.General);
            log.Priority = Priority.Normal;
            writer.Write(log);

I guess I could put this in some library as a utility but Logger.Write calls this anyway so it seems like duplication.

Anyone got any bright ideas please?

cheers

Colin

Aug 25, 2010 at 3:09 AM

Have you created the custom trace listener? And what do you exactly mean when you said "let alone deployed to the Cloud?".  You mean deploy the Logging assembly? 

 

Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com

Aug 25, 2010 at 4:16 AM

Hi Sarah,

Sorry for the confusion, what I meant to say was that I have created a customer trace listener which does the following

[ConfigurationElementType(typeof(CustomTraceListenerData))]

public class ConsoleTraceListener : CustomTraceListener

{

public ConsoleTraceListener()

: base()

{

}

public override void TraceData(TraceEventCache eventCache, string source,

TraceEventType eventType, int id, object data)

{

if (data is LogEntry && this.Formatter != null)

{

this.WriteLine(this.Formatter.Format(data as LogEntry));

}

else

{

this.WriteLine(data.ToString());

}

}

public override void Write(string message)

{

Console.Write(message);

}

public override void WriteLine(string message)

{

// Delimit each message

Console.WriteLine((string)this.Attributes["delimiter"]);

// Write formatted message

Console.WriteLine(message);

}

}

I am currently running this application using development storage, and also the app is running in my local dev fabric. I am experiencing an odd problem. If I step into my code i.e. Logger.Write(“Hello world”) which I call from my webrole onStart method as follows:

public class WebRole : RoleEntryPoint

{

public override bool OnStart()

{

DiagnosticMonitorConfiguration diagConfig = DiagnosticMonitor.GetDefaultInitialConfiguration();

diagConfig.Logs.ScheduledTransferLogLevelFilter = LogLevel.Verbose;

// Enable scheduled transfer

diagConfig.Directories.ScheduledTransferPeriod = TimeSpan.FromSeconds(15);

diagConfig.Logs.ScheduledTransferPeriod = TimeSpan.FromSeconds(15);

// For information on handling configuration changes

// see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.

RoleEnvironment.Changing += RoleEnvironmentChanging;

DiagnosticMonitor.Start("DiagnosticsConnectionString", diagConfig);

Logger.Write("Logger OnStart completed");

System.Diagnostics.Trace.TraceInformation("Trace OnStart completed");

return base.OnStart();

}

I step all the way into the code where the customtracelistener above is called the logger.write entry appears in my dev storage, albeit with a small delay of a couple or so minutes.

If however I run without any breakpoints at all nothing appears in my dev storage.

What I meant when I said let alone to the cloud I just meant I hadn’t deployed my application up into our cloud service so don’t yet know if that will be any different.

I hope this clarifies what I meant

Regards

Colin

From: AvanadeSupport [mailto:notifications@codeplex.com]
Sent: Wednesday, 25 August 2010 2:09 p.m.
To: colin@offtheroof.co.nz
Subject: Re: TraceListener for Azure [entlib:203673]

From: AvanadeSupport

Have you created the custom trace listener? And what do you exactly mean when you said "let alone deployed to the Cloud?". You mean deploy the Logging assembly?

Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com

Read the full discussion online.

To add a post to this discussion, reply to this email (entlib@discussions.codeplex.com)

To start a new discussion for this project, email entlib@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on CodePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at CodePlex.com

Aug 25, 2010 at 6:16 AM

So when debugging the code, the expected log appears but if you don't, there are no logs as well?  And why are you using Console.WriteLine in your custom trace listener and then using System.Diagnostics.Trace.TraceInformation after the call to Logger.Write? 

 

Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com

Aug 25, 2010 at 6:59 AM

Hi Sarah,

Yes when single stepping the code, it seems to work, and when I just run it, it doesn’t put anything in.

I found the code from one of the above links in this thread.

The only reason I had the traceinformation call afterwards was because this is me fooling around with different lines of code to test what works and what doesn’t.

Many thanks

Colin

Aug 25, 2010 at 7:05 AM

I believe you need to use System.Diagnostics.Trace.TraceInformation inside the custom trace listener rather than using Console.WriteLine if you're planning to use it in cloud environment.  Could you try it out and see what happens?  Maybe it's not just so obvious when writing to console.

 

Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com

Aug 25, 2010 at 4:18 PM

Has anyone read this: http://www.codeplex.com/Project/Download/FileDownload.aspx?ProjectName=wag&DownloadId=111359? It was put together by our Windows Azure Guidance team as part of their development, and may be of help.

 

Sep 3, 2010 at 12:37 AM

Hi,

I’ve changed the custom listener to use:

Trace.TraceError(message)

Trace.TraceWarning(message)

Trace.TraceInformation(message)

Accordingly depending on the TraceEventType.

I’m still finding that Logger.Write only works intermittently, but if I use

private LogWriter writer = EnterpriseLibraryContainer.Current.GetInstance<LogWriter>();

and then say:

writer.Write("This is an error!");

it works consistently, so I’m a little confused as to why one works and the other only sometimes.

Many thanks for all the guidance

Colin

Sep 3, 2010 at 2:05 AM

Try adding an Event Log Trace Listener under the Logging Errors and Warnings section.  Do not modify its Log and Source properties as one of the limitation of that trace listener under Azure is that it will not be to write to custom logs which needed to be created first (refer to the document from the link Chris Tavares has posted above).  Re-run your application and check the Application event log for log entries indicating why logging fails.

 

Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
entlib.support@avanade.com