[call-me] - add logs
This commit is contained in:
@@ -22,6 +22,14 @@ TURN_SERVER_URL=turn:a.relay.metered.ca:443
|
||||
TURN_SERVER_USERNAME=e8dd65b92c62d3e36cafb807
|
||||
TURN_SERVER_CREDENTIAL=uWdWNmkhvyqTEswO
|
||||
|
||||
# Time Zone corresponding to timezone identifiers from the IANA Time Zone Database es Europe/Rome default UTC
|
||||
|
||||
TZ=UTC
|
||||
|
||||
# Logs
|
||||
|
||||
DEBUG=true # true or false
|
||||
|
||||
# API
|
||||
|
||||
API_KEY_SECRET=call_me_api_key_secret # change me
|
||||
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
'use strict';
|
||||
|
||||
const util = require('util');
|
||||
|
||||
const colors = require('colors');
|
||||
|
||||
colors.enable(); // colors.disable();
|
||||
|
||||
const options = {
|
||||
depth: null,
|
||||
colors: true,
|
||||
};
|
||||
|
||||
module.exports = class Logs {
|
||||
constructor(appName = 'call-me') {
|
||||
this.appName = colors.yellow(appName);
|
||||
this.debugOn = process.env.DEBUG !== undefined ? process.env.DEBUG === 'true' : true;
|
||||
this.timeStart = Date.now();
|
||||
this.timeEnd = null;
|
||||
this.timeElapsedMs = null;
|
||||
this.tzOptions = {
|
||||
timeZone: process.env.TZ || 'UTC',
|
||||
hour12: false,
|
||||
};
|
||||
}
|
||||
|
||||
debug(msg, op = '') {
|
||||
if (this.debugOn) {
|
||||
this.timeEnd = Date.now();
|
||||
this.timeElapsedMs = this.getFormatTime(Math.floor(this.timeEnd - this.timeStart));
|
||||
console.debug(
|
||||
'[' + this.getDateTime() + '] [' + this.appName + '] ' + msg,
|
||||
util.inspect(op, options),
|
||||
this.timeElapsedMs,
|
||||
);
|
||||
this.timeStart = Date.now();
|
||||
}
|
||||
}
|
||||
|
||||
log(msg, op = '') {
|
||||
console.log('[' + this.getDateTime() + '] [' + this.appName + '] ' + msg, util.inspect(op, options));
|
||||
}
|
||||
|
||||
info(msg, op = '') {
|
||||
console.info(
|
||||
'[' + this.getDateTime() + '] [' + this.appName + '] ' + colors.green(msg),
|
||||
util.inspect(op, options),
|
||||
);
|
||||
}
|
||||
|
||||
warn(msg, op = '') {
|
||||
console.info(
|
||||
'[' + this.getDateTime() + '] [' + this.appName + '] ' + colors.yellow(msg),
|
||||
util.inspect(op, options),
|
||||
);
|
||||
}
|
||||
|
||||
error(msg, op = '') {
|
||||
console.info(
|
||||
'[' + this.getDateTime() + '] [' + this.appName + '] ' + colors.red(msg),
|
||||
util.inspect(op, options),
|
||||
);
|
||||
}
|
||||
|
||||
getDateTime() {
|
||||
const currentTime = new Date().toLocaleString('en-US', this.tzOptions);
|
||||
const milliseconds = String(new Date().getMilliseconds()).padStart(3, '0');
|
||||
return colors.cyan(`${currentTime}:${milliseconds}`);
|
||||
}
|
||||
|
||||
getFormatTime(ms) {
|
||||
let time = Math.floor(ms);
|
||||
let type = 'ms';
|
||||
|
||||
if (ms >= 1000) {
|
||||
time = Math.floor((ms / 1000) % 60);
|
||||
type = 's';
|
||||
}
|
||||
if (ms >= 60000) {
|
||||
time = Math.floor((ms / 1000 / 60) % 60);
|
||||
type = 'm';
|
||||
}
|
||||
if (ms >= (3, 6e6)) {
|
||||
time = Math.floor((ms / 1000 / 60 / 60) % 24);
|
||||
type = 'h';
|
||||
}
|
||||
return colors.magenta('+' + time + type);
|
||||
}
|
||||
};
|
||||
+32
-28
@@ -13,6 +13,10 @@ const yaml = require('js-yaml');
|
||||
const swaggerUi = require('swagger-ui-express');
|
||||
const packageJson = require('../package.json');
|
||||
|
||||
// Logs
|
||||
const logs = require('./logs');
|
||||
const log = new logs('server');
|
||||
|
||||
// Public directory location
|
||||
const PUBLIC_DIR = path.join(__dirname, '../', 'public');
|
||||
|
||||
@@ -79,7 +83,7 @@ if (isHttps) {
|
||||
// Create HTTPS server using Express
|
||||
server = https.createServer(options, app);
|
||||
} catch (err) {
|
||||
console.error('Error loading certificates:', err);
|
||||
log.error('Error loading certificates:', err);
|
||||
process.exit(1); // Exit the process if certificates cannot be loaded
|
||||
}
|
||||
} else {
|
||||
@@ -92,7 +96,7 @@ const io = socketIO(server);
|
||||
|
||||
// Start the server and listen on the specified port
|
||||
server.listen(port, () => {
|
||||
console.log('Server', {
|
||||
log.info('Server', {
|
||||
running_at: host,
|
||||
ice: config.iceServers,
|
||||
host: {
|
||||
@@ -114,7 +118,7 @@ app.use(config.apiBasePath + '/docs', swaggerUi.serve, swaggerUi.setup(config.sw
|
||||
|
||||
// Logs requests
|
||||
app.use((req, res, next) => {
|
||||
console.log('New request', {
|
||||
log.debug('New request', {
|
||||
//headers: req.headers,
|
||||
body: req.body,
|
||||
method: req.method,
|
||||
@@ -137,14 +141,14 @@ app.get('/randomImage', async (req, res) => {
|
||||
const data = response.data;
|
||||
res.send(data);
|
||||
} catch (error) {
|
||||
console.error('Error fetching image', error.message);
|
||||
log.error('Error fetching image', error.message);
|
||||
}
|
||||
});
|
||||
|
||||
// Direct Join room
|
||||
app.get('/join/', (req, res) => {
|
||||
if (Object.keys(req.query).length > 0) {
|
||||
console.log('Request query', req.query);
|
||||
log.debug('Request query', req.query);
|
||||
|
||||
const { user, call, password } = req.query;
|
||||
// http://localhost:8000/join?user=user1
|
||||
@@ -157,13 +161,13 @@ app.get('/join/', (req, res) => {
|
||||
}
|
||||
|
||||
const isValidUser = isValidUsername(user);
|
||||
console.log('isValidUser', { user: user, valid: isValidUser });
|
||||
log.debug('isValidUser', { user: user, valid: isValidUser });
|
||||
if (!isValidUser) {
|
||||
return unauthorized(res);
|
||||
}
|
||||
|
||||
const isValidCall = isValidUsername(user);
|
||||
console.log('isValidCall', { call: call, valid: isValidCall });
|
||||
log.debug('isValidCall', { call: call, valid: isValidCall });
|
||||
if (!isValidCall) {
|
||||
return unauthorized(res);
|
||||
}
|
||||
@@ -179,14 +183,14 @@ app.get('/join/', (req, res) => {
|
||||
app.get(`${config.apiBasePath}/connected`, (req, res) => {
|
||||
// Check if the user is authorized for this API call
|
||||
if (!isAuthorized(req)) {
|
||||
console.log('Unauthorized API call: Get Connected', {
|
||||
log.debug('Unauthorized API call: Get Connected', {
|
||||
headers: req.headers,
|
||||
body: req.body,
|
||||
});
|
||||
return res.status(403).json({ error: 'Unauthorized!' });
|
||||
}
|
||||
|
||||
//console.log(req.query);
|
||||
//log.debug(req.query);
|
||||
const { user } = req.query;
|
||||
if (!user) {
|
||||
return res.status(400).json({ error: 'User not provided in request query' });
|
||||
@@ -220,7 +224,7 @@ app.get(`${config.apiBasePath}/connected`, (req, res) => {
|
||||
app.get(`${config.apiBasePath}/users`, (req, res) => {
|
||||
// check if user is authorized for the API call
|
||||
if (!isAuthorized(req)) {
|
||||
console.log('Unauthorized API call: Get Users', {
|
||||
log.debug('Unauthorized API call: Get Users', {
|
||||
headers: req.headers,
|
||||
body: req.body,
|
||||
});
|
||||
@@ -267,7 +271,7 @@ const isAuthorized = (req) => {
|
||||
|
||||
// Function to handle individual WebSocket connections
|
||||
function handleConnection(socket) {
|
||||
console.log('User connected:', socket.id);
|
||||
log.debug('User connected:', socket.id);
|
||||
|
||||
// Refresh connected users
|
||||
broadcastConnectedUsers();
|
||||
@@ -283,7 +287,7 @@ function handleConnection(socket) {
|
||||
function handleMessage(data) {
|
||||
const { type } = data;
|
||||
|
||||
console.log('Received message', type);
|
||||
log.debug('Received message', type);
|
||||
|
||||
switch (type) {
|
||||
case 'signIn':
|
||||
@@ -302,7 +306,7 @@ function handleConnection(socket) {
|
||||
handleSignalingMessage(data);
|
||||
break;
|
||||
case 'pong':
|
||||
console.log('Client response:', data.message);
|
||||
log.debug('Client response:', data.message);
|
||||
break;
|
||||
default:
|
||||
sendError(socket, `Unknown command: ${type}`);
|
||||
@@ -324,7 +328,7 @@ function handleConnection(socket) {
|
||||
const { name } = data;
|
||||
|
||||
const isValidName = isValidUsername(name);
|
||||
console.log('isValidName', { username: name, valid: isValidName });
|
||||
log.debug('isValidName', { username: name, valid: isValidName });
|
||||
if (!isValidName) {
|
||||
sendMsgTo(socket, {
|
||||
type: 'signIn',
|
||||
@@ -338,7 +342,7 @@ function handleConnection(socket) {
|
||||
if (!users.has(name)) {
|
||||
users.set(name, socket);
|
||||
socket.username = name;
|
||||
console.log('User signed in:', name);
|
||||
log.debug('User signed in:', name);
|
||||
sendMsgTo(socket, { type: 'signIn', success: true });
|
||||
broadcastConnectedUsers();
|
||||
} else {
|
||||
@@ -348,13 +352,13 @@ function handleConnection(socket) {
|
||||
|
||||
// Function to handle offer request
|
||||
function handleOffer(data) {
|
||||
console.log('handleOffer', data);
|
||||
log.debug('handleOffer', data);
|
||||
|
||||
const { from, to, name, type } = data;
|
||||
const toName = type === 'offerAccept' ? to : from;
|
||||
const recipientSocket = users.get(toName);
|
||||
|
||||
console.log(`Handling offer for ${toName}`);
|
||||
log.debug(`Handling offer for ${toName}`);
|
||||
|
||||
switch (type) {
|
||||
case 'offerAccept':
|
||||
@@ -362,20 +366,20 @@ function handleConnection(socket) {
|
||||
if (recipientSocket) {
|
||||
sendMsgTo(recipientSocket, data);
|
||||
} else {
|
||||
console.warn(`Recipient (${toName}) not found`);
|
||||
log.warn(`Recipient (${toName}) not found`);
|
||||
sendMsgTo(socket, { type: 'notfound', username: toName });
|
||||
}
|
||||
break;
|
||||
case 'offerDecline':
|
||||
console.warn(`User ${name} declined your call`);
|
||||
log.warn(`User ${name} declined your call`);
|
||||
sendError(recipientSocket || socket, `User ${name} declined your call`);
|
||||
break;
|
||||
case 'offerBusy':
|
||||
console.warn(`User ${name} busy in another call`);
|
||||
log.warn(`User ${name} busy in another call`);
|
||||
sendError(recipientSocket || socket, `User ${name} busy in another call.`);
|
||||
break;
|
||||
default:
|
||||
console.warn(`Unknown offer type: ${type}`);
|
||||
log.warn(`Unknown offer type: ${type}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -388,7 +392,7 @@ function handleConnection(socket) {
|
||||
switch (type) {
|
||||
case 'leave':
|
||||
if (recipientSocket !== undefined) {
|
||||
console.log('Leave room', socket.username);
|
||||
log.debug('Leave room', socket.username);
|
||||
sendMsgTo(recipientSocket, { type: 'leave', name: socket.username });
|
||||
}
|
||||
break;
|
||||
@@ -404,7 +408,7 @@ function handleConnection(socket) {
|
||||
function handleClose() {
|
||||
const name = socket.username;
|
||||
if (name) {
|
||||
console.log('User disconnected:', name);
|
||||
log.debug('User disconnected:', name);
|
||||
users.delete(name);
|
||||
broadcastConnectedUsers();
|
||||
}
|
||||
@@ -425,31 +429,31 @@ function getConnectedUsers() {
|
||||
// Function to broadcast all connected users
|
||||
function broadcastConnectedUsers() {
|
||||
const connectedUsers = getConnectedUsers();
|
||||
console.log('Connected Users', connectedUsers);
|
||||
log.debug('Connected Users', connectedUsers);
|
||||
broadcastMsg({ type: 'users', users: connectedUsers });
|
||||
}
|
||||
|
||||
// Function to broadcast a message to all connected clients
|
||||
function broadcastMsg(message) {
|
||||
console.log('Broadcast message:', message);
|
||||
log.debug('Broadcast message:', message);
|
||||
io.emit('message', message);
|
||||
}
|
||||
|
||||
// Function to broadcast a message to all connected clients except the sender
|
||||
function broadcastMsgExpectSender(socket, message) {
|
||||
console.log('Broadcast message:', message);
|
||||
log.debug('Broadcast message:', message);
|
||||
socket.broadcast.emit('message', message);
|
||||
}
|
||||
|
||||
// Function to send a message to a specific connection
|
||||
function sendMsgTo(socket, message) {
|
||||
console.log('Sending message:', message.type);
|
||||
log.debug('Sending message:', message.type);
|
||||
socket.emit('message', message);
|
||||
}
|
||||
|
||||
// Function to send an error message to a specific connection
|
||||
function sendError(socket, message) {
|
||||
console.error('Error:', message);
|
||||
log.error('Error:', message);
|
||||
sendMsgTo(socket, { type: 'error', message: message });
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "call-me",
|
||||
"version": "1.0.60",
|
||||
"version": "1.0.62",
|
||||
"description": "Your Go-To for Instant Video Calls",
|
||||
"author": "Miroslav Pejic - miroslav.pejic.85@gmail.com",
|
||||
"license": "AGPLv3",
|
||||
@@ -20,6 +20,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.7.9",
|
||||
"colors": "^1.4.0",
|
||||
"dotenv": "^16.4.7",
|
||||
"express": "^4.21.2",
|
||||
"js-yaml": "4.1.0",
|
||||
|
||||
Reference in New Issue
Block a user