Not
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Den här artikeln visar OpenTelemetry-stöd i Azure Function, som möjliggör distribuerad spårning över flera funktionsanrop med hjälp av integrerat Application Insights- och OpenTelemetry-stöd. För att hjälpa dig att komma igång används en AZURE Developer CLI-mall (azd) för att skapa ditt kodprojekt samt Azure-distributionen där du kan köra din app.
I den här handledningen kommer du att använda azd-verktyget för att:
- Initiera ett OpenTelemetry-aktiverat projekt från en mall.
- Granska koden som aktiverar OpenTelemetry-integrering.
- Kör och verifiera din OpenTelemetry-aktiverade app lokalt.
- Skapa en funktionsapp och relaterade resurser i Azure.
- Distribuera kodprojektet till funktionsappen i Azure.
- Verifiera distribuerad spårning i Application Insights.
De nödvändiga Azure-resurser som skapas av den här mallen följer nuvarande bästa praxis för säkra och skalbara distributioner av funktionsappar i Azure. Samma azd kommando distribuerar även kodprojektet till din nya funktionsapp i Azure.
Som standard följer Flex Consumption-planen en faktureringsmodell för att betala för vad du använder , vilket innebär att slutförandet av den här snabbstarten medför en liten kostnad på några USDcent eller mindre på ditt Azure-konto.
Viktigt!
Den här artikeln stöder för närvarande endast C#, Python och TypeScript. Slutför snabbstarten genom att välja något av de språk som stöds överst i artikeln.
Förutsättningar
Ett Azure-konto med en aktiv prenumeration. Skapa ett konto kostnadsfritt.
Initiera projektet
azd init Använd kommandot för att skapa ett lokalt Azure Functions-kodprojekt från en mall som innehåller distribuerad spårning med OpenTelemetry.
Kör det här
azd initkommandot i en tom mapp i den lokala terminalen eller kommandotolken:azd init --template functions-quickstart-python-azd-otel -e flexquickstart-otelDet här kommandot hämtar projektfilerna från malllagringsplatsen och initierar projektet i den aktuella mappen. Flaggan
-eanger ett namn för den aktuella miljön. Iazdbehåller miljön en unik distributionskontext för din app och du kan definiera mer än en. Miljönamnet visas också i namnet på den resursgrupp som du skapar i Azure.
Kör det här
azd initkommandot i en tom mapp i den lokala terminalen eller kommandotolken:azd init --template functions-quickstart-typescript-azd-otel -e flexquickstart-otelDet här kommandot hämtar projektfilerna från malllagringsplatsen och initierar projektet i den aktuella mappen. Flaggan
-eanger ett namn för den aktuella miljön. Iazdbehåller miljön en unik distributionskontext för din app och du kan definiera mer än en. Miljönamnet visas också i namnet på den resursgrupp som du skapar i Azure.
Kör det här
azd initkommandot i en tom mapp i den lokala terminalen eller kommandotolken:azd init --template functions-quickstart-dotnet-azd-otel -e flexquickstart-otelDet här kommandot hämtar projektfilerna från malllagringsplatsen och initierar projektet i den aktuella mappen. Flaggan
-eanger ett namn för den aktuella miljön. Iazdbehåller miljön en unik distributionskontext för din app och du kan definiera mer än en. Miljönamnet visas också i namnet på den resursgrupp som du skapar i Azure.
Granska koden
Mallen skapar ett fullständigt distribuerat spårningsscenario med tre funktioner som fungerar tillsammans. Nu ska vi gå igenom viktiga OpenTelemetry-relaterade aspekter:
OpenTelemetry-konfiguration
Filen src/otel-sample/host.json aktiverar OpenTelemetry för Functions-värden:
{
"version": "2.0",
"telemetryMode": "OpenTelemetry",
"extensions": {
"serviceBus": {
"maxConcurrentCalls": 10
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[4.*, 5.0.0)"
}
}
Nyckelinställningen "telemetryMode": "OpenTelemetry" möjliggör distribuerad spårning mellan funktionsanrop.
Filen src/OTelSample/host.json aktiverar OpenTelemetry för Functions-värdenoden:
{
"version": "2.0",
"telemetryMode": "OpenTelemetry",
"logging": {
"OpenTelemetry": {
"logLevel": {
"Host.General": "Warning"
}
}
}
}
Nyckelinställningen "telemetryMode": "OpenTelemetry" möjliggör distribuerad spårning mellan funktionsanrop.
Beroenden för OpenTelemetry
Filen src/otel-sample/requirements.txt innehåller nödvändiga paket för OpenTelemetry-integrering:
azure-functions
azure-monitor-opentelemetry
requests
Paketet azure-monitor-opentelemetry tillhandahåller OpenTelemetry-integrering med Application Insights.
Filen src/otel-sample/package.json innehåller nödvändiga paket för OpenTelemetry-integrering:
{
"dependencies": {
"@azure/functions": "^4.0.0",
"@azure/functions-opentelemetry-instrumentation": "^0.1.0",
"@azure/monitor-opentelemetry-exporter": "^1.0.0",
"axios": "^1.6.0"
}
}
Paketen @azure/functions-opentelemetry-instrumentation och @azure/monitor-opentelemetry-exporter tillhandahåller OpenTelemetry-integreringen med Application Insights.
Filen .csproj innehåller nödvändiga paket för OpenTelemetry-integrering:
<PackageReference Include="Azure.Monitor.OpenTelemetry.Exporter" Version="1.4.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.OpenTelemetry" Version="1.4.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.10.0" />
Dessa paket tillhandahåller OpenTelemetry-integrering med Application Insights och HTTP-instrumentation för distribuerad spårning.
Funktionsimplementering
Funktionerna i src/otel-sample/function_app.py demonstrerar ett distribuerat spårningsflöde:
Första HTTP-funktionen
@app.function_name("first_http_function")
@app.route(route="first_http_function", auth_level=func.AuthLevel.ANONYMOUS)
def first_http_function(req: func.HttpRequest) -> func.HttpResponse:
logging.info('Python HTTP trigger function (first) processed a request.')
# Call the second function
base_url = f"{req.url.split('/api/')[0]}/api"
second_function_url = f"{base_url}/second_http_function"
response = requests.get(second_function_url)
second_function_result = response.text
result = {
"message": "Hello from the first function!",
"second_function_response": second_function_result
}
return func.HttpResponse(
json.dumps(result),
status_code=200,
mimetype="application/json"
)
Andra HTTP-funktionen
@app.function_name("second_http_function")
@app.route(route="second_http_function", auth_level=func.AuthLevel.ANONYMOUS)
@app.service_bus_queue_output(arg_name="outputsbmsg", queue_name="%ServiceBusQueueName%",
connection="ServiceBusConnection")
def second_http_function(req: func.HttpRequest, outputsbmsg: func.Out[str]) -> func.HttpResponse:
logging.info('Python HTTP trigger function (second) processed a request.')
message = "This is the second function responding."
# Send a message to the Service Bus queue
queue_message = "Message from second HTTP function to trigger ServiceBus queue processing"
outputsbmsg.set(queue_message)
logging.info('Sent message to ServiceBus queue: %s', queue_message)
return func.HttpResponse(
message,
status_code=200
)
Service Bus-köutlösare
@app.service_bus_queue_trigger(arg_name="azservicebus", queue_name="%ServiceBusQueueName%",
connection="ServiceBusConnection")
def servicebus_queue_trigger(azservicebus: func.ServiceBusMessage):
logging.info('Python ServiceBus Queue trigger start processing a message: %s',
azservicebus.get_body().decode('utf-8'))
time.sleep(5) # Simulate processing work
logging.info('Python ServiceBus Queue trigger end processing a message')
OpenTelemetry-konfigurationen konfigureras i src/otel-sample/index.ts:
import { AzureFunctionsInstrumentation } from '@azure/functions-opentelemetry-instrumentation';
import { AzureMonitorTraceExporter, AzureMonitorLogExporter } from '@azure/monitor-opentelemetry-exporter';
import { getNodeAutoInstrumentations, getResourceDetectors } from '@opentelemetry/auto-instrumentations-node';
import { registerInstrumentations } from '@opentelemetry/instrumentation';
import { detectResources } from '@opentelemetry/resources';
import { LoggerProvider, SimpleLogRecordProcessor } from '@opentelemetry/sdk-logs';
import { NodeTracerProvider, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-node';
const resource = detectResources({ detectors: getResourceDetectors() });
const tracerProvider = new NodeTracerProvider({
resource,
spanProcessors: [new SimpleSpanProcessor(new AzureMonitorTraceExporter())]
});
tracerProvider.register();
const loggerProvider = new LoggerProvider({
resource,
processors: [new SimpleLogRecordProcessor(new AzureMonitorLogExporter())],
});
registerInstrumentations({
tracerProvider,
loggerProvider,
instrumentations: [getNodeAutoInstrumentations(), new AzureFunctionsInstrumentation()],
});
Funktionerna definieras i src/otel-sample/src/functions mappen:
Första HTTP-funktionen
export async function firstHttpFunction(
request: HttpRequest,
context: InvocationContext
): Promise<HttpResponseInit> {
context.log("TypeScript HTTP trigger function (first) processed a request.");
try {
// Call the second function
const baseUrl = request.url.split("/api/")[0];
const secondFunctionUrl = `${baseUrl}/api/second_http_function`;
const response = await axios.get(secondFunctionUrl);
const secondFunctionResult = response.data;
const result = {
message: "Hello from the first function!",
second_function_response: secondFunctionResult,
};
return {
status: 200,
body: JSON.stringify(result),
headers: { "Content-Type": "application/json" },
};
} catch (error) {
return {
status: 500,
body: JSON.stringify({ error: "Failed to process request" }),
};
}
}
Andra HTTP-funktionen
export async function secondHttpFunction(
request: HttpRequest,
context: InvocationContext
): Promise<HttpResponseInit> {
context.log("TypeScript HTTP trigger function (second) processed a request.");
const message = "This is the second function responding.";
// Send a message to the Service Bus queue
const queueMessage =
"Message from second HTTP function to trigger ServiceBus queue processing";
context.extraOutputs.set(serviceBusOutput, queueMessage);
context.log("Sent message to ServiceBus queue:", queueMessage);
return {
status: 200,
body: message,
};
}
Service Bus-köutlösare
export async function serviceBusQueueTrigger(
message: unknown,
context: InvocationContext
): Promise<void> {
context.log("TypeScript ServiceBus Queue trigger start processing a message:", message);
// Simulate processing time
await new Promise((resolve) => setTimeout(resolve, 5000));
context.log("TypeScript ServiceBus Queue trigger end processing a message");
}
OpenTelemetry-konfigurationen konfigureras i src/OTelSample/Program.cs:
using Azure.Monitor.OpenTelemetry.Exporter;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.OpenTelemetry;
using OpenTelemetry.Trace;
var builder = FunctionsApplication.CreateBuilder(args);
builder.ConfigureFunctionsWebApplication();
builder.Logging.AddOpenTelemetry(logging =>
{
logging.IncludeFormattedMessage = true;
logging.IncludeScopes = true;
});
builder.Services.AddOpenTelemetry()
.WithTracing(tracing =>
{
tracing.AddHttpClientInstrumentation();
});
builder.Services.AddOpenTelemetry().UseAzureMonitorExporter();
builder.Services.AddOpenTelemetry().UseFunctionsWorkerDefaults();
builder.Services.AddHttpClient();
builder.Build().Run();
Funktionerna definieras i separata klassfiler:
Första HTTP-funktionen
public class FirstHttpTrigger
{
private readonly ILogger<FirstHttpTrigger> _logger;
private readonly IHttpClientFactory _httpClientFactory;
public FirstHttpTrigger(ILogger<FirstHttpTrigger> logger, IHttpClientFactory httpClientFactory)
{
_logger = logger;
_httpClientFactory = httpClientFactory;
}
[Function("first_http_function")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req)
{
_logger.LogInformation("first_http_function function processed a request.");
var baseUrl = $"{req.Url.AbsoluteUri.Split("/api/")[0]}/api";
var targetUri = $"{baseUrl}/second_http_function";
var client = _httpClientFactory.CreateClient();
var response = await client.GetAsync(targetUri);
var content = await response.Content.ReadAsStringAsync();
return new OkObjectResult($"Called second_http_function, status: {response.StatusCode}, content: {content}");
}
}
Andra HTTP-funktionen
public class SecondHttpTrigger
{
private readonly ILogger<SecondHttpTrigger> _logger;
public SecondHttpTrigger(ILogger<SecondHttpTrigger> logger)
{
_logger = logger;
}
[Function("second_http_function")]
public MultiResponse Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req)
{
_logger.LogInformation("second_http_function function processed a request.");
return new MultiResponse
{
Messages = new string[] { "Hello" },
HttpResponse = req.CreateResponse(System.Net.HttpStatusCode.OK)
};
}
}
public class MultiResponse
{
[ServiceBusOutput("%ServiceBusQueueName%", Connection = "ServiceBusConnection")]
public string[]? Messages { get; set; }
[HttpResult]
public HttpResponseData? HttpResponse { get; set; }
}
Service Bus-köutlösare
public class ServiceBusQueueTrigger
{
private readonly ILogger<ServiceBusQueueTrigger> _logger;
public ServiceBusQueueTrigger(ILogger<ServiceBusQueueTrigger> logger)
{
_logger = logger;
}
[Function("servicebus_queue_trigger")]
public async Task Run(
[ServiceBusTrigger("%ServiceBusQueueName%", Connection = "ServiceBusConnection")]
ServiceBusReceivedMessage message,
ServiceBusMessageActions messageActions)
{
_logger.LogInformation("Message ID: {id}", message.MessageId);
_logger.LogInformation("Message Body: {body}", message.Body);
// Complete the message
await messageActions.CompleteMessageAsync(message);
}
}
Distribuerat spårningsflöde
Den här arkitekturen skapar ett fullständigt distribuerat spårningsscenario med följande beteende:
- Den första HTTP-funktionen tar emot en HTTP-begäran och anropar den andra HTTP-funktionen
- Den andra HTTP-funktionen svarar och skickar ett meddelande till Service Bus
- Service Bus-utlösaren bearbetar meddelandet med en fördröjning för att simulera bearbetningsarbete
Viktiga aspekter av OpenTelemetry-implementeringen:
-
OpenTelemetry-integrering: Filen
host.jsonaktiverar OpenTelemetry med"telemetryMode": "OpenTelemetry" - Funktionslänkning: Den första funktionen anropar den andra med HJÄLP av HTTP-begäranden och skapar korrelerade spårningar
- Service Bus-integrering: Den andra funktionen skickar sitt resultat till Service Bus, vilket utlöser den tredje funktionen
-
Anonym autentisering: HTTP-funktionerna använder
auth_level=func.AuthLevel.ANONYMOUS, så inga funktionsnycklar krävs
Du kan granska hela mallprojektet här.
-
OpenTelemetry-integrering: Filen
index.tskonfigurerar OpenTelemetry med Azure Monitor-exportörer för spårningar och loggar - Funktionslänkning: Den första funktionen anropar den andra med axios med automatisk spårningsspridning
- Service Bus-integrering: Den andra funktionen skickar data till Service Bus genom utdatabindningar, vilket utlöser den tredje funktionen.
- Hanterad identitet: Alla Service Bus-anslutningar använder hanterad identitet i stället för anslutningssträngar
- Bearbetningssimulering: 5 sekunders fördröjning i Service Bus-utlösaren simulerar meddelandebearbetningsarbete
Du kan granska hela mallprojektet här.
-
OpenTelemetry-integrering: Filen
Program.cskonfigurerar OpenTelemetry med Azure Monitor-exportören - Funktionslänkning: Den första funktionen anropar den andra med hjälp av HttpClient med OpenTelemetry-instrumentation
- Service Bus-integrering: Den andra funktionen ger utdata till Service Bus med hjälp av utgångsbindningar, vilket utlöser den tredje funktionen
- Hanterad identitet: Alla Service Bus-anslutningar använder hanterad identitet i stället för anslutningssträngar
- .NET 8 Isolated Worker: Använder den senaste Azure Functions .NET Isolated Worker-modellen för bättre prestanda och flexibilitet
Du kan granska hela mallprojektet här.
När du har verifierat dina funktioner lokalt är det dags att publicera dem till Azure.
Distribuera till Azure
Det här projektet är konfigurerat för att använda azd up kommandot för att distribuera projektet till en ny funktionsapp i en Flex Consumption-plan i Azure med OpenTelemetry-stöd.
Tips/Råd
Det här projektet innehåller en uppsättning Bicep-filer som azd använder för att skapa en säker distribution till en Flex-förbrukningsplan som följer bästa praxis, inklusive hanterade identitetsanslutningar.
Kör det här kommandot för att
azdskapa nödvändiga Azure-resurser i Azure och distribuera kodprojektet till den nya funktionsappen:azd upRotmappen innehåller den
azure.yamldefinitionsfil som krävs avazd.Om du inte redan är inloggad uppmanas du att autentisera med ditt Azure-konto.
Ange följande nödvändiga distributionsparametrar när du uppmanas att göra det:
Parameter Description Azure-prenumeration Prenumeration där dina resurser skapas. Azure-lokalisering Azure-region där du kan skapa resursgruppen som innehåller de nya Azure-resurserna. Endast regioner som för närvarande stöder Flex Consumption-planen visas. Kommandot
azd upanvänder ditt svar på dessa frågor med Bicep-konfigurationsfilerna för att slutföra dessa distributionsuppgifter:Skapa och konfigurera de här nödvändiga Azure-resurserna (motsvarande
azd provision):- Azure Functions Flex Consumption Plan och funktionsapp med OpenTelemetry aktiverat
- Azure Storage (krävs) och Application Insights (rekommenderas)
- Service Bus-tjänstens namnrymd och kö för att demonstrera distribuerad spårning
- Åtkomstprinciper och roller för ditt konto
- Tjänst-till-tjänst-anslutningar med hanterade identiteter (i stället för lagrade anslutningssträng)
Paketera och distribuera koden till distributionscontainern (motsvarande
azd deploy). Appen startas sedan och körs i det distribuerade paketet.
När kommandot har slutförts visas länkar till de resurser som du har skapat.
Testa distribuerad spårning
Nu kan du testa funktionerna för distribuerad spårning i OpenTelemetry genom att anropa dina distribuerade funktioner och observera telemetrin i Application Insights.
Anropa funktionen på Azure
Du kan anropa funktionsslutpunkter i Azure genom att göra HTTP-begäranden till deras URL:er. Eftersom HTTP-funktionerna i den här mallen har konfigurerats med anonym åtkomst krävs inga funktionsnycklar.
I den lokala terminalen eller kommandotolken kör du det här kommandot för att hämta funktionsappens namn och konstruera URL:en:
APP_NAME=$(azd env get-value AZURE_FUNCTION_NAME) echo "Function URL: https://$APP_NAME.azurewebsites.net/api/first_http_function"Kommandot
azd env get-valuehämtar funktionsappens namn från den lokala miljön.Testa funktionen i webbläsaren genom att gå till URL:en:
https://your-function-app.azurewebsites.net/api/first_http_functionErsätt
your-function-appmed ditt faktiska funktionsappnamn från föregående steg. Den här enskilda begäran skapar en distribuerad spårning som flödar genom alla tre funktionerna.
Visa distribuerad spårning i Application Insights
När du har anropat funktionen kan du se den fullständiga distribuerade spårningen i Application Insights:
Anmärkning
Det kan ta några minuter innan telemetridata visas i Application Insights när funktionen har anropats. Om du inte ser data omedelbart väntar du några minuter och uppdaterar vyn.
Gå till din Application Insights-resurs i Azure-portalen (du hittar den i samma resursgrupp som funktionsappen).
Öppna programkartan för att se den distribuerade spårningen för alla tre funktionerna. Du bör se flödet från HTTP-begäran via dina funktioner och till Service Bus.
Kontrollera transaktionssökningen för att hitta din begäran och se den fullständiga tidslinjen för spårning. Sök efter transaktioner från funktionsappen.
Välj en specifik transaktion för att se spårningen från slutpunkt till slutpunkt som visar:
- HTTP-begäran till
first_http_function - Det interna HTTP-anropet till
second_http_function - Service Bus-meddelandet som skickas
- Bearbetningen av
servicebus_queue_triggermeddelandet från Service Bus
- HTTP-begäran till
I spårningsinformationen kan du se:
- Tidsinformation: Hur lång tid varje steg tog
- Beroenden: Anslutningarna mellan funktioner
- Loggar: Programloggar som är korrelerade med spårningen
- Prestandamått: Svarstider och dataflöde
Det här exemplet visar distribuerad spårning från slutpunkt till slutpunkt över flera Azure Functions med OpenTelemetry-integrering, vilket ger fullständig insyn i programmets beteende och prestanda.
Distribuera om koden
azd up Kör kommandot så många gånger du behöver både etablera dina Azure-resurser och distribuera koduppdateringar till funktionsappen.
Anmärkning
Det senaste distributionspaketet skriver alltid över distribuerade kodfiler.
Dina första svar på azd frågor och eventuella miljövariabler som genereras av azd lagras lokalt i din namngivna miljö.
azd env get-values Använd kommandot för att granska alla variabler i din miljö som kommandot använder när du skapar Azure-resurser.
Rensa resurser
När du är klar med funktionsappen och relaterade resurser använder du det här kommandot för att ta bort funktionsappen och dess relaterade resurser från Azure och undvika ytterligare kostnader:
azd down --no-prompt
Anmärkning
Alternativet --no-prompt instruerar azd dig att ta bort resursgruppen utan någon bekräftelse från dig.
Det här kommandot påverkar inte ditt lokala kodprojekt.