Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB logging all queries

People also ask

Is MongoDB good for logging?

If you are only logging lots and lots of simple log messages, MongoDB is a very good choice as it scales so good.

Does MongoDB log slow queries?

In mongoDB, you can log slow query log as per your convenient for monitoring of your MongoDB either for collections scan or index scan. Most of the time, you have built an index and your query taking more time as per your expectation, so set profiling level and log slow query in MongoDB.


You can log all queries:

$ 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()

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

db.setProfilingLevel(2) means "log all operations".


I ended up solving this by starting mongod like this (hammered and ugly, yeah... but works for development environment):

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

This enables profiling and sets the threshold for "slow queries" as 1ms, causing all queries to be logged as "slow queries" to the file:

/var/log/mongodb/mongodb.log

Now I get continuous log outputs using the command:

tail -f /var/log/mongodb/mongodb.log

An example 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

Because its google first answer ...
For version 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/


MongoDB has a sophisticated feature of profiling. The logging happens in system.profile collection. The logs can be seen from:

db.system.profile.find()

There are 3 logging levels (source):

  • Level 0 - the profiler is off, does not collect any data. mongod always writes operations longer than the slowOpThresholdMs threshold to its log. This is the default profiler level.
  • Level 1 - collects profiling data for slow operations only. By default slow operations are those slower than 100 milliseconds. You can modify the threshold for “slow” operations with the slowOpThresholdMs runtime option or the setParameter command. See the Specify the Threshold for Slow Operations section for more information.
  • Level 2 - collects profiling data for all database operations.

To see what profiling level the database is running in, use

db.getProfilingLevel()

and to see the status

db.getProfilingStatus()

To change the profiling status, use the command

db.setProfilingLevel(level, milliseconds)

Where level refers to the profiling level and milliseconds is the ms of which duration the queries needs to be logged. To turn off the logging, use

db.setProfilingLevel(0)

The query to look in the system profile collection for all queries that took longer than one second, ordered by timestamp descending will be

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

I made a command line tool to activate the profiler activity and see the logs in a "tail"able way --> "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"}}
...

But the more interesting feature (also like tail) is to see the changes in "real time" with the -f option, and occasionally filter the result with grep to find a particular operation.

See documentation and installation instructions in: https://github.com/mrsarm/mongotail


if you want the queries to be logged to mongodb log file, you have to set both the log level and the profiling, like for example:

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

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

Setting only the profiling would not have the queries logged to file, so you can only get it from

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

Once profiling level is set using db.setProfilingLevel(2).

The below command will print the last executed query.
You may change the limit(5) as well to see less/more queries.
$nin - will filter out profile and indexes queries
Also, use the query projection {'query':1} for only viewing query field

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

Logs with only query projection

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