MongoDB protokolliert alle Abfragen

169

Die Frage ist so einfach wie einfach ... Wie protokollieren Sie alle Abfragen in einer "tail" -fähigen Protokolldatei in Mongodb?

Ich habe versucht:

  • Festlegen der Profilierungsstufe
  • Einstellen des langsamen ms-Parameters startet
  • mongod mit der Option -vv

Das /var/log/mongodb/mongodb.log zeigt immer nur die aktuelle Anzahl aktiver Verbindungen an ...

João Rocha da Silva
quelle
mongod -vvarbeitete für mich
fguillen

Antworten:

259

Sie können alle Abfragen protokollieren:

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

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

db.setProfilingLevel(2) bedeutet "alle Operationen protokollieren".

Kristóf Dombi
quelle
3
Auf den ersten Blick sieht es so aus, als wäre dies eine bessere Antwort als die akzeptierte Antwort.
Ehtesh Choudhury
2
Nicht besser, da die Fragen nach einer anpassbaren Protokolldatei fragen, aber auf jeden Fall nützlich, wenn Sie keinen Zugriff auf die Protokolldateien haben, nur auf die Mongo-Shell, wie die, die mich hierher gebracht hat :)
inolasco
11
Ich habe versucht, die Profilierungsstufe auf 2 zu setzen, aber ich musste auch den zweiten Parameter auf -1 setzen, wiedb.setProfilingLevel(2,-1)
andresigualada
4
Für diejenigen, die interessiert sind, wohin die Protokolle gehen, heißt es im Dokument: mongod schreibt die Ausgabe des Datenbankprofilers in die system.profileSammlung.
Totymedli
5
db.system.profile.find().pretty()gibt nichts für mich
node_saini
84

Am Ende habe ich dieses Problem gelöst, indem ich mongod wie folgt gestartet habe (gehämmert und hässlich, ja ... aber funktioniert für die Entwicklungsumgebung):

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

Dies aktiviert die Profilerstellung und legt den Schwellenwert für "langsame Abfragen" auf 1 ms fest, wodurch alle Abfragen als "langsame Abfragen" in der Datei protokolliert werden:

/var/log/mongodb/mongodb.log

Jetzt erhalte ich fortlaufende Protokollausgaben mit dem folgenden Befehl:

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

Ein Beispielprotokoll:

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
quelle
6
Sollte dies gleichbedeutend mit Hinzufügen profile=1und slowms=1Zeilen sein /etc/mongodb.conf?
Andrew Magee
Ich konnte /var/log/mongodb/mongodb.log nicht finden, aber es wurde in der Konsole protokolliert, die ich brauchte. Danke
auhuman
4
Sie können fügen Sie einfach --profile=2zu /etc/mongodb.conflaut offiziellen Mongo docs, alle alle Operationen werden protokolliert.
toske
1
@auhuman Wo schreibe ich den Befehl "tail -f /var/log/mongodb/mongodb.log"?
Halbblutprinz
5
Sie müssen nicht neu starten, sondern können es einfach verwenden db.setProfilingLevel(level,slowms). Zum Beispiel: db.setProfilingLevel(2,1)setzt den Pegel auf 2 und den langsamen Abfrageschwellenwert auf 1 ms.
Abhishek Gupta
25

MongoDBhat eine ausgefeilte Funktion der Profilerstellung. Die Protokollierung erfolgt in der system.profileSammlung. Die Protokolle können gesehen werden von:

db.system.profile.find()

Es gibt 3 Protokollierungsstufen ( Quelle ):

  • Stufe 0 - Der Profiler ist ausgeschaltet und sammelt keine Daten. mongod schreibt immer Operationen, die länger als der Schwellenwert für slowOpThresholdMs sind, in sein Protokoll. Dies ist die Standard-Profiler-Ebene.
  • Stufe 1 - sammelt Profildaten nur für langsame Operationen. Standardmäßig sind langsame Operationen langsamer als 100 Millisekunden. Sie können den Schwellenwert für "langsame" Vorgänge mit der Laufzeitoption slowOpThresholdMs oder dem Befehl setParameter ändern. Weitere Informationen finden Sie im Abschnitt Festlegen des Schwellenwerts für langsame Vorgänge.
  • Stufe 2 - sammelt Profildaten für alle Datenbankoperationen.

