As our company has recently discovered, it would be very handy to have a live running stream of diagnostic from a live running Service Fabric application when one is trying to figure out why a Service won't start.
This docs.microsoft.com article provides a handy way to enable the log streaming feature in Visual Studio for a live running service in the same manner as one would get when debugging the Service Fabric Application in your local cluster.
Showing posts with label application. Show all posts
Showing posts with label application. Show all posts
Tuesday, June 04, 2019
Thursday, July 14, 2016
Configuration a web application for Application Warmup in IIS
Further to one of my previous blog posts about how to configure an ASP.NET web application for Application Initialization (warmup), here's the follow up: a powershell script for configuring the corresponding IIS application for warmup:
<#
.SYNOPSIS
Sets the required settings in the applicationHost.config file for an application to be able to automatically
initialize.
.PARAMETER WebSitePath
The name of the web application that's to have it's settings configured for application warmup.
.PARAMETER RestartService
A switch to indicate that the W3SVC (IIS) service should be restarted after the change.
#>
function Set-WebApplicationInitialization
{
[CmdletBinding(SupportsShouldProcess = $true)]
Param(
[Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][string] $WebSitePath,
[Parameter(Mandatory = $false)][switch] $RestartService
)
$pathElements = $WebSitePath.Split('/')
$site = $pathElements[0]
$appSubPath = @($pathElements | select -Skip 1) -join '/'
$webApp = Get-WebApplication -Site $site -Name $appSubPath
if ($webApp -eq $null)
{
throw "Failed to find application '$appSubPath' under web site '$site'"
}
if ($PSCmdlet.ShouldProcess($WebSitePath, "Update application to use Application Initialization settings"))
{
$appPoolPath = "IIS:\AppPools\$($webApp.applicationPool)"
Set-ItemProperty -Path $appPoolPath -Name 'autoStart' -Value 'true'
Set-ItemProperty -Path $appPoolPath -Name 'startMode' -Value 'AlwaysRunning'
Set-ItemProperty -Path $appPoolPath -Name 'processModel.idleTimeout' -Value '00:00:00'
$applicationPath = "IIS:\Sites\$($WebSitePath)"
Set-ItemProperty -Path $applicationPath -Name 'preloadEnabled' -Value $true
Write-Verbose "Updated properties for web application '$appSubPath' running on pool '$($webApp.applicationPool)'"
if ($RestartService.ToBool())
{
if ($PSCmdlet.ShouldProcess("W3SVC", "Restart web service"))
{
Restart-Service W3SVC
}
}
}
}
Friday, June 03, 2016
Implementing Application Warmup with IIS 7.5 on Windows Server 2008 R2
In order to be able to support certain features of some of our applications, we've found the need to enable application warmup. However, this isn't built-in to IIS 7.5, but rather it's available as the Application Initialization module provided by Microsoft. In order to get this working, you'll need to do the following:
- Install the Application Initialization 1.0 module available from Microsoft here.
- You'll need to edit the applicationHost.config file on your server to enable Application Initialization. To do this, you'll need to open the file at %WINDIR%\System32\inetsrv\config\applicationHost.config in your text editor of choice and make the following changes:
- Find the 'application' element that you wish to enable for Application Initialization, which you can do with an XPath similar to "/configuration/system.applicationHost/sites/site/application" and once found, set the
preloadEnabled="true"
attribute on the XML element. Add the element if it's not already there. - While on the 'application' element, take note of the 'applicationPool' value, because that's the Application Pool in which the application runs. Find the configuration node for that application pool (XPath: /configuration/system.applicationHost/applicationPools) and then set the following attributes on the <add> element for the application pool and its child 'processModel' element:
<add .... startMode="AlwaysRunning">
<processModel ... idleTimeout="0">
- In your application's web.config file, you'll need to add the following elements:
<system.webServer>
<applicationInitialization remapManagedRequestsTo="/InitializationProxyPage.txt" skipManagedModules="true" doAppInitAfterRestart="true">
<add initializationPage="/Services/MyCustomService.svc" hostName="localhost" />
</applicationInitialization>
<directoryBrowse enabled="true" />
</system.webServer>
You'll need to have the "InitializationProxyPage.txt" file in the root of your web application.
4. Enable "Anonymous" authentication in the Authentication panel of your application in IIS. This is necessary so that the warmup page can successfully execute a GET request for your initialization page to kick off the warmup.
5. If you use the system.webServer/security/authorization or system.webServer/security/authentication sections in your web.config to control access to the application, you'll also need to add the following under the /configuration element as a sibling to the system.webServer element:
5. If you use the system.webServer/security/authorization or system.webServer/security/authentication sections in your web.config to control access to the application, you'll also need to add the following under the /configuration element as a sibling to the system.webServer element:
<configuration>
<location path="InitializationProxyPage.txt">
<system.webServer>
<security>
<authorization>
<clear />
<add accessType="Allow" users="*"/>
</authorization>
</security>
</system.webServer>
</location>
</configuration>
This will grant explicit access to the InitializationProxyPage.txt file to all users (including the App Pool Identity user) so that application warmup is guaranteed to have access to that file and can bootstrap your services.Wednesday, March 30, 2016
Updating your Azure AD Application Manifest
We've recently found that as we develop more applications in Azure, we need to put safeguards on the deployment of the applications to ensure that they're configured correctly. Part of this means editing the application manifests to ensure that certain settings are always enforced on certain applications. Here's what Microsoft has to say about updating Application manifests.
Bottom line, if you want to automate anything to do with manifests, you'll have to write your own application to use the Azure Graph API libraries to retrieve the manifest / application settings and edit them.
Bottom line, if you want to automate anything to do with manifests, you'll have to write your own application to use the Azure Graph API libraries to retrieve the manifest / application settings and edit them.
Tuesday, August 25, 2015
Parameterizing ApplicationInsights.config
I've been working on a lot of web applications in Azure recently, and we're using Application Insights to analyze logs and instrument events in the application. Additionally, we're using MSDeploy to deploy all of our applications as we're trying to get to the point of having Continuous Delivery on-premise. Because we use multiple environments, we need to use the parameters.xml file and SetParameters files to set parameters at deployment time, meaning that we also need to parameterize the InstrumentationKey used by Application Insights to determine which instance of App Insights gets the instrumentation for which application.
This is a bit of a challenge because the XPath support for the parameters.xml file is incomplete and leaves something to be desired. At first glance, I tried to use the naive XPath expression to parameterize our InstrumentationKey:
Match="/ApplicationInsights/InstrumentationKey"
I realized that this wasn't working after checking our deployments, so after some Googling, I found the recommendation that to parameterize an *element* rather than an attribute, you need to use "/text()" in your XPath expression (which makes sense if you know enough about XPath and XQuery). So I tried it:
Match="/ApplicationInsights/InstrumentationKey/text()"
Still didn't work. Then I was stumped for a while and let things simmer.
After a couple more hours and getting frustrated, it hit me: when parameterizing another element a few weeks prior, I ran into issues because a parent element of the one that I wanted to parameterize overrode the default namespace. I checked the ApplicationInsights.config file, and sure enough, the default namespace was the non-empty namespace. I had to use a wildcard to solve the previous problem, so I tried the following:
Match="/*/InstrumentationKey/text()"
Still didn't work, much to my surprise this time. After a little bit more Googling around, I found out that this time it was because the *root* element itself used a non-empty namespace, and overrode the default. I stumbled across this response by Vishal Joshi to a comment on one of his blog posts, which included a suggestion for it using something I didn't even know you could do with XPath (and I've actually got quite a bit of experience using XPath): use the local-name query operator to match only on local name rather than fully qualified name. If you're querying a document that uses an empty default namespace, they're both the same, hence why the simple match expressions work 99% of the time. Updating my query to this:
Match="//*[local-name()='InstrumentationKey']/text()"
... worked like a charm!
This is a bit of a challenge because the XPath support for the parameters.xml file is incomplete and leaves something to be desired. At first glance, I tried to use the naive XPath expression to parameterize our InstrumentationKey:
Match="/ApplicationInsights/InstrumentationKey"
I realized that this wasn't working after checking our deployments, so after some Googling, I found the recommendation that to parameterize an *element* rather than an attribute, you need to use "/text()" in your XPath expression (which makes sense if you know enough about XPath and XQuery). So I tried it:
Match="/ApplicationInsights/InstrumentationKey/text()"
Still didn't work. Then I was stumped for a while and let things simmer.
After a couple more hours and getting frustrated, it hit me: when parameterizing another element a few weeks prior, I ran into issues because a parent element of the one that I wanted to parameterize overrode the default namespace. I checked the ApplicationInsights.config file, and sure enough, the default namespace was the non-empty namespace. I had to use a wildcard to solve the previous problem, so I tried the following:
Match="/*/InstrumentationKey/text()"
Still didn't work, much to my surprise this time. After a little bit more Googling around, I found out that this time it was because the *root* element itself used a non-empty namespace, and overrode the default. I stumbled across this response by Vishal Joshi to a comment on one of his blog posts, which included a suggestion for it using something I didn't even know you could do with XPath (and I've actually got quite a bit of experience using XPath): use the local-name query operator to match only on local name rather than fully qualified name. If you're querying a document that uses an empty default namespace, they're both the same, hence why the simple match expressions work 99% of the time. Updating my query to this:
Match="//*[local-name()='InstrumentationKey']/text()"
... worked like a charm!
Thursday, August 20, 2015
Logging your application with App Insights instead of Windows Azure Diagnostics
We've recently started deploying applications to Microsoft Azure. Unfortunately, we don't use Cloud Apps for our web apps, and instead use MSDeploy on the command line to enable automated deployment. Consequently, we don't have any .csdef files in which to implement Windows Azure Diagnostics (WAD).
Fortunately, there's a suitable replacement for applications in Azure App Service (rather than Cloud Services): Application Insights. Not only does this provide a TraceListener for tracing your application, but also provides a whole suite of other useful diagnostics, making this something that you should really be using anyway. Using the links here and here, I was able to get up to speed with App Insights within an hour and a half, and implement a working solution for our application.
Fortunately, there's a suitable replacement for applications in Azure App Service (rather than Cloud Services): Application Insights. Not only does this provide a TraceListener for tracing your application, but also provides a whole suite of other useful diagnostics, making this something that you should really be using anyway. Using the links here and here, I was able to get up to speed with App Insights within an hour and a half, and implement a working solution for our application.
Thursday, August 06, 2015
Adding extra files to your MSDeploy web package with MSBuild
I've recently started getting much more in depth with Azure. I've ported some web apps up into Azure, and now I need WebJobs. I've written the jobs, manually uploaded them into my web apps, tested them out and they work great. Now I need to ensure that the WebJobs get automatically deployed with my Web Application.
As it turns out, web jobs are just a sub folder with some naming conventions underneath the App_Data folder in your web application. Unfortunately, getting those files into that folder as part of the packaging process is a couple extra (non-obvious) steps.
Following this article on ASP.NET, I was able to add in the extra files. It took a lot more Googling than I care to admit to in order to find this article. As it turns out, you really need to pick your search terms well.
As it turns out, web jobs are just a sub folder with some naming conventions underneath the App_Data folder in your web application. Unfortunately, getting those files into that folder as part of the packaging process is a couple extra (non-obvious) steps.
Following this article on ASP.NET, I was able to add in the extra files. It took a lot more Googling than I care to admit to in order to find this article. As it turns out, you really need to pick your search terms well.
Subscribe to:
Posts (Atom)