Skip to content

Commit

Permalink
RCS-17 Use timestamps from incoming messages
Browse files Browse the repository at this point in the history
  • Loading branch information
flancer64 committed Feb 22, 2024
1 parent 6e466f0 commit 6e78fa9
Show file tree
Hide file tree
Showing 15 changed files with 166 additions and 123 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@
/package-lock.json
/tmp/
/var/*.pid
/var/sw_cache.zip
/var/store/**
/web/download/
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ applications. Mobile browsers lack the Developer Tools panel, which makes debugg

With this app, you have the option to launch it as a standalone server on your local computer for enhanced security.
Alternatively, you can use our public server at `https://console.wiredgeese.com/`, where all developers can share their
logs, separated by channels ( you need to know the name of the channel to see logs from this channel).
logs, separated by channels (you need to know the name of the channel to see logs from this
channel - https://console.wiredgeese.com/any-random-string/).

## Overview

Expand Down Expand Up @@ -63,6 +64,14 @@ navigator.sendBeacon('http://xxx.xxx.xxx.xxx:8080/log/', 'any log message');

If you are working in a group, all developers will be able to see the same logs through the WebUI.

### Log Modes

There are two spaces for collecting logs:

* `http://xxx.xxx.xxx.xxx:8080/log/[channel]`: Any text message without a timestamp. The server adds the timestamp.
* `http://xxx.xxx.xxx.xxx:8080/timed/[channel]`: The log record should start with a timestamp 'mm/dd hh:mm:ss.mmm' to be
ordered on the front end.

## Web UI

* `About`: Link to this repository.
Expand Down
7 changes: 6 additions & 1 deletion RELEASE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
# @flancer64/spa-remote-console: releases
# @flancer64/spa-remote-console: Releases

# 0.3.0

* Reflects the DI changes.
* Adds a new space `/timed/` to collect logs with timestamps.

# 0.2.0

Expand Down
78 changes: 40 additions & 38 deletions bin/tequila.mjs
Original file line number Diff line number Diff line change
@@ -1,60 +1,62 @@
#!/usr/bin/env node
'use strict';
/** Main script to create and to run TeqFW backend application. */
/** Main script to create and run the backend teq-app. */
// IMPORT
import Container from '@teqfw/di';
import {dirname, join} from 'node:path';
import {fileURLToPath} from 'node:url';
import {platform} from "node:process";
import {readFileSync} from 'node:fs';
import Container from '@teqfw/di';

// VARS
/* Resolve paths to main folders */
const url = new URL(import.meta.url);
const script = fileURLToPath(url);
const script = url.pathname;
const bin = dirname(script);
const root = join(bin, '..');
const path = join(bin, '..');

