Check MongoDB status in node js - javascript

I need to be able to run '/etc/init.d/mongod status' or 'service mongod status' from wihtin a node js file, in order to store the response in the database.
When I run the above commands in the command line, I get the following response:
● mongod.service - SYSV: Mongo is a scalable, document-oriented database.
Loaded: loaded (/etc/rc.d/init.d/mongod)
Active: active (running) since Thu 2017-02-02 08:07:42 UTC; 3h 27min ago
Docs: man:systemd-sysv-generator(8)
Process: 793 ExecStart=/etc/rc.d/init.d/mongod start (code=exited, status=0/SUCCESS)
Main PID: 1027 (mongod)
CGroup: /system.slice/mongod.service
└─1027 /usr/bin/mongod -f /etc/mongod.conf
However, I want to include this status in an API response that I write. Therefore, when a user request my API, I want it to return the mongoDB status check as seen above.
I have tried the following ways:
router.get('/status', function(req, res) {
var databaseCheck = service mongod status // not sure how to do this
res.json({
mongoResponse: '//to have the above status check response here'
});
});
I am new to all this, so any help would be appreciated. I may understand that my thinking is wrong - do let me know if there is a different way of doing this please

Connect a database and then check connection like db.serverConfig.isConnected(). The below code is a full example.
const app = express();
let dbClient;
let db;
let collection;
MongoClient.connect(configuration.mongoDbUri, { useNewUrlParser: true, poolSize: 30 }, (error, client) => {
if (error) {
console.log("Connection failed for some reason. Err: ", error);
return error;
}
db = client.db("myDB");
dbClient = client;
collection = db.collection('myCollection');
app.locals.mongoDb = db;
});
app.get("/status", (req, res) => {
if (db.serverConfig.isConnected()) {
console.log("db.serverConfig.isConnected :", db.serverConfig.isConnected());
return res.send({ result: true});
}
return res.send({ result: false});
});
app.listen(configuration.app.port, error => {});

You can use nodejs child-process module to run a shell command like you would from a terminal. In a terminal you would "service mongod status", in the nodejs child-process you would do the same by putting that command as an argument to the child-process execute function, like so:
const exec = require('child_process').exec;
exec('service mongod status', (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.log(`stdout: ${stdout}`);
console.log(`stderr: ${stderr}`);
});

Try code like this into you app:
db.serverConfig.isConnected();

Related

Binding socket before send with dgram in client

I am developing a node.js program that connects over UDP with another program running on the same machine. Currently I am sending data like this:
import dgram = require("dgram");
const client = dgram.createSocket("udp4");
//Some code to structure the message how the server wants it
const message = Buffer.alloc(413);
message.write("TEST\0");
client.send(message, 0, message.length, 49000, '127.0.0.1', (err) => {
if (err) {
this.client.close();
console.error(err);
}
});
This works fine, however, I want to do the code in two steps. First open the connection, and then send the message. This is the code that I wrote (skipping some repeted things):
//const message same as above
this.client.bind(49000, '127.0.0.1', (err) => {
if (err) {
this.client.close();
console.error(err);
} else {
this.client.send(message, 0, message.length, (err) => {
if (err) {
this.client.close();
console.error(err);
}
});
}
});
This throws the error: throw new ERR_SOCKET_BAD_PORT(name, port, allowZero); RangeError [ERR_SOCKET_BAD_PORT]: Port should be > 0 and < 65536. Received 0.
Edit:
Thanks leitning! .connect() is exactly what I needed.
I now have another issue. When I do .send() directly without calling .connect() before I can receive incoming datagrams by creating a .on('message') listener on the client. But when I connect and then send, the listener doesn't receive any incoming messages. I tested this with Wireshark and there are incoming messages.
The code is:
import dgram = require("dgram");
const client = dgram.createSocket("udp4");
const message = Buffer.alloc(413);
message.write("TEST\0");
client.connect(49000,'127.0.0.1',err => {
if (err) console.error(err);
client.send(message, 0, message.length, 49000, '127.0.0.1', (err) => {
if (err) {
this.client.close();
console.error(err);
}
});
});
client.on('message',(data) => {
console.log(data);
});
Is there something I missed from the docs as to how to receive messages after doing .connect() ?
When you bind a port you are claiming that port from the operating system for the purposes of sending from and receiving to. It does not have anything to do with where your messages will be sent to.
By binding to localhost:49000, packets that you send will declare that they from localhost port 49000. You can also then listen to the bound socket for incoming messages to localhost port 49000.
You still need to declare a recipient for messages that you are trying to send. You get an invalid port error because the function is interpreting your 0 argument as the destination port. dgram.send docs
It looks like the functionality you are trying to use is covered in the dgram.connect method.

