Skip to content

Improve error logging, proxy robustness, and operational quality of life #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 48 commits into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
125ef30
timestamps: add rudimentary timestamping to console output, as nc-mul…
dsriseah Aug 15, 2024
ca055d9
dev-sri/timestamps: fix broken eslintrc
dsriseah Aug 19, 2024
2ce78b1
sri-timestamp: duplicate of nc-multiplex to modify
dsriseah Aug 19, 2024
7db781c
dev-sri/timestamps: clean-up nc-multiplex-sri so it's clearer to see …
dsriseah Aug 19, 2024
2e39b66
dev-sri/timestamps: add process detection to bottom of management screen
dsriseah Aug 20, 2024
535b069
dev-sri/timestamps: add heartbeat memory and pid log every 15 minutes
dsriseah Aug 20, 2024
2842500
dev-sri/timestamps: move startup of mem logging to start of express a…
dsriseah Aug 20, 2024
3be82cd
dev-sri/timestamps: add -ef to ps command so it doesn't die on ubuntu
dsriseah Aug 20, 2024
e96fb7c
dev-sri/timestamps: standalone node utility to dump pids to console
dsriseah Aug 20, 2024
37171f1
dev-sri/timestamps: fix bug in output of ps -ef resulting in not capt…
dsriseah Aug 20, 2024
a1c6f20
timestamps: use correct extension for nc-launch-instance
dsriseah Aug 20, 2024
66e1f3f
timestamps: memory logging and general logging improvements
dsriseah Aug 20, 2024
3f51d00
timestamps: tweaks to console output
dsriseah Aug 20, 2024
a911385
timestamps: more console tweaks
dsriseah Aug 20, 2024
e487208
timestamps: adjust memory reporting to reflect mb for system memory a…
dsriseah Aug 20, 2024
bab6433
timestamps: fix formatting of memory report, add useful memory and re…
dsriseah Aug 20, 2024
5596365
timestamps: add prompting for /manage to start.sh
dsriseah Aug 20, 2024
2ebb283
timestamps: silly formatting improvements
dsriseah Aug 20, 2024
e764150
timestamps: update ReadMe to reflect current operations
dsriseah Aug 20, 2024
555b422
timestamps: detect crash conditions in nc-multiplex and report
dsriseah Aug 21, 2024
94ae66f
timestamps: improve 'error_no_database' and 'crash' output
dsriseah Aug 21, 2024
880593c
timestamps: get rid of annoying [HMR] console message
dsriseah Aug 21, 2024
f1968d5
timestamps: restore original nc-launch-instance.js so nc-multiplex.js…
dsriseah Aug 21, 2024
f4ec9ac
timestamps: remove temporary /crash path that forced process.exit(1)
dsriseah Aug 21, 2024
b7a5ebd
timestamps: add client ip address logging
dsriseah Aug 21, 2024
243f297
timestamps: add additional hardening and client ip reporting
dsriseah Aug 21, 2024
4c81a56
timestamps: replace `:` with space in `client:${req.ip}` strings for …
dsriseah Aug 21, 2024
133493f
timestamps: WIP websocket ping tests and hardening
dsriseah Aug 21, 2024
467e10f
timestamps: update http-proxy-middleware to 3.0.0
dsriseah Aug 24, 2024
d7ee4e4
timestamps: proof of concept process save + restore
dsriseah Aug 24, 2024
3424494
timestamps: example utility functions for managing the log
dsriseah Aug 24, 2024
7b30442
timestamps: fix out-of-position log message in nc-launch-config
dsriseah Aug 24, 2024
c7ae216
timestamps: move remaining debug scripts into hidden `./vscode/utilit…
dsriseah Aug 24, 2024
183b27f
timestamps: rename nc-multiplex-sri to nc-multiplex, update startup s…
dsriseah Aug 24, 2024
7279fbf
timestamps: fix management page interactivity/cookie synchronization …
dsriseah Aug 24, 2024
c9471ee
timestamps: fix weird change of "req.params'" to "STAT"
dsriseah Aug 25, 2024
65ede3a
timestamps: rename start.sh to start-nc-multiplex.sh so it's clearer …
dsriseah Aug 25, 2024
95af812
timestamps: add pm2 instructions to the start-nc-multiplex.sh comments
dsriseah Aug 25, 2024
742d40f
timestamps: add additional hardening for issue seen on digital ocean
dsriseah Aug 25, 2024
c5b4462
timestamps: correct bug in hardening logic
dsriseah Aug 25, 2024
ca3e675
timestamps: comprehensive req checking to m_RouterGraph(), add additi…
dsriseah Aug 25, 2024
32dc9a7
timestamps: harden autologout of management page where cookie is not …
dsriseah Aug 25, 2024
d04fb31
timestamps: fix autologout logic to wait longer before href redirect
dsriseah Aug 25, 2024
771795a
timestamps: remove more log, sesame patterns
dsriseah Sep 5, 2024
e90ae0d
timestamps: harden against missing req.originalUrl, if 'err' don't ro…
dsriseah Sep 5, 2024
ca8ea0a
timestamps: update Readme
dsriseah Sep 5, 2024
ce34f8b
Merge branch 'dev' into dev-sri/timestamps
dsriseah Sep 5, 2024
f9973bc
timestamps: fix incorrect memory bytes-to-mb conversion
dsriseah Sep 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const config = {
something else (e.g. parser) that ESLINT can make use of.
See: eslint.org/docs/user-guide/configuring#use-a-plugin
:*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
plugins: ['react'],
plugins: [],
extends: [
'eslint:recommended', // standard recommendations
// 'plugin:react/recommended', // handle jsx syntax
Expand Down
13 changes: 12 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,15 @@

# ignore custom password file
# this should never be commited to the repo to expose the password
SESAME
SESAME*


# ignore digital ocean start script, logs
do-start.sh
log*
/*.txt
/_archives

# ignore process saving files
.nc-process-state.json
.nc-server-start.txt
59 changes: 59 additions & 0 deletions .vscode/utilities/log-archive.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/bin/bash

printf "\nThis script will rename the current log.txt to log-yyyy-mmdd-hhmm.txt.\n"
printf "then create a new log.txt\n"
printf "\n"

# check if log.txt exists
if [ ! -f log.txt ]; then
printf "log.txt does not exist\n"
printf "did you copy this script to the root level of nc-multiplex?\n"
exit 1
fi


# POSIX check the size of log.txt and store it in SIZE
SIZE=$(wc -c < log.txt)

# if SIZE is 0, log.txt is empty so exit
if [ $SIZE -eq 0 ]; then
printf "error: log.txt is empty, so skipping archive\n"
exit 1
fi

# POSIX create a string based on current date and time YYYY-MMDD-HHMM
DATE=$(date +"%Y-%m%d-%H%M")


# POSIX set EXEC to true if any argument --execute was passed in cli
EXEC=false
if [ "$1" = "--execute" ]; then
EXEC=true
fi

archive() {
printf "# mv log.txt log-${DATE}.txt\n"
if [ "$EXEC" = true ]; then
mv log.txt log-${DATE}.txt
fi
# touch log.txt
printf "# touch log.txt\n"
if [ "$EXEC" = true ]; then
touch log.txt
fi
printf "\nlog.txt archived to log-${DATE}.txt\n"
}

# if EXEC is true, run the rotate function
if [ "$EXEC" = true ]; then
read -p "Press any key to continue. CTRL-C to cancel." -n1 -s
printf "\n"
archive
else
printf "use --execute to actually archive log.txt instead of simulating it\n"
printf "\n"
archive
fi



27 changes: 27 additions & 0 deletions .vscode/utilities/log-check.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/bin/bash

# check if log.txt exists
if [ ! -f log.txt ]; then
printf "log.txt does not exist\n"
printf "did you copy this script to the root level of nc-multiplex?\n"
exit 1
fi

# this script looks for restarts
BGBLU=$(tput setab 4)$(tput setaf 7)
RST=$(tput sgr0)

printf "\n${BGBLU} SERVER STARTS in LOG.TXT ${RST}\n"
cat log.txt | grep "nc-multiplex started"

printf "\n${BGBLU} DATASET LAUNCHES ${RST}\n"
cat log.txt | grep "instance confirmed"

printf "\n${BGBLU} ERRORS FOUND ${RST}\n"
ERRS=$(cat log.txt | grep "Error:")
if [ -z "$ERRORS" ]; then
printf ".. No errors found\n"
else
printf "$ERRORS"
fi
printf "\n"
21 changes: 21 additions & 0 deletions .vscode/utilities/log-less.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash

printf "\nThis script will strip the ansi codes from the log file and pipe it to less\n"
printf "It may take a few seconds to to load, so be patient! Type 'q' to quit when done.\n"
printf "\n"

# check if log.txt exists
if [ ! -f log.txt ]; then
printf "log.txt does not exist\n"
printf "did you copy this script to the root level of nc-multiplex?\n"
exit 1
fi

# wait for keyboard confirm before continuing
read -p "Press any key to continue... " -n1 -s
printf "\n"

npx strip-ansi-cli < log.txt | less

printf "\nless 'nc-multiplex/log.txt' complete\n"
printf "\n"
84 changes: 84 additions & 0 deletions .vscode/utilities/log-rotate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#!/bin/bash

printf "\nThis script will rotate the log.txt file to log.txt.1, log.txt.2, etc.\n"
printf "You might actually run log-archive instead, which makes a timestamped copy.\n"
printf "\n"

# check if log.txt exists
if [ ! -f log.txt ]; then
printf "log.txt does not exist\n"
printf "did you copy this script to the root level of nc-multiplex?\n"
exit 1
fi

# function to rotate log.txt.1 to log.txt.2, etc.
function rotate() {
log_files=()
while IFS= read -r -d '' file; do
log_files+=("$file")
done < <(find . -maxdepth 1 -type f -name "log.txt.*" -print0)

# filter the file list so it's only log.txt.1, log.txt.2, etc.
LEN=${#log_files[@]}
for ((i=0; i<${LEN}; i++)); do
# echo the number after log.txt and strip the leading ./ from the path, store in num var
num=$(echo ${log_files[$i]} | sed 's/\.\/log\.txt\.//')
# make sure num is an integer
num=$(echo $num | sed 's/[^0-9]*//g')
# if num is not an integer, remove it from the log_files list
if [ -z "$num" ]; then
unset log_files[$i]
fi
done
# update LEN to the new length of the log_files array
LEN=${#log_files[@]}
# sort the log_files array
IFS=$'\n' log_files=($(sort <<<"${log_files[*]}"))

# if log.txt exists but there are no existing rotated logs, mv log.txt to log.txt.1 and exit
if [ ${LEN} -eq 0 ]; then
echo "# mv log.txt log.txt.1"
if [ "$EXEC" = true ]; then
mv log.txt log.txt.1
fi
return
fi

# otherwise, rotate highest to highest+1 for everything
for ((i=${LEN}-1; i>=0; i--)); do
# otherwise, mv log.txt.i to log.txt.i+1
echo "# mv log.txt.${i} log.txt.$((i+1))"
if [ "$EXEC" = true ]; then
mv log.txt.${i} log.txt.$((i+1))
fi
done
# finally, mv log.txt to log.txt.0
echo "# mv log.txt log.txt.0"
if [ "$EXEC" = true ]; then
mv log.txt log.txt.0
fi
echo "# touch log.txt"
if [ "$EXEC" = true ]; then
touch log.txt
fi
}

# set EXEC to true if any argument --execute was passed in cli
EXEC=false
if [[ $* == *--execute* ]]; then
EXEC=true
fi

# if EXEC is true, run the rotate function
if [ "$EXEC" = true ]; then
read -p "Press any key to continue. CTRL-C to cancel." -n1 -s
printf "\n"
rotate
else
printf "use --execute to actually rotate the logs instead of simulating it\n"
printf ""
rotate
fi



100 changes: 100 additions & 0 deletions .vscode/utilities/memdump.jssh
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#!/usr/bin/env node

/*///////////////////////////////// ABOUT \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*\

Example Code
Dumps a memory and process report for the current node.js process.

\*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ * /////////////////////////////////////*/

const { execSync } = require('child_process');
const os = require('os');

/// CONSTANTS & DECLARATIONS //////////////////////////////////////////////////
/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const MIN_SYSMEM = 256; // megabytes
const LOG = console.log.bind(console);

/// HELPER FUNCTIONS //////////////////////////////////////////////////////////
/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/** get the output of ps matching nc-launch-instance.jssh entries */
function m_GetInstancePIDs() {
const stdout = execSync('ps -e -o pid -o command | grep nc-launch-instance.jssh');
const regex = /(\d+).+\/versions\/node\/(.+)/;
const lines = stdout.toString().split('\n');
let out = '';
lines.forEach(line => {
if (line.includes('/bin/node ./nc-launch-instance.jssh')) {
const match = line.match(regex);
if (match) {
const [_, pid, cli] = match;
const paddedPid = pid.padEnd(7, ' ');
out += ` ${paddedPid} .nvm/versions/${cli}\n`;
}
}
});
return out;
}
/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/** generate a memory report object */
function m_MemoryReport(unit = 'kb') {
const _fmt = x => x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
let cf;
if (unit === 'kb') cf = 1024;
if (unit === 'mb') cf = 1024 * 1024;
const { heapUsed, heapTotal } = process.memoryUsage();
const huse = _fmt(Math.trunc(heapUsed / cf));
const htot = _fmt(Math.trunc(heapTotal / cf));
const hpct = (100 * (heapUsed / heapTotal)).toFixed(2);
const hrem = _fmt(Math.trunc((heapTotal - heapUsed) / cf));
const kb2mb = 1024 * 1024;
const osTotal = Math.trunc(os.totalmem() / kb2mb);
const osFree = Math.trunc(os.freemem() / kb2mb);
const osUsed = osTotal - osFree;
const sysTotal = _fmt(osTotal);
const sysFree = _fmt(osFree);
const sysUsed = _fmt(osUsed);
const sysPercent = (100 * (osUsed / osTotal)).toFixed(2);
const sysLow = osFree < MIN_SYSMEM;

const pids = m_GetInstancePIDs();
return {
unit, // kb or mb
heapTotal: htot, // total allocated javascript heap (can grow)
heapUsed: huse, // total used heap (can grow)
heapPercent: hpct, // heap percentage used (percentage)
heapBuffer: hrem, // heap remaining
pids, // multi-line string of instance PIDs info
sysTotalMB: sysTotal, // total system memory in MB
sysFreeMB: sysFree, // free system memory in MB
sysUsedMB: sysUsed, // used system memory in MB
sysMinMem: MIN_SYSMEM, // minimum system memory in MB
sysPercent: sysPercent, // percentage of system memory used
warnLowMem: sysLow // true if system memory is below MIN_SYSMEM
};
}

/// RUNTIME ///////////////////////////////////////////////////////////////////
/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const mem = m_MemoryReport();
const { pids, sysTotalMB, sysFreeMB, sysPercent, sysMinMem, warnLowMem } = mem;
const { heapTotal, heapUsed, heapPercent } = mem;

LOG();
LOG(`# EXAMPLE MEMORY REPORT`);
LOG();
LOG(`# DETECTED PROXY INSTANCES`);
if (pids.length === 0) {
LOG(` - no instances found -`);
}
LOG(pids);

LOG(`# MEMORY USAGE`);
LOG(` system total: ${sysTotalMB} MB / free: ${sysFreeMB} MB / ${sysPercent}% used`);
LOG(` v8 heap total: ${heapTotal} KB / used: ${heapUsed} KB / ${heapPercent}% used`);
if (warnLowMem) {
LOG(` WARNING: free system memory is below ${sysMinMem} MB`);
} else {
LOG(` free system memory is above ${sysMinMem} MB`);
}
LOG();
Loading