Overview
在本指南中,您可以学习;了解如何在MongoDB Node.js驾驶员中设立和配置监控。
监控包括收集运行的程序的活动信息,您可以将这些信息与应用程序性能管理库一起使用。
通过监控 Node.js 驱动程序,您可以了解驱动程序的资源使用情况和性能,并帮助您在设计和调试应用程序时做出明智的决策。
在本指南中,您将了解如何执行这些任务:
本指南介绍如何在代码中使用有关驱动程序活动的信息。要学习如何在驱动程序中记录事件,请参阅 Node.js 驱动程序的 日志记录指南。
监控事件
您可以通过在应用程序中订阅事件来使用 Node.js驱动程序监控事件。
事件是驱动程序在操作期间发生的任何操作。Node.js驱动程序包含监听这些事件子集的功能。
Node.js驱动程序将其定义的事件组织到以下类别:
- 命令事件 
- 服务器发现和监控 (SDAM) 事件 
- 连接池事件 
以下部分将介绍如何监控每个事件类别。
命令事件
命令事件是与 MongoDB 数据库命令相关的事件。您可以在应用程序中订阅一个或多个命令监控事件,从而使用驱动程序访问这些事件。
要学习;了解有关MongoDB 数据库命令的更多信息,请参阅服务器手册中的数据库命令指南。
注意
默认情况下,命令监控处于禁用状态。 要启用命令监控,请将 monitorCommands选项作为true传递给MongoClient构造函数。
例子
以下示例展示了如何连接到副本集,以及如何订阅 MongoDB 部署创建的其中一个命令监控事件:
/* Subscribe to an event */ const { MongoClient } = require("mongodb"); // Replace the following with your MongoDB deployment's connection string const uri = "mongodb+srv://<clusterUrl>/?replicaSet=rs&writeConcern=majority"; const client = new MongoClient(uri, { monitorCommands:true }); // Replace <event name> with the name of the event you are subscribing to const eventName = "<event name>"; // Subscribes to a specified event and print a message when the event is received client.on(eventName, event => console.log(event)); async function run() {   try {     // Establishes and verifies connection to the "admin" database     await client.db("admin").command({ ping: 1 });     console.log("Connected successfully");   } finally {     // Closes the database connection on completion or error     await client.close();   } } run().catch(console.dir); 
事件描述
您可以订阅以下任何命令监控事件:
| 事件名称 | 说明 | 
|---|---|
| 
 | 启动命令时创建。 | 
| 
 | 命令成功时创建。 | 
| 
 | 命令失败时创建。 | 
以下部分显示了上述每个命令的输出示例。输出可能会有所不同,具体取决于运行的命令和设立的选项。
commandStarted
CommandStartedEvent {   name: 'commandStarted',   address: 'localhost:27017',   connectionId: 812613,   serviceId: undefined,   requestId: 1534,   databaseName: 'app',   commandName: 'find',   command: {     find: { firstName: "Jane", lastName: "Doe" }   },   serverConnectionId: 27177n } 
commandSucceeded
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' } 
commandFailed
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 事件)。示例,当您建立新连接或集群选出新的主节点 (primary node in the replica set)节点时,驾驶员会创建一个事件。
要学习;了解有关拓扑结构事件的更多信息,请参阅服务器手册中的复制指南。
以下部分演示如何记录应用程序中的拓扑更改并探索这些事件中提供的信息。
事件订阅示例
您可以通过在应用程序中订阅一个或多个 SDAM 事件访问权限这些事件。以下示例演示了如何连接到副本集并订阅由MongoDB 部署创建的 SDAM 事件之一:
/* Subscribe to SDAM event */ const { MongoClient } = require("mongodb"); // Replace the following with your MongoDB deployment's connection string const uri = "mongodb+srv://<clusterUrl>/?replicaSet=rs&writeConcern=majority"; const client = new MongoClient(uri); // Replace <event name> with the name of the event you are subscribing to const eventName = "<event name>"; // Subscribes to a specified event and prints a message when the event is received client.on(eventName, event => {   console.log(`received ${eventName}: ${JSON.stringify(event, null, 2)}`); }); async function run() {   try {     // Establishes and verifies connection to the database     await client.db("admin").command({ ping: 1 });     console.log("Connected successfully");   } finally {     // Closes the database connection on completion or error     await client.close();   } } run().catch(console.dir); 
事件描述
您可以订阅以下任何 SDAM 事件:
| 事件名称 | 说明 | 
|---|---|
| 
 | 在打开与实例的连接时创建。 | 
| 
 | 在与实例的连接关闭时创建。 | 
| 
 | 在实例状态更改(例如从节点变为主节点)时创建。 | 
| 
 | 在尝试连接到实例之前创建。 | 
| 
 | 在拓扑结构中的所有实例连接关闭后创建。 | 
| 
 | 在拓扑结构发生变化时创建,例如选举新的主节点或mongos代理断开连接。 | 
| 
 | 在向 MongoDB 实例发出 | 
| 
 | 当 | 
| 
 | 当向特定 MongoDB 实例发出的 | 
