MongoDB rejestruje wszystkie zapytania

169

Pytanie jest tak proste, jak proste ... Jak logować wszystkie zapytania w pliku dziennika w stanie „tail” w mongodb?

Próbowałem:

  • ustawienie poziomu profilowania
  • ustawienie powolnego uruchamiania parametru ms
  • mongod z opcją -vv

/Var/log/mongodb/mongodb.log wyświetla tylko aktualną liczbę aktywnych połączeń ...

João Rocha da Silva
źródło
mongod -vvpracował dla mnie
fguillen

Odpowiedzi:

259

Możesz rejestrować wszystkie zapytania:

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

Źródło: http://docs.mongodb.org/manual/reference/method/db.setProfilingLevel/

db.setProfilingLevel(2) oznacza „rejestruj wszystkie operacje”.

Kristóf Dombi
źródło
3
Na pierwszy rzut oka wygląda na to, że jest to lepsza odpowiedź niż zaakceptowana odpowiedź.
Ehtesh Choudhury
2
Nie lepiej, biorąc pod uwagę, że pytanie dotyczy pliku dziennika, który można toczyć, ale zdecydowanie przydatne, w przypadkach, gdy nie masz dostępu do plików dziennika, tylko powłokę mongo, taką jak ta, która mnie tu przywiozła :)
inolasco
11
Próbowałem ustawić poziom profilowania na 2, ale musiałem również ustawić drugi parametr na -1, na przykładdb.setProfilingLevel(2,-1)
andresigualada
4
Dla zainteresowanych, dokąd trafiają dzienniki, dokument podaje: mongod zapisuje dane wyjściowe profilera bazy danych do system.profilekolekcji.
totymedli
5
db.system.profile.find().pretty()nic dla mnie nie daje
node_saini
84

Skończyło się na rozwiązaniu tego, zaczynając mongod w ten sposób (młotkowany i brzydki, tak ... ale działa dla środowiska programistycznego):

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

Umożliwia to profilowanie i ustawia próg dla „wolnych zapytań” na 1 ms, powodując, że wszystkie zapytania są rejestrowane jako „wolne zapytania” w pliku:

/var/log/mongodb/mongodb.log

Teraz otrzymuję ciągłe dane wyjściowe dziennika za pomocą polecenia:

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

Przykładowy dziennik:

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
João Rocha da Silva
źródło
6
Czy powinno to być równoznaczne z dodawaniem profile=1i slowms=1wierszami /etc/mongodb.conf?
Andrew Magee,
Nie mogłem znaleźć /var/log/mongodb/mongodb.log, ale logowałem się w konsoli, której potrzebowałem. Dzięki
auhuman
4
Można po prostu dodać --profile=2do /etc/mongodb.confurzędowych, zgodnie z docs Mongo, wszelkie wszystkie operacje będą rejestrowane.
toske
1
@auhuman Gdzie napisać polecenie „tail -f /var/log/mongodb/mongodb.log”?
Książę Półkrwi
5
Nie ma potrzeby ponownego uruchamiania, możesz po prostu użyć db.setProfilingLevel(level,slowms). Na przykład: db.setProfilingLevel(2,1)ustawi poziom na 2, a próg wolnego zapytania na 1 ms.
Abhishek Gupta
25

MongoDBposiada wyrafinowaną funkcję profilowania. Rejestrowanie odbywa się w system.profilekolekcji. Dzienniki można zobaczyć z:

db.system.profile.find()

Istnieją 3 poziomy logowania ( źródło ):

  • Poziom 0 - profiler jest wyłączony, nie zbiera żadnych danych. mongod zawsze zapisuje operacje dłuższe niż próg slowOpThresholdMs do swojego dziennika. To jest domyślny poziom profilera.
  • Poziom 1 - zbiera dane profilowe tylko dla wolnych operacji. Domyślnie powolne operacje to te wolniejsze niż 100 milisekund. Próg dla „wolnych” operacji można zmodyfikować za pomocą opcji środowiska wykonawczego slowOpThresholdMs lub polecenia setParameter. Aby uzyskać więcej informacji, zobacz sekcję Określanie progu dla powolnych operacji.
  • Poziom 2 - zbiera dane profilujące dla wszystkich operacji na bazie danych.

