#2 implement debugger
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import { DebugBuilder } from "./modules/debugger.mjs";
|
||||
const log = new DebugBuilder("client", "cliHandler");
|
||||
import { spawn } from "child_process";
|
||||
|
||||
/**
|
||||
@@ -18,7 +20,7 @@ export const executeCommand = (command, args) => {
|
||||
|
||||
childProcess.stderr.on('data', (data) => {
|
||||
// Log any errors to stderr
|
||||
console.error(data.toString());
|
||||
log.ERROR(data.toString());
|
||||
});
|
||||
|
||||
childProcess.on('error', (error) => {
|
||||
|
||||
67
modules/debugger.mjs
Normal file
67
modules/debugger.mjs
Normal file
@@ -0,0 +1,67 @@
|
||||
// Import necessary modules
|
||||
import debug from 'debug';
|
||||
import { config } from 'dotenv';
|
||||
import { writeFile } from 'fs';
|
||||
import { inspect } from 'util';
|
||||
|
||||
// Load environment variables
|
||||
config();
|
||||
|
||||
const logLocation = process.env.LOG_LOCATION;
|
||||
|
||||
const writeToLog = async (logMessage, appName) => {
|
||||
logMessage = `${String(logMessage)}\n`;
|
||||
|
||||
writeFile(
|
||||
logLocation ?? `./${appName}.log`,
|
||||
logMessage,
|
||||
{ encoding: "utf-8", flag: 'a+' },
|
||||
(err) => {
|
||||
if (err) console.error(err);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the different logging methods for a function
|
||||
* Namespace template = ("[app]:[fileName]:['INFO', 'WARNING', 'DEBUG', 'ERROR']")
|
||||
* @param {string} appName The name of the app to be used in the 'app' portion of the namespace
|
||||
* @param {string} fileName The name of the file calling the builder to be used in the 'fileName' portion of the namespace
|
||||
*/
|
||||
export class DebugBuilder {
|
||||
constructor(appName, fileName) {
|
||||
this.INFO = (...messageParts) => {
|
||||
const _info = debug(`${appName}:${fileName}:INFO`);
|
||||
_info(messageParts);
|
||||
writeToLog(`${new Date().toLocaleString('en-US', { timeZone: 'America/New_York' })} - ${appName}:${fileName}:INFO\t-\t${messageParts.map(messagePart => inspect(messagePart))}`, appName);
|
||||
};
|
||||
|
||||
this.DEBUG = (...messageParts) => {
|
||||
const _debug = debug(`${appName}:${fileName}:DEBUG`);
|
||||
_debug(messageParts);
|
||||
writeToLog(`${new Date().toLocaleString('en-US', { timeZone: 'America/New_York' })} - ${appName}:${fileName}:DEBUG\t-\t${messageParts.map(messagePart => inspect(messagePart))}`, appName);
|
||||
};
|
||||
|
||||
this.VERBOSE = (...messageParts) => {
|
||||
const _verbose = debug(`${appName}:${fileName}:VERBOSE`);
|
||||
_verbose(messageParts);
|
||||
writeToLog(`${new Date().toLocaleString('en-US', { timeZone: 'America/New_York' })} - ${appName}:${fileName}:VERBOSE\t-\t${messageParts.map(messagePart => inspect(messagePart))}`, appName);
|
||||
};
|
||||
|
||||
this.WARN = (...messageParts) => {
|
||||
const _warn = debug(`${appName}:${fileName}:WARNING`);
|
||||
_warn(messageParts);
|
||||
writeToLog(`${new Date().toLocaleString('en-US', { timeZone: 'America/New_York' })} - ${appName}:${fileName}:WARNING\t-\t${messageParts.map(messagePart => inspect(messagePart))}`, appName);
|
||||
};
|
||||
|
||||
this.ERROR = (...messageParts) => {
|
||||
const _error = debug(`${appName}:${fileName}:ERROR`);
|
||||
_error(messageParts);
|
||||
writeToLog(`${new Date().toLocaleString('en-US', { timeZone: 'America/New_York' })} - ${appName}:${fileName}:ERROR\t-\t${messageParts.map(messagePart => inspect(messagePart))}`, appName);
|
||||
if (process.env.EXIT_ON_ERROR && process.env.EXIT_ON_ERROR > 0) {
|
||||
writeToLog("!--- EXITING ---!", appName);
|
||||
setTimeout(() => process.exit(), process.env.EXIT_ON_ERROR_DELAY ?? 0);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
// Modules
|
||||
import { DebugBuilder } from "../modules/debugger.mjs";
|
||||
const log = new DebugBuilder("client", "radioPresetsHandler");
|
||||
import { writeFile, existsSync, readFileSync } from 'fs';
|
||||
import { resolve } from "path";
|
||||
import { ensureDirectoryExists } from "./baseUtils.mjs";
|
||||
@@ -16,12 +18,12 @@ const configFilePath = process.env.CONFIG_PATH;
|
||||
* @param {function} callback The function to be called when this wrapper completes
|
||||
*/
|
||||
const writePresets = async (presets, callback = undefined) => {
|
||||
console.log(`${__dirname}`);
|
||||
log.INFO(`${__dirname}`);
|
||||
await ensureDirectoryExists(configFilePath);
|
||||
writeFile(configFilePath, JSON.stringify(presets), (err) => {
|
||||
// Error checking
|
||||
if (err) throw err;
|
||||
console.log("Write Complete");
|
||||
log.INFO("Write Complete");
|
||||
if (callback) callback(); else return
|
||||
});
|
||||
}
|
||||
@@ -38,7 +40,7 @@ const sanitizeFrequencies = async (frequenciesArray) => {
|
||||
sanitizedFrequencyArray.push(convertFrequencyToHertz(freq));
|
||||
}
|
||||
|
||||
console.log("Sanitized Frequency Array", sanitizedFrequencyArray);
|
||||
log.INFO("Sanitized Frequency Array", sanitizedFrequencyArray);
|
||||
return sanitizedFrequencyArray;
|
||||
}
|
||||
|
||||
@@ -51,19 +53,19 @@ const convertFrequencyToHertz = async (frequency) => {
|
||||
// check if the passed value is a number
|
||||
if (typeof frequency == 'number' && !isNaN(frequency)) {
|
||||
if (Number.isInteger(frequency)) {
|
||||
console.log(`${frequency} is an integer.`);
|
||||
log.INFO(`${frequency} is an integer.`);
|
||||
// Check to see if the frequency has the correct length
|
||||
if (frequency >= 1000000) return frequency
|
||||
if (frequency >= 100 && frequency <= 999) return frequency * 1000000
|
||||
console.log("Frequency hasn't matched filters: ", frequency);
|
||||
log.INFO("Frequency hasn't matched filters: ", frequency);
|
||||
}
|
||||
else {
|
||||
console.log(`${frequency} is a float value.`);
|
||||
log.INFO(`${frequency} is a float value.`);
|
||||
// Convert to a string to remove the decimal in place and then correct the length
|
||||
return parseInt(converter(frequency).from("MHz").to("Hz"));
|
||||
}
|
||||
} else {
|
||||
console.log(`${frequency} is not a number`);
|
||||
log.INFO(`${frequency} is not a number`);
|
||||
frequency = convertFrequencyToHertz(parseFloat(frequency));
|
||||
|
||||
return parseInt(frequency)
|
||||
@@ -79,7 +81,7 @@ export const getAllPresets = () => {
|
||||
if (!configFilePath) return {};
|
||||
|
||||
const presetDir = resolve(configFilePath);
|
||||
console.log(`Getting presets from directory: '${presetDir}'`);
|
||||
log.INFO(`Getting presets from directory: '${presetDir}'`);
|
||||
if (existsSync(presetDir)) return JSON.parse(readFileSync(presetDir));
|
||||
else return {};
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { DebugBuilder } from "./debugger.mjs";
|
||||
const log = new DebugBuilder("client", "selfUpdater");
|
||||
import simpleGit from 'simple-git';
|
||||
import { restartService } from './serviceHandler.mjs'
|
||||
import { launchProcess } from './subprocessHandler.mjs'
|
||||
@@ -17,14 +19,14 @@ export const checkForUpdates = async () => {
|
||||
const localCommitHash = await git.revparse(['HEAD']);
|
||||
|
||||
if (latestCommitHash !== localCommitHash) {
|
||||
console.log('An update is available. Updating...');
|
||||
log.INFO('An update is available. Updating...');
|
||||
|
||||
// Check if there have been any changes to the code
|
||||
const gitStatus = await git.status()
|
||||
console.log(gitStatus);
|
||||
log.INFO(gitStatus);
|
||||
if (gitStatus.modified.length > 0){
|
||||
// There is locally modified code
|
||||
console.log("There is locally modified code, resetting...");
|
||||
log.INFO("There is locally modified code, resetting...");
|
||||
await git.stash();
|
||||
await git.reset('hard', ['origin/master']);
|
||||
}
|
||||
@@ -33,25 +35,25 @@ export const checkForUpdates = async () => {
|
||||
await git.pull();
|
||||
|
||||
// Run the post-update script
|
||||
console.log('Running post-update script...');
|
||||
log.INFO('Running post-update script...');
|
||||
await launchProcess("bash", ['./post-update.sh'], true);
|
||||
|
||||
// Restart the application to apply the updates
|
||||
console.log('Update completed successfully. Restarting the application...');
|
||||
log.INFO('Update completed successfully. Restarting the application...');
|
||||
restartApplication();
|
||||
|
||||
return true
|
||||
} else {
|
||||
console.log('The application is up to date.');
|
||||
log.INFO('The application is up to date.');
|
||||
return false
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error checking for updates:', error);
|
||||
log.ERROR('Error checking for updates:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// Function to restart the application
|
||||
export const restartApplication = () => {
|
||||
console.log('Restarting the application...');
|
||||
log.INFO('Restarting the application...');
|
||||
restartService('discord-radio-bot');
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
import { DebugBuilder } from "./modules/debugger.mjs";
|
||||
const log = new DebugBuilder("client", "serviceHandler");
|
||||
import { exec } from 'child_process';
|
||||
|
||||
/**
|
||||
@@ -9,7 +11,7 @@ const executeCommand = (command) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
exec(command, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
console.error(`Command failed with error: ${error.message}`);
|
||||
log.ERROR(`Command failed with error: ${error.message}`);
|
||||
resolve({ stdout, stderr });
|
||||
} else {
|
||||
resolve({ stdout, stderr });
|
||||
@@ -27,7 +29,7 @@ export const startService = async (serviceName) => {
|
||||
try {
|
||||
await executeCommand(`sudo systemctl start ${serviceName}.service`);
|
||||
} catch (error) {
|
||||
console.error(`Failed to start service: ${error.message}`);
|
||||
log.ERROR(`Failed to start service: ${error.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -40,7 +42,7 @@ export const restartService = async (serviceName) => {
|
||||
try {
|
||||
await executeCommand(`sudo systemctl restart ${serviceName}.service`);
|
||||
} catch (error) {
|
||||
console.error(`Failed to restart service: ${error.message}`);
|
||||
log.ERROR(`Failed to restart service: ${error.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -53,6 +55,6 @@ export const stopService = async (serviceName) => {
|
||||
try {
|
||||
await executeCommand(`sudo systemctl stop ${serviceName}.service`);
|
||||
} catch (error) {
|
||||
console.error(`Failed to stop service: ${error.message}`);
|
||||
log.ERROR(`Failed to stop service: ${error.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { DebugBuilder } from "./debugger.mjs";
|
||||
const log = new DebugBuilder("client", "socketClient");
|
||||
import { io } from "socket.io-client";
|
||||
import { logIntoServerWrapper, nodeCheckStatus, nodeJoinServer, nodeLeaveServer, nodeGetUsername, nodeCheckDiscordClientStatus, nodeCheckCurrentSystem, nodeUpdate, nodeGetDiscordID } from "./socketClientWrappers.mjs";
|
||||
|
||||
@@ -14,13 +16,13 @@ export const initSocketConnection = async (localNodeConfig) => {
|
||||
// Socket Events ('system' events persay)
|
||||
// When the socket connects to the node server
|
||||
socket.on('connect', async () => {
|
||||
console.log('Connected to the server');
|
||||
log.INFO('Connected to the server');
|
||||
await logIntoServerWrapper(socket, localNodeConfig);
|
||||
});
|
||||
|
||||
// When the socket disconnects from the node server
|
||||
socket.on('disconnect', () => {
|
||||
console.log('Disconnected from the server');
|
||||
log.INFO('Disconnected from the server');
|
||||
});
|
||||
|
||||
// Node events/commands
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { DebugBuilder } from "./debugger.mjs";
|
||||
const log = new DebugBuilder("client", "subprocessHandler");
|
||||
import { spawn } from "child_process";
|
||||
import dotenv from 'dotenv';
|
||||
dotenv.config()
|
||||
@@ -35,14 +37,14 @@ export const launchProcess = (processName, args, waitForClose = false, returnOut
|
||||
// Get the stdout from the child process
|
||||
childProcess.stdout.setEncoding('utf8');
|
||||
childProcess.stdout.on('data', (data) => {
|
||||
if (process.env.NODE_ENV === "development") console.log(`Data from ${processName}:`, data);
|
||||
if (process.env.NODE_ENV === "development") log.INFO(`Data from ${processName}:`, data);
|
||||
scriptOutput += data.toString();
|
||||
});
|
||||
|
||||
// Get the stderr from the child process
|
||||
childProcess.stderr.setEncoding('utf8');
|
||||
childProcess.stderr.on('data', (data) => {
|
||||
if (process.env.NODE_ENV === "development") console.log(`Data from ${processName}:`, data);
|
||||
if (process.env.NODE_ENV === "development") log.INFO(`Data from ${processName}:`, data);
|
||||
scriptOutput += data.toString();
|
||||
})
|
||||
|
||||
@@ -50,8 +52,8 @@ export const launchProcess = (processName, args, waitForClose = false, returnOut
|
||||
childProcess.on('exit', (code, signal) => {
|
||||
// Remove reference to the process when it exits
|
||||
delete runningProcesses[processName];
|
||||
console.log(`${processName} process exited with code ${code} and signal ${signal}`);
|
||||
console.log("Child process console output: ", scriptOutput);
|
||||
log.INFO(`${processName} process exited with code ${code} and signal ${signal}`);
|
||||
log.INFO("Child process console output: ", scriptOutput);
|
||||
// Return the full script output if requested
|
||||
if (returnOutput === true) {
|
||||
return res(scriptOutput)
|
||||
@@ -64,9 +66,9 @@ export const launchProcess = (processName, args, waitForClose = false, returnOut
|
||||
return output
|
||||
}
|
||||
|
||||
console.log(`${processName} process started.`);
|
||||
log.INFO(`${processName} process started.`);
|
||||
} else {
|
||||
console.log(`${processName} process is already running.`);
|
||||
log.INFO(`${processName} process is already running.`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,9 +99,9 @@ export const killProcess = (processName) => {
|
||||
const childProcess = runningProcesses[processName];
|
||||
if (childProcess) {
|
||||
childProcess.kill();
|
||||
console.log(`${processName} process killed.`);
|
||||
log.INFO(`${processName} process killed.`);
|
||||
} else {
|
||||
console.log(`${processName} process is not running.`);
|
||||
log.INFO(`${processName} process is not running.`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// Modules
|
||||
import { DebugBuilder } from "./debugger.mjs";
|
||||
const log = new DebugBuilder("client", "updateConfig");
|
||||
import replace from 'replace-in-file';
|
||||
|
||||
class Options {
|
||||
@@ -19,7 +21,7 @@ class Options {
|
||||
export const updateId = async (updatedId) => {
|
||||
await updateConfig('CLIENT_NUID', updatedId);
|
||||
process.env.CLIENT_NUID = updatedId;
|
||||
console.log("Updated NUID to: ", updatedId);
|
||||
log.INFO("Updated NUID to: ", updatedId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,7 +51,7 @@ export function updateClientConfig (runningConfig, newConfigObject) {
|
||||
this.updateConfig('CLIENT_NAME', newConfigObject.name);
|
||||
updatedKeys.push({ 'CLIENT_NAME': newConfigObject.name });
|
||||
process.env.CLIENT_NAME = newConfigObject.name;
|
||||
console.log("Updated name to: ", newConfigObject.name);
|
||||
log.INFO("Updated name to: ", newConfigObject.name);
|
||||
}
|
||||
}
|
||||
if (configKeys.includes("ip")) {
|
||||
@@ -57,7 +59,7 @@ export function updateClientConfig (runningConfig, newConfigObject) {
|
||||
this.updateConfig('CLIENT_IP', newConfigObject.ip);
|
||||
updatedKeys.push({ 'CLIENT_IP': newConfigObject.ip });
|
||||
process.env.CLIENT_IP = newConfigObject.ip;
|
||||
console.log("Updated ip to: ", newConfigObject.ip);
|
||||
log.INFO("Updated ip to: ", newConfigObject.ip);
|
||||
}
|
||||
}
|
||||
if (configKeys.includes("port")) {
|
||||
@@ -65,7 +67,7 @@ export function updateClientConfig (runningConfig, newConfigObject) {
|
||||
this.updateConfig('CLIENT_PORT', newConfigObject.port);
|
||||
updatedKeys.push({ 'CLIENT_PORT': newConfigObject.port });
|
||||
process.env.CLIENT_PORT = newConfigObject.port;
|
||||
console.log("Updated port to: ", newConfigObject.port);
|
||||
log.INFO("Updated port to: ", newConfigObject.port);
|
||||
}
|
||||
}
|
||||
if (configKeys.includes("location")) {
|
||||
@@ -73,7 +75,7 @@ export function updateClientConfig (runningConfig, newConfigObject) {
|
||||
this.updateConfig('CLIENT_LOCATION', newConfigObject.location);
|
||||
updatedKeys.push({ 'CLIENT_LOCATION': newConfigObject.location });
|
||||
process.env.CLIENT_LOCATION = newConfigObject.location;
|
||||
console.log("Updated location to: ", newConfigObject.location);
|
||||
log.INFO("Updated location to: ", newConfigObject.location);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +90,7 @@ export function updateClientConfig (runningConfig, newConfigObject) {
|
||||
export function updateConfig (key, value) {
|
||||
const options = new Options(key, value);
|
||||
|
||||
console.log("Options:", options);
|
||||
log.INFO("Options:", options);
|
||||
|
||||
updateConfigFile(options, (updatedFiles) => {
|
||||
// Do Something
|
||||
@@ -102,8 +104,8 @@ export function updateConfig (key, value) {
|
||||
*/
|
||||
function updateConfigFile(options, callback) {
|
||||
replace(options, (error, changedFiles) => {
|
||||
if (error) return console.error('Error occurred:', error);
|
||||
console.log('Updated config file: ', changedFiles);
|
||||
if (error) return log.ERROR('Error occurred:', error);
|
||||
log.INFO('Updated config file: ', changedFiles);
|
||||
callback(changedFiles);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user