MongoDB记录所有查询

208
问题简单而基础...如何将所有的查询记录在可“tail” 的日志文件中?
我已经尝试过:
- 设置profiling级别 - 调整slow ms参数 - 使用mongod -vv选项
但是/var/log/mongodb/mongodb.log仅显示当前活动连接数...

mongod -vv 对我有用。 - fguillen
16个回答

309

您可以记录所有查询:

$ mongo
MongoDB shell version: 2.4.9
connecting to: test
> use myDb
switched to db myDb
> db.getProfilingLevel()
0
> db.setProfilingLevel(2)
{ "was" : 0, "slowms" : 1, "ok" : 1 }
> db.getProfilingLevel()
2
> db.system.profile.find().pretty()

来源:http://docs.mongodb.org/manual/reference/method/db.setProfilingLevel/

db.setProfilingLevel(2)的意思是“记录所有操作”。


7
乍一看,这个答案似乎比被采纳的答案更好。 - Ehtesh Choudhury
3
虽然该问题要求一个可追加的日志文件,所以并不是最好的选择,但在你没有访问日志文件而只有Mongo shell的情况下,它肯定是有用的。就像带我来到这里的情况一样 :) - inolasco
17
我尝试将分析级别设置为2,但我还需要将第二个参数设置为-1,例如 db.setProfilingLevel(2,-1) - andresigualada
5
对于那些想了解日志存储位置的人,文档说明:mongod将数据库分析器的输出写入到 system.profile 集合中。 - totymedli
6
db.system.profile.find().pretty() 对我没有任何输出。 - node_saini
显示剩余2条评论

91
我最终解决了这个问题,通过像这样启动mongod(虽然很麻烦和丑陋,但适用于开发环境):
mongod --profile=1 --slowms=1 &

这将启用分析功能,并将“慢查询”的阈值设置为1毫秒,导致所有查询都被记录为“慢查询”到文件中:
/var/log/mongodb/mongodb.log

现在我使用以下命令获取连续的日志输出:
tail -f /var/log/mongodb/mongodb.log

一个示例日志:
Mon Mar  4 15:02:55 [conn1] query dendro.quads query: { graph: "u:http://example.org/people" } ntoreturn:0 ntoskip:0 nscanned:6 keyUpdates:0 locks(micros) r:73163 nreturned:6 reslen:9884 88ms

6
这是否相当于在/etc/mongodb.conf中添加profile=1slowms=1行? - Andrew Magee
我找不到 /var/log/mongodb/mongodb.log 文件,但是它在控制台中记录了我所需要的信息。谢谢。 - auhuman
5
根据官方Mongo文档,你可以在/etc/mongodb.conf中添加--profile=2,这样所有操作都将被记录。 - toske
1
@auhuman 在哪里输入“tail -f /var/log/mongodb/mongodb.log”命令? - Half Blood Prince
7
无需重启,您可以直接使用db.setProfilingLevel(level,slowms)。例如:db.setProfilingLevel(2,1)将把级别设置为2,慢查询阈值设置为1毫秒。 - Abhishek Gupta
显示剩余3条评论

38

29

MongoDB 具有精细的性能分析功能。日志记录在 system.profile 集合中。可以从下面查看日志:

db.system.profile.find()

日志有3个级别(来源):

  • 级别 0 - 日志记录关闭,不会收集任何数据。mongod会始终将操作时间大于slowOpThresholdMs阈值的操作写入其日志中。这是默认的分析器级别。
  • 级别 1 - 仅收集缓慢操作的分析数据。默认情况下,缓慢操作是指超过100毫秒的操作。您可以使用slowOpThresholdMs运行时选项或setParameter命令修改“缓慢”操作的阈值。请参阅“指定缓慢操作的阈值”部分以获取更多信息。
  • 级别 2 - 收集所有数据库操作的分析数据。

要查看数据库正在运行的分析级别,请使用

db.getProfilingLevel()

查看状态

db.getProfilingStatus()

要更改分析配置文件的状态,请使用以下命令

db.setProfilingLevel(level, milliseconds)

level指的是分析级别,milliseconds是需要记录查询持续时间的毫秒数。要关闭日志记录,请使用

db.setProfilingLevel(0)

查询系统配置文件集合中所有超过一秒钟的查询,按时间戳降序排列的查询将是

db.system.profile.find( { millis : { $gt:1000 } } ).sort( { ts : -1 } )

1
根据文档,Loglevel 0并不意味着“没有日志记录”,而是记录慢查询:“分析器关闭,不收集任何数据。mongod始终将操作时间长于slowOpThresholdMs阈值的操作写入其日志。”来源:https://docs.mongodb.com/v3.2/tutorial/manage-the-database-profiler/#profiling-levels - kayn

24

我做了一个命令行工具来激活分析器活动并以可“tail”方式查看日志 --> "mongotail"

$ mongotail MYDATABASE
2020-02-24 19:17:01.194 QUERY  [Company] : {"_id": ObjectId("548b164144ae122dc430376b")}. 1 returned.
2020-02-24 19:17:01.195 QUERY  [User] : {"_id": ObjectId("549048806b5d3db78cf6f654")}. 1 returned.
2020-02-24 19:17:01.196 UPDATE [Activation] : {"_id": "AB524"}, {"_id": "AB524", "code": "f2cbad0c"}. 1 updated.
2020-02-24 19:17:10.729 COUNT  [User] : {"active": {"$exists": true}, "firstName": {"$regex": "mac"}}
...

但更有趣的特性(与tail类似)是使用-f选项实时查看更改,并偶尔使用grep过滤结果以查找特定操作。

文档和安装说明请参阅:https://github.com/mrsarm/mongotail

(也可从 Docker 运行,特别是如果您想要在 Windows 上执行它,请访问:https://hub.docker.com/r/mrsarm/mongotail


2
这是对OP最完整的回复,特别是关于“可尾随”的要求。 - Luke W

17

如果您希望将查询日志记录到MongoDB日志文件中,您必须同时设置日志级别和分析级别,例如:

db.setLogLevel(1)
db.setProfilingLevel(2)

(参见 https://docs.mongodb.com/manual/reference/method/db.setLogLevel)

仅设置分析不会将查询记录到文件中,因此您只能从

db.system.profile.find().pretty()

11

一旦使用db.setProfilingLevel(2)设置了分析级别。

以下命令将打印最后执行的查询。
您也可以更改限制(5)以查看更少/更多的查询。
$nin - 将筛选出配置文件和索引查询。
此外,使用查询投影{'query':1}仅查看查询字段。

db.system.profile.find(
{ 
    ns: { 
        $nin : ['meteor.system.profile','meteor.system.indexes']
    }
} 
).limit(5).sort( { ts : -1 } ).pretty()

只有查询投影的日志

db.system.profile.find(
{ 
    ns: { 
        $nin : ['meteor.system.profile','meteor.system.indexes']
    }
},
{'query':1}
).limit(5).sort( { ts : -1 } ).pretty()

7

1
是的,在激活了二级分析后,数据库中添加了一个集合。然而,每次进行调试时都必须重新加载GUI或运行命令,这真是让人烦恼...这就是为什么我想要一个可追踪的日志文件。 - João Rocha da Silva

4
我认为虽然不够优雅,但oplog可以部分地用于此目的:它记录了所有写入操作,但没有记录读取操作...。
如果我没记错,您需要启用复制功能。这些信息来自于该回答,来源于这个问题:如何监听 MongoDB 集合的变化?

4

将profilinglevel设置为2是记录所有查询的另一个选项。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接