Aby zobaczyć, na jakim poziomie profilowania działa baza danych, użyj

db.getProfilingLevel()

i zobaczyć status

db.getProfilingStatus()

Aby zmienić stan profilowania, użyj polecenia

db.setProfilingLevel(level, milliseconds)

Gdzie levelodnosi się do poziomu profilowania i millisecondsjest ms, przez jaki czas trwania zapytania muszą być rejestrowane. Aby wyłączyć rejestrowanie, użyj

db.setProfilingLevel(0)

Zapytanie mające na celu przeszukanie kolekcji profili systemowych dla wszystkich zapytań, które trwały dłużej niż jedną sekundę, uporządkowane według malejącej sygnatury czasowej, będzie

db.system.profile.find( { millis : { $gt:1000 } } ).sort( { ts : -1 } )
Zameer
źródło
1
Zgodnie z dokumentacją, LogLevel 0 robi nie oznacza „bez logowania”, ale rejestruje powolnych zapytań: „profiler jest wyłączony, nie zbiera żadnych danych mongod zawsze pisze działalność dłużej niż próg slowOpThresholdMs do swojego dziennika.” src: docs.mongodb.com/v3.2/tutorial/manage-the-database-profiler/…
kayn
23

Zrobiłem narzędzie wiersza poleceń, aby aktywować aktywność profilera i zobaczyć dzienniki w sposób „ogonowy” : „mongotail” .

Ale bardziej interesującą funkcją (również podobną tail) jest oglądanie zmian w czasie rzeczywistym” z -fopcją i od czasu do czasu filtrowanie wyniku w grepcelu znalezienia określonej operacji.

Zobacz dokumentację i instrukcje instalacji na: https://github.com/mrsarm/mongotail

Mariano Ruiz
źródło
2
jest to najpełniejsza odpowiedź na PO. zwł. w odniesieniu do wymogu umożliwiającego ogonowanie.
Łukasz W.
11

Po ustawieniu poziomu profilowania za pomocą db.setProfilingLevel(2).

Poniższe polecenie wydrukuje ostatnie wykonane zapytanie.
Możesz także zmienić limit (5), aby zobaczyć mniej / więcej zapytań.
$ nin - odfiltruje zapytania dotyczące profili i indeksów
Ponadto użyj projekcji zapytania {'query': 1} tylko do przeglądania pola zapytania

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

Dzienniki zawierające tylko projekcję zapytań

db.system.profile.find(
{ 
    ns: { 
        $nin : ['meteor.system.profile','meteor.system.indexes']
    }
},
{'query':1}
).limit(5).sort( { ts : -1 } ).pretty()
Faiz Mohamed Haneef
źródło
10

jeśli chcesz, aby zapytania były rejestrowane w pliku dziennika mongodb, musisz ustawić zarówno poziom dziennika, jak i profilowanie, na przykład:

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

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

Ustawienie samego profilowania nie spowodowałoby rejestrowania zapytań do pliku, więc można je uzyskać tylko z

db.system.profile.find().pretty()
DariusNica
źródło
7

Dane profilera są zapisywane w kolekcji w Twojej bazie danych, a nie do pliku. Zobacz http://docs.mongodb.org/manual/tutorial/manage-the-database-profiler/

Poleciłbym korzystanie z usługi MMS 10gen i przekazywać tam dane programistyczne profilera, gdzie można je filtrować i sortować w interfejsie użytkownika.

Hans N. Hjort
źródło
1
Tak, po aktywowaniu profilowania na poziomie 2 kolekcja jest dodawana do bazy danych. Jednak konieczność ponownego ładowania gui lub uruchamiania polecenia za każdym razem, gdy wykonuję debugowanie, to PITA na koniec dnia ... Dlatego chciałem udostępnić plik dziennika.
João Rocha da Silva
4

Ustawienie profilinglevel na 2 to kolejna opcja rejestrowania wszystkich zapytań.

