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

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"

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":

Adding custom property to all Application Insight traces

I want to add a custom property to all traces in Application Insights.
In Asp.Net Core I've added this code
internal class TelemetryProperties : ITelemetryInitializer
{
private IConfiguration configuration;
public TelemetryProperties(IConfiguration configuration)
{
this.configuration = configuration;
}
// TODO: Not being added to all traces.
// http://apmtips.com/blog/2014/12/01/telemetry-initializers/
public void Initialize(ITelemetry telemetry)
{
var applicationName = configuration["Application:Name"];
telemetry.Context.Properties.Add("Application", applicationName);
}
}
and in the configure method of Startup.cs I have added:
TelemetryConfiguration.Active.TelemetryInitializers.Add(new TelemetryProperties(Configuration));
The intent was to add "Application" to all traces, even ones made automatically by Application Insights, but the effect is that it is ONLY being added to my custom traces that Im calling through my code.
How do I add a property to ALL traces, even ones I do not create.
Edit: The purpose of this is that I want to have multiple APIs in the same application insights log, but I want to be able to partition when neccessary by adding a defining property such as application name.
Modifying TelemetryConfiguration.Active is not the recommended approach in Asp.Net Core apps. Can you add the telemetry initializer using the below code in ConfigureServices ?
services.AddSingleton<ITelemetryInitializer, TelemetryProperties>();
https://github.com/Microsoft/ApplicationInsights-aspnetcore/wiki/Custom-Configuration#adding-new-telemetryinitializer
Please let me know if this helps.
I used your code(without change), and at my side, all the traces(the application insights adds, I didn't use any Trackxx methods) including the exception all have the property "Application". Please see the screenshots below:
If it still occurs in your side, please provide the screenshots of the appInsights' logs.

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.

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

My custom Windows Service is not writing to my custom Event Log

I have written a custom Windows Service that writes data to a custom Event Log (in the Windows Event Viewer).
For dev'ing the biz logic that the service uses, I created a Windows Form which simulates the Start/Stop methods of the Windows Service.
When executing the biz logic via the Windows Forms, info is successfully written to my custom Event Log. However, when I run the same biz logic from the custom Windows Service, information is failing to be written to the Event Log.
To be clear, I have written a library (.dll) that does all the work that I want my custom service to do - including the create/write to the custom Event Log. My Form application references this library as does my Windows Service.
Thinking the problem is a security issue, I manually set the custom Windows Service to "Log on" as "Administrator", but the service still did not write to the Event Log.
I'm stuck on how to even troubleshoot this problem since I can't debug and step into the code when I run the service (if there is a way to debug a service, please share).
Do you have any ideas as to what could be causing my service to fail to write to the event log?
I use it like this. There can be some typos. Writed it on my phone browser...
public class MyClass
{
private EventLog eventLog = new EventLog();
public void MyClass()
{
if (!System.Diagnostics.EventLog.SourceExists("MyLogSource"))
System.Diagnostics.EventLog.CreateEventSource("MyLogSource", "MyLogSource_Log");
eventLog.Source = "MyLogSource";
eventLog.Log = "MyLogSource_Log";
}
private void MyLogWrite()
{
eventLog.WriteEntry(ex.ToString(), EventLogEntryType.Error);
}
}
To debug a running service you need to attach to the process. See here for the steps.
You could also add parameter checking to the Main entry point and have a combination service and console app which would start based on some flag. See this SO post for a good example but here's a snippet:
using System;
using System.ServiceProcess;
namespace WindowsService1
{
static class Program
{
static void Main(string[] args)
{
if (args == null)
{
Console.WriteLine("Starting service...");
ServiceBase.Run(new ServiceBase[] { new Service1() });
}
else
{
Console.WriteLine("Hi, not from service: " + args[0]);
}
}
}
}
The above starts the app in console mode if there any parameters exist and in service mode if there are no parameters. Of course it can be much fancier but that's the gist of the switch.
I discovered why my service wasn't writing to the Event Log.
The problem had nothing to do with any part of the code/security/etc that was attempting to write to the EL. The problem was that my service wasn't successfully collecting the information that is written to the EL - therefore, the service wasn't even attempting to write the log.
Now that I fixed the code that collects the data, data is successfully writing to the event log.
I'm open to having this question closed since the question was amiss to the real problem.

Resources