Error Message from MongoDB "Operation `disneys.insertOne()` buffering timed out after 10000ms""

I'm currently creating a new API with MongoDB and Express, and I'm currently having this issue "Operation disneys.insertOne() buffering timed out after 10000ms." I'm currently using route.rest to test my API.
However, I don't know what I'm currently doing wrong, could someone take a look at my Github Repository ?
This is the way that I setup my API calls:
const express = require("express");
const router = express.Router();
const Disney = require("../models/disneyCharacter");
// Getting all character
router.get("/", async (req, res) => {
try {
const character = await Disney.find();
res.json(character);
} catch (err) {
res.status(500).json({ message: err.message });
}
});
// Getting one Character
router.get("/:id", getCharacter, (req, res) => {
res.json(res.character);
});
// Creating new Character
router.post("/", async (req, res) => {
const character = new Disney({
name: req.body.name,
details: req.body.details,
});
try {
const newCharacter = await character.save();
res.status(201).json({ newCharacter });
} catch (err) {
res.status(400).json({ message: err.message });
}
});
// Updating one character
router.patch("/:id", getCharacter, async (req, res) => {
if (req.body.name != null) {
res.character.name = req.body.name;
}
if (req.body.details != null) {
res.character.details = req.body.details;
}
try {
const updateCharacter = await res.character.save();
res.json(updateCharacter);
} catch (err) {
res.status(400).json({ message: err.message });
}
});
// Deleting one character
router.delete("/:id", getCharacter, async (req, res) => {
try {
await res.character.remove();
res.json({ message: "Deleted character" });
} catch (err) {
res.status(500).json({ message: err.message });
}
});
async function getCharacter(req, res, next) {
let character;
try {
character = await character.findById(req.params.id);
if (character == null) {
return res.status(404).json({ message: "Cannot find character" });
}
} catch (err) {
return res.status(500).json({ message: err.message });
}
res.character = character;
next();
}
module.exports = router;
My parameters are the following:
const mongoose = require("mongoose");
const disneyCharacter = new mongoose.Schema({
name: {
type: String,
required: false,
},
details: {
type: String,
required: false,
},
subscribeDate: {
type: Date,
required: true,
default: Date.now,
},
});
module.exports = mongoose.model("Disney", disneyCharacter);
This is my API call:
Post http://localhost:3000/disneyCharacter
Content-Type: application/json
{
"name": "Mickey Mouse",
"details": "First Character from Disney"
}
Please let me know if you have any other questions or concerns.
try this out
How to solve Mongoose v5.11.0 model.find() error: Operation `products.find()` buffering timed out after 10000ms"
Also, your API call seem to have a problem, It should be disneyCharacters instead of disneyCharacter.
Also, probably setup a local database first instead of using process.env.DATABASE_URL.
Actually i was also getting the same error.
steps i performed to solve this error are
while creating database in mongodb
allow access from anywhere (ip configuration)
choose the nearest server
this solved my problems :)
In my application the same error message was thrown.
The difference is, that I am using MongoDB Atlas, instead of a local MongoDB.
Solution:
After added "+srv" to the URL scheme is issue was gone:
const mongoose = require("mongoose");
mongoose.set('useUnifiedTopology', true);
mongoose.set('useNewUrlParser', true);
mongoose.connect("mongodb+srv://user:password#host/dbname")
.then( () => console.log("connected to DB."))
.catch( err => console.log(err));
Dependencies in package.json:
"dependencies": {
"mongoose": "^5.11.12",
}
MongoDB Version 4.2.11
The connection string is given in the MongoDB Atlas frontend: -> Data Storage -> Cluster -> connect -> Connect your application
There you can find some code snippets.
I faced the same error. I am using mongoDB Atlas and not the local one. What worked for me was to remove the options in the .connect method (I am using mongoose for connecting to mongodb).
Previous code (that caused the error)
mongoose.connect(
"" + process.env.DB_URL,
{ useUnifiedTopology: true, useNewUrlParser: true, useFindAndModify: false },
() => { console.log("Connected to DB"); }
)
Just remove the code inside { } in this method.
mongoose.connect(
"" + process.env.DB_URL,
{ },
() => { console.log("Connected to DB"); }
)
I get this error I found Solution
Operation insertMany() buffering timed out after 10000ms"
install
API Call Server File
npm i dotenv
import express from 'express';
import mongoose from 'mongoose';
import data from './data.js';
import userRouter from './routers/userRouter.js';
import dotenv from 'dotenv';
import config from './config.js';
dotenv.config();
const mongodburl = config.MONGODB_URL
const app = express();
mongoose.connect(mongodburl, {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex:true,
}).then(() => console.log('Hurry Database Connected'));
Router File
install express async handler
npm i express-async-handler
import express from 'express';
import expressAsyncHandler from 'express-async-handler';
import data from '../data.js';
import User from '../models/userModel.js';
const userRouter = express.Router();
userRouter.get(
'/seed',
expressAsyncHandler (async(req,res)=>{
//await User.remove({});
const createdUsers = await User.insertMany(data.users);
res.send({ createdUsers });
})
);
Remove these two:
useCreateIndex: true,
useFindModify: false,
and put this:
useNewUrlParser: true,
useUnifiedTopology: true
final examples:
mongoose.connect(process.env.MONGODB_URL, {
useNewUrlParser: true,
useUnifiedTopology: true
}, err => {
if(err) throw err;
console.log('Connected to mongodb')
})
Try this way too:
In order to solve the error i kept the code in async await function. After successfully connected the db then only we can do the CRUD operation. Nodejs follows the single thread execution i.e line by line executed. if any line is waiting for any request node automatically go to the next line and execute it first. So if a line depends on a request, put in async await function.
Add ssl=true in the URL Scheme as shown in below .
mongodb+srv://:#node-rest-courses.4qhxk.mongodb.net/myFirstDatabase?retryWrites=true&w=majority&ssl=true
in my code, only have removed parameters ssl, i am working with database in digitalOcean, my code is:
mongoose.Promise=global.Promise;
mongoose.connect(process.env.MONGO_URI,{
useNewUrlParser: true,
useUnifiedTopology: true,
ssl: true,
// tlsCAFile: mongoCertPath, ----> you should remove this line
socketTimeoutMS:43200000,
}).then(
()=>{ console.log('conected to digitalOcean mongoDB: db_CRM'); },
err=>{console.log('erro to connect digitalOcean mongoDB:'+err);}
);
The solution to this problem is with the route.rest file since this file is not doing something correctly. For the same reason, I went ahead and create a new project in Mongo DB to set up a cluster and create the database.
Also, I tested by using POSTMAN
Everything is working correctly now!
It is a connection problem with mongodb server.
You can use IP address instead of domain/server name of your server in mongoose.connect().
In my case even localhost is not working so I replace 127.0.0.1 and everything works fine so I go back and change host file in my windows.

browser.saveScreenshot() hangs when called

Hi I am writing automation tests for a Cordova application.
I want to save screenshots of each page, here is my code.
it("should take screenshot", function() {
return browser.contexts().then(function(cnt){
console.log(cnt[1]);
return browser.context(cnt[1]);
}).then(function(){
return browser.saveScreenshot("/Users/User/Documents/dev/engineerappcopy/VGimages/nexLogin.png")
});
});
Here is my Appium console:
[HTTP] --> GET /wd/hub/session/610d95af-6501-4c72-ac38-0184a8608dfd/screenshot {}
[MJSONWP] Driver proxy active, passing request on via HTTP proxy
[JSONWP Proxy] Proxying [GET /wd/hub/session/610d95af-6501-4c72-ac38-0184a8608dfd/screenshot] to [GET http://127.0.0.1:9515/wd/hub/session/4d5f3f8a24e28f7fbf65eebc47cc02d8/screenshot] with body: {}
[HTTP] --> GET /wd/hub/status {}
[MJSONWP] Calling AppiumDriver.getStatus() with args: []
[MJSONWP] Responding to client with driver.getStatus() result: {"build":{"version":"1.5.3"...
[HTTP] <-- GET /wd/hub/status 200 14 ms - 83
Im new to automation and JS, thanks for any advice.
It turns out savescreenshot(), is not compatible with cordova applications.
However I did find a solution!
Using these commands we can take a screen shot directly from the emulator:
adb pull /sdcard/screenshot.png screenshot.png
adb shell /system/bin/screencap -p /sdcard/screenshot.png
So how can we do this programmatically?
well nodeJS has 'child_process' which can call commands to the terminal!
it("should take screenshot", function() {
const exec = require('child_process').exec;
exec('adb shell /system/bin/screencap -p /sdcard/tester.png', (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.log(`stdout: ${stdout}`);
console.log(`stderr: ${stderr}`);
});
exec('adb pull /sdcard/tester.png tester.png', (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.log(`stdout: ${stdout}`);
console.log(`stderr: ${stderr}`);
});
});
So using something like this ^, I can take a screenshot that is saved to the emulators sd card, and then pull this screenshot onto my directory!

Why can't I respond with output from child process in Node JS?

I am using Node JS with Express and trying to execute a script and return the output of that script to the client via AJAX. The script is completing successfully, but for some reason I cannot get the output to show in the post response.
let childProcess = require('child_process');
router.post('/update', (req, res) => {
childProcess.exec('/home/dir/app/update.sh', { shell: '/bin/bash' }, (error, stdout, stderr) => {
res.json({ error, stdout, stderr });
});
});
The Node process is run using Forever. If I look at the forever log, it shows:
Forever detected script was killed by signal: SIGKILL
Not sure what that means. It appears the script is completing successfully though.
EDIT
To address Aikon's answer below. I tried the following and still no go.
router.post('/update', (req, res) => {
console.log('start...');
childProcess.exec('/home/dir/app/update.sh', { shell: '/bin/bash' }, (error, stdout, stderr) => {
console.log('done');
error = error || '';
stdout = stdout || '';
stderr = stderr || '';
res.json({ error, stdout, stderr });
});
});
It's as if the success function is never firing because it never logs "done" in the console. It just logs "start..." and the SIGKILL error above in the console.
Your script kill(and restart) itself before it can read output from child process.
Look at your update.sh again:
#!/bin/bash
git pull
npm install
npm run build
#this command restarts your script
forever restartall
You could remove last line of update.sh, and after sending response, the script just exits, forever should restart it with updated version.
router.post('/update', (req, res) => {
childProcess.exec('/home/dir/app/update.sh', { shell: '/bin/bash' },
(error, stdout, stderr) => {
res.json({ error, stdout, stderr });
process.exit();
});
});
If error is not empty then output is undefined => fail
After stringify error is empty object.
'use strict';
let error = new Error('err');
let str = 'text';
let obj = {a: 10, b: 15}; // Try comment to get fall
console.log(JSON.stringify({error, str, obj}))
You have a syntax error in your code. Try:
res.json({ error: error, output: stdout, error_log: stderr });
alternatively you can do:
res.json([ error, stdout, stderr ]);

How to check if mongos connection still alive in Node.JS?

Let's imagine we have Node.JS app which is connecting to the Mongos process. But suddenly Mongos failed. How our app could now about it?
var db = null;
mongo.MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err, mydb) {
if(err) throw err;
db = mydb
});
..... on response we have .....
db.collection('test_collection', function(err, collection){
collection.find({}).toArray(function(err, documents){
// doing some work here
// but if Mongos failed, we are blocked on this stage
});
});
Would you not want to do the same thing that you're doing at connect, but within the function?
i.e.
...
collection.find({}).toArray(function(err, documents) {
if(err) {
throw err; //or do something equivalent. It doesn't really matter if the connection has failed, as it will still throw an error.
} else {
///continue processing
}
....
Alternatively, if you use a 3rd party mongo manager, such as mongoose, you can do something like this globally:
mongoose.connect('mongodb://' + config.mongo.host + '/' + config.mongo.db);
var db = mongo.connection;
db.on('error', console.error.bind(console, 'connection error: '));

Categories

Resources