MongoDB registra todas las consultas

169

La pregunta es tan básica como simple ... ¿Cómo se registran todas las consultas en un archivo de registro capaz de "cola" en mongodb?

Yo he tratado:

  • establecer el nivel de perfil
  • configurar el inicio lento del parámetro ms
  • mongod con la opción -vv

El /var/log/mongodb/mongodb.log sigue mostrando solo el número actual de conexiones activas ...

João Rocha da Silva
fuente
mongod -vvfuncionó para mí
fguillen

Respuestas:

259

Puede registrar todas las consultas:

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

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

db.setProfilingLevel(2) significa "registrar todas las operaciones".

Kristóf Dombi
fuente
3
De un vistazo, parece que esta es una mejor respuesta que la respuesta aceptada.
Ehtesh Choudhury
2
No mejor, dado que las preguntas piden un archivo de registro disponible, pero definitivamente útil, en casos en los que no tiene acceso a los archivos de registro, solo el shell mongo, como el que me trajo aquí :)
inolasco
11
Traté de establecer el nivel de creación de perfiles en 2 pero también necesitaba establecer el segundo parámetro en -1, comodb.setProfilingLevel(2,-1)
andresigualada
44
Para aquellos interesados ​​en dónde van los registros, el documento dice: mongod escribe el resultado del generador de perfiles de la base de datos en la system.profilecolección.
totymedli
55
db.system.profile.find().pretty()no da nada por mí
node_saini
84

Terminé resolviendo esto comenzando mongod de esta manera (martillado y feo, sí ... pero funciona para el entorno de desarrollo):

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

Esto permite la creación de perfiles y establece el umbral para "consultas lentas" como 1 ms, lo que hace que todas las consultas se registren como "consultas lentas" en el archivo:

/var/log/mongodb/mongodb.log

Ahora obtengo salidas de registro continuas usando el comando:

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

Un ejemplo de registro:

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
fuente
66
¿Debería ser equivalente a agregar profile=1y slowms=1líneas /etc/mongodb.conf?
Andrew Magee
No pude encontrar /var/log/mongodb/mongodb.log pero estaba iniciando sesión en la consola, lo que necesitaba. Gracias
auhuman
44
Solo puede agregar --profile=2de /etc/mongodb.confacuerdo con los documentos oficiales de Mongo, todas las operaciones se registrarán.
toske
1
@auhuman ¿Dónde escribir el comando "tail -f /var/log/mongodb/mongodb.log"?
Príncipe mestizo
55
No es necesario reiniciar, simplemente puede usar db.setProfilingLevel(level,slowms). Por ejemplo: db.setProfilingLevel(2,1)establecerá el nivel en 2 y el umbral de consulta lenta en 1 ms.
Abhishek Gupta
25

MongoDBtiene una característica sofisticada de perfilado. El registro ocurre en la system.profilecolección. Los registros se pueden ver desde:

db.system.profile.find()

Hay 3 niveles de registro ( fuente ):

  • Nivel 0 : el generador de perfiles está apagado, no recopila ningún dato. mongod siempre escribe operaciones más largas que el umbral slowOpThresholdMs en su registro. Este es el nivel de perfil predeterminado.
  • Nivel 1 : recopila datos de perfiles solo para operaciones lentas. Por defecto, las operaciones lentas son aquellas más lentas que 100 milisegundos. Puede modificar el umbral para operaciones "lentas" con la opción de tiempo de ejecución slowOpThresholdMs o el comando setParameter. Consulte la sección Especificar el umbral para operaciones lentas para obtener más información.
  • Nivel 2 : recopila datos de perfiles para todas las operaciones de la base de datos.

Para ver en qué nivel de perfil se está ejecutando la base de datos, use

db.getProfilingLevel()

y para ver el estado

db.getProfilingStatus()

Para cambiar el estado del perfil, use el comando

db.setProfilingLevel(level, milliseconds)

Donde se levelrefiere al nivel de creación de perfiles y millisecondses el tiempo de duración de las consultas que deben registrarse. Para desactivar el registro, use

db.setProfilingLevel(0)

La consulta para buscar en la colección de perfiles del sistema todas las consultas que tomaron más de un segundo, ordenadas por marca de tiempo descendente, será

db.system.profile.find( { millis : { $gt:1000 } } ).sort( { ts : -1 } )
Zameer
fuente
1
Según la documentación, LOGLEVEL 0 hace no significa "no registro", pero registra una consulta lenta: "el perfilador está apagado, no recoge ningún dato mongod siempre escribe las operaciones ya que el umbral slowOpThresholdMs a su registro." src: docs.mongodb.com/v3.2/tutorial/manage-the-database-profiler/…
kayn
23

Hice una herramienta de línea de comandos para activar la actividad del generador de perfiles y ver los registros de una manera capaz de "cola" : "mongotail" .

Pero la característica más interesante (también me gusta tail) es ver los cambios en "tiempo real" con la -fopción, y ocasionalmente filtrar el resultado greppara encontrar una operación en particular.

