使用 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 实例。
先决条件
- Azure OpenAI 聊天完成部署。
- Application Insights 实例。 按照此处的说明创建资源(如果没有)。 复制连接字符串以供以后使用。
- 计算机上安装了 Python 3.10、3.11 或 3.12 。
注意
语义内核可观测性尚不适用于 Java。
安装
创建新的控制台应用程序
在终端中运行以下命令,在 C# 中创建新的控制台应用程序:
dotnet new console -n TelemetryApplicationInsightsQuickstart
命令完成后,导航到新创建的项目目录。
安装所需程序包
语义内核
dotnet add package Microsoft.SemanticKernel
OpenTelemetry 控制台导出程序
dotnet add package Azure.Monitor.OpenTelemetry.Exporter
使用语义内核创建简单应用程序
从项目目录中,使用你喜欢的编辑器打开 Program.cs
该文件。 我们将创建一个简单的应用程序,该应用程序使用语义内核向聊天完成模型发送提示。 将现有内容替换为以下代码,并填写所需的值 deploymentName
, endpoint
以及 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_name
, endpoint
以及 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 门户,检查遥测数据。 数据可能需要几分钟才会显示在门户中。
事务搜索
导航到 “事务搜索 ”选项卡,查看已记录的事务。
点击刷新可查看最新事务。 当结果出现时,单击其中一个可查看更多详细信息。
在 “查看所有视图 ”和 “查看时间线 ”按钮之间切换,以查看不同视图中事务的所有跟踪和依赖项。
重要
跟踪表示传统的日志条目和 OpenTelemetry 跨事件。 它们与分布式跟踪不同。 依赖项表示对(内部和外部)组件的调用。 有关 Application Insights 中的数据模型的详细信息,请参阅本文。
对于此特定示例,应会看到两个依赖项和多个跟踪。 第一个依赖项表示从提示创建的内核函数。 第二个依赖项表示对 Azure OpenAI 聊天完成模型的调用。 展开 chat.completion {your-deployment-name}
依赖项时,应会看到调用的详细信息。 一组 gen_ai
属性附加到依赖项,该依赖项提供有关调用的其他上下文。
如果已将Microsoft.SemanticKernel.Experimental.GenAI.EnableOTelDiagnosticsSensitive
开关true
设置为,则还会看到两个跟踪,其中包含提示的敏感数据和完成结果。
单击它们,你将在自定义属性部分下看到提示和完成结果。
如果已将SEMANTICKERNEL_EXPERIMENTAL_GENAI_ENABLE_OTEL_DIAGNOSTICS_SENSITIVE
环境变量true
设置为“,则还会看到两个跟踪,其中包含提示的敏感数据和完成结果。
单击它们,你将在自定义属性部分下看到提示和完成结果。
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 后,可以探索语义内核的更多功能,以帮助监视和诊断应用程序: