Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use Application Insights locally with Azure Functions?

I'm using the interface ILogger to log events inside my Azure functions. I can publish it in Azure and connect it to Application Insights in Azure.

I want to see my logs inside Application Insights in my Visual Studio during development. In here I can see this is possible in a ASP.NET Core Web Application putting some code in Startup.cs. Is something similar possible with Azure Functions using the new project template from the tooling in VS 2017?

I'm using VS 2017 and Azure Function CLI 1.0.0-beta-100.

like image 599
gabomgp Avatar asked Aug 04 '17 15:08

gabomgp


3 Answers

Adding Application Insights (AI) telemetry to Azure Functions is simple and straightforward.

You just need these two steps from the official docs;

  1. Create an Application Insights instance.
    • Application type should be set to General
    • Grab the instrumentation key
  2. Update your Function App’s settings
    • Add App Setting – APPINSIGHTS_INSTRUMENTATIONKEY = {Instrumentation Key}

However what is not (so) obvious is how to capture AI telemetry data while developing a functions app locally, just before letting it go to the clouds. First you need to prepare your local dev environment for Azure Functions. Then you are almost ready. You just need to repeat the second step above on your local.settings.json file. So your file should look something like this;

{
  "IsEncrypted": false,
  "Values": {
    "FUNCTIONS_EXTENSION_VERSION": "beta",
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "AzureWebJobsDashboard": "UseDevelopmentStorage=true",
    "HOST_NAME": "localhost:7072",
    "APPINSIGHTS_INSTRUMENTATIONKEY": "11111111-2222-3333-4444-555555555555"
  },
  "Host": {
    "LocalHttpPort": 7072
  }
}

In my case I have 2 AI instances, the APPINSIGHTS_INSTRUMENTATIONKEYvalues in my Azure Portal and in my local dev env (local.settings.json) is different so that I would not confuse prod and dev telemetries.

like image 120
milkersarac Avatar answered Nov 12 '22 07:11

milkersarac


So, apparently due to the changes being done to the libraries, every now and then it will stop working. So this is what helped me to make it work in April 2019. Hopefully it will help others.

I haven't added any log or anything specific to my function app, right now for me it's pretty much printing all the console data to the Trace logs in my app insights (locally, not needing yet to configure anything in Azure). Also, my test scenario is running on TargetFramework netstandard2.0 and AzureFunctionsVersion 2.

First you need to add this NuGet package to the function app: https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Logging.ApplicationInsights/

Then you have to add an empty file to your project root: ApplicationInsights.config you don't need to copy it to output when building or anything, this is just something that has to be there or Application Insights won't work locally.

Then you need to add some value to your APPINSIGHTS_INSTRUMENTATIONKEY in local.settings.json. This is where it differs from regular console apps, where even if the instrumentation key is empty it will work locally. In function apps apparently you need to add some value there. It can be anything, I've done this and it worked fine:

"APPINSIGHTS_INSTRUMENTATIONKEY": "you-need-to-have-anything-at-all-here-so-it-will-work-locally"
like image 30
Rafael Merlin Avatar answered Nov 12 '22 06:11

Rafael Merlin


As far as I know, currently we couldn't directly include the Application Insights in your local azure function project.

Here is a workaround:

You need implement it by yourself. After installed the Microsoft.ApplicationInsights from the Nuget package manager.

Then use TelemetryClient to send the logs to the azure.

More details, you could refer to below codes:

[FunctionName("HttpTriggerCSharp")]
public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]HttpRequestMessage req, TraceWriter log)
{
    var appInsights = GetTelemetryClient();
    //track an event
    appInsights.TrackEvent("I am starting now. I'm timer triggered");
    // track a numeric value
    appInsights.TrackMetric("Ticks based on current time", DateTime.Now.Ticks);
    // track an exception
    appInsights.TrackException(new Exception($"Random exception at {DateTime.Now}"));

    // send data to azure
    appInsights.Flush();

    log.Info($"C# Timer trigger function executed at: {DateTime.Now}");

    log.Info("C# HTTP trigger function processed a request.");

    // parse query parameter
    string name = req.GetQueryNameValuePairs()
        .FirstOrDefault(q => string.Compare(q.Key, "name", true) == 0)
        .Value;

    // Get request body
    dynamic data = await req.Content.ReadAsAsync<object>();

    // Set name to query string or body data
    name = name ?? data?.name;

    return name == null
        ? req.CreateResponse(HttpStatusCode.BadRequest, "Please pass a name on the query string or in the request body")
        : req.CreateResponse(HttpStatusCode.OK, "Hello " + name);
}

private static TelemetryClient GetTelemetryClient()
{
    var telemetryClient = new TelemetryClient();
    telemetryClient.InstrumentationKey = "Your InstrumentationKey";
    return telemetryClient;
}

Result:

enter image description here

like image 2
Brando Zhang Avatar answered Nov 12 '22 06:11

Brando Zhang