Udostępnij za pośrednictwem


Inspekcja danych telemetrycznych za pomocą usługi Application Insights

Usługa Application Insights jest częścią usługi Azure Monitor, która jest kompleksowym rozwiązaniem do zbierania, analizowania i działania na danych telemetrycznych ze środowisk chmurowych i lokalnych. Usługa Application Insights umożliwia monitorowanie wydajności aplikacji, wykrywanie problemów i diagnozowanie problemów.

W tym przykładzie dowiesz się, jak wyeksportować dane telemetryczne do usługi Application Insights i sprawdzić dane w portalu usługi Application Insights.

Eksporter

Eksporterzy są odpowiedzialni za wysyłanie danych telemetrycznych do miejsca docelowego. Przeczytaj więcej na temat eksporterów tutaj. W tym przykładzie używamy eksportera usługi Azure Monitor do wyprowadzania danych telemetrycznych do wystąpienia usługi Application Insights.

Wymagania wstępne

  • Wdrożenie uzupełniania czatu usługi Azure OpenAI.
  • Wystąpienie usługi Application Insights. Postępuj zgodnie z instrukcjami podanymi tutaj, aby utworzyć zasób, jeśli go nie masz. Skopiuj parametry połączenia do późniejszego użycia.
  • Najnowszy zestaw .Net SDK dla systemu operacyjnego.

Uwaga

Możliwość obserwowania jądra semantycznego nie jest jeszcze dostępna dla języka Java.

Ustawienia

Tworzenie nowej aplikacji konsolowej

W terminalu uruchom następujące polecenie, aby utworzyć nową aplikację konsolową w języku C#:

dotnet new console -n TelemetryApplicationInsightsQuickstart

Przejdź do nowo utworzonego katalogu projektu po zakończeniu wykonywania polecenia.

Instalowanie wymaganych pakietów

  • Jądro semantyczne

    dotnet add package Microsoft.SemanticKernel
    
  • Eksporter konsoli OpenTelemetry

    dotnet add package Azure.Monitor.OpenTelemetry.Exporter
    

Tworzenie prostej aplikacji za pomocą jądra semantycznego

W katalogu projektu otwórz plik za pomocą ulubionego Program.cs edytora. Utworzymy prostą aplikację, która używa jądra semantycznego do wysyłania monitu do modelu uzupełniania czatu. Zastąp istniejącą zawartość następującym kodem i wypełnij wymagane wartości dla deploymentName, endpointi apiKey:

using Azure.Monitor.OpenTelemetry.Exporter;

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.SemanticKernel;
using OpenTelemetry;
using OpenTelemetry.Logs;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;

namespace TelemetryApplicationInsightsQuickstart
{
    class Program
    {
        static async Task Main(string[] args)
        {
            // Telemetry setup code goes here

            IKernelBuilder builder = Kernel.CreateBuilder();
            // builder.Services.AddSingleton(loggerFactory);
            builder.AddAzureOpenAIChatCompletion(
                deploymentName: "your-deployment-name",
                endpoint: "your-azure-openai-endpoint",
                apiKey: "your-azure-openai-api-key"
            );

            Kernel kernel = builder.Build();

            var answer = await kernel.InvokePromptAsync(
                "Why is the sky blue in one sentence?"
            );

            Console.WriteLine(answer);
        }
    }
}

Dodawanie telemetrii

Jeśli teraz uruchomisz aplikację konsolową, należy oczekiwać zdania wyjaśniającego, dlaczego niebo jest niebieskie. Aby obserwować jądro za pośrednictwem telemetrii, zastąp // Telemetry setup code goes here komentarz następującym kodem:

// Replace the connection string with your Application Insights connection string
var connectionString = "your-application-insights-connection-string";

var resourceBuilder = ResourceBuilder
    .CreateDefault()
    .AddService("TelemetryApplicationInsightsQuickstart");

