190

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

我努力了:

  • 设置分析级别
  • 设置慢速 ms 参数启动
  • 带有 -vv 选项的 mongod

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

4

16 回答 16

288

您可以记录所有查询:

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

于 2014-02-12T11:01:12.347 回答
88

我最终通过像这样启动 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
于 2013-03-04T15:07:03.473 回答
36

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

于 2015-04-24T14:03:52.017 回答
28

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是需要记录查询的持续时间的毫秒数。要关闭日志记录,请使用

db.setProfilingLevel(0)

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

db.system.profile.find( { millis : { $gt:1000 } } ).sort( { ts : -1 } )
于 2016-09-05T11:17:30.360 回答
22

我制作了一个命令行工具来激活分析器活动并以“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查看变化,并偶尔过滤结果以查找特定操作。-fgrep

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

于 2015-02-24T19:17:36.183 回答
13

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

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

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

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

db.system.profile.find().pretty()
于 2019-01-21T22:24:39.430 回答
11

一旦使用db.setProfilingLevel(2).

下面的命令将打印最后执行的查询。
您也可以更改 limit(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()
于 2015-10-23T16:11:38.883 回答
7

探查器数据被写入数据库中的集合,而不是文件。请参阅http://docs.mongodb.org/manual/tutorial/manage-the-database-profiler/

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

于 2013-03-04T14:56:40.290 回答
4

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

于 2013-11-27T15:58:01.433 回答
4

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

如果我是对的,您必须启用复制。信息来自这个问题的答案How to listen for changes to a MongoDB collection?

于 2013-03-04T14:57:46.220 回答
4
db.setProfilingLevel(2,-1)

这行得通!它在 mongod 日志文件中记录了所有查询信息

于 2021-01-06T16:59:24.277 回答
3

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

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

于 2013-12-17T20:33:20.120 回答
1

我编写了一个脚本,该脚本将在查询进入时实时打印出 system.profile 日志。您需要首先启用日志记录,如其他答案中所述。我需要这个,因为我正在使用适用于 Linux 的 Windows 子系统,但 tail 仍然无法正常工作。

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

于 2016-12-14T14:53:18.800 回答
1
db.adminCommand( { getLog: "*" } )

然后

db.adminCommand( { getLog : "global" } )
于 2019-05-24T06:42:45.063 回答
1

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

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

  1. --profile=2使用启用记录所有查询 的选项启动 mongod 实例,或者如果 mongod 实例已经在运行,从 mongoshell,db.setProfilingLevel(2)在选择数据库后运行。(可以通过 验证 db.getProfilingLevel(),应该返回2
  2. 在此之后,我创建了一个脚本,它利用 mongodb 的可尾游标来尾随这个 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)

注意:Tailable 光标仅适用于有上限的集合。它不能用于直接记录对集合的操作,而是使用过滤器:'ns': 'MyDb.MyCollection'

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

使用此链接在您的语言/驱动程序选择中查找可尾光标的文档Mongodb Drivers

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

于 2019-09-09T11:27:26.180 回答
0

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

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

于 2018-12-17T18:25:58.280 回答