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 ...


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".


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

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

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


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

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

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.


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.


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/


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


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

Então

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

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 .


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.