MongoDB记录所有查询

时间:2013-03-04 14:53:33

标签: mongodb logging

问题是基本的,因为它很简单...如何在mongodb中的“尾部”日志文件中记录所有查询?

我试过了:

  • 设置性能分析级别
  • 设置慢速ms参数
  • mongod with -vv option

/var/log/mongodb/mongodb.log只显示当前的活动连接数...

16 个答案:

答案 0 :(得分:227)

您可以记录所有查询:

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

答案 1 :(得分:77)

我最终通过启动像这样的mongod来解决这个问题(锤击和丑陋,是的......但是适用于开发环境):

mongod --profile=1 --slowms=1 &

这使得能够进行性能分析并将“慢速查询”的阈值设置为1ms,从而导致所有查询被记录为对文件的“慢查询”:

/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

答案 2 :(得分:30)

因为谷歌的第一个答案是......
对于版本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/

答案 3 :(得分:21)

MongoDB具有复杂的分析功能。日志记录发生在system.profile集合中。日志可以从以下地址看到:

db.system.profile.find()

有3个日志记录级别(source):

  • 等级0 - 分析器已关闭,不会收集任何数据。 mongod总是将比slowOpThresholdMs阈值更长的操作写入其日志。这是默认的探查器级别。
  • 级别1 - 仅收集慢速操作的分析数据。默认情况下,慢速操作慢于100毫秒。 您可以使用slowOpThresholdMs运行时选项或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 } )

答案 4 :(得分:20)

我制作了一个命令行工具来激活探查器活动并以&#34;尾部&#34;能够的方式查看日志:&#34; mongotail&#34; < /强>

但更有趣的功能(也类似于tail)是使用-f选项查看&#34;实时&#34; 中的更改,偶尔使用grep过滤结果以查找特定操作。

请参阅:https://github.com/mrsarm/mongotail

中的文档和安装说明

答案 5 :(得分:9)

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

答案 6 :(得分:7)

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

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

答案 7 :(得分:5)

如果要将查询记录到mongodb日志文件中,则必须同时设置两者 日志级别和配置文件,例如:

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

(请参阅https://docs.mongodb.com/manual/reference/method/db.setLogLevel

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

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

答案 8 :(得分:4)

我认为虽然不优雅,oplog 可以部分用于此目的:它记录所有写入 - 但不记录读取...

如果我是对的,你必须启用replicatoon。该信息来自此问题的this answerHow to listen for changes to a MongoDB collection?

答案 9 :(得分:4)

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

答案 10 :(得分:3)

我建议退房mongosniff。这个工具可以做你想要的一切,甚至更多。特别是它可以帮助诊断大规模mongo系统的问题,以及如何通过监听所有与mongo相关的通信的网络接口来确定路由以及它们的来源。

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

答案 11 :(得分:1)

我编写了一个脚本,可以在查询进入时实时打印出system.profile日志。您需要先按照其他答案中的说明启用日志记录。我之所以需要这个,是因为我使用Windows子系统Linux,但尾部仍然没有用。

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

答案 12 :(得分:1)

这是很久以前问过的,但这仍然可以帮助某人:

MongoDB Profiler将所有查询记录在上限集合 system.profile 中。看到这个:database profiler

  1. 使用--profile=2选项启动mongod实例,该选项可以记录所有查询 OR (如果已运行mongod实例),请从mongoshell中选择数据库后运行db.setProfilingLevel(2)。 (可以通过db.getProfilingLevel()进行验证,它应该返回2
  2. 在此之后,我创建了一个脚本,该脚本利用mongodb的tailable cursor来结尾这个system.profile集合并将条目写入文件中。 要查看日志,我只需要拖尾它即可:tail -f ../logs/mongologs.txt。 该脚本可以在后台启动,并将所有操作记录在文件中的数据库上。

我的system.profile集合可拖尾游标的代码在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'))
    })

});

}

对于使用pymongo的python中的可尾光标,请参考以下代码,该代码过滤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)

注意:可尾光标仅适用于加盖的集合。它不能用于直接记录对集合的操作,而要使用过滤器:'ns': 'MyDb.MyCollection'

注意:我了解上面的nodejs和python代码对某些人可能没有太大帮助。我刚刚提供了代码以供参考。

使用此链接可在您的语言/驱动程序选择Mongodb Drivers

中查找可尾光标的文档

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

答案 13 :(得分:1)

db.setProfilingLevel(2,-1)

这奏效了!它在 mongod 日志文件中记录了所有查询信息

答案 14 :(得分:0)

尝试使用此程序包跟踪所有查询(无oplog操作):https://www.npmjs.com/package/mongo-tail-queries

(免责声明:我正是出于这种需要编写了此程序包)

答案 15 :(得分:0)

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

然后

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