Docs 菜单
Docs 主页
/ / /
Node.js 驱动程序
/

监控应用程序事件

在本指南中,您可以学习;了解如何在MongoDB Node.js驾驶员中设立和配置监控

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

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

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

  • 监控命令事件

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

  • 监控连接池事件

本指南介绍如何在代码中使用有关驾驶员活动的信息。要学习;了解如何在驾驶员中记录事件,请参阅 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

启动命令时创建。

commandSucceeded

命令成功时创建。

commandFailed

命令失败时创建。

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

当您连接到的实例或集群的状态发生变化时,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 事件:

事件名称
说明

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 { 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

在创建连接池时创建。

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文档:

后退

监控和日志记录

在此页面上