对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

使用 OpenTelemetry 跟踪操作

在本指南中,您可以学习;了解如何将 OpenTelemetry 跟踪与.NET/ C#驱动程序结合使用。 OpenTelemetry 是一个开源可观察性框架,它提供了一种标准化方法来检测、生成、收集和导出遥测数据。

.NET/ C#驱动程序通过 System.Diagnostics.ActivitySource API发出跟踪数据。当您将侦听器订阅驱动程序的 ActivitySource 时,驾驶员会创建表示MongoDB操作的跨度,例如查询和事务。这些跨度包括遵循 OpenTelemetry 语义约定的属性。

注意

OpenTelemetry 跟踪在.NET/ C#驱动程序3.7 或更高版本中可用。

本指南中的示例使用Atlas示例数据集中的 sample_mflix.movies集合。要学习;了解如何创建免费的MongoDB Atlas 群集并加载示例数据集,请参阅.NET/ C#驱动程序入门。

以下代码创建 MongoClient 并访问示例集合:

var connectionString = "<connection string>";
var client = new MongoClient(connectionString);
var collection = client.GetDatabase("sample_mflix").GetCollection<BsonDocument>("movies");

该驾驶员不依赖于 OpenTelemetry SDK。它通过 ActivitySource 发出跨度,因此任何侦听器都可以收集它们,包括 System.Diagnostics.ActivityListener对象。

要使用 OpenTelemetry SDK 收集驱动程序的跨度,请将 SDK 和导出器添加到您的应用中。本页上的示例使用内存中导出器,因此您可以检查驾驶员生成的跨度。从项目目录运行以下命令:

dotnet add package OpenTelemetry
dotnet add package OpenTelemetry.Exporter.InMemory

当侦听器订阅驱动程序的 ActivitySource 并且客户端已启用跟踪时,驾驶员会创建 span。要禁用客户端端跟踪,请将 TracingOptions.Disabled属性设立为 true。

如果没有订阅侦听器,驾驶员将跳过所有跟踪工作,并且对性能的影响可以忽略不计。

驾驶员在名为 MongoDB.Driver 的 ActivitySource 上注册其跨度。要收集驱动程序的跨度,请在配置 OpenTelemetry 时将 MongoTelemetry.ActivitySourceName 常量传递给 AddSource() 方法。

要在使用.NET托管模型(例如 ASP .NET Core 或辅助线程服务)的应用中配置 OpenTelemetry,请添加以下包:

dotnet add package OpenTelemetry.Extensions.Hosting

如果您的应用已有托管,请将驱动程序的 ActivitySource 添加到其 OpenTelemetry设置中,如以下示例所示:

// Register the driver's ActivitySource with an OpenTelemetry
// TracerProvider in a generic host.
var exportedSpans = new List<Activity>();
var builder = Host.CreateApplicationBuilder();
builder.Services.AddOpenTelemetry()
.WithTracing(tracing => tracing
.AddSource(MongoTelemetry.ActivitySourceName)
.AddInMemoryExporter(exportedSpans));
var host = builder.Build();

前面的示例使用 OpenTelemetry.Exporter.InMemory包来收集跨度。在您的应用中,将其替换为跟踪后端的导出器。

如果您的应用没有托管,构建TracerProvider,如以下示例所示:

// Register the driver's ActivitySource with an OpenTelemetry
// TracerProvider.
var exportedSpans = new List<Activity>();
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddSource(MongoTelemetry.ActivitySourceName)
.AddInMemoryExporter(exportedSpans)
.Build();

前面的示例使用 OpenTelemetry.Exporter.InMemory包来收集跨度。在您的应用中,将其替换为跟踪后端的导出器,例如 OpenTelemetry Protocol (OTLP) 导出器。

订阅ActivitySource 后,驾驶员会为应用程序运行的操作发出 span,如以下示例所示:

var filter = Builders<BsonDocument>.Filter.Eq("title", "Back to the Future");
var movie = collection.Find(filter).First();

如果您不想依赖 OpenTelemetry SDK,则可以使用 System.Diagnostics.ActivityListener对象订阅驱动程序的 ActivitySource。以下示例注册了一个侦听器,用于接收驾驶员发出的每个范围:

// Subscribe to the driver's ActivitySource by using an ActivityListener.
// This approach avoids a dependency on the OpenTelemetry SDK.
var exportedSpans = new List<Activity>();
using var listener = new ActivityListener
{
ShouldListenTo = source => source.Name == MongoTelemetry.ActivitySourceName,
Sample = (ref ActivityCreationOptions<ActivityContext> _) =>
ActivitySamplingResult.AllDataAndRecorded,
ActivityStopped = exportedSpans.Add
};
ActivitySource.AddActivityListener(listener);

要为单个客户端配置跟踪,请将 MongoClientSettings.TracingOptions属性设立为 TracingOptions实例。 TracingOptions 类具有以下属性:

属性
类型
说明

Disabled

bool

