Clear steps for setting up Azure Diagnostics - azure

I am trying to get diagnostics tracing working, but I am confused about necessary steps I have to follow. I will present what I have done until now:
In app.config I have following:
<system.diagnostics>
<trace autoflush="true" />
<sources>
<source name="ProfileTrace" switchName="profileTraceSwitch" switchType="System.Diagnostics.SourceSwitch">
<listeners>
<add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=2.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" name="AzureDiagnostics">
<filter type="" initializeData="Warning" />
</add>
<add name="LogFileListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="..\..\..\skype.portal.profile.log" traceOutputOptions="ProcessId, ThreadId" />
</listeners>
</source>
</sources>
<switches>
<add name="profileTraceSwitch" value="Verbose"/>
</switches>
</system.diagnostics>
In Service.Definition I have following:
<Imports>
<Import moduleName="Diagnostics" />
</Imports>
In Service.Configuration I have:
<ConfigurationSettings>
<Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" value="DefaultEndpointsProtocol=https;AccountName=<snip>;AccountKey=<snip>" />
I have following confusion right now. As you can see in app.config I tried to add a filter for DiagnosticMonitorTraceListener to trace only Warnings, but this filter was ignored. I found this post, which suggests to use custom trace listener that derives from DiagnosticMonitorTraceListener http://social.msdn.microsoft.com/forums/wpapps/en-us/92ed1175-d6b7-4173-a224-0f7eb3e99481/diagnosticmonitortracelistener-ignors-filter
On the other hand in following official link from microsoft http://msdn.microsoft.com/en-us/library/ee758610.aspx they leave filter type empty:
<add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener,
Microsoft.WindowsAzure.Diagnostics,
Version=1.0.0.0,
Culture=neutral,
PublicKeyToken=31bf3856ad364e35"
name="AzureDiagnostics">
<filter type="" />
</add>
Then they mention about configuring Logs property http://msdn.microsoft.com/en-us/library/microsoft.windowsazure.diagnostics.diagnosticmonitorconfiguration.logs.aspx where I see:
public override bool OnStart() {
......
// Filter the logs so that only error-level logs are transferred to persistent storage.
diagnosticConfiguration.Logs.ScheduledTransferLogLevelFilter = LogLevel.Error;
......
return base.OnStart();
}
}
So, I have following 2 questions:
In my current solution I haven't written any code on Start method of WorkerRole to configure Diagnostic Monitor, but after some searching I found that many people do this. I ran my project locally and I was able to see data stored in Azure WADLogsTable. So, is it mandatory to add Diagnostic Monitor configuration code to my Worker role or can I just have diagnostics.wadcfg?
Since filters for DiagnosticMonitorTraceListener in app.config file are ignored, if I skip the use of a custom trace listener that derives from DiagnosticMonitorTraceListener suggested here http://social.msdn.microsoft.com/forums/wpapps/en-us/92ed1175-d6b7-4173-a224-0f7eb3e99481/diagnosticmonitortracelistener-ignors-filter and use ScheduledTransferLogLevelFilter of Logs property in my WorkerRole, will I achieve the log filter I want? Or maybe filter in app.config and ScheduledTransferLogLevelFilter refer to 2 different kind of filters?

I would recommend against setting the Azure diagnostic configuration in code. Instead, I would recommend using the diagnostic.wadcfg file approach. You can find some info here - http://msdn.microsoft.com/en-us/library/hh411551.aspx. Visual Studio will help generate this file as well.
It is not mandatory to set any Azure diagnostic configuration in your role's OnStart() method.
Setting the ScheduledTransferLogLevelFilter should suffice. Plus, that also enables you to easily change the filter level at runtime if needed (via an API call, Visual Studio, or 3rd party tool like Cerebrata Azure Management Studio).

Related

Azure API Apps Diagnostics

I have an Azure API App that needs to log trace data, so have chosen to use Azure Diagnostics and .Net System.Diagnostics.Trace.
The trace message logs to Table Storage, but the Event Id field is 0. The documentation online suggests 0 is the default value, but I cannot see an obvious way to set the Event Id.
Trace.TraceError, Trace.TraceInformation and Trace.TraceWarning only take a string or a formatted message.
Would some know if it is possible to set the Event Id and if so how?
Thanks
Andy
Although I cannot take credit for the answer, I thought I should post the answer I found here: https://blogs.msdn.microsoft.com/mcsuksoldev/2014/09/04/adding-trace-to-azure-web-sites-and-web-jobs/
Basically you use the System.Diagnostics.TraceSource type and call the TraceEvent() method. Although this won't work without some configuration first.
There are three trace listeners to be aware of, although for just TableStorage it is only the first:
AzureTableTraceListener
AzureBlobTraceListener
AzureDriveTraceListener
You will need to install the nuget package: Microsoft.WindowsAzure.WebSites.Diagnostics
The code example from the link above is:
public static readonly TraceSource Operational = new TraceSource("Operational");
Operational.TraceEvent(TraceEventType.Verbose, 101, "TraceEvent WebSite Operational");
For the TraceSource to log to TableStorage you need to add the following to the web.config:
<system.diagnostics>
<sharedListeners>
<add name="AzureTableTraceListener" type="Microsoft.WindowsAzure.WebSites.Diagnostics.AzureTableTraceListener, Microsoft.WindowsAzure.WebSites.Diagnostics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</sharedListeners>
<sources>
<source name="Operational" switchName="OperationalSourceSwitch" switchType="System.Diagnostics.SourceSwitch">
<listeners>
<add name="AzureTableTraceListener"/>
<add name="AzureBlobTraceListener"/>
</listeners>
</source>
</sources>
<switches>
<add name="OperationalSourceSwitch" value="All" />
</switches>
<trace autoflush="true" indentsize="4" />
Andy

Disable pool recycling on Azure Websites

I have a website deployed on Azure Websites and I want to disable pool recycling.
If you have a regular IIS installation, you can disable this in application pool advanced settings by setting "Recycling -> Disable overlapped recycle" to true.
Yet I can't seem to find this option in the azure management console, nor do I find any information on this subject online.
Any pointers would be greatly appreciated!
Thanks a lot Puneet Gupta for pointing me in the right direction!
I couldn't use the exact solution, but it set me on the right path.
Here's how I solved this:
1) Get your hands on the applicationHost.config.
The easiest way is going through the SCM Console via "files" and then follow the links in json.
In the end, you end up here: https://YOUR_WEBSITE_NAME.scm.azurewebsites.net/api/vfs/LocalSiteRoot/Config/applicationhost.config
2) Identify the current status of overlapped recycle.
In the applicationHost.config file, look for the "applicationPools" element
It should look like this:
<applicationPools>
<add name="YOUR_SITE_NAME" managedRuntimeVersion="v4.0">
<processModel identityType="ApplicationPoolIdentity" />
</add>
<add name="~1YOUR_SITE_NAME" managedRuntimeVersion="v4.0" managedPipelineMode="Integrated">
<processModel identityType="ApplicationPoolIdentity" />
</add>
</applicationPools>
If you see this, then overlapped recycle is ENABLED!
You can't write directly to this file but fortunately microsoft gives us the power to transform it!
3) Transform it!
You can transform the applicationHost.config file by placing an applicationHost.xdt file in the /site directory of your website (mind you that the website itself is deployed in the /site/wwwroot directory, so your applicationHost.xdt transform must reside in the parent folder of where your website is.
If you want to disable overlapped recycle, then this is what you put in the file:
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">>
<system.applicationHost>
<applicationPools>
<add name="YOUR_SITE_NAME" xdt:Locator="Match(name)">
<recycling disallowOverlappingRotation="true" xdt:Transform="Insert" />
</add>
<add name="~1YOUR_SITE_NAMEd" xdt:Locator="Match(name)">
<recycling disallowOverlappingRotation="true" xdt:Transform="Insert" />
</add>
</applicationPools>
</system.applicationHost>
</configuration>
4) restart the site
finally you need to restart your site to have your transformations applied.
After restart, go to step 1 again and you should now see this instead:
<applicationPools>
<add name="YOUR_SITE_NAME" managedRuntimeVersion="v4.0">
<processModel identityType="ApplicationPoolIdentity" />
<recycling disallowOverlappingRotation="true" />
</add>
<add name="~1YOUR_SITE_NAME" managedRuntimeVersion="v4.0" managedPipelineMode="Integrated">
<processModel identityType="ApplicationPoolIdentity" />
<recycling disallowOverlappingRotation="true" />
</add>
</applicationPools>
et voila: overlapped recycle is now disabled on your azure website.
You will have to use a XDT transform similar to the one mentioned in https://github.com/projectkudu/kudu/wiki/Xdt-transform-samples#remove-all-your-recycling-options-from-your-net-4-application-pool-and-make-it-available-always.
More details on using transforms is in http://blogs.msdn.com/b/waws/archive/2014/06/17/transform-your-microsoft-azure-web-site.aspx

