【问题标题】:MongoDB logging all queriesMongoDB 记录所有查询
【发布时间】:2013-02-18 16:55:47
【问题描述】:

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

我试过了:

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

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

【问题讨论】:

  • mongod -vv 为我工作

标签: mongodb logging


【解决方案1】:

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

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

【讨论】:

  • 是的,在激活 2 级分析后,一个集合被添加到数据库中。但是,每次我执行调试时都必须重新加载 gui 或运行命令是一天结束时的 PITA ......这就是我想要一个可尾日志文件的原因。
【解决方案2】:

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

如果我是对的,您必须启用复制。资料来自this answer来自这个问题:How to listen for changes to a MongoDB collection?

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 这是否应该等同于在/etc/mongodb.conf 中添加profile=1slowms=1 行?
    • 我找不到 /var/log/mongodb/mongodb.log 但它正在登录控制台,这是我需要的。谢谢
    • 你可以根据Mongo官方文档将--profile=2添加到/etc/mongodb.conf,任何操作都会被记录。
    • @auhuman 在哪里写“tail -f /var/log/mongodb/mongodb.log”命令??
    • 无需重启即可使用db.setProfilingLevel(level,slowms)。例如:db.setProfilingLevel(2,1) 将设置级别为 2,慢查询阈值为 1ms。
    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

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

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

      【讨论】:

      • 根据该页面,它仅适用于 UNIX enviros,我在 windows 的 bin 目录中没有它。任何推荐的 windows equiv?
      • 您是在远程 Windows 服务器(Azure 云等)上运行,还是在您的 PC 上本地运行?如果都是本地的,wireshark 就绰绰有余了。要在 Windows 上安装它,您需要构建 mongosniff.exe,这有点无证。你按照linux的说明操作,但是你需要安装winpcap的开发版。
      • 感谢您的回复。我最终能够从 mongo 分析器中获取我需要的信息,但如果再次出现更严重的问题,我会将wireshark 放在口袋里。
      【解决方案6】:

      您可以记录所有查询:

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

      【讨论】:

      • 乍一看,这似乎是一个比接受的答案更好的答案。
      • 不是更好,因为这些问题要求提供一个可跟踪的日志文件,但绝对有用,在您无权访问日志文件的情况下,只有 mongo shell,比如带来我在这里:)
      • 我尝试将分析级别设置为 2,但我还需要将第二个参数设置为 -1,例如 db.setProfilingLevel(2,-1)
      • 对于那些对日志去向感兴趣的人,文档指出:mongod 将数据库分析器的输出写入system.profile 集合。
      • db.system.profile.find().pretty() 什么都没给我
      【解决方案7】:

      我制作了一个命令行工具来激活分析器活动并以 "tail"able 方式查看日志 --> "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 选项以“实时”查看变化,偶尔使用grep 过滤结果以查找一个特定的操作。

      查看文档和安装说明:https://github.com/mrsarm/mongotail

      【讨论】:

      • 这是对OP最完整的回应。尤其是关于'tail-able'要求。
      【解决方案8】:

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

      【讨论】:

        【解决方案9】:

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

        【讨论】:

          【解决方案10】:

          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 } )
          

          【讨论】:

          【解决方案11】:

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

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

          【讨论】:

            【解决方案12】:

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

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

            【讨论】:

              【解决方案13】:

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

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

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

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

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

              【讨论】:

                【解决方案14】:
                db.adminCommand( { getLog: "*" } )
                

                然后

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

                【讨论】:

                • 欢迎来到 Stack Overflow!虽然这段代码可以解决问题,但including an explanation 确实有助于提高帖子的质量。
                【解决方案15】:

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

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

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

                我的 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中的tailable cursor,请参考以下代码过滤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 之后添加的另一个功能。

                【讨论】:

                  【解决方案16】:
                  db.setProfilingLevel(2,-1)
                  

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

                  【讨论】:

                  • 日志文件可以在哪里找到...?
                  • 您可以在MongoDB的配置文件中归档日志文件路径信息。示例:“C:\Program Files\MongoDB\Server\4.0\bin\mongod.cfg”
                  猜你喜欢
                  • 1970-01-01
                  • 2018-04-27
                  • 2015-02-02
                  • 2021-06-05
                  • 1970-01-01
                  • 2014-06-10
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多