@akc42/server-utils 2.0.3 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -7,8 +7,8 @@ The packages are:-
7
7
 
8
8
  `logger` provides a logging service for the app. It is controlled by three environment variables LOG_NONE prevents it from logging anything.
9
9
  This is designed to be used during testing of the server side of the app so that nothing is logged. LOG_NO_DATE omits the date and time from
10
- the logged output. This is generally used when another logger (e.g PM2 log output) is also adding date/time. Finally LOG_NO_ENCODE is used
11
- to say don't try and anonomise client ip addresses (see below). `logger` is called so `logger([clientip,] level, ...messages);`.
10
+ the logged output. This is generally used when another logger (e.g PM2 log output) is also adding date/time. Finally LOG_HIDDEN_IP is used
11
+ to say to try and anonomise client ip addresses (see below). `logger` is called so `logger([clientip,] level, ...messages);`.
12
12
 
13
13
  `Responder` is a class to provide the ability to stream JSON responses to a node js http request. It is instanciated
14
14
  with `new Responder(response);` and the resultant object has three methods;
@@ -39,8 +39,13 @@ separated list of topics to be logged), then this is output. Regardless, all
39
39
  debug calls are stored in a 50 line cache, and will be output (newest first) on a call
40
40
  to `dumpDebugCache`
41
41
 
42
+ Breaking change as of 3.0.0 logger is now an async function returning a promise fulfilled when (if set) a log file entry is made
42
43
 
43
- Thise are installed with as many of few of the items that you want like so:-
44
+ both `Debug` and `logger` bit now support LOG_FILE environment variable. When set points to a log file rather than the
45
+ console. If it is not undefined these two modules will write to the log file rather than the console.
46
+
47
+
48
+ These are installed with as many of few of the items that you want like so:-
44
49
  ```
45
50
  import {logger,Responder,Debug} from '@akc42/server-utils';
46
51
  ```
package/debug.js CHANGED
@@ -17,7 +17,7 @@
17
17
  You should have received a copy of the GNU General Public License
18
18
  along with Server Utils. If not, see <http://www.gnu.org/licenses/>.
19
19
  */
20
-
20
+ import fs from 'node:fs/promises';
21
21
  import chalk from 'chalk';
22
22
  let config = '';
23
23
  let cache = [];
