3

I just leverage default Application Insights logging to log the request telemetry without ANY custom code. The request telemetry looks like this:

timestamp [UTC]     2019-12-19T00:22:10.2563938Z
id                  |a758472d124b6e4688a33b2ad9755f33.b3979544_
name                GET MyMethod [type]
url                 https://xxxx
success             True
resultCode          200
duration            153.2676
performanceBucket   <250ms
itemType            request
customDimensions 
    AppId                           xxxx-xxxx-xxxx-xxxx-xxxxxx
    AspNetCoreEnvironment:          west us
   _MS.ProcessedByMetricExtractors (Name:'Requests', Ver:'1.1')

Now I want to add a new property to customDimensions in Request telemetry, say, correlationId. What is the easiest way to to it? I just want to expend the existing request telemetry, don't want to create new event.

Youxu
  • 1,050
  • 1
  • 9
  • 34
  • Which program language are you using? – Ivan Glasenberg Dec 19 '19 at 01:20
  • By default Application Insights - are you referring to onboarding on Application Insights in App Service itself? Or to adding AI SDK but not doing anything extra except registering it? – ZakiMa Dec 19 '19 at 07:12

3 Answers3

3

If you're interested in massaging data (i.e. modify based on what's available in telemetry item itself) then Ivan's answer is the right one.

If you'd like to add something to existing request then you need to do a few things:

1) Use Activity.Tags property bag while in a request

Activity.Current?.AddTag("TagName", "TagValue");

2) Have Telemetry initializer which puts tags as custom dimensions (in next versions we might add it as default initializer and this step will no longer be required)

/// <summary>
/// Helper class to workaround AI SDK not collecting activity tags by default.
/// This initializer allows the business logic to have no AI references.
/// </summary>
public class ActivityTagsTelemetryInitializer : ITelemetryInitializer
{
    public void Initialize(ITelemetry telemetry)
    {
        var activity = Activity.Current;
        var requestTelemetry = telemetry as ISupportProperties;

        if (requestTelemetry == null || activity == null) return;

        foreach (var tag in activity.Tags)
        {
            requestTelemetry.Properties[tag.Key] = tag.Value;
        }
    }
}

3) Register in Startup

services.AddSingleton<ITelemetryInitializer, ActivityTagsTelemetryInitializer>();
ZakiMa
  • 5,637
  • 1
  • 24
  • 48
  • This is a year after you posted this answer but do you know (or have a link) to the AI issue about tags/baggage not being propagated? I'm hitting a similar issue with Azure Functions. – Sean Feldman Jan 01 '21 at 19:44
  • @SeanFeldman, sorry, just noticed. I guess it is a little bit too late. I think only one of these two (either tags or baggage) is supposed to be propagated according to standard. If neither propagates it might warrant a separate question. – ZakiMa Aug 24 '21 at 03:35
  • 1
    In my testing (App Insights v2.19.0) Tags are not recorded. I don't know why. Baggage added via `System.Diagnostics.Activity.Current.AddBaggage()` is recorded as custom dimensions but only in `dependencies` and `traces` tables, not in `requests`. To add to `requests` I use just `httpContext.Features.Get().Properties["MyCustomDimension"] = someValue;` (with appropriate null-checking). Some vaguely-related discussion here https://github.com/Azure/azure-functions-host/issues/2617 – Rory Mar 03 '22 at 14:05
  • 1
    @Rory It is a regression in recent versions of App Insights/`System.Diagnostics.DiagnosticSource`. Can be worked around by downgrading App Insights to `2.14.0`, or maybe upgrading to .NET 6. See the discussions at https://github.com/microsoft/ApplicationInsights-dotnet/issues/562 and https://github.com/Azure/azure-functions-host/issues/7278 for more info. – Zero3 Jun 30 '22 at 09:35
1

For adding custom dimensions, you can take use of ITelemetryInitializer.

Here is an example for a .NET core web project:

1.Add a class named MyTelemetryInitializer to the project, and the code like below:

public class MyTelemetryInitializer : ITelemetryInitializer
{
    public void Initialize(ITelemetry telemetry)
    {
        var requestTelemetry = telemetry as RequestTelemetry;

        //if it's not a request, just return.
        if (requestTelemetry == null) return;

        if (!requestTelemetry.Properties.ContainsKey("correlationId"))
        {
            requestTelemetry.Properties.Add("correlationId", "id_123456");
        }
    }

 }

2.In Startup.cs -> ConfigureServices method, use the following code:

    public void ConfigureServices(IServiceCollection services)
    {
       //your other code           

        //register the class MyTelemetryInitializer.
        services.AddSingleton<ITelemetryInitializer, MyTelemetryInitializer>();
    }

The test result:

enter image description here

If you're using other programming language, please follow the official doc and use the proper method for ITelemetryInitializer.

Ivan Glasenberg
  • 29,865
  • 2
  • 44
  • 60
0

You don't need to create your own TelemetryInitializer but can just do this from anywhere you can reference the httpContext:

var requestTelemetry = httpContext.Features.Get<RequestTelemetry>();
if (requestTelemetry != null)
{
    requestTelemetry.Properties["YourCustomDimension"] = someValue;
}

Properties added in this way will be added to the requests table in Application Insights.

To add for the dependencies and traces tables you can use

System.Diagnostics.Activity.Current.AddBaggage("YourCustomDimension" someValue);

To add to traces when you write a log entry just pass in objects to the LogXXX method with a placeholder in the log message, e.g.

_logger.LogWarning("hello {YourCustomDimension}", someValue);

someValue will be serialized to json so can be a complex object if you like.

Rory
  • 40,559
  • 52
  • 175
  • 261