// FUNCS
/**
* Create and setup DI container.
* @param {string} root
* @returns {TeqFw_Di_Shared_Container}
* Create and manually set up the DI container.
* @param {string} root - The root folder of the app (where the `node_modules` folder is located).
* @returns {Promise<TeqFw_Di_Api_Container>}
*/
function initContainer(root) {
/** @type {TeqFw_Di_Shared_Container} */
async function initContainer(root) {
/** @type {TeqFw_Di_Api_Container} */
const res = new Container();
res.getNsResolver().isWindows = (platform === 'win32');
const pathDi = join(root, 'node_modules/@teqfw/di/src');
const pathCore = join(root, 'node_modules/@teqfw/core/src');
res.addSourceMapping('TeqFw_Di', pathDi, true, 'mjs');
res.addSourceMapping('TeqFw_Core', pathCore, true, 'mjs');
res.setDebug(false);
// add path mapping for @teqfw/core to the DI resolver
const resolver = res.getResolver();
const pathDi = join(root, 'node_modules', '@teqfw', 'di', 'src');
const pathCore = join(root, 'node_modules', '@teqfw', 'core', 'src');
resolver.addNamespaceRoot('TeqFw_Di_', pathDi, 'js');
resolver.addNamespaceRoot('TeqFw_Core_', pathCore, 'mjs');
// setup parser for the legacy code
/** @type {TeqFw_Core_Shared_App_Di_Parser_Legacy} */
const parserLegacy = await res.get('TeqFw_Core_Shared_App_Di_Parser_Legacy$');
res.getParser().addChunk(parserLegacy);
// add pre-processors: replace
const pre = res.getPreProcessor();
const preReplace = await res.get(`TeqFw_Core_Shared_App_Di_PreProcessor_Replace$`);
pre.addChunk(preReplace);
// add post-processors: Factory, Proxy, Logger
const post = res.getPostProcessor();
/** @type {TeqFw_Core_Shared_App_Di_PostProcessor_Factory} */
const postFactory = await res.get('TeqFw_Core_Shared_App_Di_PostProcessor_Factory$');
post.addChunk(postFactory);
/** @type {TeqFw_Core_Shared_App_Di_PostProcessor_Proxy} */
const postProxy = await res.get('TeqFw_Core_Shared_App_Di_PostProcessor_Proxy$');
post.addChunk(postProxy);
/** @type {TeqFw_Core_Shared_App_Di_PostProcessor_Logger} */
const postLogger = await res.get('TeqFw_Core_Shared_App_Di_PostProcessor_Logger$');
post.addChunk(postLogger);
return res;
}

/**
* Read project version from './package.json' or use default one.
* @param root
* @returns {*|string}
*/
function readVersion(root) {
const filename = join(root, 'package.json');
const buffer = readFileSync(filename);
const content = buffer.toString();
const json = JSON.parse(content);
return json?.version ?? '0.1.0';
}

// MAIN
try {
const container = initContainer(root);
const version = readVersion(root);
/** Construct backend app instance using Container then init app & run it */
// Initialize the DI container, then create and run the backend teq-app.
const container = await initContainer(path);
/** @type {TeqFw_Core_Back_App} */
const app = await container.get('TeqFw_Core_Back_App$');
await app.init({path: root, version});
await app.run();
await app.run({path});
} catch (e) {
console.error('Cannot create or run TeqFW application.');
console.dir(e);
}
console.error(e);
}
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"name": "@flancer64/spa-remote-console",
"version": "0.2.0",
"version": "0.3.0",
"type": "module",
"description": "Web application to redirect incoming log messages to Web UI.",
"homepage": "https://github.com/flancer64/spa-remote-console/",
"bugs": {
Expand All @@ -20,7 +21,9 @@
"stop": "node ./bin/tequila.mjs web-server-stop"
},
"dependencies": {
"@teqfw/web": ">=0.11.0"
"@teqfw/web": ">=0.11.0",
"archiver": "latest",
"unzipit": "latest"
},
"engines": {
"node": ">=17"
Expand Down
26 changes: 26 additions & 0 deletions src/Back/Defaults.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* Plugin constants (hardcoded configuration) for backend code.
*/
export default class Remote_Console_Back_Defaults {

/** @type {TeqFw_Web_Back_Defaults} */
MOD_WEB;

/** @type {Remote_Console_Shared_Defaults} */
SHARED;

/**
* @param {TeqFw_Web_Back_Defaults} MOD_WEB
* @param {Remote_Console_Shared_Defaults} SHARED
*/
constructor(
{
TeqFw_Web_Back_Defaults$: MOD_WEB,
Remote_Console_Shared_Defaults$: SHARED,
}
) {
this.MOD_WEB = MOD_WEB;
this.SHARED = SHARED;
Object.freeze(this);
}
}
17 changes: 0 additions & 17 deletions src/Back/Defaults.mjs

This file was deleted.

14 changes: 8 additions & 6 deletions src/Back/Mod/Registry.mjs → src/Back/Mod/Registry.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
* Registry to collect connected users.
*/
export default class Remote_Console_Back_Mod_Registry {
constructor(spec) {
// DEPS
/** @type {TeqFw_Core_Shared_Api_Logger} */
const logger = spec['TeqFw_Core_Shared_Api_Logger$$']; // instance

/**
* @param {TeqFw_Core_Shared_Api_Logger} logger - instance
*/
constructor(
{
TeqFw_Core_Shared_Api_Logger$$: logger,
}
) {
// VARS
logger.setNamespace(this.constructor.name);
const _store = [];

// INSTANCE METHODS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,19 @@ const {
* @implements TeqFw_Web_Back_Api_Dispatcher_IHandler
*/
export default class Remote_Console_Back_Web_Handler_Channel {
constructor(spec) {
// DEPS
/** @type {Remote_Console_Back_Defaults} */
const DEF = spec['Remote_Console_Back_Defaults$'];
/** @type {TeqFw_Core_Shared_Api_Logger} */
const logger = spec['TeqFw_Core_Shared_Api_Logger$$']; // instance
/** @type {TeqFw_Core_Back_Config} */
const config = spec['TeqFw_Core_Back_Config$'];

/**
* @param {Remote_Console_Back_Defaults} DEF
* @param {TeqFw_Core_Shared_Api_Logger} logger - instance
* @param {TeqFw_Core_Back_Config} config
*/
constructor(
{
Remote_Console_Back_Defaults$: DEF,
TeqFw_Core_Shared_Api_Logger$$: logger,
TeqFw_Core_Back_Config$: config,
}
) {
// MAIN
logger.setNamespace(this.constructor.name);
const pathToRoot = config.getPathToRoot(); // path to project root
const pathToIndex = join(pathToRoot, DEF.MOD_WEB.FS_STATIC_ROOT, 'index.html');
const INDEX = existsSync(pathToIndex) ? pathToIndex : null;
Expand Down
36 changes: 19 additions & 17 deletions src/Back/Web/Handler/Log.mjs → src/Back/Web/Handler/Log.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,23 @@ const {
* @implements TeqFw_Web_Back_Api_Dispatcher_IHandler
*/
export default class Remote_Console_Back_Web_Handler_Log {
constructor(spec) {
// DEPS
/** @type {Remote_Console_Back_Defaults} */
const DEF = spec['Remote_Console_Back_Defaults$'];
/** @type {TeqFw_Core_Shared_Api_Logger} */
const logger = spec['TeqFw_Core_Shared_Api_Logger$$']; // instance
/** @type {TeqFw_Core_Shared_Util_Format.dateTimeForLog|function} */
const dateTimeForLog = spec['TeqFw_Core_Shared_Util_Format.dateTimeForLog'];
/** @type {Remote_Console_Back_Mod_Registry} */
const modReg = spec['Remote_Console_Back_Mod_Registry$'];
/** @type {TeqFw_Web_Back_Mod_Address} */
const modAddr = spec['TeqFw_Web_Back_Mod_Address$'];

/**
* @param {Remote_Console_Back_Defaults} DEF
* @param {TeqFw_Core_Shared_Api_Logger} logger - instance
* @param {TeqFw_Core_Shared_Util_Format.dateTimeForLog|function} dateTimeForLog
* @param {Remote_Console_Back_Mod_Registry} modReg
* @param {TeqFw_Web_Back_Mod_Address} modAddr
*/
constructor(
{
Remote_Console_Back_Defaults$: DEF,
TeqFw_Core_Shared_Api_Logger$$: logger,
'TeqFw_Core_Shared_Util_Format.dateTimeForLog': dateTimeForLog,
Remote_Console_Back_Mod_Registry$: modReg,
TeqFw_Web_Back_Mod_Address$: modAddr,
}
) {
// MAIN
logger.setNamespace(this.constructor.name);
Object.defineProperty(process, 'namespace', {value: this.constructor.name});

// FUNCS
Expand All @@ -48,10 +50,10 @@ export default class Remote_Console_Back_Web_Handler_Log {
// parse input data
/** @type {string} */
const body = shares[DEF.MOD_WEB.SHARE_REQ_BODY];
// add timestamp to the message
const msg = `${dateTimeForLog()}: ${body}`;
// get channel
const addr = modAddr.parsePath(req.url);
// add timestamp to the message
const msg = (addr.space === DEF.SHARED.SPACE_LOG) ? `${dateTimeForLog()}: ${body}` : body;
// re-translate messages to all connected sockets
/** @type {WebSocket[]} */
const sockets = modReg.all(addr.route);
Expand All @@ -73,7 +75,7 @@ export default class Remote_Console_Back_Web_Handler_Log {
this.canProcess = function ({method, address} = {}) {
return (
(method === HTTP2_METHOD_POST)
&& (address?.space === DEF.SHARED.SPACE)
&& ((address?.space === DEF.SHARED.SPACE_LOG) || address?.space === DEF.SHARED.SPACE_TIMED)
);
};
}
Expand Down
25 changes: 13 additions & 12 deletions src/Back/Web/Socket.mjs → src/Back/Web/Socket.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,16 @@
* @implements TeqFw_Web_Back_Api_Listener_Socket
*/
export default class Remote_Console_Back_Web_Socket {
constructor(spec) {
// DEPS
/** @type {TeqFw_Core_Shared_Api_Logger} */
const logger = spec['TeqFw_Core_Shared_Api_Logger$$']; // instance
/** @type {Remote_Console_Back_Mod_Registry} */
const modReg = spec['Remote_Console_Back_Mod_Registry$'];
/** @type {TeqFw_Web_Back_Mod_Address} */
const modAddr = spec['TeqFw_Web_Back_Mod_Address$'];

// VARS
logger.setNamespace(this.constructor.name);

/**
* @param {Remote_Console_Back_Mod_Registry} modReg
* @param {TeqFw_Web_Back_Mod_Address} modAddr
*/
constructor(
{
Remote_Console_Back_Mod_Registry$: modReg,
TeqFw_Web_Back_Mod_Address$: modAddr,
}
) {
// INSTANCE METHODS

this.canProcess = function () {
Expand All @@ -38,4 +36,7 @@ export default class Remote_Console_Back_Web_Socket {

}

process(ws, req) {
// do nothing
}
}
13 changes: 0 additions & 13 deletions src/Front/Defaults.mjs

This file was deleted.

3 changes: 2 additions & 1 deletion src/Shared/Defaults.mjs → src/Shared/Defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ export default class Remote_Console_Shared_Defaults {
// should be the same as `name` property in `./package.json`
NAME = '@flancer64/spa-remote-console';

SPACE = 'log'; // web handler space to collect incoming logs: '/log/'
SPACE_LOG = 'log'; // web handler space to collect incoming logs w/o timestamp: '/log/'
SPACE_TIMED = 'timed'; // web handler space to collect incoming logs with timestamp: '/timed/'

constructor() {
Object.freeze(this);
Expand Down
2 changes: 1 addition & 1 deletion teqfw.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"handlers": {
"Remote_Console_Back_Web_Handler_Log": {
"before": ["TeqFw_Web_Back_App_Server_Handler_Static"],
"spaces": ["log"]
"spaces": ["log", "timed"]
},
"Remote_Console_Back_Web_Handler_Channel": {
"after": ["TeqFw_Web_Back_App_Server_Handler_Static"],
Expand Down
Loading

0 comments on commit 6e78fa9

Please sign in to comment.