示例事件文档
以下部分显示了每种类型的 SDAM 事件的输出示例。
serverDescriptionChanged
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字段包含以下可能的值之一:
| 类型 | 说明 | 
|---|---|
| 
 | 未知实例 | 
| 
 | 独立运行的实例 | 
| 
 | Mongo 代理实例 | 
| 
 | 至少一台服务器将其识别为主节点,但尚未得到所有实例的验证。 | 
| 
 | 主实例 | 
| 
 | 从节点实例 | 
| 
 | 仲裁节点实例 | 
| 
 | |
| 
 | 
serverHeartbeatStarted
ServerHeartbeatStartedEvent {   connectionId: 'localhost:27017' } 
serverHeartbeatSucceeded
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
ServerHeartbeatFailed {   duration: 20,   failure: MongoError('some error'),   connectionId: 'localhost:27017' } 
serverOpening
ServerOpeningEvent {   topologyId: 0,   address: 'localhost:27017' } 
serverClosed
ServerClosedEvent {   topologyId: 0,   address: 'localhost:27017' } 
拓扑结构Opening
TopologyOpeningEvent {   topologyId: 0 } 
topologyClosed
TopologyClosedEvent {   topologyId: 0 } 
topologyDescriptionChanged
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字段包含以下可能的值之一:
| 类型 | 说明 | 
|---|---|
| 
 | 独立运行的实例 | 
| 
 | 具有主节点的副本集 | 
| 
 | 没有主节点的副本集 | 
| 
 | 分片集群 | 
| 
 | 未知拓扑 | 
连接池事件
连接池是驱动程序与 MongoDB 实例之间维护的一组开放的 TCP 连接。连接池有助于减少应用程序需要执行的网络握手次数,还能帮助应用程序更快地运行。
以下部分演示如何在应用程序中记录连接池事件并探索这些事件中提供的信息。
事件订阅示例
您可以在应用程序中订阅一个或多个连接池事件,从而使用驱动程序访问这些事件。以下示例展示了如何连接到副本集,如何订阅 MongoDB 部署创建的其中一个连接池监控事件:
const { MongoClient } = require("mongodb"); // Replace the following with your MongoDB deployment's connection string const uri =   "mongodb+srv://<clusterUrl>/?replicaSet=rs&writeConcern=majority"; const client = new MongoClient(uri); // Replace <event name> with the name of the event you are subscribing to const eventName = "<event name>"; // Subscribes to the event client.on(eventName, (event) =>   console.log("\nreceived event:\n", event) ); async function run() {   try {     // Establishes and verifies connection     await client.db("admin").command({ ping: 1 });     console.log("\nConnected successfully!\n");   } finally {     // Ensures that the client will close when you finish/error     await client.close();   } } run().catch(console.dir); 
连接池监控事件可以帮助您调试和了解应用程序连接池的行为。 以下示例使用连接池监控事件返回池中已签出连接的计数:
function connectionPoolStatus(client) {   let checkedOut = 0;   function onCheckout() {     checkedOut++;   }   function onCheckin() {     checkedOut--;   }   function onClose() {     client.removeListener('connectionCheckedOut', onCheckout);     client.removeListener('connectionCheckedIn', onCheckin);     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
ConnectionPoolCreatedEvent {   time: 2023-02-13T15:54:06.944Z,   address: '...',   options: {...} } 
connectionPoolReady
ConnectionPoolReadyEvent {   time: 2023-02-13T15:56:38.440Z,   address: '...' } 
connectionPoolClosed
ConnectionPoolClosedEvent {   time: 2023-02-13T15:56:38.440Z,   address: '...' } 
connectionCreated
ConnectionCreatedEvent {   time: 2023-02-13T15:56:38.291Z,   address: '...',   connectionId: 1 } 
connectionReady
ConnectionReadyEvent {   time: 2023-02-13T15:56:38.291Z,   address: '...',   connectionId: 1,   durationMS: 60 } 
connectionClosed
ConnectionClosedEvent {   time: 2023-02-13T15:56:38.439Z,   address: '...',   connectionId: 1,   reason: 'poolClosed',   serviceId: undefined } 
connectionCheckOutStarted
ConnectionCheckOutStartedEvent {   time: 2023-02-13T15:56:38.291Z,   address: '...', } 
connectionCheckOutFailed
ConnectionCheckOutFailedEvent {   time: 2023-02-13T15:56:38.291Z,   address: '...',   reason: ...,   durationMS: 60 } 
connectionCheckedOut
ConnectionCheckedOutEvent {   time: 2023-02-13T15:54:07.188Z,   address: '...',   connectionId: 1,   durationMS: 60 } 
connectionCheckedIn
ConnectionCheckedInEvent {   time: 2023-02-13T15:54:07.189Z,   address: '...',   connectionId: 1 } 
connectionPoolCleared
ConnectionPoolClearedEvent {   time: 2023-02-13T15:56:38.439Z,   address: '...',   serviceId: undefined,   interruptInUseConnections: true, } 
API 文档
要学习;了解有关本指南中讨论的任何选项或类型的更多信息,请参阅以下API文档: