I have an azure function running in the isolated worker process locally. My intention is to use the OpenTelemetry contrib packages rather than the built in features with the functions runtime, as I intend to integrate with OpenTelemtry.
From what I can tell .AddSqlClientInstrumentation() from OpenTelemetry.Instrumentation.SqlClient
Should trace SQL calls when using Microsoft.Data.SQLClient, of which the output bindings in Azure Functions appear to be using.
However I do not see any evidence of it working.
Is the OpenTelemetry package compatible with Azure Functions SQL output binding when using isolated functions?
I can see HttpClient instrumentation working fine, so in general I have OpenTelemetry packages configured ok.
My guess is that the extensions work in the host worker process, rather than the application worker process? But reading through the extension lifecycle docs, I cannot confirm that for sure, as they don’t highlight it directly.
EDIT
Some additional context to illustrate what I am looking to achieve.
p.s. I’m less interested in problem solving the code, more whether the architecture of the Sql instrumentation libraries have any issues working in the azure functions runtime. But I certainly see the benefit of listing the code to add more context (thanks for the feedback).
var builder = new HostBuilder()
.ConfigureFunctionsWebApplication()
.ConfigureServices(services =>
{
services.AddOpenTelemetry()
.ConfigureResource(resource => resource.AddService(serviceName))
.WithTracing(tracing => tracing
.AddAspNetCoreInstrumentation()
.AddSqlClientInstrumentation(options => options.SetDbStatementForText = true)
.AddHttpClientInstrumentation()
.AddConsoleExporter()
.AddAzureMonitorTraceExporter(options => options.ConnectionString = "XXX")
);
})
.ConfigureLogging(logging =>
{
logging.AddOpenTelemetry(options => options
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(serviceName))
.AddAzureMonitorLogExporter(options => options.ConnectionString = "XXX")
.AddConsoleExporter());
})
.UseDefaultServiceProvider(x => x.ValidateOnBuild = true);
var host = builder.Build();
host.Run();
I have the following package references:
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Azure.Monitor.OpenTelemetry.Exporter" Version="1.3.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.23.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.2.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="1.3.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Sql" Version="3.0.534" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.17.3-preview2" />
<PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.22.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.2.0" />
<PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.SqlClient" Version="1.9.0-beta.1" />
And the following in the host.json, notably I have also been toying with appinsights native integration as well as OpenTelemetry, I did wonder whether appinsights might be consuming it and not allowing OpenTelemtry libraries to get the telemetry, but I can’t imagine it’s architected like that.
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
},
"enableLiveMetricsFilters": true,
"enableDependencyTracking": true,
"dependencyTrackingOptions": {
"enableSqlCommandTextInstrumentation": true
}
}
},
"logLevel": {
"default": "Information"
},
"telemetryMode": "openTelemetry"
}
EDIT 2:
I’m using azure functions output bindings i.e. via decorating the returned type with SqlOutput.
public class NewUserOutputBinding
{
[SqlOutput("dbo.Users", connectionStringSetting: "SqlConnectionString")]
public required User User { get; set; }
[HttpResult]
public required IActionResult HttpResponse { get; set; }
}
16