在 MongoDB 中记录所有查询
在本文中,您将了解如何在 MongoDB 中记录查询。 此外,还详细解释了用于在 MongoDB 中记录查询的运算符。
MongoDB 中的 getLog 命令
管理员命令 getLog 检索最近记录的 1024 个 mongod 事件。 getLog 命令不会从 mongod 日志文件中检索日志数据; 相反,它从记录的 mongod 事件的 RAM 缓存中获取信息。
使用 db.adminCommand() 函数执行 getLog。 从 MongoDB 4.4 开始,getLog 以转义的 Relaxed Extended JSON v2.0 格式提供日志数据。 日志数据以前以纯文本形式提供。
getLog 命令的语法如下:
db.adminCommand( { getLog: <value> } )
getLog 的可能值为:
值 | 描述 -- | --
- | 返回 getLog 命令的可用值列表。 global | 返回所有日志条目的组合输出。 startupwarnings | 从 MongoDB 的日志中返回日志条目,其中可能包含当前进程启动时的错误或警告。 如果 mongod 在没有迹象的情况下启动,则此过滤器可能会返回一个空数组。
如果提供 *
,该命令将返回包含其他有效值名称的文档。 否则,该命令会生成包含以下字段的文档:
- 包含日志事件数量的 totalLinesWritten 字段;
- 包含日志事件数组的日志字段;
- 提供来自 db.adminCommand() 的状态和时间戳信息的响应文档。
MongoDB 中 getLog 命令的行截断行为
从 MongoDB 4.2 开始,getLog 会截断任何超过 1024 个字符的事件。 在以前的版本中,它会在 512 个字符后截断。
MongoDB 中 getLog 命令的字符规避行为
从 MongoDB 4.4 开始,getLog 以转义的 Relaxed Extended JSON v2.0 格式提供日志数据,利用下面列出的转义序列将日志输出转换为有效的 JSON:
字符表示 | 转义序列 |
---|---|
反斜杠 () | \ |
引号 (") | " |
换页 (0x0C) | \f |
退格键 (0x08) | \b |
回车 (0x0D) | \r |
水平制表符 (0x09) | \t |
换行符 (0x0A) | \n |
上面未提及的控制字符使用 uXXXX 进行转义,其中 XXXX 是 Unicode 代码点的十六进制代码点。 UTF-8 编码不正确的字节将替换为 ufffd Unicode 替换字符。
MongoDB 中记录查询的详细级别
您可以更改日志记录的详细级别以增加或减少 MongoDB 生成的日志消息的数量。 可以为所有组件一起修改详细程度,也可以为单独标识的组件修改详细程度。
只有信息和调试严重性类别中的日志条目受详细程度影响。 在这些级别之上,将始终显示严重性类别。
将详细程度设置设置为高值以在调试或开发期间进行大量日志记录,或将详细程度设置为低值以限制已验证的生产部署上的日志写入。
检查 MongoDB 中的当前日志详细级别
使用 db.getLogComponents()
函数查看当前的详细级别:
db.getLogComponents()
您的输出可能类似于以下内容:
第一个条目 verbosity 是所有组件的全局详细级别。 随后命名的组件(例如 accessControl)指示该组件的特定详细级别,如果已设置则覆盖全局详细级别。
值 -1 表示如果组件不具有全局详细级别之一(与命令一样),则该组件将继承父级的详细级别。
在 MongoDB 中配置日志详细级别
systemLog.verbosity 和 systemLog.component.name>.verbosity 设置 logComponentVerbosity 参数,并且 db.setLogLevel()
函数都可用于更改详细程度。
使用 systemLog Verbosity 设置来控制级别
使用 systemLog.verbosity 参数指定所有组件的默认日志级别。 使用 systemLog.component.name>.verbosity
设置来控制某些组件的级别。
例如,以下配置将 systemLog.verbosity 设置为 1,将 systemLog.component.query.verbosity 设置为 2,将 systemLog.component.storage.verbosity 设置为 2,并将 systemLog.component.storage.journal.verbosity 设置为 1:
systemLog:
verbosity: 1
component:
query:
verbosity: 2
storage:
verbosity: 2
journal:
verbosity: 1
对于您的 mongod 或 mongos 实例,请在配置文件或命令行中指定这些设置。
配置中未明确给出的所有组件的详细级别为 -1。 这表明如果他们具有全局详细级别之一,则他们将采用其父级的详细级别。
更改 logComponentVerbosity 参数
传递包含详细设置的文档以更改 logComponentVerbosity 选项。
例如,以下命令将默认详细级别更改为 2,将查询更改为 3,将存储更改为 4,并将 storage.journal 更改为 1。
db.adminCommand( {
setParameter: 1,
logComponentVerbosity: {
verbosity: 2,
query: {
verbosity: 3
},
storage: {
verbosity: 4,
journal: {
verbosity: 1
}
}
}
} )
您可以从 mongosh 设置这些值。
使用 db.setLogLevel() 更改 MongoDB 中的日志级别
要更改单个组件的日志级别,请使用 db.setLogLevel() 函数。 您可以为组件定义 0 到 5 的详细级别,或指定 -1 以继承父组件的详细级别。
例如,将 systemLog.component.query.verbosity 设置为其父详细程度(即默认详细程度)如下:
db.setLogLevel(-1, "query")
您可以从 mongosh 设置此值。
在 MongoDB 中记录缓慢的操作
如果客户端操作(例如查询)花费的时间超过慢速操作阈值,或者日志详细级别设置为 1 或更高,则会记录这些操作。
对于读/写操作,从 MongoDB 4.2 开始,分析器条目和诊断日志消息(即 mongod/mongos 日志消息)包括:
- queryHash,一个可以检测具有相同查询形式的缓慢搜索的函数;
- planCacheKey 提供有关慢速查询的查询计划缓存的额外信息。
从 MongoDB 5.0 开始,慢速操作日志消息现在包含一个指定客户端 IP 地址的远程列。
给定的示例输出包括有关缓慢聚合操作的信息:
{"t":{"$date":"2020-05-20T20:10:08.731+00:00"},"s":"I", "c":"COMMAND", "id":51803, "ctx":"conn281","msg":"Slow query","attr":{"type":"command","ns":"stocks.trades","appName":"MongoDB Shell","command":{"aggregate":"trades","pipeline":[{"$project":{"ticker":1.0,"price":2.0,"priceGTE110":{"$gte":["$price",111.0]},"_id":0.0}},{"$sort":{"price":-1.0}}],"allowDiskUse":true,"cursor":{},"lsid":{"id":{"$uuid":"fa658f9e-9cd6-42d4-b1c8-c9160fabf2a2"}},"$clusterTime":{"clusterTime":{"$timestamp":{"t":1590005405,"i":1}},"signature":{"hash":{"$binary":{"base64":"AAAAAAAAAAAAAAAAAAAAAAAAAAA=","subType":"0"}},"keyId":0}},"$db":"test"},"planSummary":"COLLSCAN","cursorid":1912190691485054730,"keysExamined":0,"docsExamined":1000001,"hasSortStage":true,"usedDisk":true,"numYields":1002,"nreturned":101,"reslen":17738,"locks":{"ReplicationStateTransition":{"acquireCount":{"w":1119}},"Global":{"acquireCount":{"r":1119}},"Database":{"acquireCount":{"r":1119}},"Collection":{"acquireCount":{"r":1119}},"Mutex":{"acquireCount":{"r":117}}},"storage":{"data":{"bytesRead":232899899,"timeReadingMicros":186017},"timeWaitingMicros":{"cache":849}},"remote": "192.168.14.15:37666","protocol":"op_msg","durationMillis":22427}}
在 remoteOpWaitMillis 字段中获取分片的等待时间
从 MongoDB 5.0 开始,您可以使用 remoteOpWaitMillis 日志字段获取分片结果的等待时间(以毫秒为单位)。
仅为 remoteOpWaitMillis 报告以下值:
- 如果操作缓慢,则启用日志记录。
- 在合并结果的分片或 mongos 上
比较日志中的durationMillis和remoteOpWaitMillis时间列,看看是合并操作还是分片问题导致查询慢。 durationMillis 是查询完成所花费的全部时间。
具体来说,
- 如果 durationMillis 超过 remoteOpWaitMillis,则大部分时间都花在等待分片响应上。 例如,18 的 durationMillis 和 15 的 remoteOpWaitMillis 是可接受的值。
- 如果 durationMillis 明显大于 remoteOpWaitMillis,则大部分时间都花在了合并上。 例如,durationMillis 为 150,remoteOpWaitMillis 为 15。
在 mongosh 中过滤日志查询的结果
可以过滤 getLog 的输出以使结果更易于阅读或匹配特定条件。
以下命令仅打印日志字段(其中包含所有当前日志事件的数组),同时从每个日志消息中删除转义字符:
db.adminCommand( { getLog:'global'} ).log.forEach(x => {print(x)})
在此操作中,getLog 的输出以与 MongoDB 日志文件相同的格式呈现。
注意:getLog 仅显示最后 1024 个记录的 mongod 事件,并不打算替换 MongoDB 日志文件。
使用 jq 过滤 mongosh 外部日志查询的结果
第三方 jq 命令行程序在处理 MongoDB 结构化日志记录时得心应手。 它支持快速漂亮地打印日志条目和健壮的基于键的匹配和过滤。
jq 是适用于 Linux、Windows 和 macOS 的免费开源 JSON 解析器。
您必须使用 mongosh 的 -eval 选项才能将 jq 与 getLog 输出一起使用。 以下操作使用 jq 来过滤 REPL 组件,以便仅显示与复制相关的日志消息:
mongosh --quiet --eval "db.adminCommand( { getLog:'global'} ).log.forEach(x => {print(x)})" | jq -c '. | select(.c=="REPL")'
小心地为 mongosh 提供它需要的任何特定于连接的参数,例如 -host 或 -port。
mongosh --quiet --eval "db.adminCommand( { getLog:'global'} ).log.forEach(x => {print(x)})" | jq -r ".msg" | sort | uniq -c | sort -rn | head -10
检索可用的日志过滤器
以下操作从 mongosh 运行,返回可用的日志过滤器以传递给 getLog:
db.adminCommand( { getLog: "" } )
该操作返回以下文档:
{ "names" : [ "global", "startupWarnings" ], "ok" : 1 }
从日志中检索最近的事件
以下命令从 mongosh 运行,获取 mongod 的最新全局事件:
db.adminCommand( { getLog : "global" } )
该操作生成如下所示的文档:
相关文章
在 MongoDB Shell 中列出所有数据库
发布时间:2023/05/11 浏览次数:180 分类:MongoDB
-
交互式 Mongo Shell 提供了多个用于获取数据的选项。 本文介绍了在 Mongo Shell 中列出数据库的几种不同方法。
MongoDB 中检查字段包含的字符串
发布时间:2023/05/11 浏览次数:1024 分类:MongoDB
-
这篇文章解决了如何在 MongoDB 中使用正则表达式来确定字段是否包含字符串。在 MongoDB 中使用正则表达式 正则表达式 (regex) 是定义搜索模式的文本字符串。
在 MongoDB 中 upsert 更新插入
发布时间:2023/05/11 浏览次数:214 分类:MongoDB
-
在 MongoDB 中,upsert 结合了更新和插入命令。 它可以在 update() 和 findAndModify() 操作中使用。MongoDB 中的 upsert 查询 upsert 采用单个布尔参数。
如何卸载 MongoDB
发布时间:2023/05/11 浏览次数:745 分类:MongoDB
-
要从您的计算机中卸载 MongoDB,您必须先删除 MongoDB 服务、数据库和日志文件。使用这篇 MongoDB 文章,您将能够从 Ubuntu Linux、Mac 和 Windows 卸载 MongoDB。 请务必保留数据备份,因为一旦卸载,便
在 MongoDB 中存储日期和时间
发布时间:2023/05/11 浏览次数:762 分类:MongoDB
-
本 MongoDB 教程解释了 Date() 对象是什么以及如何使用 Date() 方法对集合进行排序。 这也将帮助您找到在 MongoDB 中显示和存储日期/时间的最佳方法。
MongoDB 按 ID 查找
发布时间:2023/05/11 浏览次数:1856 分类:MongoDB
-
MongoDB 中的 find by Id() 函数用于获取与用户提供的 id 相匹配的文档。 如果找不到与指定 ID 匹配的文档,则返回空值。
检查 MongoDB 服务器是否正在运行
发布时间:2023/05/11 浏览次数:247 分类:MongoDB
-
这篇 MongoDB 教程将告诉您如何检查是否安装了 MongoDB 以及安装的 MongoDB 服务器的版本。 它在 Windows、UBUNTU 和 MAC 等不同的操作系统中实现。
MongoDB 中的分页
发布时间:2023/05/11 浏览次数:174 分类:MongoDB
-
这篇文章将介绍什么是 MongoDB 中的分页。 为什么在 MongoDB 中需要分页以及在 MongoDB 中完成分页的不同方法或方式是什么。
MongoDB 从查询开始
发布时间:2023/05/11 浏览次数:186 分类:MongoDB
-
在这篇 MongoDB 文章中,用户将学习如何使用 $regex 进行开始查询。 它为查询中的模式匹配字符串提供正则表达式功能。