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

监控应用程序事件

在本指南中,您可以了解如何在 MongoDB Node.js 驱动程序中设置和配置监控。

监控包括收集运行的程序的活动信息,您可以将这些信息与应用程序性能管理库一起使用。

通过监控 Node.js 驱动程序,您可以了解驱动程序的资源使用情况和性能,并帮助您在设计和调试应用程序时做出明智的决策。

在本指南中,您将了解如何执行这些任务:

本指南介绍如何在代码中使用有关驱动程序活动的信息。要学习如何在驱动程序中记录事件,请参阅 Node.js 驱动程序的 日志记录指南。

您可以通过在应用程序中订阅事件来使用 Node.js驱动程序监控事件。

事件是驱动程序在操作期间发生的任何操作。Node.js驱动程序包含监听这些事件子集的功能。

Node.js驱动程序将其定义的事件组织到以下类别:

  • 命令事件

  • 服务器发现和监控 (SDAM) 事件

  • 连接池事件

以下部分将介绍如何监控每个事件类别。

命令事件是与 MongoDB 数据库命令相关的事件。您可以在应用程序中订阅一个或多个命令监控事件,从而使用驱动程序访问这些事件。

要学习;了解有关MongoDB 数据库命令的更多信息,请参阅服务器手册中的数据库命令指南。

注意

默认情况下,命令监控处于禁用状态。 要启用命令监控,请将monitorCommands选项作为true传递给MongoClient构造函数。

以下示例展示了如何连接到副本集,以及如何订阅 MongoDB 部署创建的其中一个命令监控事件:

const client = new MongoClient(uri, { monitorCommands: true });const eventName = 'commandStarted'; client.on(eventName, (event) => console.log('\nreceived event:\n', event)); try { await client.db('admin').command({ ping: 1 });} finally { await client.close();}

您可以订阅以下任何命令监控事件:

事件名称
说明

commandStarted

启动命令时创建。

commandSucceeded

命令成功时创建。

commandFailed

命令失败时创建。

以下部分显示了上述每个命令的输出示例。输出可能会有所不同,具体取决于运行的命令和设立的选项。

CommandStartedEvent { name: 'commandStarted', address: 'localhost:27017', connectionId: 812613, serviceId: undefined, requestId: 1534, databaseName: 'app', commandName: 'find', command: { find: { firstName: "Jane", lastName: "Doe" } }, serverConnectionId: 27177n}
CommandSucceededEvent { name: 'commandSucceeded', address: 'localhost:27017', connectionId: 812613, serviceId: undefined, requestId: 1534, commandName: 'find', duration: 15, reply: { cursor: { firstBatch: [ { _id: ObjectId("5e8e2ca217b5324fa9847435"), firstName: "Jane", lastName: "Doe" } ], _id: 0, ns: "app.users" }, ok: 1, operationTime: 1586380205 }, serverConnectionId: 27096n, databaseName: 'app'}
CommandFailedEvent { name: 'commandFailed', address: 'localhost:27017', connectionId: 812613, serviceId: undefined, requestId: 1534, commandName: 'find', duration: 11, failure: Error("something failed"), serverConnectionId: 27208n, databaseName: 'app'}

当您连接到的实例或集群的状态发生变化时,Node.js 驱动程序会创建拓扑结构事件,也称为 SDAM 事件。例如,当您建立新连接或当集群选举出新的主节点时,驱动程序会创建一个事件。

要学习;了解有关拓扑结构事件的更多信息,请参阅服务器手册中的复制指南。

以下部分演示如何记录应用程序中的拓扑更改并探索这些事件中提供的信息。

您可以通过在应用程序中订阅一个或多个 SDAM 事件访问权限这些事件。以下示例演示了如何连接到副本集并订阅由MongoDB 部署创建的 SDAM 事件之一:

const client = new MongoClient(uri);const eventName = 'serverOpening'; client.on(eventName, (event) => console.log(`received ${eventName}: ${JSON.stringify(event, null, 2)}`)); try { await client.db('admin').command({ ping: 1 });} finally { await client.close();}

您可以订阅以下任何 SDAM 事件:

事件名称
说明

serverOpening

在打开与实例的连接时创建。

serverClosed

在与实例的连接关闭时创建。

serverDescriptionChanged

在实例状态更改(例如从节点变为主节点)时创建。

topologyOpening

在尝试连接到实例之前创建。

topologyClosed

