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


169

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

Я пытался:

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

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


mongod -vvработал для меня
fguillen

Ответы:


259

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

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


3
На первый взгляд, похоже, что это лучший ответ, чем принятый ответ.
Эхтеш Чоудхури

2
Не лучше, учитывая, что вопросы требуют настраиваемого файла журнала, но, безусловно, полезно, в случаях, когда у вас нет доступа к файлам журнала, только оболочка mongo, как та, что привела меня сюда :)
inolasco

11
Я попытался установить уровень профилирования на 2, но мне также нужно было установить второй параметр на -1, какdb.setProfilingLevel(2,-1)
andresigualada

4
Для тех, кому интересно, куда ведут журналы, документ doc сообщает: mongod записывает выходные данные профилировщика базы данных в system.profileколлекцию.
Тотимедли

5
db.system.profile.find().pretty()ничего не дает для меня
node_saini

84

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

6
Должно ли это быть эквивалентно добавлению profile=1и slowms=1строкам /etc/mongodb.conf?
Эндрю Маги

Я не смог найти /var/log/mongodb/mongodb.log, но это входило в консоль, которая мне была нужна. Спасибо
auhuman

4
Вы можете просто добавить --profile=2в /etc/mongodb.confсоответствии с официальными документами Mongo, любые все операции будут зарегистрированы.
Тоскэ

1
@auhuman Где написать команду "tail -f /var/log/mongodb/mongodb.log" ??
Принц-полукровка

5
Не нужно перезагружать, вы можете просто использовать db.setProfilingLevel(level,slowms). Например: db.setProfilingLevel(2,1)установит уровень равным 2, а медленный порог запроса - 1 мс.
Абхишек Гупта


25

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

1
Согласно документации, LOGLEVEL- не делает не среднюю «нет регистрации» , но он регистрирует медленные запросы: «профайлер выключен, не собирают данные mongod всегда пишут операции больше , чем пороговое значение slowOpThresholdMs в свой журнал.» src: docs.mongodb.com/v3.2/tutorial/manage-the-database-profiler/…
kayn

23

Я создал инструмент командной строки, чтобы активировать активность профилировщика и просматривать журналы «хвостовым» способом: «mongotail» .

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

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


2
это самый полный ответ на ФП. особенно относительно требования «хвостовой».
Люк W

11

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

10

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

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

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

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

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

7

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

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


1
Да, после активации профилирования уровня 2, коллекция добавляется в базу данных. Однако необходимость перезагружать графический интерфейс или запускать команду каждый раз, когда я выполняю отладку, - это PITA в конце дня ... Вот почему я хотел настраиваемый файл журнала.
Жоао Роша да Силва

4

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

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


4

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


3

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

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


Согласно этой странице, он работает только в среде UNIX, и у меня его нет в папке bin в Windows. Любые рекомендуемые Windows эквивалент?
распространено

Вы работаете на удаленном сервере Windows (Azure Cloud и т. Д.) Или локально на вашем компьютере? Если все это локально, Wireshark будет более чем достаточно. Чтобы установить его на Windows, вам нужно собрать mongosniff.exe, который немного недокументирован. Вы следуете инструкциям linux, но вам нужно установить версию winpcap для разработчиков.
Даниэль Уильямс,

Спасибо за ответ. Я смог получить необходимую информацию из профилировщика Монго, но я буду держать проволочную акулу в своем кармане, если что-то более серьезное возникнет снова.
распространено

1

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

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


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

затем

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

5
Добро пожаловать в стек переполнения! Хотя этот код может решить вопрос, в том числе объяснение действительно помогает улучшить качество вашего поста.
Shree

1

Это было задано давно, но это может кому-то помочь:

Профилировщик 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 Drivers

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


0

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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.