@@ -26,7 +26,7 @@ let cachelimit = 50;
26
26
  export function Debug (topic) {
27
27
  const t = topic;
28
28
  let timestamp = new Date().getTime();
29
- return function (...args) {
29
+ return async function (...args) {
30
30
  let enabled = false;
31
31
  if (config) {
32
32
  const topics = config.split(':');
@@ -40,27 +40,63 @@ export function Debug (topic) {
40
40
  }, '');
41
41
  const output = `${chalk.greenBright(topic)} ${chalk.cyan(message)} ${chalk.whiteBright(`(${gap}ms)`)}`
42
42
  if (enabled) {
43
- console.log(output);
43
+ if (typeof process.env.LOG_FILE === 'undefined') {
44
+ //eslint-disable-next-line no-console
45
+ console.log(output);
46
+ } else {
47
+ try {
48
+ await fs.appendFile(process.env.LOG_FILE, output + '\n',{flush: true})
49
+ } catch(err) {
50
+ console.warn('Failed to write following message to log file', output);
51
+ }
52
+ }
44
53
  }
45
54
  cache.push(output);
46
55
  if (cache.length > cachelimit) cache.splice(0,cache.length - cachelimit); //prevent it getting too big
47
56
  }
48
57
  };
49
- export function dumpDebugCache() {
58
+ export async function dumpDebugCache() {
50
59
  const output = chalk.white.bgBlue('Above are all the debug calls (most recent first) which lead up to, and then followed on from, the error above');
51
60
  cache.reverse();
52
61
  for(const line of cache) {
53
- console.log(line);
62
+ if (typeof process.env.LOG_FILE === 'undefined') {
63
+ //eslint-disable-next-line no-console
64
+ console.log(line);
65
+ } else {
66
+ try {
67
+ await fs.appendFile(process.env.LOG_FILE, line + '\n',{flush: true});
68
+ } catch (err) {
69
+ console.warn('Failed to write following message to log file', line);
70
+ }
71
+ }
54
72
  }
55
73
  cache.reverse();
56
- console.log(output);
74
+ if (typeof process.env.LOG_FILE === 'undefined') {
75
+ //eslint-disable-next-line no-console
76
+ console.log(output);
77
+ } else {
78
+ try {
79
+ await fs.appendFile(process.env.LOG_FILE, output + '\n',{flush: true});
80
+ } catch(err) {
81
+ console.warn('Failed to write following message to log file', output);
82
+ }
83
+ }
57
84
  };
58
- export function setDebugConfig(con, limit = 50) {
85
+ export async function setDebugConfig(con, limit = 50) {
59
86
  cachelimit = limit;
60
87
  if (con !== config) {
61
88
  config = con;
62
89
  const output = `${chalk.greenBright('debug server config')} ${chalk.redBright(`new server config "${config}"`)}`
63
- console.log(output);
90
+ if (typeof process.env.LOG_FILE === 'undefined') {
91
+ //eslint-disable-next-line no-console
92
+ console.log(output);
93
+ } else {
94
+ try {
95
+ await fs.appendFile(process.env.LOG_FILE, output + '\n',{flush: true})
96
+ } catch (err) {
97
+ console.warn('Failed to write following message to log file', output);
98
+ }
99
+ }
64
100
  }
65
101
  };
66
102
 
package/logger.js CHANGED
@@ -19,7 +19,8 @@
19
19
  */
20
20
 
21
21
  import chalk from 'chalk';
22
- import { isIP } from 'net';
22
+ import { isIP } from 'node:net';
23
+ import fs from 'node:fs/promises'
23
24
 
24
25
  const COLOURS = {
25
26
  app: chalk.rgb(255, 136, 0).bold, //orange,
@@ -34,11 +35,7 @@ const COLOURS = {
34
35
  error: chalk.white.bgRed
35
36
 
36
37
  };
37
- let cyrb53;
38
- if (process.env.LOG_NO_ENCODE) {
39
- cyrb53 = (str, seed = 0) => {return str;};
40
- } else {
41
- cyrb53 = (str, seed = 0) => {
38
+ function cyrb53 (str, seed = 0) {
42
39
  let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed;
43
40
  for (let i = 0, ch; i < str.length; i++) {
44
41
  ch = str.charCodeAt(i);
@@ -48,27 +45,34 @@ if (process.env.LOG_NO_ENCODE) {
48
45
  h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507) ^ Math.imul(h2 ^ h2 >>> 13, 3266489909);
49
46
  h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507) ^ Math.imul(h1 ^ h1 >>> 13, 3266489909);
50
47
  return 4294967296 * (2097151 & h2) + (h1 >>> 0);
51
- };
52
48
  }
53
49
 
54
- export default function logger(ip,level, ...messages) {
50
+ export default async function logger(ip,level, ...messages) {
55
51
  if (process.env.LOG_NONE === undefined) {
56
52
  let logLine = '';
57
- if (process.env.LOG_NO_DATE === undefined) logLine += new Date().toISOString() + ': ';
53
+ if (typeof process.env.LOG_NO_DATE === 'undefined') logLine += new Date().toISOString() + ': ';
58
54
  let message;
59
55
  let logcolor;
60
56
  if (isIP(ip) === 0 ) {
61
57
  logcolor = ip;
62
58
  message = level + messages.join(' ');
63
59
  } else {
64
- const client = process.env.LOG_IP_HIDDEN !== undefined ? cyrb53(ip): ip;
60
+ const client = typeof process.env.LOG_IP_HIDDEN !== 'undefined' ? cyrb53(ip): ip;
65
61
  logLine += COLOURS.client(client + ': ');
66
62
  logcolor = level
67
63
  message = messages.join(' ');
68
64
  }
69
65
  logLine += COLOURS[logcolor](message);
70
- //eslint-disable-next-line no-console
71
- console.log(logLine.trim());
66
+ if (typeof process.env.LOG_FILE === 'undefined') {
67
+ //eslint-disable-next-line no-console
68
+ console.log(logLine.trim());
69
+ } else {
70
+ try {
71
+ await fs.appendFile(process.env.LOG_FILE, logLine.trim() + '\n',{flush: true})
72
+ } catch(err) {
73
+ console.warn('Error writing log file:',err,'message being logged', logLine.trim());
74
+ }
75
+ }
72
76
  }
73
77
  }
74
78
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akc42/server-utils",
3
- "version": "2.0.3",
3
+ "version": "3.1.0",
4
4
  "type": "module",
5
5
  "description": "A Set of Utilities to use on the Server Side of a Project",
6
6
  "main": "./utils.js",
@@ -22,9 +22,6 @@
22
22
  },
23
23
  "homepage": "https://github.com/akc42/server-utils#readme",
24
24
  "dependencies": {
25
- "app-root-path": "^3.1.0",
26
- "chalk": "^5.3.0",
27
- "debug": "^4.3.4"
25
+ "chalk": "^5.3.0"
28
26
  }
29
-
30
27
  }
package/version.js CHANGED
@@ -25,16 +25,16 @@ import { exec } from 'node:child_process';
25
25
 
26
26
  const debug = Debug('version');
27
27
 
28
- function shCmd(cmd, root) {
29
- debug('About to execute Command ', cmd);
30
- return new Promise((accept, reject) => {
31
- exec(cmd, { cwd: root }, (err, stdout, stderr) => {
28
+ async function shCmd(cmd, root) {
29
+ await debug('About to execute Command ', cmd);
30
+ return new Promise(async (accept, reject) => {
31
+ exec(cmd, { cwd: root }, async (err, stdout, stderr) => {
32
32
  if (stderr) {
33
- debug('Command ', cmd, 'about to fail with ', err);
33
+ await debug('Command ', cmd, 'about to fail with ', err);
34
34
  reject(err);
35
35
  } else {
36
36
  const out = stdout.trim();
37
- debug('Command ', cmd, 'Success with ', out);
37
+ await debug('Command ', cmd, 'Success with ', out);
38
38
  accept(out);
39
39
  }
40
40
  });
@@ -46,9 +46,9 @@ export default async function(root) {
46
46
  let vtime;
47
47
 
48
48
  try {
49
- debug('Look for git')
49
+ await debug('Look for git')
50
50
  await access(resolve(root, '.git'));
51
- debug('Git found, so use it to get data')
51
+ await debug('Git found, so use it to get data')
52
52
  //we get here if there is a git directory, so we can look up version and latest commit from them
53
53
  version = await shCmd('git describe --abbrev=0 --tags');
54
54
  //git is installed and we found a tag
@@ -60,7 +60,7 @@ export default async function(root) {
60
60
  } catch (e) {
61
61
  //no git, or no tag, so we must look for a version file
62
62
  try {
63
- debug('Git approach failed, so look for release info');
63
+ await debug('Git approach failed, so look for release info');
64
64
  version = await readFile(resolve(root, 'release.info'), 'utf8');
65
65
  try {
66
66
  const { mtime } = await stat(resolve(root, 'release.info'));
@@ -88,7 +88,7 @@ export default async function(root) {
88
88
  } finally {
89
89
  const finalversion = version.replace(/\s+/g, ' ').trim(); //trim out new lines and multiple spaces just one.
90
90
  const copyrightTime = new Date(vtime);
91
- debug('Resolving with Git copyright Year is ', copyrightTime.getUTCFullYear());
91
+ await debug('Resolving with Git copyright Year is ', copyrightTime.getUTCFullYear());
92
92
  return({ version: finalversion, year: copyrightTime.getUTCFullYear() });
93
93
  }
94
94
  };