6

I am creating a new Function app using v2.x and I am integrating Application Insights for request logging that is automatically being done as Azure Function is now integrated with App Insights (as mentioned in the documentation link). What I would need to do is log few custom fields in the custom dimensions in Application Insights Request Telemetry. Is it possible without using Custom Request logging (using TrackRequest method)

Silly John
  • 1,584
  • 2
  • 16
  • 34

3 Answers3

5

About adding custom properties, you could refer to this tutorial:Add properties: ITelemetryInitializer. The below is my test a HTTP trigger function.

public static class Function1
{
    private static string key = "Your InstrumentationKey";
    private static TelemetryClient telemetry = new TelemetryClient() { InstrumentationKey = key };
    [FunctionName("Function1")]
    public static async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
        ILogger log)
    {
        log.LogInformation("C# HTTP trigger function processed a request.");

        if (!telemetry.Context.Properties.ContainsKey("Function_appName"))
        {
            telemetry.Context.Properties.Add("Function_appName", "testfunc");
        }
        else
        {
            telemetry.Context.Properties["Function_appName"] = "testfunc";
        }

        telemetry.TrackEvent("eventtest");
        telemetry.TrackTrace("tracetest");

        string name = req.Query["name"];

        string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
        dynamic data = JsonConvert.DeserializeObject(requestBody);
        name = name ?? data?.name;

        return name != null
            ? (ActionResult)new OkObjectResult($"Hello, {name}")
            : new BadRequestObjectResult("Please pass a name on the query string or in the request body");
    }
}

After running this function, go to the Application Insights Search could check the data Or go to Logs(Analytics).

enter image description here

enter image description here

Update:

enter image description here

enter image description here

spottedmahn
  • 14,823
  • 13
  • 108
  • 178
George Chen
  • 13,703
  • 2
  • 11
  • 26
  • 1
    As i mentioned, what i want is to add custom properties to the request and not to the event. The above screenshot shows the custom properties got created for the event and not the request – Silly John Jul 18 '19 at 06:13
  • @Silly John, the request is also could be added, check my update. – George Chen Jul 18 '19 at 06:45
  • 1
    I have mentioned in my post that i do not want to do custom request logging. In the above details, you are explicitly starting and stopping the operating which is actually custom request logging. – Silly John Jul 18 '19 at 09:08
  • 2
    why do we need to do declare this as a member `new TelemetryClient()` why cant we simply use the `ILogger` without having to do anything `telemetryclient` ? – Alex Gordon Oct 11 '19 at 19:42
5

You should use ITelemetry Initializer(which can add custom dimension to a specified telemetry like only for request) in function app, please follow the steps below:

1.In Visual studio, create a function app(In my test, I create a blob triggerd function), and install the following nuget packages:

Microsoft.ApplicationInsights, version 2.10.0

Microsoft.NET.Sdk.Functions, version 1.0.29

2.Then in the Function1.cs, write code like below:

using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System.IO;

[assembly: WebJobsStartup(typeof(FunctionApp21.MyStartup))]
namespace FunctionApp21
{
    public static class Function1
    {


        [FunctionName("Function1")]
        public static void Run([BlobTrigger("samples-workitems/{name}", Connection = "AzureWebJobsStorage")]Stream myBlob, string name, ILogger log)
        {
            log.LogInformation($"C# Blob trigger function Processed blob\n Name:{name} \n Size: {myBlob.Length} Bytes");
        }
    }

    internal class MyTelemetryInitializer : ITelemetryInitializer
    {
        public void Initialize(ITelemetry telemetry)
        {           

            //use telemetry is RequestTelemetry to make sure only add to request
            if (telemetry != null && telemetry is RequestTelemetry && !telemetry.Context.GlobalProperties.ContainsKey("my_custom_dimen22"))
            {
                telemetry.Context.GlobalProperties.Add("my_custom_dimen22", "Hello, this is custom dimension for request!!!");
            }
        }
    }

    public class MyStartup : IWebJobsStartup
    {
        public void Configure(IWebJobsBuilder builder)
        {
            builder.Services.AddSingleton<ITelemetryInitializer, MyTelemetryInitializer>();

        }
    }
}

3.Publish it to azure, then nav to azure portal -> the published function app -> Monitor -> Add an application insights.

4.Run the function from azure. And wait for a few minutes -> nav to the application insights portal, check the telemetry data, and you can see the custom dimension is only added to request telemetry:

enter image description here

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

The other solutions don't quite answer the question, how to add custom properties to the request telemetry. There is a very simple solution, add the following within your function's code:

Activity.Current?.AddTag("my_prop", "my_value");

You'll need:

using System.Diagnostics;

This then can be dynamic per function invocation / request, rather a fixed global property.

Simon Ness
  • 2,272
  • 22
  • 28