Assign Application Insights cloud_RoleName to Windows Service running w/ OWIN - 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.

Related

Azure Monitor... or is it Log Analytics? Or Application Insights? Or Operational Insights? Or

Here's my scenario.
Application:
Created an asp.net core app
Grab an ILogger<T> logger;
logger.LogInformation(new EventId(123456, "HelloEvent"), "Hello there");
Infrastructure:
Deploy service fabric (via ARM template)
Deploy app to service fabric
Me:
Click around hopelessly looking for "Hello there" in my HelloEvent
So...
The BIG question: What are all the pieces of log collection/processing offered by Microsoft Azure, and how do they fit together?
Application Insights... Looks cool. I added .UseApplicationInsights() in my builder and .AddApplicationInsightsTelemetry(..) into my Startup.
And I get beautiful logs... ...about service fabric events, dependencies like http calls, etc. But I can't find my "Hello there" HelloEvent.
Where do I get it?
...
Moving onwards, I looked into logs, monitoring, etc, with Azure.
I find "Log Analytics", which looks cool. Apparently Application Insights uses it. But I already have Application Insights. Does that mean I have Log Analytics? Or do I create my own Log Analytics workspace. If so, do my logs go to two places? Do I connect Application Insights to it somehow?
The ARM template for that actually is from 2015 for something called OperationalInsights. Although there's a 2017 version in examples, but not in the reference documentation.
So Operational Insights? Apparently that's from some Microsoft Operations Management Suite / OMS. Which was MMS before...?
And the more recent docs all talk about "Azure Monitor". But that's not even something I can deploy in Azure. Is it just a concept?
…
All I want to do is collect logs somewhere and then have cool stuff to search & visualize them :)
...and I still haven't found my "HelloEvent"
Can anyone shed light on either my simple "Where's my HelloEvent" or speak to the bigger picture question "What are the pieces and how do they all fit together"?
Regarding the "Where's my HelloEvent" with application insights:
Please make sure in Startup.cs -> Configure method, you specify the loglevel to information, like below:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
// other code
//specify the LogLevel to Information, the default is warning
loggerFactory.AddApplicationInsights(app.ApplicationServices,LogLevel.Information);
}
(Update)and if you want to include event id in the logs, Simply setup ApplicationInsightsLoggerOptions instance in Startup.ConfigureServices method.
services
.AddOptions<ApplicationInsightsLoggerOptions>()
.Configure(o => o.IncludeEventId = true);
My test code as below:
public class HomeController : Controller
{
ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
_logger.LogInformation(new EventId(123456, "HelloEvent"), "Hello there");
return View();
}
// other code
}
And in the azure portal, I can see "hello there":

Is there a way to set appName in Application Insights custom events?

I noticed that App Insights has a field called appName (and appId) when querying in the analytics tool (see below), however I don't see a way of setting this in the client library. Can this be set?
I'm trying to log related items to app insights, though the log source may be different. Using that field seems like a nice way to handle that scenario, though I'm open to different scenarios.
There is a preview where you can set the application name. This is done in the following way:
enable the preview Application Map
set the ITelemetry.Context.Cloud.RoleName (this is the application name)
Enable preview: Go to the portal -> the application insights -> previews -> Enable Multi-role Application Map
Set the application name:
This is done by adding an interceptor:
public class ServiceNameInitializer : ITelemetryInitializer
{
    public void Initialize(ITelemetry telemetry)
    {
        telemetry.Context.Cloud.RoleName = "MyProcessName";
// RoleInstance property modifies the app name in the telmetry dashboard
telemetry.Context.Cloud.RoleInstance = "MyAppInstanceName";
    }
}
Add the interceptor to the application insights configuration in startup.cs:
private void ConfigureAppInsights(IServiceCollection services)
{
    services.AddApplicationInsightsTelemetry(Configuration);
    TelemetryConfiguration.Active.TelemetryInitializers
       .Add(new ServiceNameInitializer());
}
Read more at: cross-process-application-insights-with-multi-role-application-map
Those values are populated in the backend and specify Application Insights resource details and thus cannot be changed.
What your're looking for is custom dimensions.
For example, to send the telemetry:
EventTelemetry telemetry = new EventTelemetry("my custom event");
telemetry.Properties.Add("MyApp", "HelloWorld");
telemetryClient.TrackEvent(telemetry);
To query those custom dimensions:
customEvents
| where customDimensions['MyApp'] == "HelloWorld"

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

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

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)

Can ACS Service Namespace creation be automated?

First, let me state my real problem: I've got code that makes calls to the ACS Management service, and I'd like my integration tests to be able to be run concurrently without each test run clobbering the others. That is, since multiple people / build servers might end up running these tests concurrently, if they're all using the same ACS service namespace, concurrency issues arise.
My thinking is the simplest means of achieving this would be to generate new, unique ACS service namespaces for each test runner -- but as far as I can tell, there's no automated way of creating new service namespaces (or management client keys). Am I wrong? Is there another way of going about this?
An automated method of creating new service namespaces would be extraordinarily helpful.
You are correct. That's not possible today. Maybe you can describe your scenario in more detail and there might be some alternative solutions to avoid having to recreate the namespace?
Technically it should be possible, since the Management Portal is a Silverlight application accessing a WCF RIA Service.
If you dig deep enough you'll find some useful information:
This is the Silverlight XAP for the management of Windows Azure AppFabric: https://appfabricportal.windows.azure.com/ClientBin/Microsoft.AppFabric.WebConsole.4.1.3.xap
This is the service being used when listing/creating/... namespaces etc..: https://appfabricportal.windows.azure.com/Services/Microsoft-AppFabric-Web-Services-AppFabricDomainService.svc?wsdl
And this is a piece of the DomainContext:
public sealed class AppFabricDomainContext : DomainContext
{
public AppFabricDomainContext(Uri serviceUri)
: this((DomainClient) new WebDomainClient<AppFabricDomainContext.IAppFabricDomainServiceContract>(serviceUri, true))
{
}
...
public InvokeOperation CreateServiceNamespace(IEnumerable<string> serviceNames, string parentProjectKey, string serviceNamespace, IEnumerable<string> packageKeys, string regionKey, Action<InvokeOperation> callback, object userState)
{
Dictionary<string, object> dictionary = new Dictionary<string, object>();
dictionary.Add("serviceNames", (object) serviceNames);
dictionary.Add("parentProjectKey", (object) parentProjectKey);
dictionary.Add("serviceNamespace", (object) serviceNamespace);
dictionary.Add("packageKeys", (object) packageKeys);
dictionary.Add("regionKey", (object) regionKey);
this.ValidateMethod("CreateServiceNamespace", (IDictionary<string, object>) dictionary);
return this.InvokeOperation("CreateServiceNamespace", typeof (void), (IDictionary<string, object>) dictionary, true, callback, userState);
}
}
Finding this info was the easy part, getting it to work... that's something else. Take the authentication part for example, you'll need to authenticate with Windows Live and use those credentials when calling the WCF RIA Service.
Good luck!

Resources