Shnkc
źródło
3

Polecam sprawdzić mongosniff. To narzędzie może zrobić wszystko, co chcesz, a nawet więcej. W szczególności może pomóc zdiagnozować problemy z systemami mongo na większą skalę oraz sposobem kierowania zapytań i ich pochodzeniem, ponieważ działa poprzez nasłuchiwanie interfejsu sieciowego dla całej komunikacji związanej z mongo.

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

Daniel Williams
źródło
Według tej strony działa tylko w środowisku UNIX i nie mam go w moim katalogu bin dir w systemie Windows. Jakieś zalecane odpowiedniki systemu Windows?
propagowane
Czy pracujesz na zdalnym serwerze Windows (lazurowa chmura itp.) Czy lokalnie na swoim komputerze? Jeśli to wszystko lokalnie, wireshark będzie więcej niż wystarczający. Aby zainstalować go w systemie Windows, musisz skompilować mongosniff.exe, który jest nieco nieudokumentowany. Postępujesz zgodnie z instrukcjami Linuksa, ale musisz zainstalować wersję rozwojową winpcap.
Daniel Williams,
Dziękuję za odpowiedź. Skończyło się na tym, że udało mi się wydobyć potrzebne informacje z programu Mongo Profiler, ale zachowam wireshark w kieszeni, jeśli znowu stanie się coś poważniejszego.
propagowane
1

Napisałem skrypt, który wydrukuje system.profile zaloguj się w czasie rzeczywistym w miarę pojawiania się zapytań. Musisz najpierw włączyć logowanie, jak podano w innych odpowiedziach. Potrzebowałem tego, ponieważ używam podsystemu Windows dla systemu Linux, dla którego ogon nadal nie działa.

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

user3413723
źródło
1
db.adminCommand( { getLog: "*" } )

Następnie

db.adminCommand( { getLog : "global" } )
HareesH P
źródło
5
Witamy w Stack Overflow! Chociaż ten kod może rozwiązać problem, dołączenie wyjaśnienia naprawdę pomaga poprawić jakość twojego postu.
Shree
1

Zadano to dawno temu, ale może to komuś pomóc:

Profiler MongoDB rejestruje wszystkie zapytania w ograniczonym kolekcji system.profile . Zobacz to: profiler bazy danych

  1. Uruchom instancję mongod z --profile=2opcją włączającą logowanie wszystkich zapytań LUB jeśli instancje mongod już działają, z mongoshell uruchom db.setProfilingLevel(2)po wybraniu bazy danych. (można to zweryfikować przez db.getProfilingLevel(), który powinien zwrócić2 )
  2. Następnie stworzyłem skrypt, który wykorzystuje kursor token mongodb do śledzenia tej kolekcji system.profile i zapisywania wpisów w pliku. Aby wyświetlić dzienniki Muszę tylko ogon go: tail -f ../logs/mongologs.txt. Ten skrypt można uruchomić w tle i będzie rejestrował wszystkie operacje na bazie danych w pliku.

Mój kod dla kursora dostępnego dla kolekcji system.profile jest w nodejs; rejestruje wszystkie operacje wraz z zapytaniami zachodzącymi w każdej kolekcji 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'))
    })

});

}

W przypadku kursora dostępnego w Pythonie korzystającym z pymongo, zapoznaj się z następującym kodem, który filtruje dla MyCollection i tylko operację wstawiania:

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)

Uwaga: Kursor dostępny działa tylko w przypadku kolekcji z ograniczeniami. Nie można go używać do bezpośredniego rejestrowania operacji na kolekcji, zamiast tego użyj filtru:'ns': 'MyDb.MyCollection'

Uwaga: Rozumiem, że powyższy kod nodejs i Python może nie być zbyt pomocny dla niektórych. Właśnie podałem kody w celach informacyjnych.

Użyj tego łącza, aby znaleźć dokumentację dotyczącą kursora dostępnego w wybranym języku / sterowniku Mongodb Drivers

Kolejna funkcja, którą dodałem po tym logrotate .

Ankit
źródło