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
На перший погляд, схоже, що це краща відповідь, ніж прийнята відповідь.
Ehtesh Choudhury

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

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

4
Для тих, хто цікавиться, куди ходять журнали, doc заявляє: mongod записує висновки профілера бази даних в system.profileколекцію.
totymedli

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

84

Я врешті-решт вирішив це, запустивши подібний монгод (забито і потворно, так ... але працює на середовище розробки):

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, будь-які всі операції будуть реєструватися.
toske

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
це найбільш повна відповідь на ОП. особливо стосовно вимоги "здатність до хвоста".
Лука Ш

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 до бази даних додається колекція. Однак, перезавантажувати gui або виконувати команду кожного разу, коли я виконую налагодження, це PITA в кінці дня ... Ось чому я хотів отримати доступний файл журналу.
Жоао Роша да Сілва

4

Я думаю, що, хоча це не елегантно, опілог може бути частково використаний для цієї мети: він записує всі записи - але не читає ...

Ви повинні ввімкнути реплікату, якщо я маю рацію. Інформація з цієї відповіді з цього питання: Як слухати зміни в колекції MongoDB?


4

Встановлення рівня профілю 2 є ще одним варіантом реєстрації всіх запитів.


3

Рекомендую перевірити монгосніф. Цей інструмент може робити все, що завгодно, і більше. Особливо це може допомогти діагностувати проблеми із системами монго більшого масштабу та те, як направляються запити і звідки вони надходять, оскільки це працює, прослуховуючи ваш мережевий інтерфейс для всіх комунікацій, пов'язаних з монго.

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


Згідно з цією сторінкою, вона працює лише в середовищі UNIX, і я не маю її в своєму директорі для вікон. Будь-які рекомендовані windows equiv?
розповсюджується

Ви працюєте на віддаленому сервері Windows (блакитна хмара тощо) або локально на своєму ПК? Якщо все це локально, то проводів буде більш ніж достатньо. Щоб встановити його на Windows, вам потрібно буде скласти mongosniff.exe, який трохи недокументований. Ви слідуєте інструкціям Linux, але вам потрібно встановити розробну версію winpcap.
Даніель Вільямс

Дякую за відповідь. Я в кінцевому підсумку змогла отримати необхідну інформацію у профілера mongo, але я триматиму проводку в кишені, якщо знову виникне щось більш серйозне.
розповсюджується

1

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

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


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

Тоді

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

5
Ласкаво просимо до переповнення стека! Хоча цей код може вирішити питання, у тому числі пояснення дійсно допомагає покращити якість вашої публікації.
Шрі

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. Цей скрипт можна запустити у фоновому режимі, і він запише всю операцію на 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'))
    })

});

}

Щоб отримати доступний курсор у 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

Ще одна особливість, яку я додав після цього логротату .


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.