设立为 true 时,此客户端不会创建 span。订阅其他客户端的监听器不受影响。

默认: false

QueryTextMaxLength

int

指定要包含在 span 属性中的查询文本的最大长度。设立为 0 时,驾驶员将忽略查询文本。查询文本显示在 db.query.text 属性中。

默认: 0

以下示例将 QueryTextMaxLength 设置为 1024,这会捕获命令文本的最多 1024 个字符:

var settings = MongoClientSettings.FromConnectionString(connectionString);
settings.TracingOptions = new TracingOptions
{
Disabled = false,
QueryTextMaxLength = 1024
};
var client = new MongoClient(settings);

.NET/ C#驱动程序创建以下类型的跨度:

跨度类型
说明

操作级别 span

表示高级驾驶员操作的跨度,例如 find、insert 或 aggregate。操作级 span 包括 db.operation.name 属性。

命令级 span

代表驾驶员发送到服务器的各个命令的跨度。命令级 span 包含 db.command.name 属性,并嵌套在相应的操作级 span 下。

事务跨度

包含在显式ACID 事务中运行的所有操作的跨度。

示例,find 操作会创建一个操作级范围,其中包含一个嵌套的命令级范围,如以下层次结构所示:

find sample_mflix.movies
└── find

.NET/ C#驱动程序遵循 OpenTelemetry 语义约定,并包含提供每个操作上下文的属性。

Span 包括以下常规属性:

  • db.system.name:始终设立为 mongodb

  • db.operation.name:高级操作的名称(仅限跨度操作)

  • db.operation.summary:高级操作摘要(仅限操作 span)

  • db.command.name: MongoDB命令的名称(仅限命令 span)

  • db.namespace:数据库名称

  • db.collection.name:集合名称(如果适用)

  • db.query.summary:查询摘要(仅限命令 span)

命令范围包括以下网络属性:

  • server.address: MongoDB 服务器托管

  • server.port: MongoDB服务器端口

  • network.transport:传输协议,例如 tcp 或 unix

命令范围包括以下连接属性:

  • db.mongodb.server_connection_id:服务器分配的连接ID

  • db.mongodb.driver_connection_id:驱动程序分配的连接ID

使用会话或事务时,命令范围包括以下属性:

  • db.mongodb.lsid:逻辑会话ID (使用会话时)

  • db.mongodb.txn_number:事务编号(处于ACID 事务中时)

  • db.mongodb.cursor_id:游标ID (适用于返回游标的操作)

当您将 QueryTextMaxLength 配置为大于 0 的值时,命令范围将包含以下属性:

  • db.query.text:命令文本,截断为指定的最大长度

当操作失败时,驾驶员会记录异常详细信息并包含以下属性:

  • exception.type:异常类型

  • exception.message:异常消息

  • exception.stacktrace:异常堆栈跟踪

  • db.response.status_code: MongoDB错误代码(仅限命令 span)

驾驶员应用以下安全措施来保护敏感信息:

  • 驾驶员不会为敏感命令(例如身份验证命令)创建 span。这些命令包括 authenticate、saslStart、saslContinue、getNonce、createUser、updateUser、copyDbSaslStart 和 copyDb。当 hello 命令包含 speculativeAuthenticate字段时,驾驶员也会跳过该命令。

  • 驾驶员默认禁用 db.query.text 属性。仅在必要时启用此属性。

  • 当驾驶员捕获查询文本时,它会从命令中删除 lsid、$db、$clusterTime 和 signature 字段。

警告

启用db.query.text 属性时,驾驶员会在 span 属性中包含命令文本,并且导出器会将 span 发送到跟踪后端。该驾驶员仅删除会话和集群元数据。跟踪后端仍会记录过滤值、查询运算符以及插入或更新文档的内容。

当操作失败时,驾驶员会将异常详细信息记录为遵循 OpenTelemetry 语义约定的 span 属性,并将 span 状态设置为 Error。

对于MongoDB命令失败,驾驶员会将操作范围及其命令范围的状态设置为 Error。驾驶员会在命令范围的 db.response.status_code 属性中记录错误代码。

服务器在成功的命令响应中返回的写入错误(例如重复键错误)不会设立db.response.status_code。驾驶员会将这些错误记录为操作范围的异常属性。

错误不会阻止驱动程序向应用程序引发异常。

使用 OpenTelemetry 跟踪时,请考虑以下性能影响:

  • 捕获 db.query.text 属性会增加开销。仅在必要时捕获命令文本,或将 QueryTextMaxLength设立为 0 以将其禁用。

  • 当没有侦听器订阅驱动程序的 ActivitySource 时,跟踪对性能的影响可以忽略不计,因为驾驶员会跳过所有跟踪工作。

要学习;了解有关 OpenTelemetry 跟踪的更多信息,请参阅 OpenTelemetry .NET文档。

要学习;了解有关驾驶员中用于跟踪操作的类的更多信息,请参阅以下API文档: