MongoDB регистрирует все запросы

Вопрос настолько же простой, насколько и простой... Как вы регистрируете все запросы в "хвостовом" файле журнала в mongodb?

Я пытался:

  • установка уровня профилирования
  • установка медленного запуска мс параметра
  • mongod с опцией -vv

/Var/log/mongodb/mongodb.log показывает только текущее количество активных соединений...

16 ответов

Решение

В итоге я решил эту проблему, запустив 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

Вы можете войти все запросы:

$ 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) означает "регистрировать все операции".

Потому что это первый ответ Google...
Для версии 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 имеет сложную функцию профилирования. Регистрация происходит в system.profile коллекция. Журналы можно увидеть из:

db.system.profile.find()

Есть 3 уровня ведения журнала ( источник):

  • Уровень 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 } )

Я создал инструмент командной строки для активации активности профилировщика и просмотра журналов "хвостовым" способом: "mongotail".

Но более интересная особенность (тоже нравится tail), чтобы увидеть изменения в "реальном времени" с -f вариант, и иногда фильтровать результат с grep найти конкретную операцию.

См. Документацию и инструкции по установке по адресу: https://github.com/mrsarm/mongotail

Если вы хотите, чтобы запросы регистрировались в файле журнала mongodb, вам нужно установить уровень журнала и профилирование, например:

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

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

Установка только профилирования не приведет к тому, что запросы будут записаны в файл, поэтому вы можете получить его только из

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

После того, как уровень профилирования установлен с помощью 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()

Данные профилировщика записываются в коллекцию в вашей БД, а не в файл. См. http://docs.mongodb.org/manual/tutorial/manage-the-database-profiler/

Я бы порекомендовал воспользоваться услугой MMS 10gen и направить туда данные профилировщика разработки, где вы можете фильтровать и сортировать их в пользовательском интерфейсе.

Установка profilinglevel в 2 - это еще одна опция для регистрации всех запросов.

Я думаю, что, хотя и не элегантно, оплог может быть частично использован для этой цели: он записывает все записи - но не чтения...

Вы должны включить репликацию, если я прав. Информация взята из этого ответа на этот вопрос: как прослушать изменения в коллекции MongoDB?

      db.setProfilingLevel(2,-1)

Это сработало! он регистрировал всю информацию о запросе в файле журнала mongod

Я рекомендую проверить Mongosniff. Этот инструмент может делать все, что вы хотите, и даже больше. Особенно это может помочь в диагностике проблем с крупномасштабными системами монго, а также о том, как маршрутизируются запросы и откуда они поступают, поскольку он работает, прослушивая сетевой интерфейс для всех сообщений, связанных с монго.

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

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

затем

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

Я написал скрипт, который будет распечатывать журнал system.profile в режиме реального времени при поступлении запросов. Сначала нужно включить ведение журнала, как указано в других ответах. Я нуждался в этом, потому что я использую Подсистему Windows для Linux, для которой хвост все еще не работает.

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

Об этом спрашивали давно, но это может кому-то помочь:

Профилировщик MongoDB регистрирует все запросы в закрытом файле system.profile. Смотрите это: профилировщик базы данных

  1. Запустите экземпляр mongod с --profile=2опция, которая включает регистрацию всех запросовИЛИ, если экземпляры 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'))
    })

});

}

Для настраиваемого курсора в 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)

Примечание. Настраиваемый курсор работает только с ограниченными коллекциями. Его нельзя использовать для непосредственного ведения журнала операций в коллекции, вместо этого используйте фильтр:'ns': 'MyDb.MyCollection'

Примечание: я понимаю, что приведенный выше код nodejs и python может не очень помочь некоторым. Я только что предоставил коды для справки.

Используйте эту ссылку, чтобы найти документацию для настраиваемого курсора в выбранном вами языке / драйвере. Драйверы Mongodb

Еще одна функция, которую я добавил после этого logrotate.

Попробуйте этот пакет, чтобы выполнить все запросы (без операций с оплогами): https://www.npmjs.com/package/mongo-tail-queries

(Отказ от ответственности: я написал этот пакет именно для этой необходимости)

Другие вопросы по тегам