在拓扑结构中的所有实例连接关闭后创建。

topologyDescriptionChanged

在拓扑结构发生变化时创建,例如选举新的主节点或mongos代理断开连接。

serverHeartbeatStarted

在向 MongoDB 实例发出hello命令之前创建。

serverHeartbeatSucceeded

当hello命令从 MongoDB 实例成功返回时创建。

serverHeartbeatFailed

当向特定 MongoDB 实例发出的hello命令无法返回成功响应时创建。

以下部分显示了每种类型的 SDAM 事件的输出示例。

ServerDescriptionChangedEvent { topologyId: 0, address: 'localhost:27017', previousDescription: ServerDescription { address: 'localhost:27017', error: null, roundTripTime: 0, lastUpdateTime: 1571251089030, lastWriteDate: null, opTime: null, type: 'Unknown', minWireVersion: 0, maxWireVersion: 0, hosts: [], passives: [], arbiters: [], tags: [] }, newDescription: ServerDescription { address: 'localhost:27017', error: null, roundTripTime: 0, lastUpdateTime: 1571251089051, lastWriteDate: 2019-10-16T18:38:07.000Z, opTime: { ts: Timestamp, t: 18 }, type: 'RSPrimary', minWireVersion: 0, maxWireVersion: 7, maxBsonObjectSize: 16777216, maxMessageSizeBytes: 48000000, maxWriteBatchSize: 100000, me: 'localhost:27017', hosts: [ 'localhost:27017' ], passives: [], arbiters: [], tags: [], setName: 'rs', setVersion: 1, electionId: ObjectID, primary: 'localhost:27017', logicalSessionTimeoutMinutes: 30, '$clusterTime': ClusterTime }}

此事件中ServerDescription对象的type字段包含以下可能的值之一:

类型
说明

Unknown

未知实例

Standalone

独立运行的实例

Mongos

Mongo 代理实例

PossiblePrimary

至少一台服务器将其识别为主节点,但尚未得到所有实例的验证。

RSPrimary

主实例

RSSecondary

从节点实例

RSArbiter

仲裁节点实例

RSOther

RSGhost

ServerHeartbeatStartedEvent { connectionId: 'localhost:27017'}
ServerHeartbeatSucceededEvent { duration: 1.939997, reply:{ hosts: [ 'localhost:27017' ], setName: 'rs', setVersion: 1, isWritablePrimary: true, secondary: false, primary: 'localhost:27017', me: 'localhost:27017', electionId: ObjectID, lastWrite: { opTime: { ts: [Timestamp], t: 18 }, lastWriteDate: 2019-10-16T18:38:17.000Z, majorityOpTime: { ts: [Timestamp], t: 18 }, majorityWriteDate: 2019-10-16T18:38:17.000Z }, maxBsonObjectSize: 16777216, maxMessageSizeBytes: 48000000, maxWriteBatchSize: 100000, localTime: 2019-10-16T18:38:19.589Z, logicalSessionTimeoutMinutes: 30, minWireVersion: 0, maxWireVersion: 7, readOnly: false, ok: 1, operationTime: Timestamp, '$clusterTime': ClusterTime }, connectionId: 'localhost:27017'}
ServerHeartbeatFailed { duration: 20, failure: MongoError('some error'), connectionId: 'localhost:27017'}
ServerOpeningEvent { topologyId: 0, address: 'localhost:27017'}
ServerClosedEvent { topologyId: 0, address: 'localhost:27017'}
TopologyOpeningEvent { topologyId: 0}
TopologyClosedEvent { topologyId: 0}
TopologyDescriptionChangedEvent { topologyId: 0, previousDescription: TopologyDescription { type: 'ReplicaSetNoPrimary', setName: null, maxSetVersion: null, maxElectionId: null, servers: Map { 'localhost:27017' => ServerDescription }, stale: false, compatible: true, compatibilityError: null, logicalSessionTimeoutMinutes: null, heartbeatFrequencyMS: 10000, localThresholdMS: 15, options: Object, error: undefined, commonWireVersion: null }, newDescription: TopologyDescription { type: 'ReplicaSetWithPrimary', setName: 'rs', maxSetVersion: 1, maxElectionId: null, servers: Map { 'localhost:27017' => ServerDescription }, stale: false, compatible: true, compatibilityError: null, logicalSessionTimeoutMinutes: 30, heartbeatFrequencyMS: 10000, localThresholdMS: 15, options: Object, error: undefined, commonWireVersion: 7 }}

