I have a project written in .net 6. I use Azure Function to send data to Service bus and MediatR. How can I add Open Telemetry to my Azure functions?
[Function("EBcktErroredFunction")]
public Task EBcktErroredFunctionAsync([ServiceBusTrigger("e-bckt-errored", "bckts-creation-finalize")] EBcktErrored payload)
{
return _mediator.Send(
new SyncBcktErroredToStoreCommand
{
SBcktId = payload.BcktId,
EBcktId = payload.ExternalBcktId
}
);
Not related but in the bicep file it looks like this;
resource eBcktErroredSubscription 'Microsoft.ServiceBus/namespaces/topics/subscriptions' = {
name: '${serviceBusName}/e-bckt-errored/${appName}'
properties: {
autoDeleteOnIdle: ''
deadLetteringOnMessageExpiration:
defaultMessageTimeToLive: ''
enableBatchedOperations: true
lockDuration: ''
}
}
CodePudding user response:
You can find a full example on GitHub and a corresponding discussion about "Using OpenTelemetry Sdk with Azure Functions".
Most relevant code (you should look at the full code for reference):
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
// OpenTelemetry Resource to be associated with logs, metrics and traces
var openTelemetryResourceBuilder = ResourceBuilder.CreateDefault().AddService("opentelemetry-service");
// Enable Logging with OpenTelemetry
builder.Services.AddLogging( (loggingBuilder) =>
{
// Only Warning or above will be sent to Opentelemetry
loggingBuilder.AddFilter<OpenTelemetryLoggerProvider>("*", LogLevel.Warning);
}
);
builder.Services.AddSingleton<ILoggerProvider, OpenTelemetryLoggerProvider>();
builder.Services.Configure<OpenTelemetryLoggerOptions>( (openTelemetryLoggerOptions) =>
{
openTelemetryLoggerOptions.SetResourceBuilder(openTelemetryResourceBuilder);
openTelemetryLoggerOptions.IncludeFormattedMessage = true;
openTelemetryLoggerOptions.AddConsoleExporter();
}
);
// Enable Tracing with OpenTelemetry
var openTelemetryTracerProvider = Sdk.CreateTracerProviderBuilder()
.SetResourceBuilder(openTelemetryResourceBuilder)
.SetSampler(new AlwaysOnSampler())
.AddAspNetCoreInstrumentation()
.AddConsoleExporter()
.Build();
builder.Services.AddSingleton(openTelemetryTracerProvider);
// Enable Metrics with OpenTelemetry
var openTelemetryMeterProvider = Sdk.CreateMeterProviderBuilder()
.SetResourceBuilder(openTelemetryResourceBuilder)
.AddAspNetCoreInstrumentation()
.AddMeter(Function1.MyMeter.Name)
.AddConsoleExporter(consoleOptions =>
{
consoleOptions.MetricReaderType = MetricReaderType.Periodic;
consoleOptions.AggregationTemporality = AggregationTemporality.Cumulative;
consoleOptions.PeriodicExportingMetricReaderOptions.ExportIntervalMilliseconds = 10000;
})
.Build();
builder.Services.AddSingleton(openTelemetryMeterProvider);
[FunctionName("Function1")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
log.LogWarning("C# HTTP trigger function processed a request.");
MyCounter.Add(1, new("name", "apple"), new("color", "red"));
string name = req.Query["name"];
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
name = name ?? data?.name;
string responseMessage = string.IsNullOrEmpty(name)
? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
: $"Hello, {name}. This HTTP triggered function executed successfully.";
log.LogWarning("Name is {name}", name);
Activity.Current?.SetTag("name", name);
return new OkObjectResult(responseMessage);
}