cayasso / mongo-oplog

Watch mongodb oplog in a simple way
380 stars 91 forks source link

Not seeing events in 2.1.0 for replica set configured environment #59

Closed doktoroblivion closed 6 years ago

doktoroblivion commented 6 years ago

I tried to install your latest software, but it throws the following warnings, which may explain why when I use it I am not seeing any oplog events.

npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.0.0 (node_modules/chokidar/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

Is Linux not supported?

doktoroblivion commented 6 years ago

I kind of corrected the issue by using npm i -f, but still not seeing any events. Test code snippet and output follow, tell me what I am doing wrong or whether there actually is Linux support or not.

'use strict'

const MongoOplog = require('../mongo-oplog-2.1.0/src/index.js');
const mongo = require('mongodb');
const fs = require('fs');
const util = require('util');

var format = util.format;
var MongoClient = mongo.MongoClient;

// **** RIPPED OUT FOR PRIVACY ******//

console.log("Connecting to mongo: " + t_url + " ");
// Connect using MongoClient
MongoClient.connect(t_url, { sslCA:t_sslCA,
                             sslCert:t_sslCert,
                             sslKey:t_sslKey }, function(err, db) { 

    console.log("Connected to mongo!");
    if (err == null) {
        var oplog = MongoOplog(t_url, {sslCA:t_sslCA,
                                       sslCert:t_sslCert,
                                       sslKey:t_sslKey });
        console.log("Connected to mongo oplog!");

        oplog.tail(function (err) {
            if (err) return done(err);

            console.log('tailing started')

            const coll = db.collection('mycollection');

            console.log('Insert document into mycollection')
            coll.insert({ n: 'JBL', c: 'speakers' }, function (err) {
                if (err) {
                    return done(err);
                } else {
                    console.log('Document inserted, look for interrupt!'); 
                }
            })
        });

        oplog.on('op', function (err, data) {
            if (err) {
                console.log("Op error");
            } else {
                console.log("Op: "+data);
            }
        });

        oplog.on('update', function (data) {
            if (err) {
                console.log("Update error");
            } else {
                console.log("Update: "+data);
            }
        });

        oplog.on('insert', function (data) {
            console.log("Insert: " + data);
            if (err) {
                console.log("Insert error");
            } else {
                console.log("Insert: " + data);
            }
        });

        oplog.on('delete', function (data) {
            console.log("delete: " + data);
            if (err) {
                console.log("delete error");
            } else {
                console.log("delete: " + data);
            }
        });

        oplog.on('error', function (data) {
            console.log("error: " + data);
            if (err) {
                console.log("error error");
            } else {
                console.log("error: " + data);
            }
        });

        oplog.on('end', function (data) {
            console.log("end: " + data);
            if (err) {
                console.log("end error");
            } else {
                console.log("end: " + data);
            }
        });

    } else {
        console.log("An error occurred connecting to mongodb replicaset, it could be one of the following:");
        console.log("  1. VPN issue");
        console.log("  2. No network connectivity");
        console.log("  3. MongoDB is down or not listening on port 27017 of the private IPs provided");
        console.log(""+err);
    }

Output:

$ node oplog_app.js 
start
Connecting to mongo: mongodb://CN%3DmongoAdmin%2COU%3Dmongodb-client%2CO%3DME%2CL%3DNYU%2CST%3DNY%2CC%3DUS@10.144.107.26:27017,10.144.107.29:27017,10.144.107.119:27017/local?ssl=true&authMechanism=MONGODB-X509&authSource=$external&replicaSet=cloudeng-mongodb-rs 
Connected to mongo!
Connected to mongo oplog!
tailing started
Insert document into mycollection
Document inserted, look for interrupt!
doktoroblivion commented 6 years ago

I re-wrote the above using promises, but that did not work either. In fact, I am unable to explain why the stop got called, any thoughts?

        const oplog = MongoOplog(t_url, {sslCA:t_sslCA,
                                         sslCert:t_sslCert,
                                         sslKey:t_sslKey });
        console.log("Connected to mongo oplog!");

        oplog.tail().then(() => {
            console.log('tailing started')
        }).catch(err => console.error(err))

        oplog.on('op', data => {
                console.log("Op: " + data);
        });

        oplog.on('update', data => {
            console.log("Update: " + data);
        });

        oplog.on('insert', data => {
            console.log("Insert: " + data);
        });

        oplog.on('delete', data => {
            console.log("deleted: " + data.o._id);
        });

        oplog.on('error', data => {
            console.log("error: " + data);
        });

        oplog.on('end', data => {
            console.log("stream ended");
        });

Output:

$ node oplog_app.js 
start
Connected to mongo oplog!
server tailing stopped.
tailing started
doktoroblivion commented 6 years ago

SO, I have done the following. I have verified your minimal mocha tests against a simple (really simple) replica set with one member. All mocha tests ran fine. However, an actual real life replica set running remotely the tests will not work. So I think there is much work to do. I have a replica set setup, which I call simple, with 3 members running in TLS configuration, private IPs over VPN only! No worries, (I have access to the VPN to conduct tests.) I update and ran the oplog acceptance of an already connected DB, that succeeded...! Then I went the next step to see if same would pass the op emit test, it does not..! I extended the mocha timeout value to 2mins, still failed. So I suspect an event emitter issue or something similar. Please ping me if you want particulars or if you even care.(?)

doktoroblivion commented 6 years ago

I got this to work, but had to HACK the code.

$ DEBUG=* node oplog_emit.js 
Connected to mongo oplog!
  mongo-oplog Connected to oplog database +0ms
tailing started
Insert object: { result: 
   { ok: 1,
     n: 1,
     opTime: 
      { ts: Timestamp { _bsontype: 'Timestamp', low_: 1, high_: 1512480038 },
        t: 1 } },
  ops: [ { n: 'JB', c: 1, _id: 5a269d267ec6080869f6ef66 } ],
  insertedCount: 1,
  insertedIds: [ 5a269d267ec6080869f6ef66 ] }
  mongo-oplog incoming data {"ts":"6496052299062837249","t":1,"h":"-3098392589224970073","v":2,"op":"i","ns":"optest.mycollection","o":{"_id":"5a269d267ec6080869f6ef66","n":"JB","c":1}} +2s
Op: [object Object]
Insert: [object Object]
  mongo-oplog incoming data {"ts":"6496052303357804545","t":1,"h":"6442844189461439981","v":2,"op":"d","ns":"optest.mycollection","o":{"_id":"5a269d267ec6080869f6ef66"}} +709ms
Op: [object Object]
deleted: 5a269d267ec6080869f6ef66

My only additional thoughts here are that there may be issues with your promises implementation.

doktoroblivion commented 6 years ago

I fixed the code in several places so that it now passes all the tests. I will contribute back once I have finished up my own project. Several areas of thought, filters need work, comms over the wire need better threshold limits or adjustable, delete has some issue, readme needs more and better doc!