pino logger and express attach custom property to all logs - javascript

First up, node is not my thing. Nevertheless I find myself trying to figure out how to combine pino/pino-http and express to deliver some formatted logs. This part I have achieved.
What I was attempting to figure out for a short while was how to pass express via app.use(logger) a logger object that has got some base properties injected into it.
I tried a bunch of stuff, including creating a child logger and passing that to pinoHTTP() but although that did not error, i'd end up getting very long log objects which seemed full of goop and undesirable content.
pseudo code
const express = require('express');
const pino = require('pino');
const log = pino({level: process.env.LOG_LEVEL || 'info'});
const childLogger = log.child({'exampleProp': 'example-value'});
const logger = require('pino-http')({
logger: childLogger
});
const app = express();
const port = 3000;
app.use(logger);
app.get('/', (req, res) => {
logger.info('Hello World');
res.send('Hello World!');
});
app.listen(port, () => {
console.log('Example app listening on port ${port}')
});

Related

Separating express queries from routes

I'm trying to make an express route that basically allows me to input an equity name as a query by putting ?symbol= on the URL. After the equity name, I want to add a new route.
const express = require("express")
const app = express()
app.get("/api/v1/equity/latest", (req, res) => {
res.send(req.query)
})
app.listen (3000, () => {
console.log("listening to port 3000")
})
when I give then GET the URL as localhost:3000/api/v1/equity?symbol=BBNI/latest/ and then look at the queries received, it received as symbol = BBNI/latest/
How do I separate the symbol query from the next /latest route?
It's a weird URL pattern, because if any dev sees this url:
/v1/equity?symbol=BBNI/latest/
It is implied that the symbol parameter is indeed BBNI/latest/ and not just BBNI
However, if you want to 'separate' these parts, you can just do:
const [symbol, latest] = req.query.symbol.split('/', 2);
But you probably should design a better URL structure.
I think it's not a good method.
Please try this.
const express = require("express")
const app = express()
app.get("/api/v1/equity/:symbol/latest", (req, res) => {
res.send(req.params.symbol)
})
app.listen (3000, () => {
console.log("listening to port 3000")
})

Dynamically changing routes in Express

I have an express server. This is my index.js
let some_parameter = some_value;
const configuredHandler = new Handler(some_parameter);
const server = express();
server
.get("*", configuredHandler.handleRequest)
.post("*", configuredHandler.handleRequest)
.put("*", configuredHandler.handleRequest)
.delete("*", configuredHandler.handleRequest);
I am trying to update the routes if some_parameter to the Handler changes. So it should create a new instance of configuredHandler and the routes should automatically pick the new handler.
Ideally I want to be able to change some_parameter anywhere else in the code.
I am not sure how to structure it for this.
Please help.
What you could do is use something similar to a factory. That factory would create a new middleware every time some_parameter changes and save that middleware for future reference.
Whenever one of your routes is called, express would then refer to the current handler in your factory.
I wrote a simple example:
const express = require('express');
class HandlerFactory {
static currentHandler = (req, res) => res.send('Hello');
static setValue(value) {
this.currentHandler = (req, res) => res.send(value);
}
}
const app = express();
app.post('/change-value', (req, res) => {
HandlerFactory.setValue(req.query.value);
res.send();
});
app.use('/handler', (req, res) => HandlerFactory.currentHandler(req, res));
app.listen(3000);
Just run the app, then test its functionality:
$ curl http://localhost:3000/handler
Hello
$ curl -X POST http://localhost:3000/change-value?value=SecondMessage
$ curl http://localhost:3000/handler
SecondMessage
You can use Router module from expressjs
import { Router } from 'express';
const route1 = new Router();
const route2 = new Router();
const route3 = new Router();
route1.get('/', handler1);
route2.get('/', handler2);
route3.get('/', handler3);
..
..
// similarly define other HTTP routes
const routeMap = {
route1,
route2
route3
}
let some_parameter = 'route1';
const server = express();
const selectedRouter = routerMap[some_parameter];
server.use('*', routerMap[some_parameter]);
I have a sample project on Github that uses similar pattern

Access to Discord.Client instance from other modules

I wonder if there is any way to access a Discord.Client instance from another file.
What I've tried:
posts.js
const express = require('express')
const router = express.Router()
router.post('/checkRole', function (req, res) {
const guild = client.guilds.find(guild => guild.id === '688678156374044803');
let member = guild.members.get(req.body.id); // member ID
// Here I get an error which says the 'guild' is undefined.
res.send(response);
});
module.exports = router
index.js
const Discord = require("discord.js");
global.client = new Discord.Client();
const express = require('express');
const postsRoute = require('./routes/posts')
app = express()
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use('/posts', postsRoute)
/* ... some other code ... */
client.login(config.token);
app.listen(8080);
module.exports = { client }
I've also tried a similar approach like this but it didn't work either. Lastly I tried to store the client instance as a global variable but still no luck. Is there any way to achieve this?
It seems like the problem is not the fact that you can't properly export the client, but that the code that you want to use it with runs when the client is not ready yet: in fact, you're getting an error that says that no guild was found with the .find method, but it means that the client has the .guilds property and a .find method.
The client exists, the problem is that your code run before the ready event is fired: to avoid that, you can require your module inside the ready event handler. Here's an example:
// index.js
client.on('ready', () => {
const postsRoute = require('./routes/posts')
let app = express()
app.use(express.urlencoded({ extended: true }))
app.use(express.json())
app.use('/posts', postsRoute)
app.listen(8080);
})

NodeJS and console.log not logging

So, its been a hot minute since I've used node, and i can not for the life of me, understand why this isn't working.
const body_parser = require("body-parser");
var express = require("express");
var app = express();
app.use("/", express.static(__dirname + "/Contents/"));
app.get("/", function(req, res) {
//Why wont this log to my terminal when a user visits the site?
console.log("log it pleaseeeeeeeeee");
});
app.listen(5004, () => {
console.log("server up and listening on port 5004");
});
I'm trying to log "Log it Pleaseeeee" every time a user visits the site, into the terminal where my nodejs app is running. Why wont this work?
You can't have 2 seperate handlers for an endpoint, in your case "/"
To achieve what you want, you must provide a middleware function.
express will know based on the type of the second argument what to do. middleware functions expect 3 arguments; the last being a callback so it knows when you are ready.
You should change your code by moving your get function into your app.use('/', ...) function and including the callback parameter as follows:
const body_parser = require("body-parser");
var express = require("express");
var app = express();
app.use("/", function(req, res, callback) {
console.log("log it pleaseeeeeeeeee");
callback()
}, express.static(__dirname + "/Contents/"));
/** GET RID OF THIS
app.get("/", function(req, res) {
//Why wont this log to my terminal when a user visits the site?
console.log("log it pleaseeeeeeeeee");
});
*/
app.listen(5004, () => {
console.log("server up and listening on port 5004");
});

Socket.io connection keep increasing each time a new connect has been made

I'm using Express4 with a router that points to path /, and that is handled by a JS file named chat.js.
And my IO object is already bind to app.io, so inside my chat.js I'll call my Socket.IO by using req.app.io, but the problem is, I use to be using socket.emit and the code just work fine, but now if I want to sync up with the client I have to using req.app.io.emit.
And since because I'm using req.app.io.emit, I have the connection keep increasing problem.
index.js
const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const path = require('path');
const randomstring = require('randomstring');
const sha256 = require('sha256');
const io = require('socket.io').listen(server);
app.io = io;
const port = process.env.PORT || 3000;
module.exports.users = {};
server.listen(port, () => {
console.log(`Serer is running on port ${port}`);
});
app.set('view engine', 'ejs');
app.set('views', path.join(`${__dirname}/../public`));
app.use('/static', express.static(path.join(`${__dirname}/../public`)));
app.use('/', require('./chat'));
chat.js
const express = require('express');
const router = express.Router();
const users = require('./index').users;
const randomstring = require('randomstring');
router.get('/', (req, res) => {
res.render('index');
const uid = randomstring.generate(30);
users[uid] = true;
req.app.io.on('connection', socket => {
console.log('hello');
socket.on('disconnect', () => {
console.log('bye');
});
});
});
module.exports = router;
Log(Image)
Serer is running on port 3000
hello
bye
hello
hello
bye
bye
Every time your / route is hit, you create a new duplicate io.on('connection', ...) event handler. So, after that route is hit 3 times, you have 3 event handlers for the connection event. So, when it occurs, your code gets called 3 times.
Instead, you should do the io.on('connection', ...) only once outside the route.
FYI, you don't seem to be doing anything useful with the uid you are creating because you don't associate it with any particular connection. FYI, each socket.io connection already has a unique socket.id which is uniquely associated with each socket.io connection so that you can get the id from the socket or can retrieve the socket given only the id.

Categories

Resources