NServiceBus saga not handling messages on azure

I'm getting strange behavior of working NServiceBus sagas deployed on azure cloud service. They never get replied message, never wake up... although if it's deployed locally everything works fine, also sagas works correctly when it's on WebApi cloud service role...
public class EndpointConfiguration : IConfigureThisEndpoint, IWantCustomInitialization,
AsA_Worker, UsingTransport<AzureStorageQueue>
{
public void Init()
{
Feature.Disable<Gateway>();
Feature.Disable<SecondLevelRetries>();
Feature.Enable<TimeoutManager>();
Feature.Enable<Sagas>();
Configure.With()
.UsingContainer<AutofacContainerBuilder>()
.AzureConfigurationSource()
.AzureMessageQueue()
.QueuePerInstance()
.UseNHibernateSagaPersister()
.UseNHibernateSubscriptionPersister()
.UseNHibernateTimeoutPersister()
.UnicastBus();
}
}
that's my config for nsb
<configSections>
<section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core" />
<section name="DBSubscriptionStorageConfig" type="NServiceBus.Config.DBSubscriptionStorageConfig, NServiceBus.NHibernate" />
<section name="NHibernateSagaPersisterConfig" type="NServiceBus.Config.NHibernateSagaPersisterConfig, NServiceBus.NHibernate" />
<section name="TimeoutPersisterConfig" type="NServiceBus.Config.TimeoutPersisterConfig, NServiceBus.NHibernate" />
</configSections>
<UnicastBusConfig>
<MessageEndpointMappings>
<add Messages="Service.InternalMessages" Endpoint="service" />
<add Messages="Messages" Endpoint="service" />
</MessageEndpointMappings>
</UnicastBusConfig>
<DBSubscriptionStorageConfig>
<NHibernateProperties>
<add Key="connection.provider" Value="NHibernate.Connection.DriverConnectionProvider" />
<add Key="connection.driver_class" Value="NHibernate.Driver.SqlClientDriver" />
<add Key="connection.connection_string" Value="Data_Source;Connection Timeout=30;" />
<add Key="dialect" Value="NHibernate.Dialect.MsSql2008Dialect" />
<add Key="hbm2ddl.auto" Value="update" />
</NHibernateProperties>
</DBSubscriptionStorageConfig>
<NHibernateSagaPersisterConfig>
<NHibernateProperties>
<add Key="connection.provider" Value="NHibernate.Connection.DriverConnectionProvider" />
<add Key="connection.driver_class" Value="NHibernate.Driver.SqlClientDriver" />
<add Key="connection.connection_string" Value="Data_Source;Connection Timeout=30;" />
<add Key="dialect" Value="NHibernate.Dialect.MsSql2008Dialect" />
<add Key="hbm2ddl.auto" Value="update" />
</NHibernateProperties>
</NHibernateSagaPersisterConfig>
<TimeoutPersisterConfig>
<NHibernateProperties>
<add Key="connection.provider" Value="NHibernate.Connection.DriverConnectionProvider" />
<add Key="connection.driver_class" Value="NHibernate.Driver.SqlClientDriver" />
<add Key="connection.connection_string" Value="Data_Source;Connection Timeout=30;" />
<add Key="dialect" Value="NHibernate.Dialect.MsSql2008Dialect" />
<add Key="hbm2ddl.auto" Value="update" />
</NHibernateProperties>
</TimeoutPersisterConfig>
that's the configs that I'm using for persisters
NServiceBus.Hosting.Azure, NServiceBus.NHibernate, NServiceBus.Core, NServiceBus.Azure, NServiceBus all of v4.0.30319
I'm using AzureStorageQueue and also I'm sure that I have overridden ConfigureHowToFindSaga with proper ConfigureMapping and I'm replying message with all filed specified correctly...
I would be really appreciate for any ideas, thanks.
This will be an interesting one to figure out. I don't see anything obviously wrong.
So the symptoms are, it works locally (with the exact same config?) and it works when deployed in a webrole (are these the same saga's or different ones?).
Some background info on the latter: a webrole only differs from a worker role in that IIS is properly configured, that's it. This also means that in a webrole, your code is running in 2 places, in an IIS process and in the roleentrypoint process. So you may want to validate that you're actually hosting in a roleentrypoint (namespace NServiceBus.Azure.Hosting and not the default azure sdk one.)
If you're sure the initialisation is done in the right place, you may want to check if you get any errors in the azure logs?
If that doesn't give more detail, you can also enable intellitrace in your solution and download the traces to see what is going on in more detail.
And as a last option, you can also use windbg on the azure instance (RDP'd in) to debug in real time.
Hope any of the above helps!

Azure project lost endpoints and uses default now?

A weird thing happened to my project. I have an Azure WCF project which basically consists of the WebRole and the Azure project. Azure Project contains ServiceDefinition.csdef which in turn contains stuff like endpoint information.
I was playing around in my WebRole and manually set an endpoint there. However, my original issue, due to a stupid user error, did not require this. After I removed the endpoint devinition from web.config, my webrole still gets bound to port 6627 instead of the two endpoints described in my Azure project (80 & 8080). I can't find that port being mentioned anywhere so I'm guessing it is the default.
Here's the part of the web.config that I edited (the removed part is in comments). How do I revert back to getting the configuration from the Azure project?
<system.serviceModel>
<!-- services>
<service name="MyWebRole.MyService" behaviorConfiguration="MyWebRole.BasicUserInformationBehavior">
<endpoint address="" binding="mexHttpBinding" contract="MyWebRole.IMyService"/>
</service>
</services -->
<extensions>
<behaviorExtensions>
<add name="userInformationProcessor" type="MyWebRole.BasicUserInformationBehaviorExtensionElement, MyWebRole, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</behaviorExtensions>
</extensions>
<bindings />
<client />
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<userInformationProcessor />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
[Edit] More information on the subject! The problem is related to compute emulator no longer starting at all! I don't know why the service works then, but I guess it's running it IIS alone.
I think the solution as mentioned in the comment is that you have to set up the Windows Azure project as the startup project not the webrole.

Logging of OpenRasta exceptions in IIS

How can I enable logging of any exceptions that occur in my handlers, or codecs etc. in IIS?
When googling for that, I found a couple of different ways on how to setup tracing. One of those actually worked, but the trace file (xml) is not very user-friendly. I'd like to have something like a standard text log file that I can view and manipulate using standard tools.
OpenRasta uses TraceSources to log requests, so you can use any implementation of log files for tracesources by providing the right configuration in your web.config.
<system.diagnostics>
<sources>
<source name="openrasta" switchName="OpenRasta">
<listeners>
<add name="ErrorLog" />
</listeners>
</source>
</sources>
<switches>
<!--<add name="OpenRasta" value="Warning,Error"/>-->
<add name="OpenRasta" value="All"/>
</switches>
<sharedListeners>
<add name="ErrorLog"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="c:\myListener.log" />
</sharedListeners>
</system.diagnostics>
I'm not sure however what you mean by standard text log files. Standard log files use standard logs that IIS generates itself already, this part of your logging does not change and is configured the usual way in IIS.

Resources