Consulte la documentación y las instrucciones de instalación en: https://github.com/mrsarm/mongotail

Mariano Ruiz
fuente
2
Esta es la respuesta más completa al OP. especialmente con respecto al requisito de 'cola'.
Luke W
11

Una vez perfilado nivel se ajusta utilizando db.setProfilingLevel(2).

El siguiente comando imprimirá la última consulta ejecutada.
También puede cambiar el límite (5) para ver menos / más consultas.
$ nin: filtrará las consultas de perfil e índices
Además, use la proyección de consulta {'query': 1} para ver solo el campo de consulta

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

Registros con solo proyección de consulta

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

si desea que las consultas se registren en el archivo de registro mongodb, debe establecer tanto el nivel de registro como el perfil, como por ejemplo:

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

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

Establecer solo el perfil no tendría las consultas registradas en el archivo, por lo que solo puede obtenerlo de

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

Los datos del generador de perfiles se escriben en una colección en su base de datos, no en un archivo. Ver http://docs.mongodb.org/manual/tutorial/manage-the-database-profiler/

Recomendaría usar el servicio MMS de 10gen y alimentar los datos del generador de perfiles de desarrollo allí, donde puede filtrarlos y ordenarlos en la interfaz de usuario.

Hans N. Hjort
fuente
1
Sí, después de activar el perfil de nivel 2, se agrega una colección a la base de datos. Sin embargo, tener que volver a cargar una interfaz gráfica de usuario o ejecutar un comando cada vez que realizo la depuración es un PITA al final del día ... Es por eso que quería un archivo de registro disponible.
João Rocha da Silva
4

Establecer profilinglevel en 2 es otra opción para registrar todas las consultas.

Shnkc
fuente
3

Recomiendo visitar mongosniff. Esta herramienta puede hacer todo lo que quieras y más. Especialmente puede ayudar a diagnosticar problemas con sistemas mongo de mayor escala y cómo se enrutan las consultas y de dónde provienen, ya que funciona al escuchar su interfaz de red para todas las comunicaciones relacionadas con mongo.

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

Daniel Williams
fuente
De acuerdo con esa página, solo funciona en UNIX enviros, y no lo tengo en mi directorio bin en Windows. ¿Alguna ventana recomendada equiv?
propagado el
¿Está ejecutando en un servidor remoto de Windows (nube azul, etc.) o localmente en su PC? Si todo es localmente, Wirehark será más que suficiente. Para instalarlo en Windows, deberá compilar mongosniff.exe, que está un poco indocumentado. Sigue las instrucciones de Linux pero necesita instalar la versión de desarrollo de winpcap.
Daniel Williams
Gracias por la respuesta. Terminé siendo capaz de obtener la información que necesitaba del perfilador de mongo, pero mantendré a Wirehark en mi bolsillo si surge algo más serio.
propagado el
1

Escribí un script que imprimirá el registro del perfil del sistema en tiempo real a medida que entren las consultas. Primero debe habilitar el registro como se indica en otras respuestas. Necesitaba esto porque estoy usando el Subsistema de Windows para Linux, para el cual la cola todavía no funciona.

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

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

Luego

db.adminCommand( { getLog : "global" } )
LiebresH P
fuente
55
¡Bienvenido a Stack Overflow! Si bien este código puede resolver la pregunta, incluir una explicación realmente ayuda a mejorar la calidad de su publicación.
Shree
1

Esto se preguntó hace mucho tiempo, pero aún puede ayudar a alguien:

El generador de perfiles MongoDB registra todas las consultas en el sistema de recopilación con tope.perfil . Ver esto: perfil de base de datos

  1. Inicie la instancia mongod con la --profile=2opción que permite registrar todas las consultas O si las instancias mongod ya se están ejecutando, desde mongoshell, ejecute db.setProfilingLevel(2)después de seleccionar la base de datos. (se puede verificar por db.getProfilingLevel(), que debería volver 2)
  2. Después de esto, he creado un script que utiliza el cursor de Taong de mongodb para ajustar esta colección system.profile y escribir las entradas en un archivo. Para ver los registros que sólo tiene que la cola es: tail -f ../logs/mongologs.txt. Este script se puede iniciar en segundo plano y registrará todas las operaciones en la base de datos del archivo.

Mi código para el cursor disponible para la colección system.profile está en nodejs; registra todas las operaciones junto con las consultas que ocurren en cada colección de 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'))
    })

});

}

Para el cursor disponible en python usando pymongo, consulte el siguiente código que filtra para MyCollection y solo inserta la operación:

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)

Nota: El cursor disponible solo funciona con colecciones con límite. No se puede usar para registrar operaciones en una colección directamente, en su lugar use filter:'ns': 'MyDb.MyCollection'

Nota: Entiendo que los nodos anteriores y el código de Python pueden no ser de mucha ayuda para algunos. Acabo de proporcionar los códigos de referencia.

Utilice este enlace para buscar documentación para el cursor disponible en su idioma / controlador . Controladores Mongodb

Otra característica que he agregado después de este logrotate .

Ankit
fuente