This article shows you how to configure your function app to export log and trace data in an OpenTelemetry format. Azure Functions generates telemetry data on your function executions from both the Functions host process and the language-specific worker process in which your function code runs. By default, this telemetry data is sent to Application Insights using the Application Insights SDK. However, you can choose to export this data using OpenTelemetry semantics. While you can still use an OpenTelemetry format to send your data to Application Insights, you can now also export the same data to any other OpenTelemetry-compliant endpoint.
Tip
Because this article is targeted at your development language of choice, remember to choose the correct language at the top of the article.
You can obtain these benefits by enabling OpenTelemetry in your function app:
OpenTelemetry is enabled at the function app level, both in host configuration (host.json
) and in your code project. Functions also provides a client optimized experience for exporting OpenTelemetry data from your function code that's running in a language-specific worker process.
When you enable OpenTelemetry output in the function app's host.json file, your host exports OpenTelemetry output regardless of the language stack used by your app.
To enable OpenTelemetry output from the Functions host, update the host.json file in your code project to add a "telemetryMode": "OpenTelemetry"
element to the root collection. With OpenTelemetry enabled, your host.json file might look like this:
{
"version": "2.0",
"telemetryMode": "OpenTelemetry",
...
}
Configure application settings
When OpenTelemetry is enabled in the host.json file, the endpoints to which data is sent is determined based on which OpenTelemetry-supported application settings are available in your app's environment variables.
Create specific application settings in your function app based on the OpenTelemetry output destination. When connection settings are provided for both Application Insights and an OpenTelemetry protocol (OTLP) exporter, OpenTelemetry data is sent to both endpoints.
Enable OpenTelemetry in your appWith the Functions host configured to use OpenTelemetry, you should also update your application code to output OpenTelemetry data. Enabling OpenTelemetry in both the host and your application code enables better correlation between traces and logs emitted both by the Functions host process and from your language worker process.
The way that you instrument your application to use OpenTelemetry depends on your target OpenTelemetry endpoint:
Examples in this article assume your app is using IHostApplicationBuilder
, which is available in version 2.x and later version of Microsoft.Azure.Functions.Worker. For more information, see Version 2.x in the C# isolated worker model guide.
Run these commands to install the required assemblies in your app:
dotnet add package Microsoft.Azure.Functions.Worker.OpenTelemetry --version 1.1.0-preview6
dotnet add package OpenTelemetry.Extensions.Hosting
dotnet add package Azure.Monitor.OpenTelemetry.Exporter
dotnet add package Microsoft.Azure.Functions.Worker.OpenTelemetry --version 1.1.0-preview6
dotnet add package OpenTelemetry.Extensions.Hosting
dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol
In your Program.cs project file, add this using
statement:
The way that you configure OpenTelemetry depends if your project startup uses IHostBuilder
or IHostApplicationBuilder
, which was introduced in v2.x of the .NET isolated worker model extension.
In program.cs, add this line of code after ConfigureFunctionsWebApplication
:
builder.Services.AddOpenTelemetry()
.UseFunctionsWorkerDefaults()
.UseAzureMonitorExporter();
In program.cs, add this ConfigureServices
call in your HostBuilder
pipeline:
.ConfigureServices(s =>
{
s.AddOpenTelemetry()
.UseFunctionsWorkerDefaults()
.UseAzureMonitorExporter();
})
In program.cs, add this line of code after ConfigureFunctionsWebApplication
:
builder.Services.AddOpenTelemetry()
.UseFunctionsWorkerDefaults()
.UseOtlpExporter();
In program.cs, add this ConfigureServices
call in your HostBuilder
pipeline:
.ConfigureServices(s =>
{
s.AddOpenTelemetry()
.UseFunctionsWorkerDefaults()
.UseOtlpExporter();
})
You can export to both OpenTelemetry endpoints from the same app.
Add the required libraries to your app. The way you add libraries depends on whether you deploy using Maven or Kotlin and if you want to also send data to Application Insights.
<dependency>
<groupId>com.microsoft.azure.functions</groupId>
<artifactId>azure-functions-java-opentelemetry</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-monitor-opentelemetry-autoconfigure</artifactId>
<version>1.2.0</version>
</dependency>
implementation("com.microsoft.azure.functions:azure-functions-java-opentelemetry:1.0.0")
implementation("com.azure:azure-monitor-opentelemetry-autoconfigure:1.2.0")
<dependency>
<groupId>com.microsoft.azure.functions</groupId>
<artifactId>azure-functions-java-opentelemetry</artifactId>
<version>1.0.0</version>
</dependency>
implementation("com.microsoft.azure.functions:azure-functions-java-opentelemetry:1.0.0")
You can optionally add this code to create custom spans:
import com.microsoft.azure.functions.opentelemetry.FunctionsOpenTelemetry;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.context.Scope;
Span span = FunctionsOpenTelemetry.startSpan(
"com.contoso.PaymentFunction", // tracer name
"validateCharge", // span name
null, // parent = current context
SpanKind.INTERNAL);
try (Scope ignored = span.makeCurrent()) {
// business logic here
} finally {
span.end();
}
Install these npm packages in your project:
npm install @opentelemetry/api
npm install @opentelemetry/auto-instrumentations-node
npm install @azure/monitor-opentelemetry-exporter
npm install @azure/functions-opentelemetry-instrumentation
npm install @opentelemetry/api
npm install @opentelemetry/auto-instrumentations-node
npm install @opentelemetry/exporter-logs-otlp-http
npm install @azure/functions-opentelemetry-instrumentation
Create a code file in your project, copy and paste the following code in this new file, and save the file as src/index.js
:
const { AzureFunctionsInstrumentation } = require('@azure/functions-opentelemetry-instrumentation');
const { AzureMonitorLogExporter, AzureMonitorTraceExporter } = require('@azure/monitor-opentelemetry-exporter');
const { getNodeAutoInstrumentations, getResourceDetectors } = require('@opentelemetry/auto-instrumentations-node');
const { registerInstrumentations } = require('@opentelemetry/instrumentation');
const { detectResourcesSync } = require('@opentelemetry/resources');
const { LoggerProvider, SimpleLogRecordProcessor } = require('@opentelemetry/sdk-logs');
const { NodeTracerProvider, SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-node');
const resource = detectResourcesSync({ detectors: getResourceDetectors() });
const tracerProvider = new NodeTracerProvider({ resource });
tracerProvider.addSpanProcessor(new SimpleSpanProcessor(new AzureMonitorTraceExporter()));
tracerProvider.register();
const loggerProvider = new LoggerProvider({ resource });
loggerProvider.addLogRecordProcessor(new SimpleLogRecordProcessor(new AzureMonitorLogExporter()));
registerInstrumentations({
tracerProvider,
loggerProvider,
instrumentations: [getNodeAutoInstrumentations(), new AzureFunctionsInstrumentation()],
});
const { AzureFunctionsInstrumentation } = require('@azure/functions-opentelemetry-instrumentation');
const { getNodeAutoInstrumentations, getResourceDetectors } = require('@opentelemetry/auto-instrumentations-node');
const { OTLPLogExporter } = require('@opentelemetry/exporter-logs-otlp-http');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
const { registerInstrumentations } = require('@opentelemetry/instrumentation');
const { detectResourcesSync } = require('@opentelemetry/resources');
const { LoggerProvider, SimpleLogRecordProcessor } = require('@opentelemetry/sdk-logs');
const { NodeTracerProvider, SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-node');
const resource = detectResourcesSync({ detectors: getResourceDetectors() });
const tracerProvider = new NodeTracerProvider({ resource });
tracerProvider.addSpanProcessor(new SimpleSpanProcessor(new OTLPTraceExporter()));
tracerProvider.register();
const loggerProvider = new LoggerProvider({ resource });
loggerProvider.addLogRecordProcessor(new SimpleLogRecordProcessor(new OTLPLogExporter()));
registerInstrumentations({
tracerProvider,
loggerProvider,
instrumentations: [getNodeAutoInstrumentations(), new AzureFunctionsInstrumentation()],
});
Update the main
field in your package.json file to include this new src/index.js
file, which might look like this:
"main": "src/{index.js,functions/*.js}"
Create a code file in your project, copy and paste the following code in this new file, and save the file as src/index.ts
:
import { AzureFunctionsInstrumentation } from '@azure/functions-opentelemetry-instrumentation';
import { AzureMonitorLogExporter, AzureMonitorTraceExporter } from '@azure/monitor-opentelemetry-exporter';
import { getNodeAutoInstrumentations, getResourceDetectors } from '@opentelemetry/auto-instrumentations-node';
import { registerInstrumentations } from '@opentelemetry/instrumentation';
import { detectResourcesSync } from '@opentelemetry/resources';
import { LoggerProvider, SimpleLogRecordProcessor } from '@opentelemetry/sdk-logs';
import { NodeTracerProvider, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-node';
const resource = detectResourcesSync({ detectors: getResourceDetectors() });
const tracerProvider = new NodeTracerProvider({ resource });
tracerProvider.addSpanProcessor(new SimpleSpanProcessor(new AzureMonitorTraceExporter()));
tracerProvider.register();
const loggerProvider = new LoggerProvider({ resource });
loggerProvider.addLogRecordProcessor(new SimpleLogRecordProcessor(new AzureMonitorLogExporter()));
registerInstrumentations({
tracerProvider,
loggerProvider,
instrumentations: [getNodeAutoInstrumentations(), new AzureFunctionsInstrumentation()],
});
import { AzureFunctionsInstrumentation } from '@azure/functions-opentelemetry-instrumentation';
import { getNodeAutoInstrumentations, getResourceDetectors } from '@opentelemetry/auto-instrumentations-node';
import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
import { registerInstrumentations } from '@opentelemetry/instrumentation';
import { detectResourcesSync } from '@opentelemetry/resources';
import { LoggerProvider, SimpleLogRecordProcessor } from '@opentelemetry/sdk-logs';
import { NodeTracerProvider, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-node';
const resource = detectResourcesSync({ detectors: getResourceDetectors() });
const tracerProvider = new NodeTracerProvider({ resource });
tracerProvider.addSpanProcessor(new SimpleSpanProcessor(new OTLPTraceExporter()));
tracerProvider.register();
const loggerProvider = new LoggerProvider({ resource });
loggerProvider.addLogRecordProcessor(new SimpleLogRecordProcessor(new OTLPLogExporter()));
registerInstrumentations({
tracerProvider,
loggerProvider,
instrumentations: [getNodeAutoInstrumentations(), new AzureFunctionsInstrumentation()],
});
Update the main
field in your package.json file to include the output of this new src/index.ts
file, which might look like this:
"main": "dist/src/{index.js,functions/*.js}"
Important
OpenTelemetry output to Application Insights from the language worker isn't currently supported for PowerShell apps. You might instead want to use an OTLP exporter endpoint. When your host is configured for OpenTelemetry output to Application Insights, the logs generated by the PowerShell worker process are still be forwarded, but distributed tracing isn't supported at this time.
These instructions only apply for an OTLP exporter:
Add an application setting named OTEL_FUNCTIONS_WORKER_ENABLED
with value of True
.
Create an app-level Modules
folder in the root of your app and run the following command:
Save-Module -Name AzureFunctions.PowerShell.OpenTelemetry.SDK
This installs the required AzureFunctions.PowerShell.OpenTelemetry.SDK
module directly in your app. You can't use the requirements.psd1
file to automatically install this dependency because managed dependencies isn't currently supported in the Flex Consumption plan preview.
Add this code to your profile.ps1 file:
Import-Module AzureFunctions.PowerShell.OpenTelemetry.SDK -Force -ErrorAction Stop
Initialize-FunctionsOpenTelemetry
Make sure these libraries are in your requirements.txt
file, whether from uncommenting or adding yourself:
Add this code to your function_app.py
main entry point file:
If you already added PYTHON_APPLICATIONINSIGHTS_ENABLE_TELEMETRY=true
in your application settings, you can skip this step. To manually enable Application Insights collection without automatic instrumentation, add this code to your app:
from azure.monitor.opentelemetry import configure_azure_monitor
configure_azure_monitor()
Exporting traces, metrics, and logs using OpenTelemetry must be configured manually. For more information, see Instrumentation for Python.
This is a simple implementation for exporting logs:
logging.basicConfig(level=logging.DEBUG)
from opentelemetry import _logs
from opentelemetry.sdk._logs import LoggerProvider, LoggingHandler
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor
from opentelemetry.exporter.otlp.proto.http._log_exporter import OTLPLogExporter
# Initialize logging and an exporter that can send data to an OTLP endpoint by attaching OTLP handler to root logger
# SELECT * FROM Log WHERE instrumentation.provider='opentelemetry'
_logs.set_logger_provider(
LoggerProvider(resource=Resource.create(OTEL_RESOURCE_ATTRIBUTES))
)
logging.getLogger().addHandler(
LoggingHandler(
logger_provider=_logs.get_logger_provider().add_log_record_processor(
BatchLogRecordProcessor(OTLPLogExporter())
)
)
)
Review the OpenTelemetry Logging SDK to learn how to use OpenTelemetry components to collect logs.
Review Azure monitor Distro usage documentation for options on how to further configure the SDK.
When you export your data using OpenTelemetry, keep these current considerations in mind.
At this time, only HTTP, Service Bus and Event Hubs triggers are supported with OpenTelemetry outputs.
When the host is configured to use OpenTelemetry, the Azure portal doesn't support log streaming or recent function invocation traces.
Custom spans automatically include all resource attributes and use the exporters configured in your app.
When your app runs outside Azure, including during local development, the resource detector sets the service.name
attribute to java-function-app
by default.
Use these Java Virtual Machine (JVM) flags to silence telemetry when running locally during unit tests:
-Dotel.traces.exporter=none
-Dotel.metrics.exporter=none
-Dotel.logs.exporter=none
OpenTelemetryInvocationMiddleware
.To access diagnostics in your app:
In the Azure portal, navigate to your function app resource.
In the left pane, select Diagnose and solve problems and search for the Function App missing telemetry Application Insights or OpenTelemetry workflow.
Select this workflow, choose your ingestion method, and select Next.
Review the guidelines and any recommendations provided by the troubleshooter.
Monitor Azure Functions Flex Consumption plan
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4