此事件中TopologyDescription对象的type字段包含以下可能的值之一:

类型
说明

Single

独立运行的实例

ReplicaSetWithPrimary

具有主节点的副本集

ReplicaSetNoPrimary

没有主节点的副本集

Sharded

分片集群

Unknown

未知拓扑

连接池是驱动程序与 MongoDB 实例之间维护的一组开放的 TCP 连接。连接池有助于减少应用程序需要执行的网络握手次数,还能帮助应用程序更快地运行。

以下部分演示如何在应用程序中记录连接池事件并探索这些事件中提供的信息。

您可以在应用程序中订阅一个或多个连接池事件,从而使用驱动程序访问这些事件。以下示例展示了如何连接到副本集,如何订阅 MongoDB 部署创建的其中一个连接池监控事件:

const client = new MongoClient(uri);const eventName = 'connectionPoolCreated'; client.on(eventName, (event) => console.log('\nreceived event:\n', event)); try { await client.db('admin').command({ ping: 1 });} finally { await client.close();}

连接池监控事件可以帮助您调试和了解应用程序连接池的行为。以下示例展示了如何通过订阅连接池监控事件来追踪已签出的连接:

function connectionPoolStatus(client) { let checkedOut = 0; function onCheckout() { checkedOut++; } function onCheckin() { checkedOut--; } function onClose() { client.removeListener('connectionCheckedOut', onCheckout); client.removeListener('connectionCheckedIn', onCheckin); client.removeListener('close', onClose); checkedOut = NaN; } // Decreases count of connections checked out of the pool when connectionCheckedIn event is triggered client.on('connectionCheckedIn', onCheckin); // Increases count of connections checked out of the pool when connectionCheckedOut event is triggered client.on('connectionCheckedOut', onCheckout); // Cleans up event listeners when client is closed client.on('close', onClose); return { count: () => checkedOut, cleanUp: onClose, };}

您可以订阅以下任何连接池监控事件:

事件名称
说明

connectionPoolCreated

在创建连接池时创建。

connectionPoolReady

当连接池准备就绪时创建。

connectionPoolClosed

在服务器实例销毁之前关闭连接池时创建。

connectionCreated

在创建连接时创建,但不一定是在用于操作时创建。

connectionReady

在连接成功完成一次握手并可用于操作后创建。

connectionClosed

在连接关闭时创建。

connectionCheckOutStarted

当操作尝试获取用于执行的连接时创建。

connectionCheckOutFailed

当操作无法获取用于执行的连接时创建。

connectionCheckedOut

当操作成功获取用于执行的连接时创建。

connectionCheckedIn

在执行操作后,当连接被检回连接池时创建。

connectionPoolCleared

在关闭所有连接并清除连接池时创建。

以下几节显示了每种类型的连接池监控事件的样本输出。

ConnectionPoolCreatedEvent { time: 2023-02-13T15:54:06.944Z, address: '...', options: {...}}
ConnectionPoolReadyEvent { time: 2023-02-13T15:56:38.440Z, address: '...'}
ConnectionPoolClosedEvent { time: 2023-02-13T15:56:38.440Z, address: '...'}
ConnectionCreatedEvent { time: 2023-02-13T15:56:38.291Z, address: '...', connectionId: 1}
ConnectionReadyEvent { time: 2023-02-13T15:56:38.291Z, address: '...', connectionId: 1, durationMS: 60}
ConnectionClosedEvent { time: 2023-02-13T15:56:38.439Z, address: '...', connectionId: 1, reason: 'poolClosed', serviceId: undefined}
ConnectionCheckOutStartedEvent { time: 2023-02-13T15:56:38.291Z, address: '...',}
ConnectionCheckOutFailedEvent { time: 2023-02-13T15:56:38.291Z, address: '...', reason: ..., durationMS: 60}
ConnectionCheckedOutEvent { time: 2023-02-13T15:54:07.188Z, address: '...', connectionId: 1, durationMS: 60}
ConnectionCheckedInEvent { time: 2023-02-13T15:54:07.189Z, address: '...', connectionId: 1}
ConnectionPoolClearedEvent { time: 2023-02-13T15:56:38.439Z, address: '...', serviceId: undefined, interruptInUseConnections: true,}

要学习;了解有关本指南中讨论的任何选项或类型的更多信息,请参阅以下API文档: