MongoDB ghi nhật ký tất cả các truy vấn


169

Câu hỏi là cơ bản vì nó đơn giản ... Làm thế nào để bạn đăng nhập tất cả các truy vấn trong một tệp nhật ký có thể "đuôi" trong mongodb?

Tôi đã thử:

  • thiết lập mức độ hồ sơ
  • thiết lập tham số ms chậm bắt đầu
  • mongod với tùy chọn -vv

/Rar/log/mongodb/mongodb.log tiếp tục chỉ hiển thị số lượng kết nối hoạt động hiện tại ...


mongod -vvlàm việc cho tôi
fguillen

Câu trả lời:


259

Bạn có thể đăng nhập tất cả các truy vấn:

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

Nguồn: http://docs.mongodb.org/manual/reference/method/db.setProfilingLevel/

db.setProfilingLevel(2) có nghĩa là "đăng nhập tất cả các hoạt động".


3
Nhìn thoáng qua, có vẻ như đây là một câu trả lời tốt hơn câu trả lời được chấp nhận.
Ehtesh Choudhury

2
Không tốt hơn, vì các câu hỏi yêu cầu tệp nhật ký khả dụng, nhưng chắc chắn hữu ích, trong trường hợp bạn không có quyền truy cập vào tệp nhật ký, chỉ có vỏ mongo, như tệp đã đưa tôi đến đây :)
inolasco

11
Tôi đã thử đặt mức định hình thành 2 nhưng tôi cũng cần đặt tham số thứ hai thành -1, nhưdb.setProfilingLevel(2,-1)
andresigualada

4
Đối với những người quan tâm nơi các bản ghi đi, doc nói: mongod ghi đầu ra của trình lược tả cơ sở dữ liệu vào system.profilebộ sưu tập.
totymedli

5
db.system.profile.find().pretty()không mang lại gì cho tôi
node_saini

84

Cuối cùng tôi đã giải quyết điều này bằng cách bắt đầu mongod như thế này (búa và xấu xí, vâng ... nhưng hoạt động cho môi trường phát triển):

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

Điều này cho phép định hình và đặt ngưỡng cho "truy vấn chậm" là 1ms, khiến tất cả các truy vấn được ghi lại dưới dạng "truy vấn chậm" vào tệp:

/var/log/mongodb/mongodb.log

Bây giờ tôi nhận được đầu ra nhật ký liên tục bằng cách sử dụng lệnh:

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

Một nhật ký ví dụ:

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
Điều này có nên tương đương với việc thêm profile=1slowms=1dòng trong /etc/mongodb.conf?
Andrew Magee

Tôi không thể tìm thấy /var/log/mongodb/mongodb.log nhưng nó đã đăng nhập vào bảng điều khiển mà tôi cần. Cảm ơn
auhuman

4
Bạn chỉ có thể thêm --profile=2vào /etc/mongodb.conftheo tài liệu Mongo chính thức, mọi hoạt động sẽ được ghi lại.
toske

1
@auhuman Viết lệnh "tail -f /var/log/mongodb/mongodb.log" ở đâu ??
Hoàng tử máu lai

5
Không cần phải khởi động lại, bạn chỉ cần sử dụng db.setProfilingLevel(level,slowms). Ví dụ: db.setProfilingLevel(2,1)sẽ đặt mức là 2 và ngưỡng truy vấn chậm là 1ms.
Abhishek Gupta


25

MongoDBcó một tính năng tinh vi của hồ sơ. Việc đăng nhập xảy ra trong system.profilebộ sưu tập. Các bản ghi có thể được nhìn thấy từ:

db.system.profile.find()

Có 3 cấp ghi nhật ký ( nguồn ):

  • Cấp 0 - trình lược tả tắt, không thu thập bất kỳ dữ liệu nào. mongod luôn ghi các hoạt động dài hơn ngưỡng SlowOpThr Ngưỡng vào nhật ký của nó. Đây là mức hồ sơ mặc định.
  • Cấp 1 - chỉ thu thập dữ liệu định hình cho các hoạt động chậm. Theo mặc định, các hoạt động chậm là những hoạt động chậm hơn 100 mili giây. Bạn có thể sửa đổi ngưỡng cho các hoạt động của Slow chậm với các tùy chọn thời gian chạy SlowOpThrưỡngMs hoặc lệnh setParameter. Xem phần Chỉ định Ngưỡng cho các hoạt động chậm để biết thêm thông tin.
  • Cấp độ 2 - thu thập dữ liệu lược tả cho tất cả các hoạt động cơ sở dữ liệu.

