nintexvictor / DoNothingApp

0 stars 1 forks source link

Refactor to Register Service #1

Open kolanos opened 3 years ago

kolanos commented 3 years ago

@nintexvictor There's been some changes to how OpenTelemetry .NET works in Azure that haven't been addressed in the New Relic Azure Binding Extension yet. But you should still be able to wire up OpenTelemetry to your Azure Functions and export your telemetry data to New Relic.

First, you'll want to create a Startup.cs in your project. The Azure runtime will use this to bootstrap your FunctionApp. It should have something like this:

[assembly: FunctionsStartup(typeof(FunctionApp1.Startup))]
namespace FunctionApp1
{
    public class Startup : FunctionsStartup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddOpenTelemetryTracing((serviceProvider, tracerBuilder) =>
            {
                // Make the logger factory available to the dependency injection
                // container so that it may be injected into the OpenTelemetry Tracer.
                var loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();

                // Adds the New Relic Exporter loading settings from the appsettings.json
                tracerBuilder
                    .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(this.Configuration.GetValue<string>("NewRelic:ServiceName")))
                    .AddNewRelicExporter(options =>
                    {
                        options.ApiKey = this.Configuration.GetValue<string>("NewRelic:ApiKey");
                    })
                    .AddAspNetCoreInstrumentation()
                    .AddHttpClientInstrumentation();
            });
        }
    }
}

You can change the configuration keys to whatever you prefer. This is similar to how you would configure a ASP.NET Core application, since FunctionApps are built upon ASP .NET Core.

For dependencies you'll want to remove NewRelic.Azure.BindingExtension for now and add the following:

You'll then want to remove the New Relic Azure Binding Extension code, including the binding itself. You can add tags, spans and such using System.Diagnostics directly. This is now what OpenTelemetry .NET recommends.

Let me know if you have any questions.

kolanos commented 3 years ago

Check here to see some working examples using NewRelic.OpenTelemetry.

kolanos commented 3 years ago

For debugging, there's an exporter that will write the data OpenTelemetry collects to the console. Add the OpenTelemetry.Exporter.Console package to your project and then add .AddConsoleExporter() before the line with .AddNewRelicExporter(...). This will allow you to see traces when running locally. You'll likely want to remove this when deploying, though.

Additionally, OpenTelemetry does sampling by default. If you want OpenTelemetry to collect data on every invocation you can add .SetSampler(new AlwaysOnSampler()). This will require you to import OpenTelemetry and OpenTelemetry.Trace.

kolanos commented 3 years ago
        public void Configure(IWebJobsBuilder builder)
        {
kolanos commented 3 years ago
builder.Services.AddOpenTelemetryTracing(tracingBuilder =>
kolanos commented 3 years ago

@nintexvictor This service builder is based on the following Azure documentation.

kolanos commented 3 years ago

@nintexvictor The above docs say Microsoft.Extensions.DependencyInjection (3.x) is required, but appears to be missing here. Can we add this dependency and try a redeploy? Please report back your results. Thanks.

nintexvictor commented 3 years ago

Hey @kolanos I have added Microsoft.Extensions.DependencyInjection -v 3.1.10 and published the app, I'm still not able to find data for my functions in New Relic.

kolanos commented 3 years ago

@nintexvictor It looks like Azure is still blocking the hosting extensions for OpenTelemetry. Can you try this approach and see if it works? https://github.com/open-telemetry/opentelemetry-dotnet/issues/1602#issuecomment-731498274

This approach should run locally as well.