// Enable model diagnostics with sensitive data.
AppContext.SetSwitch("Microsoft.SemanticKernel.Experimental.GenAI.EnableOTelDiagnosticsSensitive", true);

using var traceProvider = Sdk.CreateTracerProviderBuilder()
    .SetResourceBuilder(resourceBuilder)
    .AddSource("Microsoft.SemanticKernel*")
    .AddAzureMonitorTraceExporter(options => options.ConnectionString = connectionString)
    .Build();

using var meterProvider = Sdk.CreateMeterProviderBuilder()
    .SetResourceBuilder(resourceBuilder)
    .AddMeter("Microsoft.SemanticKernel*")
    .AddAzureMonitorMetricExporter(options => options.ConnectionString = connectionString)
    .Build();

using var loggerFactory = LoggerFactory.Create(builder =>
{
    // Add OpenTelemetry as a logging provider
    builder.AddOpenTelemetry(options =>
    {
        options.SetResourceBuilder(resourceBuilder);
        options.AddAzureMonitorLogExporter(options => options.ConnectionString = connectionString);
        // Format log messages. This is default to false.
        options.IncludeFormattedMessage = true;
        options.IncludeScopes = true;
    });
    builder.SetMinimumLevel(LogLevel.Information);
});

Na koniec usuń komentarz z wiersza // builder.Services.AddSingleton(loggerFactory); , aby dodać fabrykę rejestratora do konstruktora.

Aby uzyskać więcej informacji na temat kodu konfiguracji telemetrii, zapoznaj się z tym artykułem . Jedyną różnicą jest to, że używamy AddAzureMonitor[Trace|Metric|Log]Exporter do eksportowania danych telemetrycznych do usługi Application Insights.

Tworzenie nowego środowiska wirtualnego języka Python

python -m venv telemetry-application-insights-quickstart

Aktywuj środowisko wirtualne.

telemetry-application-insights-quickstart\Scripts\activate

Instalowanie wymaganych pakietów

pip install semantic-kernel azure-monitor-opentelemetry-exporter

Tworzenie prostego skryptu języka Python za pomocą jądra semantycznego

Utwórz nowy skrypt języka Python i otwórz go za pomocą ulubionego edytora.

New-Item -Path telemetry_application_insights_quickstart.py -ItemType file

Utworzymy prosty skrypt języka Python, który używa jądra semantycznego do wysyłania monitu do modelu uzupełniania czatu. Zastąp istniejącą zawartość następującym kodem i wypełnij wymagane wartości dla deployment_name, endpointi api_key:

import asyncio
import logging

from azure.monitor.opentelemetry.exporter import (
    AzureMonitorLogExporter,
    AzureMonitorMetricExporter,
    AzureMonitorTraceExporter,
)

from opentelemetry._logs import set_logger_provider
from opentelemetry.metrics import set_meter_provider
from opentelemetry.sdk._logs import LoggerProvider, LoggingHandler
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
from opentelemetry.sdk.metrics.view import DropAggregation, View
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.semconv.resource import ResourceAttributes
from opentelemetry.trace import set_tracer_provider

from semantic_kernel import Kernel
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion


# Telemetry setup code goes here

async def main():
    # Create a kernel and add a service
    kernel = Kernel()
    kernel.add_service(AzureChatCompletion(
        api_key="your-azure-openai-api-key",
        endpoint="your-azure-openai-endpoint",
        deployment_name="your-deployment-name"
    ))

    answer = await kernel.invoke_prompt("Why is the sky blue in one sentence?")
    print(answer)


if __name__ == "__main__":
    asyncio.run(main())

Dodawanie telemetrii

Zmienne środowiskowe

Zapoznaj się z tym artykułem , aby uzyskać więcej informacji na temat konfigurowania wymaganych zmiennych środowiskowych, aby umożliwić jądro emitowania zakresów dla łączników sztucznej inteligencji.

Kod

