Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
In dit artikel wordt ondersteuning voor OpenTelemetry in Azure Function gedemonstreerd, waardoor gedistribueerde tracering mogelijk is voor meerdere functieaanroepen met behulp van geïntegreerde ondersteuning voor Application Insights en OpenTelemetry. Om u te helpen aan de slag te gaan, wordt een Azure Developer CLI-sjabloon (azd) gebruikt om uw codeproject te maken, evenals de Azure-implementatie waarin u uw app kunt uitvoeren.
In deze zelfstudie gebruikt u de azd tool om:
- Initialiseer een project met OpenTelemetry op basis van een sjabloon.
- Controleer de code waarmee OpenTelemetry-integratie mogelijk is.
- Voer uw OpenTelemetry-compatibele app lokaal uit en verifieer deze.
- Maak een functie-app en gerelateerde resources in Azure.
- Implementeer uw codeproject in de functie-app in Azure.
- Gedistribueerde tracering controleren in Application Insights.
De vereiste Azure-resources die met deze sjabloon zijn gemaakt, volgen de huidige aanbevolen procedures voor veilige en schaalbare functie-app-implementaties in Azure. Met dezelfde azd opdracht wordt ook uw codeproject geïmplementeerd in uw nieuwe functie-app in Azure.
Het Flex Consumption-abonnement volgt standaard een factureringsmodel met betalen voor wat u gebruikt . Dit betekent dat voor het voltooien van deze quickstart een kleine kosten van een paar cent of minder in uw Azure-account in rekening worden gebracht.
Belangrijk
Dit artikel ondersteunt momenteel alleen C#, Python en TypeScript. Als u de quickstart wilt voltooien, selecteert u een van deze ondersteunde talen bovenaan het artikel.
Vereiste voorwaarden
Een Azure-account met een actief abonnement. Gratis een account maken
Het project initialiseren
Gebruik de azd init opdracht om een lokaal Azure Functions-codeproject te maken op basis van een sjabloon met gedistribueerde OpenTelemetry-tracering.
Voer in uw lokale terminal of opdrachtprompt deze
azd initopdracht uit in een lege map:azd init --template functions-quickstart-python-azd-otel -e flexquickstart-otelMet deze opdracht worden de projectbestanden opgehaald uit de sjabloonopslagplaats en wordt het project in de huidige map geïnitialiseerd. Met
-ede vlag wordt een naam ingesteld voor de huidige omgeving. Inazdde omgeving wordt een unieke implementatiecontext voor uw app onderhouden en kunt u meer dan één definiëren. De omgevingsnaam wordt ook weergegeven in de naam van de resourcegroep die u in Azure maakt.
Voer in uw lokale terminal of opdrachtprompt deze
azd initopdracht uit in een lege map:azd init --template functions-quickstart-typescript-azd-otel -e flexquickstart-otelMet deze opdracht worden de projectbestanden opgehaald uit de sjabloonopslagplaats en wordt het project in de huidige map geïnitialiseerd. Met
-ede vlag wordt een naam ingesteld voor de huidige omgeving. Inazdde omgeving wordt een unieke implementatiecontext voor uw app onderhouden en kunt u meer dan één definiëren. De omgevingsnaam wordt ook weergegeven in de naam van de resourcegroep die u in Azure maakt.
Voer in uw lokale terminal of opdrachtprompt deze
azd initopdracht uit in een lege map:azd init --template functions-quickstart-dotnet-azd-otel -e flexquickstart-otelMet deze opdracht worden de projectbestanden opgehaald uit de sjabloonopslagplaats en wordt het project in de huidige map geïnitialiseerd. Met
-ede vlag wordt een naam ingesteld voor de huidige omgeving. Inazdde omgeving wordt een unieke implementatiecontext voor uw app onderhouden en kunt u meer dan één definiëren. De omgevingsnaam wordt ook weergegeven in de naam van de resourcegroep die u in Azure maakt.
De code bekijken
De sjabloon maakt een volledig scenario voor gedistribueerde tracering met drie functies die samenwerken. Laten we de belangrijkste aspecten van OpenTelemetry bekijken:
Configuratie van OpenTelemetry
Het src/otel-sample/host.json bestand schakelt OpenTelemetry in voor de Functions-host:
{
"version": "2.0",
"telemetryMode": "OpenTelemetry",
"extensions": {
"serviceBus": {
"maxConcurrentCalls": 10
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[4.*, 5.0.0)"
}
}
Met de sleutelinstelling "telemetryMode": "OpenTelemetry" kunt u gedistribueerde tracering tussen functieoproepen inschakelen.
Het src/OTelSample/host.json bestand schakelt OpenTelemetry in voor de Functions-host:
{
"version": "2.0",
"telemetryMode": "OpenTelemetry",
"logging": {
"OpenTelemetry": {
"logLevel": {
"Host.General": "Warning"
}
}
}
}
Met de sleutelinstelling "telemetryMode": "OpenTelemetry" kunt u gedistribueerde tracering tussen functieoproepen inschakelen.
Afhankelijkheden voor OpenTelemetry
Het src/otel-sample/requirements.txt bestand bevat de benodigde pakketten voor OpenTelemetry-integratie:
azure-functions
azure-monitor-opentelemetry
requests
Het azure-monitor-opentelemetry pakket biedt de OpenTelemetry-integratie met Application Insights.
Het src/otel-sample/package.json bestand bevat de benodigde pakketten voor OpenTelemetry-integratie:
{
"dependencies": {
"@azure/functions": "^4.0.0",
"@azure/functions-opentelemetry-instrumentation": "^0.1.0",
"@azure/monitor-opentelemetry-exporter": "^1.0.0",
"axios": "^1.6.0"
}
}
De @azure/functions-opentelemetry-instrumentation en @azure/monitor-opentelemetry-exporter pakketten bieden de OpenTelemetry-integratie met Application Insights.
Het .csproj bestand bevat de benodigde pakketten voor OpenTelemetry-integratie:
<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" />
Deze pakketten bieden de Integratie van OpenTelemetry met Application Insights en HTTP-instrumentatie voor gedistribueerde tracering.
Functie-implementatie
De functies in src/otel-sample/function_app.py demonstreren een gedistribueerde traceringsstroom.
Eerste HTTP-functie
@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"
)
Tweede HTTP-functie
@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-wachtrijtrigger
@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')
De Configuratie van OpenTelemetry is ingesteld in 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()],
});
De functies worden gedefinieerd in de src/otel-sample/src/functions folder.
Eerste HTTP-functie
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" }),
};
}
}
Tweede HTTP-functie
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-wachtrijtrigger
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");
}
De Configuratie van OpenTelemetry is ingesteld in 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();
De functies worden gedefinieerd in afzonderlijke klassebestanden:
Eerste HTTP-functie
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}");
}
}
Tweede HTTP-functie
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-wachtrijtrigger
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);
}
}
Gedistribueerde traceringsstroom
Deze architectuur maakt een volledig scenario voor gedistribueerde tracering, met dit gedrag:
- De eerste HTTP-functie ontvangt een HTTP-aanvraag en roept de tweede HTTP-functie aan
- De tweede HTTP-functie reageert en verzendt een bericht naar Service Bus
- De Service Bus-trigger verwerkt het bericht met een vertraging om het verwerkingswerk te simuleren
Belangrijke aspecten van de OpenTelemetry-implementatie:
-
Integratie van OpenTelemetry: Het
host.jsonbestand schakelt OpenTelemetry in met"telemetryMode": "OpenTelemetry" - Functiekoppeling: De eerste functie roept de tweede aan met behulp van HTTP-aanvragen, waardoor gecorreleerde traceringen worden gemaakt
- Service Bus-integratie: de tweede functie wordt uitgevoerd naar Service Bus, waarmee de derde functie wordt geactiveerd
-
Anonieme verificatie: de HTTP-functies gebruiken
auth_level=func.AuthLevel.ANONYMOUS, dus er zijn geen functiesleutels vereist
U kunt hier het volledige sjabloonproject bekijken.
-
OpenTelemetry-integratie: Het
index.tsbestand configureert OpenTelemetry met Azure Monitor-exporteurs voor traceringen en logboeken - Functiekoppeling: De eerste functie roept de tweede aan met axios met automatische tracepropagatie
- Service Bus-integratie: De tweede functie voert uit naar Service Bus met behulp van uitvoerbindingen, waarmee de derde functie wordt geactiveerd
- Beheerde identiteit: alle Service Bus-verbindingen gebruiken beheerde identiteit in plaats van verbindingsreeksen
- Verwerkingssimulatie: De vertraging van 5 seconden in de Service Bus-trigger simuleert het verwerken van berichten
U kunt hier het volledige sjabloonproject bekijken.
-
Integratie van OpenTelemetry: Het
Program.csbestand configureert OpenTelemetry met Azure Monitor-exporteur - Functiekoppeling: De eerste functie roept de tweede aan met behulp van HttpClient met OpenTelemetry-instrumentatie
- Service Bus-integratie: De tweede functie voert uit naar Service Bus met behulp van uitvoerbindingen, waarmee de derde functie wordt geactiveerd
- Beheerde identiteit: alle Service Bus-verbindingen gebruiken beheerde identiteit in plaats van verbindingsreeksen
- .NET 8 Isolated Worker: maakt gebruik van het nieuwste Azure Functions .NET Isolated Worker-model voor betere prestaties en flexibiliteit
U kunt hier het volledige sjabloonproject bekijken.
Nadat u uw functies lokaal hebt gecontroleerd, is het tijd om ze te publiceren naar Azure.
Implementeren in Azure
Dit project is geconfigureerd voor het gebruik van de azd up opdracht om dit project te implementeren in een nieuwe functie-app in een Flex Consumption-abonnement in Azure met ondersteuning voor OpenTelemetry.
Aanbeveling
Dit project bevat een set Bicep-bestanden die azd wordt gebruikt om een veilige implementatie te maken voor een Flex-verbruiksplan dat de aanbevolen procedures volgt, waaronder beheerde identiteitsverbindingen.
Voer deze opdracht uit om de vereiste Azure-resources in Azure te maken
azden uw codeproject te implementeren in de nieuwe functie-app:azd upDe hoofdmap bevat het
azure.yamldefinitiebestand dat vereist is voorazd.Als u nog niet bent aangemeld, wordt u gevraagd om u te verifiëren met uw Azure-account.
Geef de volgende vereiste implementatieparameters op wanneer u hierom wordt gevraagd:
Kenmerk Description Azure-abonnement Abonnement waarin uw resources worden gemaakt. Azure-locatie Azure-regio waarin de resourcegroep wordt gemaakt die de nieuwe Azure-resources bevat. Alleen regio's die momenteel ondersteuning bieden voor het Flex Consumption-abonnement, worden weergegeven. De
azd upopdracht gebruikt uw reactie op deze prompts met de Bicep-configuratiebestanden om deze implementatietaken te voltooien:Maak en configureer deze vereiste Azure-resources (equivalent aan
azd provision):- Azure Functions Flex Consumption-abonnement en functie-app waarvoor OpenTelemetry is ingeschakeld
- Azure Storage (vereist) en Application Insights (aanbevolen)
- Service Bus-naamruimte en -wachtrij voor demonstratie van gedistribueerde tracering
- Toegangsbeleid en rollen voor uw account
- Service-naar-service-verbindingen met behulp van beheerde identiteiten (in plaats van opgeslagen verbindingsreeks s)
Verpakt en implementeer uw code in de implementatiecontainer (equivalent aan
azd deploy). De app wordt vervolgens gestart en uitgevoerd in het geïmplementeerde pakket.
Nadat de opdracht is voltooid, ziet u koppelingen naar de resources die u hebt gemaakt.
Gedistribueerde tracering testen
U kunt nu de gedistribueerde traceringsfunctionaliteit van OpenTelemetry testen door uw geïmplementeerde functies aan te roepen en de telemetrie in Application Insights te observeren.
De functie aanroepen in Azure
U kunt uw functie-eindpunten in Azure aanroepen door HTTP-aanvragen naar hun URL's te verzenden. Omdat de HTTP-functies in deze sjabloon zijn geconfigureerd met anonieme toegang, zijn er geen functiesleutels vereist.
Voer in uw lokale terminal of opdrachtprompt deze opdracht uit om de naam van de functie-app op te halen en de URL samen te stellen:
APP_NAME=$(azd env get-value AZURE_FUNCTION_NAME) echo "Function URL: https://$APP_NAME.azurewebsites.net/api/first_http_function"Met
azd env get-valuede opdracht wordt de naam van uw functie-app opgehaald uit de lokale omgeving.Test de functie in uw browser door naar de URL te navigeren:
https://your-function-app.azurewebsites.net/api/first_http_functionVervang door
your-function-appde naam van uw werkelijke functie-app uit de vorige stap. Met deze enkele aanvraag maakt u een gedistribueerde tracering die door alle drie de functies loopt.
Gedistribueerde tracering weergeven in Application Insights
Nadat u de functie hebt aangeroepen, kunt u de volledige gedistribueerde tracering in Application Insights bekijken:
Opmerking
Het kan enkele minuten duren voordat telemetriegegevens worden weergegeven in Application Insights nadat u uw functie hebt aangeroepen. Als u geen gegevens onmiddellijk ziet, wacht u enkele minuten en vernieuwt u de weergave.
Ga naar uw Application Insights-resource in Azure Portal (u vindt deze in dezelfde resourcegroep als uw functie-app).
Open het toepassingsoverzicht om de gedistribueerde tracering over alle drie de functies weer te geven. U ziet nu de stroom van de HTTP-aanvraag via uw functies en naar Service Bus.
Controleer de transactiezoekopdracht om uw aanvraag te vinden en bekijk de volledige traceringstijdlijn. Zoek naar transacties vanuit uw functie-app.
Selecteer een specifieke transactie om de end-to-end trace weer te geven waarin het volgende wordt weergegeven:
- De HTTP-aanvraag voor
first_http_function - De interne HTTP-aanroep naar
second_http_function - Het Service Bus-bericht dat wordt verzonden
- Het
servicebus_queue_triggerbericht verwerken vanuit Service Bus
- De HTTP-aanvraag voor
In de traceringsgegevens ziet u het volgende:
- Timinginformatie: Hoe lang elke stap duurde
- Afhankelijkheden: De verbindingen tussen functies
- Logboeken: Toepassingslogboeken die zijn gecorreleerd met de tracering
- Metrische prestatiegegevens: reactietijden en doorvoer
In dit voorbeeld ziet u end-to-end gedistribueerde tracering in meerdere Azure Functions met OpenTelemetry-integratie, waardoor u volledig inzicht verleent in het gedrag en de prestaties van uw toepassing.
Uw code opnieuw implementeren
Voer de azd up opdracht zo vaak uit als nodig is om uw Azure-resources in te richten en code-updates te implementeren voor uw functie-app.
Opmerking
Met het meest recente implementatiepakket worden geïmplementeerde codebestanden altijd overschreven.
Uw eerste antwoorden op azd prompts en eventuele omgevingsvariabelen die worden azd gegenereerd, worden lokaal opgeslagen in uw benoemde omgeving. Gebruik de azd env get-values opdracht om alle variabelen in uw omgeving te controleren die door de opdracht worden gebruikt bij het maken van Azure-resources.
De hulpbronnen opschonen
Wanneer u klaar bent met het werken met uw functie-app en gerelateerde resources, gebruikt u deze opdracht om de functie-app en de bijbehorende resources uit Azure te verwijderen en te voorkomen dat er verdere kosten in rekening worden gebracht:
azd down --no-prompt
Opmerking
Met de --no-prompt optie krijgt u de opdracht azd om uw resourcegroep te verwijderen zonder een bevestiging van u.
Deze opdracht heeft geen invloed op uw lokale codeproject.