MongoDB记录所有查询

这个问题既简单又基本。如何将所有查询记录在mongodb中的“尾部”日志文件中?

我试过:

  • 设置概要级别
  • 设置启动慢ms参数
  • 使用-vv选项Mongod

/var/log/mongodb/mongodb.log一直显示当前活动连接的数量…

218852 次浏览

分析器数据被写入DB中的集合,而不是文件。看到http://docs.mongodb.org/manual/tutorial/manage-the-database-profiler/

我建议使用10gen的MMS服务,并在那里提供开发剖析器数据,在那里你可以在UI中过滤和排序。

我认为虽然不优雅,oplog 可以可以部分用于此目的:它记录所有的写操作——但不记录读操作……

如果我没猜错的话,你必须马上启用复制。该信息来自这个答案,来自这个问题:如何监听MongoDB集合的变化?

我最终通过像这样开始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

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

我建议你看看mongosniff。这个工具可以做任何你想做的事情,甚至更多。特别是它可以帮助诊断大规模mongo系统的问题,以及查询是如何路由的以及它们来自哪里,因为它是通过监听您的网络接口进行所有与mongo相关的通信来工作的。

http://docs.mongodb.org/v2.2/reference/mongosniff/

您可以记录所有查询:

$ 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)表示“记录所有操作”。

我做了一个命令行工具来激活分析器活动,并以“tail"能力的方式查看日志——>“mongotail":

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

但更有趣的特性(也像tail)是使用-f选项查看“真正的time"中的变化,并偶尔使用grep过滤结果以查找特定的操作。

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

因为它谷歌第一个答案…
对于版本3

$ mongo
MongoDB shell version: 3.0.2
connecting to: test
> use myDb
switched to db
> db.setLogLevel(1)

http://docs.mongodb.org/manual/reference/method/db.setLogLevel/

一旦使用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()

MongoDB有一个复杂的分析特性。日志记录发生在system.profile集合中。日志内容如下:

db.system.profile.find()

有3个日志级别():

  • 0级 -分析器关闭,不收集任何数据。mongod总是将长于slowOpThresholdMs阈值的操作写入其日志。这是默认的分析器级别。
  • 1级 -仅为慢操作收集分析数据。默认情况下,慢速操作为慢于100毫秒的操作。 您可以使用slowOpThresholdMs runtime选项或setParameter命令修改“慢”操作的阈值。有关详细信息,请参见为慢速操作指定阈值部分
  • 2级 -收集所有数据库操作的分析数据。

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

db.getProfilingLevel()

并查看状态

db.getProfilingStatus()

要更改分析状态,使用该命令

db.setProfilingLevel(level, milliseconds)

其中level指的是分析级别,而milliseconds是需要记录查询持续时间的ms。若要关闭日志记录,请使用

db.setProfilingLevel(0)

在系统概要集合中查找耗时超过一秒的所有查询(按时间戳降序排序)的查询将为

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

我写了一个脚本,将打印出系统。当查询进来时,配置文件实时登录。如其他回答中所述,您需要首先启用日志记录。我需要这个,因为我正在使用Linux的Windows子系统,对于它,tail仍然不起作用。

https://github.com/dtruel/mongo-live-logger

尝试这个包来跟踪所有的查询(没有oplog操作):https://www.npmjs.com/package/mongo-tail-queries

(免责声明:我写这个包正是为了这个需要)

如果你想要查询记录到mongodb日志文件,你必须同时设置 日志级别和分析,例如:

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

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

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

db.system.profile.find().pretty()
db.adminCommand( { getLog: "*" } )

然后

db.adminCommand( { getLog : "global" } )

很久以前有人问过这个问题,但这仍然可以帮助到一些人:

MongoDB分析器将所有查询记录在有上限的集合system.profile中。看这个:数据库分析器

  1. 使用--profile=2选项启动mongod实例,允许记录所有查询 OR如果mongod instances已经在运行,在mongoshell中,选择database后运行db.setProfilingLevel(2)。(它可以通过db.getProfilingLevel()验证,返回2)
  2. 在这之后,我创建了一个脚本,利用mongodb的tailable光标来跟踪这个系统。配置文件集合并将条目写入文件。 要查看日志,我只需要跟踪它:tail -f ../logs/mongologs.txt。 此脚本可以在后台启动,它将记录文件中对db的所有操作

我为系统编写的可尾游标代码。配置文件收集在nodejs中;它记录MyDb的每个集合中发生的所有操作和查询:

const MongoClient = require('mongodb').MongoClient;
const assert = require('assert');
const fs = require('fs');
const file = '../logs/mongologs'
// Connection URL
const url = 'mongodb://localhost:27017';


// Database Name
const dbName = 'MyDb';
//Mongodb connection


MongoClient.connect(url, function (err, client) {
assert.equal(null, err);
const db = client.db(dbName);
listen(db, {})
});


function listen(db, conditions) {
var filter = { ns: { $ne: 'MyDb.system.profile' } }; //filter for query
//e.g. if we need to log only insert queries, use {op:'insert'}
//e.g. if we need to log operation on only 'MyCollection' collection, use {ns: 'MyDb.MyCollection'}
//we can give a lot of filters, print and check the 'document' variable below


// set MongoDB cursor options
var cursorOptions = {
tailable: true,
awaitdata: true,
numberOfRetries: -1
};


// create stream and listen
var stream = db.collection('system.profile').find(filter, cursorOptions).stream();


// call the callback
stream.on('data', function (document) {
//this will run on every operation/query done on our database
//print 'document' to check the keys based on which we can filter
//delete data which we dont need in our log file


delete document.execStats;
delete document.keysExamined;
//-----
//-----


//append the log generated in our log file which can be tailed from command line
fs.appendFile(file, JSON.stringify(document) + '\n', function (err) {
if (err) (console.log('err'))
})


});


}

对于python中使用pymongo的可尾游标,请参考以下代码,该代码过滤MyCollection并且只进行插入操作:

import pymongo
import time
client = pymongo.MongoClient()
oplog = client.MyDb.system.profile
first = oplog.find().sort('$natural', pymongo.ASCENDING).limit(-1).next()


ts = first['ts']
while True:
cursor = oplog.find({'ts': {'$gt': ts}, 'ns': 'MyDb.MyCollection', 'op': 'insert'},
cursor_type=pymongo.CursorType.TAILABLE_AWAIT)
while cursor.alive:
for doc in cursor:
ts = doc['ts']
print(doc)
print('\n')
time.sleep(1)

注意:可尾随游标仅适用于有上限的集合。它不能直接用于记录对集合的操作,而是使用filter: 'ns': 'MyDb.MyCollection'

注意:我明白上面的nodejs和python代码可能对一些人没有太大的帮助。我只是提供了代码供参考

使用此链接查找语言/驱动程序选择Mongodb的司机中的可尾游标文档

我在logrotate之后添加的另一个功能。

db.setProfilingLevel(2,-1)

这个工作!它在mongod日志文件中记录了所有查询信息