Jeśli teraz uruchomisz skrypt, należy oczekiwać zdania wyjaśniającego, dlaczego niebo jest niebieskie. Aby obserwować jądro za pośrednictwem telemetrii, zastąp # Telemetry setup code goes here komentarz następującym kodem:

# Replace the connection string with your Application Insights connection string
connection_string = "your-application-insights-connection-string"

# Create a resource to represent the service/sample
resource = Resource.create({ResourceAttributes.SERVICE_NAME: "telemetry-application-insights-quickstart"})


def set_up_logging():
    exporter = AzureMonitorLogExporter(connection_string=connection_string)

    # Create and set a global logger provider for the application.
    logger_provider = LoggerProvider(resource=resource)
    # Log processors are initialized with an exporter which is responsible
    # for sending the telemetry data to a particular backend.
    logger_provider.add_log_record_processor(BatchLogRecordProcessor(exporter))
    # Sets the global default logger provider
    set_logger_provider(logger_provider)

    # Create a logging handler to write logging records, in OTLP format, to the exporter.
    handler = LoggingHandler()
    # Add filters to the handler to only process records from semantic_kernel.
    handler.addFilter(logging.Filter("semantic_kernel"))
    # Attach the handler to the root logger. `getLogger()` with no arguments returns the root logger.
    # Events from all child loggers will be processed by this handler.
    logger = logging.getLogger()
    logger.addHandler(handler)
    logger.setLevel(logging.INFO)


def set_up_tracing():
    exporter = AzureMonitorTraceExporter(connection_string=connection_string)

    # Initialize a trace provider for the application. This is a factory for creating tracers.
    tracer_provider = TracerProvider(resource=resource)
    # Span processors are initialized with an exporter which is responsible
    # for sending the telemetry data to a particular backend.
    tracer_provider.add_span_processor(BatchSpanProcessor(exporter))
    # Sets the global default tracer provider
    set_tracer_provider(tracer_provider)


def set_up_metrics():
    exporter = AzureMonitorMetricExporter(connection_string=connection_string)

    # Initialize a metric provider for the application. This is a factory for creating meters.
    meter_provider = MeterProvider(
        metric_readers=[PeriodicExportingMetricReader(exporter, export_interval_millis=5000)],
        resource=resource,
        views=[
            # Dropping all instrument names except for those starting with "semantic_kernel"
            View(instrument_name="*", aggregation=DropAggregation()),
            View(instrument_name="semantic_kernel*"),
        ],
    )
    # Sets the global default meter provider
    set_meter_provider(meter_provider)


# This must be done before any other telemetry calls
set_up_logging()
set_up_tracing()
set_up_metrics()

Aby uzyskać więcej informacji na temat kodu konfiguracji telemetrii, zapoznaj się z tym artykułem . Jedyną różnicą jest to, że używamy AzureMonitor[Trace|Metric|Log]Exporter do eksportowania danych telemetrycznych do usługi Application Insights.

Uwaga

Możliwość obserwowania jądra semantycznego nie jest jeszcze dostępna dla języka Java.

Uruchom

Uruchom aplikację konsolową za pomocą następującego polecenia:

dotnet run

Uruchom skrypt języka Python za pomocą następującego polecenia:

python telemetry_application_insights_quickstart.py

Uwaga

Możliwość obserwowania jądra semantycznego nie jest jeszcze dostępna dla języka Java.

Inspekcja danych telemetrycznych

Po uruchomieniu aplikacji przejdź do portalu usługi Application Insights, aby sprawdzić dane telemetryczne. Wyświetlenie danych w portalu może potrwać kilka minut.

Przejdź do karty Wyszukiwanie transakcji, aby wyświetlić zarejestrowane transakcje.

Panel po lewej stronie usługi AppInsights

Naciśnij pozycję Odśwież, aby wyświetlić najnowsze transakcje. Po wyświetleniu wyników kliknij jeden z nich, aby wyświetlić więcej szczegółów.