Verwenden Sie, um zu sehen, auf welcher Profilebene die Datenbank ausgeführt wird

db.getProfilingLevel()

und um den Status zu sehen

db.getProfilingStatus()

Verwenden Sie den Befehl, um den Profilstatus zu ändern

db.setProfilingLevel(level, milliseconds)

Wobei levelsich auf die Profilebene bezieht und millisecondsdie ms ist, von welcher Dauer die Abfragen protokolliert werden müssen. Verwenden Sie zum Deaktivieren der Protokollierung

db.setProfilingLevel(0)

Die Abfrage, die in der Systemprofilsammlung nach allen Abfragen gesucht werden soll, die länger als eine Sekunde gedauert haben, sortiert nach absteigendem Zeitstempel

db.system.profile.find( { millis : { $gt:1000 } } ).sort( { ts : -1 } )
Mohammed Zameer
quelle
1
Gemäß der Dokumentation, Loglevel 0 funktioniert nicht mean „keine Protokollierung“ , aber es langsame Abfragen protokolliert: „der Profiler ausgeschaltet ist, werden alle Daten nicht collect mongod immer Operationen länger als die slowOpThresholdMs Schwelle zu sein Protokoll schreibt.“ src: docs.mongodb.com/v3.2/tutorial/manage-the-database-profiler/…
Kayn
22

Ich habe ein Befehlszeilen-Tool erstellt, um die Profiler-Aktivität zu aktivieren und die Protokolle auf "tail " -fähige Weise anzuzeigen : "mongotail" .

Das interessantere Feature (auch wie tail) ist es jedoch, die Änderungen in "Echtzeit" mit der -fOption zu sehen und gelegentlich das Ergebnis mit grepzu filtern , um eine bestimmte Operation zu finden.

Siehe Dokumentation und Installationsanweisungen unter: https://github.com/mrsarm/mongotail

Mariano Ruiz
quelle
2
Dies ist die vollständigste Antwort auf das OP. insb. in Bezug auf die "Tail-fähige" Anforderung.
Luke W
11

Sobald die Profilstufe mit eingestellt ist db.setProfilingLevel(2).

Der folgende Befehl gibt die zuletzt ausgeführte Abfrage aus.
Sie können auch das Limit (5) ändern, um weniger / mehr Abfragen anzuzeigen.
$ nin - filtert Profil- und Indexabfragen heraus
. Verwenden Sie außerdem die Abfrageprojektion {'query': 1}, um nur das Abfragefeld anzuzeigen

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

Protokolle mit nur Abfrageprojektion

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

Wenn Sie möchten, dass die Abfragen in der Mongodb-Protokolldatei protokolliert werden, müssen Sie sowohl die Protokollstufe als auch die Profilerstellung festlegen, z. B.:

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

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

Wenn Sie nur die Profilerstellung festlegen, werden die Abfragen nicht in der Datei protokolliert, sodass Sie sie nur von abrufen können

db.system.profile.find().pretty()
DariusNica
quelle
7

Die Profilerdaten werden in eine Sammlung in Ihrer Datenbank geschrieben und nicht in eine Datei. Siehe http://docs.mongodb.org/manual/tutorial/manage-the-database-profiler/

Ich würde empfehlen, den MMS- Dienst von 10gen zu verwenden und dort Daten des Entwicklungsprofilers einzugeben , wo Sie sie in der Benutzeroberfläche filtern und sortieren können.

Hans N. Hjort
quelle
1
Ja, nach dem Aktivieren der Profilerstellung der Ebene 2 wird der Datenbank eine Sammlung hinzugefügt. Allerdings ist es am Ende des Tages eine PITA, jedes Mal, wenn ich ein Debugging durchführe, eine GUI neu laden oder einen Befehl ausführen zu müssen ... Deshalb wollte ich eine anpassbare Protokolldatei.
João Rocha da Silva
4

Das Festlegen der Profilebene auf 2 ist eine weitere Option zum Protokollieren aller Abfragen.

Shnkc
quelle
3

Ich empfehle mongosniff. Dieses Dosenwerkzeug kann alles tun, was Sie wollen und mehr. Insbesondere kann es dabei helfen, Probleme mit größeren Mongo-Systemen zu diagnostizieren und zu ermitteln, wie Abfragen weitergeleitet werden und woher sie kommen, da es auf Ihre Netzwerkschnittstelle für alle mongo-bezogenen Kommunikationen wartet.

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

Daniel Williams
quelle
Laut dieser Seite funktioniert es nur in UNIX-Umgebungen, und ich habe es nicht in meinem Bin-Verzeichnis in Windows. Irgendwelche empfohlenen Windows-Äquivalente?
propagiert
Laufen Sie auf einem Remote-Windows-Server (Azure Cloud usw.) oder lokal auf Ihrem PC? Wenn alles lokal ist, ist Wireshark mehr als ausreichend. Um es unter Windows zu installieren, müssen Sie mongosniff.exe erstellen, was etwas undokumentiert ist. Sie folgen den Linux-Anweisungen, müssen jedoch die Entwicklungsversion von winpcap installieren.
Daniel Williams
Danke für die Antwort. Am Ende konnte ich die benötigten Informationen aus dem Mongo-Profiler holen, aber ich werde Wireshark in meiner Tasche behalten, wenn wieder etwas Ernsthafteres auftaucht.
propagiert
1

Ich habe ein Skript geschrieben, das das system.profile-Protokoll in Echtzeit ausgibt, wenn Abfragen eingehen. Sie müssen zuerst die Protokollierung aktivieren, wie in anderen Antworten angegeben. Ich brauchte das, weil ich Windows Subsystem für Linux verwende, für das Tail immer noch nicht funktioniert.

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

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

Dann

db.adminCommand( { getLog : "global" } )
HareesH P.
quelle
5
Willkommen bei Stack Overflow! Während dieser Code die Frage lösen kann, hilft das Hinzufügen einer Erklärung wirklich, die Qualität Ihres Beitrags zu verbessern.
Shree
1

Dies wurde vor langer Zeit gefragt, aber dies kann immer noch jemandem helfen:

Der MongoDB-Profiler protokolliert alle Abfragen in der begrenzten Sammlung system.profile . Siehe dies: Datenbankprofiler

  1. Start mongod Instanz mit --profile=2Option , die alle Abfragen aktiviert die Protokollierung oder wenn mongod Instanzen bereits ausgeführt wird , von mongoshell, führte db.setProfilingLevel(2)nach der Auswahl Datenbank. (es kann überprüft werden durch db.getProfilingLevel(), welche zurückkehren sollte 2)
  2. Danach habe ich ein Skript erstellt, das den tailable Cursor von mongodb verwendet, um diese system.profile-Sammlung zu verfolgen und die Einträge in eine Datei zu schreiben. Um die Protokolle anzuzeigen, muss ich sie nur verfolgen : tail -f ../logs/mongologs.txt. Dieses Skript kann im Hintergrund gestartet werden und protokolliert alle Vorgänge auf der Datenbank in der Datei.

Mein Code für den abschließbaren Cursor für die system.profile-Auflistung befindet sich in nodejs. Es protokolliert alle Vorgänge zusammen mit Abfragen, die in jeder Sammlung von MyDb auftreten:

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

});

}

Informationen zum abschließbaren Cursor in Python mit Pymongo finden Sie im folgenden Code, der nach MyCollection filtert und nur Operationen einfügt:

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)

Hinweis: Der Cursor "Tailable" funktioniert nur mit begrenzten Sammlungen. Es kann nicht verwendet werden, um Vorgänge in einer Sammlung direkt zu protokollieren. Verwenden Sie stattdessen den Filter:'ns': 'MyDb.MyCollection'

Hinweis: Ich verstehe, dass die oben genannten Nodejs und der Python-Code für einige möglicherweise keine große Hilfe sind. Ich habe gerade die Codes als Referenz bereitgestellt.

Verwenden Sie diesen Link, um eine Dokumentation für den anpassbaren Cursor in den Mongodb-Treibern Ihrer Sprache / Treiberauswahl zu finden

Eine weitere Funktion, die ich nach diesem Logrotate hinzugefügt habe .

Ankit
quelle