How do I get telemetry into a Windows 10 UWP App? - azure

The Azure documentation for App Insights doesn't appear to have fresh articles relating to Windows 10 UWP Apps specifically. This appears to be endemic throughout all services (Notification Hub, Mobile Apps, Azure AD, etc.). So far I have found only references to Windows 8/8.1 Universal apps. I'm not sure how applicable they are but some code snippets do seem to compile at least.
My problem is that I have just setup a new App Insights instance for a 'WindowsStore App'. This is intended for a Windows 10 UWP app.
In my app, I have done the following:
Ingested the nuget package for App Insights which has created an ApplicationInsights.config file.
Updated the Instrumentation Key with the one from my WindowsStore App Insights Instance in the Azure Portal.
Added Internet (Client) capability in application manifest.
Created a static TelemetryClient that I use throughout all my Views / View Models.
private static TelemetryClient telemetry = new TelemetryClient();
public static TelemetryClient Telemetry
{
get { return telemetry; }
}
Updated the WindowsAppInitializer to include several WindowsCollectors.
Microsoft.ApplicationInsights.WindowsAppInitializer.InitializeAsync(
WindowsCollectors.Metadata |
WindowsCollectors.Session |
WindowsCollectors.PageView |
WindowsCollectors.UnhandledException
);
Added an event handler within App.xaml.cs for Unhandled Exception and call TelemetryClient.TrackException on the exception.
private void App_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
ViewModelDispatcher.Telemetry.TrackException(e.Exception);
}
Added TelemetryClient.TrackPageViews to OnNavigatedTo overrides in my views.
But so far, after doing all that, my App Insights dashboard in the Azure Portal is showing zip, zilch, nada. :\
This makes me think one of two things is going on. Either I am missing some critical piece of this recipe or I'm still within the refresh window for the App Insights Dashboard.

Have you tried to include your instrumentation key to the call of InitializeAsync?
I'm using the following code at the constructor of App class.
Microsoft.ApplicationInsights.WindowsAppInitializer.InitializeAsync(
"YOURINST-RUME-NTAT-IONK-EY012345678",
WindowsCollectors.Metadata |
WindowsCollectors.PageView |
WindowsCollectors.Session |
WindowsCollectors.UnhandledException);
I haven't confirmed the current specs (yes...the documentation of ApplicationInsight is an labyrinth :( ), but from AI v1.0, you have not to include your instrumentation key to your applicationinsight.config. Instead of it, you can specify the key with the call of initializer.

Recently found this (i work on the AI team and it still happened to me!).
If you manually added the applicationinsights.config file, make sure it is set to "Content" and "Copy if newer" in the project settings. If it isn't, then the sdk can't find the instrumentation key at runtime, since the applicationinsights.config file didn't get deployed to the device.
Update 1/11/2016: i just learned of another issue that can cause this: comments in the xml file that look like xml tags.
If your config file has any comments of the form:
<!-- <InstrumentationKey>anything</InstrumentationKey> -->
Or
<!--
Learn more about Application Insights configuration with ApplicationInsights.config here:
http://go.microsoft.com/fwlink/?LinkID=513840
Note: If not present, please add <InstrumentationKey>Your Key</InstrumentationKey> to the top of this file.
-->
(Like is common in examples you might have gotten online, or migrating from a previous version of the AI SDK's)
If those comments appear in your config file before your real key, then the win10 sdk startup code will find those in the comments instead of your real key.
So if you see debug output that says it is using the literal string "YourKey" instead your actual key, that's the reason. (The win10 sdk uses a regex to find your key instead of loading system.xml assemblies to parse the file)

Related

App Settings not being observed by Core WebJob

I have a Core WebJob deployed into an Azure Web App. I'm using WebJobs version 3.0.6.
I've noticed that changes to Connection Strings and App Settings (added via the Azure web UI) are not being picked up immediately by the WebJob code.
This seems to correlate with the same Connection Strings and App Settings not being displayed on the app's KUDU env page straight away (although I acknowledge this may be a red herring and could be some KUDU caching thing which I'm unaware of).
I've deployed a few non-Core WebJobs in the past and have not come across this issue so wonder if it's Core related? Although I can't see how that might affect configs showing up KUDU though.
I was having this issue the other day (where the configs were not getting picked up by the WebJob or shown in KUDU) and was getting nowhere, so left it. When I checked back the following day, the configs were now correctly showing in KUDU and being picked up by the WebJob. So I'd like to know what has happened in the meantime which means the configs are now being picked up as expected.
I've tried re-starting the WebJob and re-starting the app after making config changes but neither seem to have an effect.
It's worth also noting that I'm not loading appSettings.json during the program setup. That being said, the connection string being loaded was consistenly the connection string from that file i.e. my local machine SQL Server/DB. My understanding was always that the anything in the Azure web UI would override any equivalent settings from config files. This post from David Ebbo indicates that by calling AddEnvironmentVariables() during the setup will cause the Azure configs to be observed, but that doesn't seem to be the case here. Has this changed or is it loading the configs from this file by convention because it can't see the stuff from Azure?
Here's my WebJob Program code:
public static void Main(string[] args)
{
var host = new HostBuilder()
.ConfigureHostConfiguration(config =>
{
config.AddEnvironmentVariables();
})
.ConfigureWebJobs(webJobConfiguration =>
{
webJobConfiguration.AddTimers();
webJobConfiguration.AddAzureStorageCoreServices();
}
)
.ConfigureServices((context, services) =>
{
var connectionString = context.Configuration.GetConnectionString("MyConnectionStringKey");
services.AddDbContext<DatabaseContext>(options =>
options
.UseLazyLoadingProxies()
.UseSqlServer(connectionString)
);
// Add other services
})
.Build();
using(host)
{
host.Run();
}
}
So my questions are:
How quickly should configs added/updated via the Azure web UI be displayed in KUDU?
Is the fact they're not showing in KUDU related to my Core WebJob also not seeing the updated configs?
Is appSettings.json getting loaded even though I'm not calling .AddJsonFile("appSettings.json")?
What can I do to force the new configs added via Azure to be available to my WebJob immediately?
The order in which configuration sources are specified is important, as this establishes the precedence with which settings will be applied if they exist in multiple locations. In the example below, if the same setting exists in both appsettings.json and in an environment variable, the setting from the environment variable will be the one that is used. The last configuration source specified “wins” if a setting exists in more than one location. The ASP.NET team recommends specifying environment variables last, so that the environment where your app is running can override anything set in deployed configuration files.
You can refer here for more details on Azure App Services Application Settings and Connection Strings in ASP.NET Core

Assign Application Insights cloud_RoleName to Windows Service running w/ OWIN

I have an application built from a series of web servers and microservices, perhaps 12 in all. I would like to monitor and, importantly, map this suite of services in Applications Insights. Some of the services are built with Dot Net framework 4.6 and deployed as Windows services using OWIN to receive and respond to requests.
In order to get the instrumentation working with OWIN I'm using the ApplicationInsights.OwinExtensions package. I'm using a single instrumentation key across all my services.
When I look at my Applications Insights Application Map, it appears that all the services that I've instrumented are grouped into a single "application", with a few "links" to outside dependencies. I do not seem to be able to produce the "Composite Application Map" the existence of which is suggested here: https://learn.microsoft.com/en-us/azure/application-insights/app-insights-app-map.
I'm assuming that this is because I have not set a different "RoleName" for each of my services. Unfortunately, I cannot find any documentation that describes how to do so. My map looks as follow, but the big circle in the middle is actually several different microservices:
I do see that the OwinExtensions package offers the ability to customize some aspects of the telemetry reported but, without a deep knowledge of the internal structure of App Insights telemetry, I can't figure out whether it allows the RoleName to be set and, if so, how to accomplish this. Here's what I've tried so far:
appBuilder.UseApplicationInsights(
new RequestTrackingConfiguration
{
GetAdditionalContextProperties =
ctx =>
Task.FromResult(
new [] { new KeyValuePair<string, string>("cloud_RoleName", ServiceConfiguration.SERVICE_NAME) }.AsEnumerable()
)
}
);
Can anyone tell me how, in this context, I can instruct App Insights to collect telemetry which will cause a Composite Application Map to be built?
The following is the overall doc about TelemetryInitializer which is exactly what you want to set additional properties to the collected telemetry - in this case set Cloud Rolename to enable application map.
https://learn.microsoft.com/en-us/azure/application-insights/app-insights-api-filtering-sampling#add-properties-itelemetryinitializer
Your telemetry initializer code would be something along the following lines...
public void Initialize(ITelemetry telemetry)
{
if (string.IsNullOrEmpty(telemetry.Context.Cloud.RoleName))
{
// set role name correctly here.
telemetry.Context.Cloud.RoleName = "RoleName";
}
}
Please try this and see if this helps.

Setting up Application Insights on a console app

I've got Log4Net running on a console app, and would like the log events to go to Application Insights.
I'm not able to add AI by right-clicking on my project-it does not appear as an option.
I've installed the AI SDK through NuGet, and am able to create telemetry clients, but don't know where to add the instrumentation key.
This tutorial says:
Set the instrumentation key either in your code:
TelemetryConfiguration.Active.InstrumentationKey = " your key ";
or in ApplicationInsights.config (if you installed one of the standard telemetry packages):
<InstrumentationKey>your key</InstrumentationKey>
I don't have an ApplicationInsights.config file, since I was not able to add AI to the project. Would it work if I just added the key as I instantiate the telemetry client, like this?
var telemetryClient = new TelemetryClient { InstrumentationKey = ConfigurationManager.AppSettings["applicationInsights"] };
You last suggestion will probably work. You can also do it like this:
TelemetryConfiguration.Active.InstrumentationKey = ConfigurationManager.AppSettings["applicationInsights"];

AppInsights instrumentation key is replaced when win universal app is published to Windows Store

I have a simple Windows Univeral Application with Azure Application Insights enabled in it. First published version worked well - all telemetry data was visible in AppInsights dashboard. But after I updated the app, strange thing happened - no telemetry data is generated at all.
After installing the version of the application from Windows Store, and tracing web requests with Fiddler, I've found out VERY strange thing - instrumentation key (iKey) sent in AppInsights requests is UNKNOWN for me. I mean that this is not a one of my AppInsights instances!
On the other hand, when I sideload the same package I've used for publish, than correct (expected) iKey is used in traced web requests.
This makes me think that my iKey is somehow replaced in published version of application. How is this possible?
IMPORTANT NOTE: AppInsights initialization code is the following (in App class):
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
var instrumentationKey =
#if DEBUG
Current.Resources["ApplicationInsights.InstrumentationKey.Debug"].ToString();
#else
Current.Resources["ApplicationInsights.InstrumentationKey.Release"].ToString();
#endif
Microsoft.ApplicationInsights.WindowsAppInitializer.InitializeAsync(instrumentationKey);
// ...
}
And one more time - this worked well in first version of the application and was broken only after update (wich did not touch any AppInsights related stuff).
UPDATE (2016-03-21): Following recommendations in the answers, I've done the following:
Moved release iKey into ApplicationInsights.config file
Changed initialization logic to replace the iKey only in case of Debug mode:
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
#if DEBUG
var instrumentationKey = Current.Resources["ApplicationInsights.InstrumentationKey.Debug"].ToString();
await Microsoft.ApplicationInsights.WindowsAppInitializer.InitializeAsync(instrumentationKey);
#else
await Microsoft.ApplicationInsights.WindowsAppInitializer.InitializeAsync()
#endif
// ...
}
Republished the application to Windows Store.
Now AppInsights is working correctly - my iKey is used in AppInsights web requests and data appears in admin panel.
do you have an applicationinsights.config file in your project?
if you do not, I believe the store will create one for you so that the reports work, because it doesn't know you're setting the key in code. you might want to add an applicationinsights.config file, and put in one of your ikeys, even if you are then setting the key explicitly in code.
The ApplicationInsights SDK for Store apps, only works with ApplicationInsights.config.
The Store looks for this file, and if no instrumentation key is set, it injects one.
The SDK on the other hand, will always respect instrumentation key coming from the configuration file.

How to configure logging for ASP.NET 5 running in Azure Web App

I'm trying to follow this link to set up logging for my ASP.NET 5 app in azure https://docs.asp.net/en/latest/fundamentals/logging.html but can't make it work.
What is the way to do it?
You can configure logging through the Startup constructor. Here is a sample:
public Startup(ILoggerFactory loggerFactory)
{
var serilogLogger = new LoggerConfiguration()
.WriteTo
.TextWriter(Console.Out)
#if DNX451
.WriteTo.Elasticsearch()
#endif
.MinimumLevel.Verbose()
.CreateLogger();
loggerFactory.MinimumLevel = LogLevel.Debug;
loggerFactory.AddSerilog(serilogLogger);
}
That's all you need for configuration. From there, you can inject either ILoggerFactory or ILogger<T> (which is mostly the type for the class you want to inject the logger into) to the places you want to log stuff.
My sample configuration makes use of Serilog.Framework.Logging version 1.0.0-rc1-final-10071. Also, under dnx451, it will use Serilog.Sinks.ElasticSearch version 2.0.60.
In Azure Web App, there is no difference the way you configure it. You just need to choose the right provider.
You can see the entire sample here. Also check out ASP.NET 5 and Log Correlation by Request Id which might give you some more ideas.
At this point Azure AppService doesn't support ASP.NET 5 standard trace logging. Here is a potential workaround:
https://github.com/davidebbo-test/ConsoleInterceptor

Resources