使用 Application Insights 检查遥测数据

Application Insights 是 Azure Monitor一部分,它是一种全面的解决方案,用于从云和本地环境收集、分析和处理遥测数据。 借助 Application Insights,可以监视应用程序的性能、检测问题和诊断问题。

在此示例中,我们将了解如何将遥测数据导出到 Application Insights,并在 Application Insights 门户中检查数据。

警告

语义内核利用称为键式服务的 .NET 8 功能。 Application Insights 与服务注册存在问题,使其与密钥服务不兼容。 如果将语义内核与键式服务配合使用并遇到与 Application Insights 依赖项注入相关的意外错误,则应在任何关键服务之前注册 Application Insights 以解决此问题。 有关详细信息,请参阅 microsoft/ApplicationInsights-dotnet#2879

出口商

导出程序负责将遥测数据发送到目标。 在此处阅读有关出口商的详细信息。 在此示例中,我们使用 Azure Monitor 导出程序将遥测数据输出到 Application Insights 实例。

先决条件

注意

语义内核可观测性尚不适用于 Java。

安装

创建新的控制台应用程序

在终端中运行以下命令,在 C# 中创建新的控制台应用程序:

dotnet new console -n TelemetryApplicationInsightsQuickstart

命令完成后,导航到新创建的项目目录。

安装所需程序包

  • 语义内核

    dotnet add package Microsoft.SemanticKernel
    
  • OpenTelemetry 控制台导出程序

    dotnet add package Azure.Monitor.OpenTelemetry.Exporter
    

使用语义内核创建简单应用程序

从项目目录中,使用你喜欢的编辑器打开 Program.cs 该文件。 我们将创建一个简单的应用程序,该应用程序使用语义内核向聊天完成模型发送提示。 将现有内容替换为以下代码,并填写所需的值 deploymentNameendpoint以及 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);
        }
    }
}

添加遥测

如果现在运行控制台应用,应该会看到一句话,说明天空为何为蓝色。 若要通过遥测观察内核,请将 // Telemetry setup code goes here 注释替换为以下代码:

// 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);
});

最后取消注释要向生成器添加记录器工厂的行 // builder.Services.AddSingleton(loggerFactory);

有关遥测设置代码的详细信息,请参阅本文。 此处的唯一区别在于,我们用于 AddAzureMonitor[Trace|Metric|Log]Exporter 将遥测数据导出到 Application Insights。

创建新的 Python 虚拟环境

python -m venv telemetry-application-insights-quickstart

激活虚拟环境。

telemetry-application-insights-quickstart\Scripts\activate

安装所需程序包

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

使用语义内核创建简单的 Python 脚本

创建新的 Python 脚本,并使用你喜欢的编辑器打开它。

New-Item -Path telemetry_application_insights_quickstart.py -ItemType file

我们将创建一个简单的 Python 脚本,该脚本使用语义内核向聊天完成模型发送提示。 将现有内容替换为以下代码,并填写所需的值 deployment_nameendpoint以及 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())

添加遥测

环境变量

有关设置所需环境变量以使内核能够发出 AI 连接器跨度的详细信息,请参阅本文

代码

如果现在运行该脚本,应该会看到一个句子,说明天空为何为蓝色。 若要通过遥测观察内核,请将 # Telemetry setup code goes here 注释替换为以下代码:

# 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()

有关遥测设置代码的详细信息,请参阅本文。 此处的唯一区别在于,我们用于 AzureMonitor[Trace|Metric|Log]Exporter 将遥测数据导出到 Application Insights。

注意

语义内核可观测性尚不适用于 Java。

运行

使用以下命令运行控制台应用程序:

dotnet run

使用以下命令运行 Python 脚本:

python telemetry_application_insights_quickstart.py

注意

语义内核可观测性尚不适用于 Java。

检查遥测数据

运行应用程序后,转到 Application Insights 门户,检查遥测数据。 数据可能需要几分钟才会显示在门户中。

导航到 “事务搜索 ”选项卡,查看已记录的事务。

AppInsights 左面板

点击刷新可查看最新事务。 当结果出现时,单击其中一个可查看更多详细信息。

AppInsights 事务搜索

“查看所有视图 ”和 “查看时间线 ”按钮之间切换,以查看不同视图中事务的所有跟踪和依赖项。

重要

跟踪表示传统的日志条目和 OpenTelemetry 跨事件。 它们与分布式跟踪不同。 依赖项表示对(内部和外部)组件的调用。 有关 Application Insights 中的数据模型的详细信息,请参阅本文

对于此特定示例,应会看到两个依赖项和多个跟踪。 第一个依赖项表示从提示创建的内核函数。 第二个依赖项表示对 Azure OpenAI 聊天完成模型的调用。 展开 chat.completion {your-deployment-name} 依赖项时,应会看到调用的详细信息。 一组 gen_ai 属性附加到依赖项,该依赖项提供有关调用的其他上下文。

GenAI 属性

如果已将Microsoft.SemanticKernel.Experimental.GenAI.EnableOTelDiagnosticsSensitive开关true设置为,则还会看到两个跟踪,其中包含提示的敏感数据和完成结果。

GenAI 敏感属性

单击它们,你将在自定义属性部分下看到提示和完成结果。

如果已将SEMANTICKERNEL_EXPERIMENTAL_GENAI_ENABLE_OTEL_DIAGNOSTICS_SENSITIVE环境变量true设置为“,则还会看到两个跟踪,其中包含提示的敏感数据和完成结果。

GenAI 敏感属性

单击它们,你将在自定义属性部分下看到提示和完成结果。

Log Analytics

事务搜索并不是检查遥测数据的唯一方法。 还可以使用 Log Analytics 来查询和分析数据。 导航到“监视下的日志以启动。

按照本文档开始浏览 Log Analytics 接口。

下面是可用于此示例的一些示例查询:

// 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)

查询结果

后续步骤

成功将遥测数据输出到 Application Insights 后,可以探索语义内核的更多功能,以帮助监视和诊断应用程序: