MongoDB registrando todas as consultas

169

A questão é tão básica quanto simples ... Como você registra todas as consultas em um arquivo de log capaz de "cauda" no mongodb?

Eu tentei:

  • definindo o nível de criação de perfil
  • definir o parâmetro ms lento começando
  • mongod com a opção -vv

O /var/log/mongodb/mongodb.log continua mostrando apenas o número atual de conexões ativas ...

João Rocha da Silva
fonte
mongod -vvtrabalhou para mim
fguillen 02/09/19

Respostas:

259

Você pode registrar todas as 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()

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

db.setProfilingLevel(2) significa "registrar todas as operações".

Kristóf Dombi
fonte
3
À primeira vista, parece que essa é uma resposta melhor do que a resposta aceita.
Ehtesh Choudhury
2
Não é melhor, já que as perguntas solicitam um arquivo de log disponível, mas definitivamente útil, nos casos em que você não tem acesso aos arquivos de log, apenas o shell mongo, como o que me trouxe aqui :)
inolasco
11
Tentei configurar o nível de criação de perfis para 2, mas eu também precisava para definir o segundo parâmetro para -1, comodb.setProfilingLevel(2,-1)
andresigualada
4
Para os interessados ​​para onde os logs vão, o documento declara: mongod grava a saída do criador de perfil de banco de dados na system.profilecoleção.
totymedli
5
db.system.profile.find().pretty()não dá nada para mim
node_saini
84

Acabei resolvendo isso iniciando o mongod assim (martelado e feio, sim ... mas funciona para o ambiente de desenvolvimento):

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

Isso permite a criação de perfil e define o limite para "consultas lentas" como 1 ms, fazendo com que todas as consultas sejam registradas como "consultas lentas" no arquivo:

/var/log/mongodb/mongodb.log

Agora eu recebo saídas de log contínuas usando o comando:

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

Um log de exemplo:

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
fonte
6
Isso deve ser equivalente a adição profile=1e slowms=1linhas /etc/mongodb.conf?
Andrew Magee
Não consegui encontrar o /var/log/mongodb/mongodb.log, mas estava efetuando login no console, o que eu precisava. Graças
auhuman
4
Você pode adicionar, --profile=2de /etc/mongodb.confacordo com os documentos oficiais do Mongo, todas as operações serão registradas.
Toske
1
@auhuman Onde escrever o comando "tail -f /var/log/mongodb/mongodb.log"?
Príncipe Sangrento
5
Não há necessidade de reiniciar, você pode simplesmente usar db.setProfilingLevel(level,slowms). Por exemplo: db.setProfilingLevel(2,1)definirá o nível como 2 e o limite de consulta lento será 1ms.
Abhishek Gupta
25

MongoDBpossui um recurso sofisticado de criação de perfil. O log acontece na system.profilecoleção. Os logs podem ser vistos em:

db.system.profile.find()

Existem 3 níveis de log ( origem ):

  • Nível 0 - o criador de perfil está desativado, não coleta nenhum dado. O mongod sempre grava operações mais longas do que o limite slowOpThresholdMs em seu log. Este é o nível padrão do criador de perfil.
  • Nível 1 - coleta dados de criação de perfil apenas para operações lentas. Por padrão, operações lentas são aquelas mais lentas que 100 milissegundos. Você pode modificar o limite para operações "lentas" com a opção de tempo de execução slowOpThresholdMs ou o comando setParameter. Consulte a seção Especificar o limite para operações lentas para obter mais informações.
  • Nível 2 - coleta dados de criação de perfil para todas as operações do banco de dados.

Para ver em que nível de perfil o banco de dados está sendo executado, use

db.getProfilingLevel()

e para ver o status

db.getProfilingStatus()

Para alterar o status da criação de perfil, use o comando

db.setProfilingLevel(level, milliseconds)

Onde levelrefere-se ao nível de criação de perfil e millisecondsé o ms de qual duração as consultas precisam ser registradas. Para desativar o log, use

db.setProfilingLevel(0)

A consulta para procurar na coleção de perfis do sistema todas as consultas que levaram mais de um segundo, ordenadas por carimbo de data e hora decrescente, será

db.system.profile.find( { millis : { $gt:1000 } } ).sort( { ts : -1 } )
Zameer
fonte
1
De acordo com a documentação, LOGLEVEL 0 faz não significa "nenhum registro", mas ele registra consultas lentas: "o profiler estiver desligado, não recolhe quaisquer dados mongod sempre escreve operações mais tempo do que o limiar slowOpThresholdMs ao seu log." src: docs.mongodb.com/v3.2/tutorial/manage-the-database-profiler/…
kayn
23

Eu criei uma ferramenta de linha de comando para ativar a atividade do criador de perfil e ver os logs de uma maneira capaz de "cauda" : "mongotail" .

Mas o recurso mais interessante (também como tail) é ver as alterações em "tempo real" com a -fopção e, ocasionalmente, filtrar o resultado com greppara encontrar uma operação específica.

Consulte as instruções de documentação e instalação em: https://github.com/mrsarm/mongotail

Mariano Ruiz
fonte
2
essa é a resposta mais completa ao OP. esp. em relação ao requisito de "capacidade de cauda".
Luke W
11

Depois de perfil nível é definido usando db.setProfilingLevel(2).

O comando abaixo imprimirá a última consulta executada.
Você também pode alterar o limite (5) para ver menos / mais consultas.
$ nin - filtrará as consultas de perfil e indexação
Além disso, use a projeção de consulta {'query': 1} para visualizar apenas o campo de consulta

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

Logs com apenas projeção 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
fonte
10

se você deseja que as consultas sejam registradas no arquivo de log mongodb, é necessário definir o nível do log e a criação de perfil, como por exemplo:

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

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

Definir apenas a criação de perfil não teria as consultas registradas no arquivo; portanto, você só pode obtê-lo em

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

Os dados do criador de perfil são gravados em uma coleção no seu banco de dados, não no arquivo. Consulte http://docs.mongodb.org/manual/tutorial/manage-the-database-profiler/

Eu recomendaria usar o serviço MMS da 10gen e alimentar os dados do perfil de desenvolvimento, onde você pode filtrar e classificar na interface do usuário.

Hans N. Hjort
fonte
1
Sim, depois de ativar a criação de perfil de nível 2, uma coleção é adicionada ao banco de dados. No entanto, ter que recarregar uma GUI ou executar um comando sempre que eu executar depuração é uma PITA no final do dia ... É por isso que eu queria um arquivo de log disponível.
João Rocha da Silva
4

Definir o nível de perfil como 2 é outra opção para registrar todas as consultas.

Shnkc
fonte
3

Eu recomendo verificar mongosniff. Esta ferramenta pode fazer tudo o que você deseja e muito mais. Especialmente, ele pode ajudar a diagnosticar problemas com sistemas mongo de maior escala e como as consultas estão sendo roteadas e de onde elas vêm, uma vez que funciona ouvindo sua interface de rede para todas as comunicações relacionadas ao mongo.

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

Daniel Williams
fonte
De acordo com essa página, ele só funciona em ambientes UNIX, e eu não o tenho no meu diretório bin no Windows. Qualquer Windows recomendado equiv?
propagada
Você está executando em um servidor remoto do Windows (nuvem azul, etc) ou localmente no seu PC? Se tudo estiver localmente, o wireshark será mais que suficiente. Para instalá-lo no Windows, você precisará criar o mongosniff.exe, que é um pouco indocumentado. Você segue as instruções do linux, mas precisa instalar a versão de desenvolvimento do winpcap.
11114 Daniel Williams
Obrigado pela resposta. Acabei conseguindo obter as informações de que precisava do mongo profiler, mas vou manter o wireshark no bolso se algo mais sério surgir novamente.
propagada
1

Eu escrevi um script que imprimirá o log system.profile em tempo real, à medida que as consultas chegarem. É necessário ativar o log primeiro, conforme indicado em outras respostas. Eu precisava disso porque estou usando o Windows Subsystem para Linux, cuja cauda ainda não funciona.

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

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

Então

db.adminCommand( { getLog : "global" } )
HareesH P
fonte
5
Bem-vindo ao Stack Overflow! Embora esse código possa resolver a questão, incluir uma explicação realmente ajuda a melhorar a qualidade da sua postagem.
Shree
1

Isso foi solicitado há muito tempo, mas isso ainda pode ajudar alguém:

O criador de perfil do MongoDB registra todas as consultas no system.profile de coleção limitada . Veja isto: criador de perfil de banco de dados

  1. Inicie a instância mongod com a --profile=2opção que permite registrar todas as consultas OU se as instâncias mongod já estiverem em execução, a partir de mongoshell, execute db.setProfilingLevel(2)após selecionar o banco de dados. (pode ser verificado por db.getProfilingLevel(), que deve retornar 2)
  2. Depois disso, criei um script que utiliza o cursor disponível do mongodb para finalizar essa coleção system.profile e gravar as entradas em um arquivo. Para ver os registos Eu só preciso cauda-lo: tail -f ../logs/mongologs.txt. Esse script pode ser iniciado em segundo plano e registrará toda a operação no banco de dados no arquivo.

Meu código para o cursor disponível para a coleção system.profile está em nodejs; ele registra todas as operações junto com as consultas que acontecem em todas as coleções do 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 o cursor disponível no python usando o pymongo, consulte o seguinte código que filtra o MyCollection e insere apenas a operação:

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: O cursor disponível só funciona com coleções limitadas. Ele não pode ser usado para registrar operações em uma coleção diretamente; em vez disso, use o filtro:'ns': 'MyDb.MyCollection'

Nota: Entendo que os códigos nodejs e python acima podem não ser de grande ajuda para alguns. Acabei de fornecer os códigos para referência.

Use este link para encontrar documentação para o cursor disponível na sua escolha de idioma / driver . Drivers Mongodb

Outro recurso que eu adicionei após este logrotate .

Ankit
fonte