Wyszukiwanie transakcji w usłudze AppInsights

Przełącz się między przyciskiem Wyświetl wszystko i Wyświetl oś czasu , aby wyświetlić wszystkie ślady i zależności transakcji w różnych widokach.

Ważne

Ślady reprezentują tradycyjne wpisy dziennika i zdarzenia typu OpenTelemetry span. Nie są one takie same jak rozproszone ślady. Zależności reprezentują wywołania składników (wewnętrznych i zewnętrznych). Aby uzyskać więcej informacji na temat modelu danych w usłudze Application Insights, zapoznaj się z tym artykułem .

W tym konkretnym przykładzie powinny zostać wyświetlone dwie zależności i wiele śladów. Pierwsza zależność reprezentuje funkcję jądra utworzoną na podstawie monitu. Druga zależność reprezentuje wywołanie modelu uzupełniania czatu usługi Azure OpenAI. Po rozwinięciu chat.completion {your-deployment-name} zależności powinny zostać wyświetlone szczegóły wywołania. Zestaw atrybutów gen_ai jest dołączony do zależności, co zapewnia dodatkowy kontekst dotyczący wywołania.

Atrybuty genai

Microsoft.SemanticKernel.Experimental.GenAI.EnableOTelDiagnosticsSensitive Jeśli masz przełącznik ustawiony na true, zobaczysz również dwa ślady, które zawierają poufne dane monitu i wynik ukończenia.

Atrybuty poufne genai

Kliknij je i zobaczysz monit i wynik ukończenia w sekcji właściwości niestandardowych.

Jeśli masz zmienną środowiskową SEMANTICKERNEL_EXPERIMENTAL_GENAI_ENABLE_OTEL_DIAGNOSTICS_SENSITIVE ustawioną na true, zobaczysz również dwa ślady, które zawierają poufne dane monitu i wynik ukończenia.

Atrybuty poufne genai

Kliknij je i zobaczysz monit i wynik ukończenia w sekcji właściwości niestandardowych.

Analiza dziennika

Wyszukiwanie transakcji nie jest jedynym sposobem inspekcji danych telemetrycznych. Możesz również użyć usługi Log Analytics do wykonywania zapytań i analizowania danych. Przejdź do obszaru Dzienniki w obszarze Monitorowanie, aby rozpocząć.

Postępuj zgodnie z tym dokumentem , aby rozpocząć eksplorowanie interfejsu usługi Log Analytics.

Poniżej przedstawiono kilka przykładowych zapytań, których można użyć w tym przykładzie:

// Retrieves the total number of completion and prompt tokens used for the model if you run the application multiple times.
dependencies
| where name startswith "chat"
| project model = customDimensions["gen_ai.request.model"], completion_token = toint(customDimensions["gen_ai.response.completion_tokens"]), prompt_token = toint(customDimensions["gen_ai.response.prompt_tokens"])
| where model == "gpt-4o"
| project completion_token, prompt_token
| summarize total_completion_tokens = sum(completion_token), total_prompt_tokens = sum(prompt_token)
// Retrieves all the prompts and completions and their corresponding token usage.
dependencies
| where name startswith "chat"
| project timestamp, operation_Id, name, completion_token = customDimensions["gen_ai.response.completion_tokens"], prompt_token = customDimensions["gen_ai.response.prompt_tokens"]
| join traces on operation_Id
| where message startswith "gen_ai"
|project timestamp, messages = customDimensions, token=iff(customDimensions contains "gen_ai.prompt", prompt_token, completion_token)

Wynik zapytania

Następne kroki

Teraz, gdy dane telemetryczne zostały pomyślnie wyjściowe do usługi Application Insights, możesz zapoznać się z bardziej funkcjami jądra semantycznego, które mogą ułatwić monitorowanie i diagnozowanie aplikacji: