问题
I d'like to add custom properties to metrics taken by Application Insights to each request of my app. For example, I want to add the user login and the tenant code, such as I can segment/group the metrics in the Azure portal.
The relevant doc page seems to be this one : Set default property values
But the example is for an event (i.e. gameTelemetry.TrackEvent("WinGame");
), not for an HTTP request :
var context = new TelemetryContext();
context.Properties["Game"] = currentGame.Name;
var gameTelemetry = new TelemetryClient(context);
gameTelemetry.TrackEvent("WinGame");
My questions :
- What is the relevant code for a request, as I have no specific code at this time (it seems to be automatically managed by the App Insights SDK) : Is just creating a
TelemetryContext
sufficient ? Should I create also aTelemetryClient
and if so, should I link it to the current request ? How ? - Where should I put this code ? Is it ok in the
Application_BeginRequest
method ofglobal.asax
?
回答1:
It looks like adding new properties to existing request is possible using ITelemetryInitializer as mentioned here.
I created sample class as given below and added new property called "LoggedInUser" to request telemetry.
public class CustomTelemetry : ITelemetryInitializer
{
public void Initialize(ITelemetry telemetry)
{
var requestTelemetry = telemetry as RequestTelemetry;
if (requestTelemetry == null) return;
requestTelemetry.Properties.Add("LoggedInUserName", "DummyUser");
}
}
Register this class at application start event. Example below is carved out of sample MVC application I created
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
TelemetryConfiguration.Active.TelemetryInitializers
.Add(new CustomTelemetry());
}
}
Now you can see custom property "LoggedInUserName" is displayed under Custom group of request properties. (please refer screen grab below)
Appinsight with custom property
回答2:
Related to the first question "how to add custom event to my request / what is the relevant code to a request", I think the main confusion here is related to the naming.
The first thing that we need to point out is that there are different kinds of information that we can capture with Application Insights:
- Custom Event
- Request
- Exception
- Trace
- Page View
- Dependency
Once we know this, we can say that TrackEvent is related to "Custom Events", as TrackRequest is related to Requests.
When we want to save a request, what we need to do is the following:
var request = new RequestTelemetry();
var client = new TelemetryClient();
request.Name = "My Request";
client.TrackRequest(request);
So let's imagine that your user login and tenant code both are strings. We could make a new request just to log this information using the following code:
public void LogUserNameAndTenant(string userName, string tenantCode)
{
var request = new RequestTelemetry();
request.Name = "My Request";
request.Context.Properties["User Name"] = userName;
request.Context.Properties["Tenant Code"] = tenantCode;
var client = new TelemetryClient();
client.TrackRequest(request);
}
Doing just a TelemetryContext will not be enough, because we need a way to send the information, and that's where the TelemetryClient gets in place.
I hope it helps.
回答3:
As mentioned by Alan, you could implement the IContextInitializer
interface to add custom properties to ALL telemetry sent by Application Insights. However, I would also suggest looking into the ITelemtryInitializer
interface. It is very similar to the context initializer, but it is called for every piece of telemetry sent rather than only at the creation of a telemetry client. This seems more useful to me for logging property values that might change over the lifetime of your app such as user and tenant related info like you had mentioned.
I hope that helps you out. Here is a blog post with an example of using the ITelemetryInitializer
.
回答4:
You can use the static HttpContext.Current
's Items
dictionary as a short term (near stateless) storage space to deliver your custom property values into the default telemetry handler with a custom ITelemetryInitializer
Implement handler
class AppInsightCustomProps : ITelemetryInitializer
{
public void Initialize(ITelemetry telemetry)
{
var requestTelemetry = telemetry as RequestTelemetry;
// Is this a TrackRequest() ?
if (requestTelemetry == null) return;
var httpCtx = HttpContext.Current;
if (httpCtx != null)
{
var customPropVal = (string)httpCtx.Items["PerRequestMyCustomProp"];
if (!string.IsNullOrWhiteSpace(customPropVal))
{
requestTelemetry.Properties["MyCustomProp"] = customPropVal;
}
}
}
}
Hook it in. Put this inside Application_Start
in global.asax.cs
TelemetryConfiguration.Active.TelemetryInitializers.Add(new AppInsightCustomProps());
Program the desired custom property, anywhere in your request pipeline have something like
if (HttpContext.Current != null)
{
HttpContext.Current.Items["PerRequestMyCustomProp"] = myCustomPropValue;
}
回答5:
In that doc, scroll down a few lines to where it talks about creating an implementation of IContextInitializer. You can call that in any method that will be called before telemetry starts rolling.
Your custom properties will be added to all events, exceptions, metrics, requests, everything.
来源:https://stackoverflow.com/questions/29036729/adding-custom-properties-for-each-request-in-application-insights-metrics