Để xem mức độ hồ sơ cơ sở dữ liệu đang chạy, sử dụng

db.getProfilingLevel()

và để xem trạng thái

db.getProfilingStatus()

Để thay đổi trạng thái định hình, sử dụng lệnh

db.setProfilingLevel(level, milliseconds)

Trong đó levelđề cập đến mức độ hồ sơ và millisecondslà ms trong đó thời gian truy vấn cần phải được ghi lại. Để tắt đăng nhập, sử dụng

db.setProfilingLevel(0)

Truy vấn để tìm trong bộ sưu tập hồ sơ hệ thống cho tất cả các truy vấn mất nhiều hơn một giây, được sắp xếp theo dấu thời gian giảm dần sẽ là

db.system.profile.find( { millis : { $gt:1000 } } ).sort( { ts : -1 } )

1
Theo tài liệu, LogLevel 0 không không có nghĩa là "không đăng nhập", nhưng nó ghi lại các truy vấn chậm: "profiler tắt, không thu thập bất kỳ dữ liệu mongod luôn viết hoạt động dài hơn ngưỡng slowOpThresholdMs để log của nó." src: docs.mongodb.com/v3.2/tutorial/manage-the-database-profiler/ Kẻ
kayn

22

Tôi đã tạo một công cụ dòng lệnh để kích hoạt hoạt động hồ sơ và xem nhật ký theo cách có thể "đuôi" : "mongotail" .

Nhưng tính năng thú vị hơn (cũng giống như tail) là để xem các thay đổi trong "thời gian thực" với -ftùy chọn và đôi khi lọc kết quả grepđể tìm một thao tác cụ thể.

Xem tài liệu và hướng dẫn cài đặt tại: https://github.com/mrsarm/mongotail


2
đây là phản hồi đầy đủ nhất cho OP. đặc biệt liên quan đến yêu cầu 'đuôi có thể'.
Luke W

11

Khi mức độ định hình được thiết lập bằng cách sử dụng db.setProfilingLevel(2).

Lệnh dưới đây sẽ in truy vấn được thực hiện cuối cùng.
Bạn cũng có thể thay đổi giới hạn (5) để xem ít / nhiều truy vấn hơn.
$ nin - sẽ lọc ra các truy vấn hồ sơ và lập chỉ mục
Ngoài ra, hãy sử dụng phép chiếu truy vấn {'query': 1} để chỉ xem trường truy vấn

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

Nhật ký chỉ có phép chiếu truy vấn

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

10

nếu bạn muốn các truy vấn được ghi vào tệp nhật ký mongodb, bạn phải đặt cả mức ghi nhật ký và hồ sơ, ví dụ như:

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

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

Chỉ thiết lập hồ sơ sẽ không có các truy vấn được ghi vào tệp, vì vậy bạn chỉ có thể lấy nó từ

db.system.profile.find().pretty()

7

Dữ liệu hồ sơ được ghi vào một bộ sưu tập trong DB của bạn, không phải vào tệp. Xem http://docs.mongodb.org/manual/tutorial/manage-the-database-profiler/

Tôi sẽ khuyên bạn nên sử dụng dịch vụ MMS của 10gen và cung cấp dữ liệu trình biên dịch phát triển ở đó, nơi bạn có thể lọc và sắp xếp nó trong Giao diện người dùng.


1
Vâng, sau khi kích hoạt hồ sơ cấp 2, một bộ sưu tập được thêm vào cơ sở dữ liệu. Tuy nhiên, phải tải lại một gui hoặc chạy lệnh mỗi khi tôi thực hiện gỡ lỗi là một PITA vào cuối ngày ... Đó là lý do tại sao tôi muốn có một tệp nhật ký khả dụng.
João Rocha da Silva


4

Đặt profilinglevel thành 2 là một tùy chọn khác để ghi nhật ký tất cả các truy vấn.


3

Tôi khuyên bạn nên kiểm tra mongosniff. Công cụ này có thể làm mọi thứ bạn muốn và hơn thế nữa. Đặc biệt, nó có thể giúp chẩn đoán các sự cố với các hệ thống mongo quy mô lớn hơn và cách truy vấn được định tuyến và chúng đến từ đâu vì nó hoạt động bằng cách lắng nghe giao diện mạng của bạn cho tất cả các giao tiếp liên quan đến mongo.

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


Theo trang đó, nó chỉ hoạt động trong UNIX enviros và tôi không có nó trong thư mục bin của mình trong các cửa sổ. Bất kỳ cửa sổ đề nghị Equiv?
tuyên truyền

Bạn đang chạy trên một máy chủ windows từ xa (azure cloud, v.v.) hoặc cục bộ trên máy tính của bạn? Nếu đó là tất cả các wireshark địa phương sẽ là quá đủ. Để cài đặt nó trên windows, bạn sẽ cần xây dựng mongosniff.exe, một chút không có giấy tờ. Bạn làm theo hướng dẫn linux nhưng bạn cần cài đặt phiên bản phát triển của winpcap.
Daniel Williams

Cảm ơn vi đa trả lơi. Cuối cùng tôi đã có thể lấy thông tin tôi cần ra khỏi trình hồ sơ mongo, nhưng tôi sẽ giữ wireshark trong túi nếu có thứ gì đó nghiêm trọng hơn phát sinh trở lại.
tuyên truyền

1

Tôi đã viết một tập lệnh sẽ in ra nhật ký system.profile trong thời gian thực khi các truy vấn đến. Bạn cần kích hoạt đăng nhập trước như đã nêu trong các câu trả lời khác. Tôi cần điều này bởi vì tôi đang sử dụng Windows subsystem cho Linux, mà phần đuôi vẫn không hoạt động.

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


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

Sau đó

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

5
Chào mừng bạn đến với Stack Overflow! Mặc dù mã này có thể giải quyết câu hỏi, bao gồm một lời giải thích thực sự giúp cải thiện chất lượng bài đăng của bạn.
Shree

1

Điều này đã được hỏi từ lâu nhưng điều này vẫn có thể giúp ai đó:

Trình biên dịch MongoDB ghi lại tất cả các truy vấn trong bộ sưu tập cap.profile . Xem này: cơ sở dữ liệu hồ sơ

  1. Bắt đầu cá thể mongod với --profile=2tùy chọn cho phép ghi nhật ký tất cả các truy vấn HOẶC nếu các phiên bản mongod đang chạy, từ mongoshell, chạy db.setProfilingLevel(2)sau khi chọn cơ sở dữ liệu. (nó có thể được xác minh bởi db.getProfilingLevel(), cái nào sẽ trả về 2)
  2. Sau này, tôi đã tạo một tập lệnh sử dụng con trỏ có sẵn của mongodb để theo đuôi bộ sưu tập system.profile này và viết các mục trong một tệp. Để xem nhật ký tôi chỉ cần theo đuôi nó : tail -f ../logs/mongologs.txt. Kịch bản này có thể được bắt đầu trong nền và nó sẽ ghi lại tất cả các hoạt động trên db trong tệp.

Mã của tôi cho con trỏ có sẵn cho bộ sưu tập system.profile nằm trong nodejs; nó ghi nhật ký tất cả các hoạt động cùng với các truy vấn xảy ra trong mọi bộ sưu tập của 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'))
    })

});

}

Đối với con trỏ có sẵn trong python bằng pymongo, hãy tham khảo đoạn mã sau đây lọc cho MyCollection và chỉ thao tác chè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)

Lưu ý: Con trỏ có sẵn chỉ hoạt động với các bộ sưu tập được giới hạn. Nó không thể được sử dụng để ghi nhật ký các hoạt động trên một bộ sưu tập, thay vào đó sử dụng bộ lọc:'ns': 'MyDb.MyCollection'

Lưu ý: Tôi hiểu rằng mã nodejs và python ở trên có thể không giúp ích nhiều cho một số người. Tôi vừa cung cấp các mã để tham khảo.

Sử dụng liên kết này để tìm tài liệu cho con trỏ khả dụng trong lựa chọn trình điều khiển / trình điều khiển Mongodb của bạn

Một tính năng khác mà tôi đã thêm sau logrotate này .


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.