Unable to create custom performance counters in Azure Web Role - azure

When trying to create custom performance counters as explained in this MSDN article, I still get a security exception.
The code I am using is the same as in that article, only I am creating a different counters.
I understand that I can try to create it in a start-up task, but for now I want to do it inside the role.. it should work :/
The exception:
[SecurityException: Requested registry access is not allowed.]
Microsoft.Win32.RegistryKey.OpenSubKey(String name, Boolean writable) +12746267
System.Diagnostics.PerformanceCounterLib.CreateRegistryEntry(String categoryName, PerformanceCounterCategoryType categoryType, CounterCreationDataCollection creationData, Boolean& iniRegistered) +170
System.Diagnostics.PerformanceCounterLib.RegisterCategory(String categoryName, PerformanceCounterCategoryType categoryType, String categoryHelp, CounterCreationDataCollection creationData) +49
System.Diagnostics.PerformanceCounterCategory.Create(String categoryName, String categoryHelp, PerformanceCounterCategoryType categoryType, CounterCreationDataCollection counterData) +558
The beginning of my ServiceDefinition.csdef:
<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="Jonathan.Cloud" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
<WebRole name="WebDriver" vmsize="Small" enableNativeCodeExecution="true">
<Runtime executionContext="elevated" />
When I RDP into the role, I can see that the application pool is still running with the NetworkService identity, was expecting it to run under a different principal as I changed the role to be 'elevated' - manually setting up a custom principal with permissions solves this, but it will be over-ridden once the role reconfigure itself or if I deploy an upgrade - in any case, this is not really a solution but a hack :/ [frustrated]

In the case of Web Role of Full IIS, the special privilege which you appointed in Runtime element is applied to RoleEntoryPoint. I think that it is necessary to register a custom performance counter by inner RoleEntryPoint (usually WebRole.cs) OnStart method.

Related

Do Elmah.config updates restart IIS?

This seems like a relatively simple question, but I didn't see it clearly indicated in the documentation I examined. Assuming a typical Elmah usage on a Windows Server 2012/IIS 7 webserver installation, if the Elmah web.config settings are pointed to an Elmah.config file, will altering that file trigger under the running application cause IIS to restart?
While the answer provided by Josh would normally be true, it is not in the case of ELMAH. ELMAH instantiates a new error log implementation every time it is needed, reading the configuration from either web.config or the configSource provided.
You can do a simple test to prove this. If you configure ELMAH to use an external config file for the errorLog element like this:
<elmah>
<errorLog configSource="elmah.config"/>
</elmah>
and your elmah.config looks like this:
<?xml version="1.0" encoding="utf-8"?>
<errorLog type="Elmah.XmlFileErrorLog, Elmah" logPath="~/App_Data" />
When you start the project and force an error, a new XML file is written to the App_Data folder. Change the logPath like this (without restarting the application):
<?xml version="1.0" encoding="utf-8"?>
<errorLog type="Elmah.XmlFileErrorLog, Elmah" logPath="~/App_Data2" />
(I changed to App_Data2).
Force a new error and you will now see ELMAH create the App_Data2 folder on the file system.
No: Straight from MSDN:
Saving a Web.config file restarts the application. You can alternatively use the configSource attribute of individual section elements to point to a secondary configuration file that does not cause an application restart when it is changed. For more information, see configSource in General Attributes Inherited by Section Elements.
MSDN

Issue accessing service setting from an executable running as a start up task

I'm relatively new to Azure development and need some help overcoming the following predicament:
I have an executable that I need to run as part of my Azure service startup. The executable needs access to one of the service's application settings.
So I added the following to my csdef (the batch script just runs the executable with output redirected to a file):
<Startup>
<Task commandLine="StartupTask.cmd" executionContext="elevated" taskType="background">
<Environment>
<Variable name="Var">
<RoleInstanceValue
xpath="/RoleEnvironment/CurrentInstance/ConfigurationSettings/ConfigurationSetting[#name='SomeAppSetting']/#value" />
</Variable>
</Environment>
</Task>
</Startup>
Adding the task caused the deployment to fail and after much hair tearing I realized it was because SomeAppSetting value was too long (see http://blogs.msdn.com/b/cie/archive/2013/07/30/windows-azure-role-recycling-due-to-setting-more-than-256-character-in-environmental-variable-through-azure-start-up-task.aspx) and now I'm at a loss of what to do.
Are the following possible:
1. Accessing the role environment from inside the executable somehow?
2. Passing the setting value to the script as a parameter?
Thanks in advance for any tips!
One option would be to move the app setting from the service configuration to blob storage from where it is accessible to both the startup task and the running service.
You can load the RoleEnvironment information in a PowerShell script (which you load in the startup task) which will let you access your ServiceConfiguration settings:
[Reflection.Assembly]::LoadWithPartialName("Microsoft.WindowsAzure.ServiceRuntime")
$mySetting = [Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment]::GetConfigurationSettingValue("MySetting")
if($mySetting -eq "True"){ .....}
In my ServiceConfiguration (.cscfg) I have a setting called MySettig which is True/False.

Blob wad-iis-logfiles is never created

I just started checking out Windows Azure and I have trouble getting any access logs from IIS for my test web role. The web role itself works fine, but I would like to see a log for accesses (both successful and failed).
As far as I can see the default configuration files for a web role contain instructions to send those logs to a blob named "wad-iis-logfiles", but that blob is never even created (it doesn't exist in my blob storage).
My diagnostics.wadcfg for the web role currently is:
<DiagnosticMonitorConfiguration configurationChangePollInterval="PT1M" overallQuotaInMB="4096" xmlns="http://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration">
<DiagnosticInfrastructureLogs bufferQuotaInMB="512" scheduledTransferPeriod="PT5M" />
<Directories bufferQuotaInMB="512" scheduledTransferPeriod="PT5M">
<IISLogs container="wad-iis-logfiles" />
<CrashDumps container="wad-crash-dumps" />
</Directories>
<Logs bufferQuotaInMB="512" scheduledTransferPeriod="PT5M" scheduledTransferLogLevelFilter="Information" />
<PerformanceCounters bufferQuotaInMB="512">
(... snip...)
</PerformanceCounters>
<WindowsEventLog bufferQuotaInMB="512" scheduledTransferPeriod="PT1M" scheduledTransferLogLevelFilter="Error">
<DataSource name="Application!*" />
</WindowsEventLog>
</DiagnosticMonitorConfiguration>
Question 1: is this configuration file correct?
Question 2: are there other things that need to be set before I can get the IIS log files?
With the help of the commenters I was able to solve the issue.
There are several interacting things causing the issue.
As commenter #kwill mentioned, an existing configuration blob in wad-control-container overrides any other configuration, and that configuration is not replaced during an in-place update. I was using in-place update to put my modified diagnostics.wadcfg in place, so that is the explanation why my attempts to change settings that way didn't work. Note that editing the properties of the web test role (in the "Roles" branch of the Azure Cloud services project operates by editing that same file, so that didn't work either. More information on how that wad-control-container overrides setting can be found in http://msdn.microsoft.com/en-us/library/windowsazure/dn205146.aspx .
The reason that blob already existed may have been that I had been changing some other performance measurement settings in the azure management window earlier.
I managed to "fix" the situation by editing the blob found in wad-control-container for my instance, using the tool mentioned by commenter #Gaurav Mantri - "Azure Explorer". As mentioned, without that tool you can download the blob and edit it, but never put it back properly, since the '/' characters in the blob's name get translated to '%2F', and those are not translated back on upload.
Note that the XML schema is not the same as the schema for diagnostics.wadcfg, but some similarities exist. I changed the "Directories" element toward the bottom of the blob to read:
<Directories>
<BufferQuotaInMB>512</BufferQuotaInMB>
<ScheduledTransferPeriodInMinutes>2</ScheduledTransferPeriodInMinutes>
<Subscriptions>
<DirectoryConfiguration>
<Path>C:\Resources\directory\8091b0be14e54213ac12fcbd5f9c8e1b.WebTestRole.DiagnosticStore\CrashDumps</Path>
<Container>wad-crash-dumps</Container>
<DirectoryQuotaInMB>0</DirectoryQuotaInMB>
</DirectoryConfiguration>
<DirectoryConfiguration>
<Path>C:\Resources\directory\8091b0be14e54213ac12fcbd5f9c8e1b.WebTestRole.DiagnosticStore\LogFiles</Path>
<Container>wad-iis-logfiles</Container>
<DirectoryQuotaInMB>16</DirectoryQuotaInMB>
</DirectoryConfiguration>
</Subscriptions>
</Directories>
In the original version the "BufferQuotaInMB" and "DirectoryQuotaInMB" fields were 0.
Note that after uploading the blob again the effect is not immediate. It takes a while for the changed configuration to get picked up, and then it takes another while before the IIS log files are copied for the first time.
Last note: it may be obvious, but I don't think editing that blob is a recommendable solution. It is good to know the option exists though.

MVC5 fails on 1 and 1 Internet shared hosting

My MVC4 sites work without problems on 1 and 1 Internet shared hosting, but when I tried MVC5's default site using the VS2013 beta, it failed and I haven;t been able to figure out why. Can anyone help? Here are the error messages:
Server Error in '/' Application.
Security Exception
Description: The application attempted to perform an operation not allowed by the >security policy. To grant this application the required permission please contact your >system administrator or change the application's trust level in the configuration file.
Exception Details: System.Security.SecurityException: Request for the permission of type >'System.Security.Permissions.ReflectionPermission, mscorlib, Version=4.0.0.0, >Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
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.
Stack Trace:
[SecurityException: Request for the permission of type >'System.Security.Permissions.ReflectionPermission, mscorlib, Version=4.0.0.0, >Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.]
System.Delegate.DelegateConstruct(Object target, IntPtr slot) +0
Owin.Loader.DefaultLoader..ctor() +47
Microsoft.Owin.Host.SystemWeb.OwinHttpModule.InitializeBlueprint() +66
System.Threading.LazyInitializer.EnsureInitializedCore(T& target, Boolean& initialized, > Object& syncLock, Func`1 valueFactory) +115
Microsoft.Owin.Host.SystemWeb.OwinHttpModule.Init(HttpApplication context) +106
System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, >HttpContext context, MethodInfo[] handlers) +418
System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] >handlers, IntPtr appContext, HttpContext context) +172
System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, >HttpContext context) +336
System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext) +296
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET >Version:4.0.30319.18044
In general, most applications should run fine under Medium Trust. If your application requires Full Trust, you can override the trust level at the application level by adding the following to your web.config file:
<configuration>
<system.web>
<trust level="Full" />
</system.web>
</configuration>
The ASP.NET team has killed support for medium trust. MVC 5 now requires full trust. See my answer at https://stackoverflow.com/a/17218344/59641 for more information.
Ask your hoster to run your site in full trust, or choose a different hoster.
Do they support ASP.NET 4.5.1 yet? The default MVC 5 template uses ASP.NET 4.5.1 which is still in beta as well. Can you target your project to the current ASP.NET 4.5 or 4?

Cache referred to does not exist

History
In my development environment I've battled a reoccurring error with running Windows Azure Emulator. To resolve before I created a new Solution and projects based on the Azure template, along with reinstalling the October 2012 update SDK. Then I had to copy over all the files into the new projects. Before going through all that, since I know it can work, I wanted to see if there was something else I can do.
Setup
Windows 8
Visual Studio 2012 Update 1
IIS Express 8
Windows Azure Tools - October 2012
Windows Azure Caching 1.8.1.0
ASP.NET MVC 4.0 project
Web Role (2 Instances)
Cache Worker Role (2 Instances)
Caching Enabled on Cache Work Roles and set to Dedicated Role (Local Role state is: UseDevelopmentStorage=true)
Session uses Distributed Cache
Output Cache uses Distributed Cache
Web.config settings
<sessionState mode="Custom" customProvider="AFCacheSessionStateProvider" cookieName="abc_session">
<providers>
<add name="AFCacheSessionStateProvider" type="Microsoft.Web.DistributedCache.DistributedCacheSessionStateStoreProvider, Microsoft.Web.DistributedCache" cacheName="default" dataCacheClientName="default" applicationName="AFCacheSessionState" />
</providers>
</sessionState>
<outputCache defaultProvider="AFCacheOutputCacheProvider">
<providers>
<add name="AFCacheOutputCacheProvider" type="Microsoft.Web.DistributedCache.DistributedCacheOutputCacheProvider, Microsoft.Web.DistributedCache" cacheName="default" dataCacheClientName="default" applicationName="AFCacheOutputCache" />
</providers>
</outputCache>
</caching>
<dataCacheClients>
<dataCacheClient name="default">
<autoDiscover isEnabled="true" identifier="AppNameCacheWorkerRole" />
</dataCacheClient>
</dataCacheClients>
Error Details
ErrorCode<ERRCA0009>:SubStatus<ES0001>:Cache referred to does not exist
[DataCacheException: ErrorCode<ERRCA0009>:SubStatus<ES0001>:Cache referred to does not exist. Contact administrator or use the Cache administration tool to create a Cache.]
Microsoft.ApplicationServer.Caching.DataCache.ThrowException(ErrStatus errStatus, Guid trackingId, Exception responseException, Byte[][] payload, EndpointID destination) +767
Microsoft.ApplicationServer.Caching.DataCache.ThrowException(ResponseBody respBody, EndpointID destination) +149
Microsoft.ApplicationServer.Caching.DataCacheFactory.EstablishConnection(IEnumerable`1 servers, RequestBody request, Func`3 sendMessageDelegate, DataCacheReadyRetryPolicy retryPolicy) +967
Microsoft.ApplicationServer.Caching.<>c__DisplayClass4.<Initialize>b__1(RequestBody req) +198
Microsoft.ApplicationServer.Caching.SocketClientProtocol.SendReceive(IVelocityRequestPacket request, Func`2 delegate, EndpointID& destination) +121
Microsoft.ApplicationServer.Caching.SocketClientProtocol.Initialize(IEnumerable`1 servers) +1011
Microsoft.ApplicationServer.Caching.DataCacheFactory.GetCache(String cacheName, CreateNewCacheDelegate cacheCreationDelegate, DataCacheInitializationViaCopyDelegate initializeDelegate) +1103
Microsoft.ApplicationServer.Caching.DataCacheFactory.GetCache(String cacheName) +131
Microsoft.Web.DistributedCache.DataCacheFactoryWrapper.CreateDataCacheFromFactory(DataCacheFactory factory, String cacheName) +63
Microsoft.Web.DistributedCache.CacheHelpers.RunCacheCreationHooks(CacheConnectingEventArgs fetchingEventArgs, IDataCacheFactory dataCacheFactory, Object sender, EventHandler`1 fetchingHandler, EventHandler`1 fetchedHandler) +356
Microsoft.Web.DistributedCache.DistributedCacheOutputCacheProvider.CreateInternalProvider(IHttpRuntime httpRuntime, OutputCacheInitializationData initData, IDataCacheFactory dataCacheFactory, EventHandler`1 cacheFetching, EventHandler`1 cacheFetched) +399
Microsoft.Web.DistributedCache.DistributedCacheOutputCacheProvider.GetInternalProvider() +315
Microsoft.Web.DistributedCache.DistributedCacheOutputCacheProvider.Get(String key) +54
System.Web.Caching.OutputCache.Get(String key) +80
System.Web.Caching.OutputCacheModule.OnEnter(Object source, EventArgs eventArgs) +341
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +80
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +165
Misc Notes:
The same configuration works fine when it is deployed to Azure, so has something to do with my local environment.
IIS Express was crashing when I had more than one instance of web roles setup, and I found a suggestion to run the Visual Studio 2010 SP1 to resolve. I had VS2010 on the system because one tools (believe it was SQL) installed it. Installing SP1 resolved the issue with IIS Express crashing, but then this error reappeared.
If I comment out the OutputCache node listed above the error goes away.
If I switch the Cache Worker Role from Dedicated Role to Co-located Role the error goes away.
Spoke with Microsoft tech support and it appears this a known issue. Most of the time it can be resolved by forcing a refresh in the browser. I've had mixed success. The fix for this issue will be part of the next Azure SDK release.
This happens to me in production a lot! I upload my package to staging first, and have to always wait until all the instances are running before hitting the staging URL. Sometimes this error still occurs and I restart all my instances for it to fix itself.

Resources