"plugin:sonarjs/recommended"
],
"parserOptions": {
- "ecmaVersion": 2018
+ "ecmaVersion": "latest"
},
"plugins": [
"node",
"@squeep/api-dingus": "git+https://git.squeep.com/squeep-api-dingus/#v1.2.9",
"@squeep/authentication-module": "git+https://git.squeep.com/squeep-authentication-module/#v1.3.0",
"@squeep/html-template-helper": "git+https://git.squeep.com/squeep-html-template-helper#v1.4.0",
- "@squeep/logger-json-console": "git+https://git.squeep.com/squeep-logger-json-console#v1.0.2",
+ "@squeep/logger-json-console": "git+https://git.squeep.com/squeep-logger-json-console#v2.0.0",
"@squeep/web-linking": "^1.0.7",
"axios": "^1.4.0",
"feedparser": "^2.2.10",
}
},
"node_modules/@squeep/logger-json-console": {
- "version": "1.0.2",
- "resolved": "git+https://git.squeep.com/squeep-logger-json-console#dbff0fa5f018f7a302f73250e55f761c0ccf24b1",
+ "version": "2.0.0",
+ "resolved": "git+https://git.squeep.com/squeep-logger-json-console#9df1ebe7b067a00a012b1deb303278e51a711e37",
"license": "ISC",
"engines": {
- "node": ">=12.0.0"
+ "node": ">=14"
}
},
"node_modules/@squeep/mystery-box": {
"integrity": "sha512-wRdR4IOqWXoDMArx0HPo5MtM2Wk5wemAULbZ6PabVw1ylSQekkzKfoAUuupxsKuzjcRPjZvbpGDv+i04hBMnQw=="
},
"@squeep/logger-json-console": {
- "version": "git+https://git.squeep.com/squeep-logger-json-console#dbff0fa5f018f7a302f73250e55f761c0ccf24b1",
- "from": "@squeep/logger-json-console@git+https://git.squeep.com/squeep-logger-json-console#v1.0.2"
+ "version": "git+https://git.squeep.com/squeep-logger-json-console#9df1ebe7b067a00a012b1deb303278e51a711e37",
+ "from": "@squeep/logger-json-console@git+https://git.squeep.com/squeep-logger-json-console#v2.0.0"
},
"@squeep/mystery-box": {
"version": "2.0.1",
"@squeep/api-dingus": "git+https://git.squeep.com/squeep-api-dingus/#v1.2.9",
"@squeep/authentication-module": "git+https://git.squeep.com/squeep-authentication-module/#v1.3.0",
"@squeep/html-template-helper": "git+https://git.squeep.com/squeep-html-template-helper#v1.4.0",
- "@squeep/logger-json-console": "git+https://git.squeep.com/squeep-logger-json-console#v1.0.2",
+ "@squeep/logger-json-console": "git+https://git.squeep.com/squeep-logger-json-console#v2.0.0",
"@squeep/web-linking": "^1.0.7",
"axios": "^1.4.0",
"feedparser": "^2.2.10",
'use strict';
-const http = require('http');
+const http = require('node:http');
+const { AsyncLocalStorage } = require('node:async_hooks');
const DB = require('./src/db');
const Logger = require('./src/logger');
const Service = require('./src/service');
(async function main () {
let config, logger, db, service;
try {
+ const asyncLocalStorage = new AsyncLocalStorage();
config = new Config(process.env.NODE_ENV);
- logger = new Logger(config);
+ logger = new Logger(config.logger, { nodeId: config.nodeId }, asyncLocalStorage);
db = new DB(logger, config);
await db.initialize();
- service = new Service(logger, db, config);
+ service = new Service(logger, db, config, asyncLocalStorage);
- http.createServer((req, res) => {
- service.dispatch(req, res);
+ http.createServer(async (req, res) => {
+ await asyncLocalStorage.run({}, async () => {
+ await service.dispatch(req, res);
+ });
}).listen(PORT, ADDR, (err) => {
if (err) {
logger.error(_scope, 'error creating server', err);
});
} catch (e) {
(logger || console).error(_scope, 'error starting server', e);
- db && db.listener && await db.listener.stop();
+ db?.listener && await db.listener.stop();
}
})();
\ No newline at end of file
const _fileScope = common.fileScope(__filename);
class Service extends Dingus {
- constructor(logger, db, options) {
+ constructor(logger, db, options, asyncLocalStorage) {
super(logger, {
...options.dingus,
ignoreTrailingSlash: false,
});
-
+ this.asyncLocalStorage = asyncLocalStorage;
this.manager = new Manager(logger, db, options);
this.authenticator = new Authenticator(logger, db, options);
this.sessionManager = new SessionManager(logger, this.authenticator, options);
}
+ /**
+ * Rearrange logging data.
+ */
+ async preHandler(req, res, ctx) {
+ await super.preHandler(req, res, ctx);
+ const logObject = this.asyncLocalStorage.getStore();
+ logObject.requestId = ctx.requestId;
+ delete ctx.requestId;
+ }
+
+
/**
* @param {http.ClientRequest} req
* @param {http.ServerResponse} res
const stubLogger = require('../stub-logger');
const Service = require('../../src/service');
const Config = require('../../config');
+const { AsyncLocalStorage } = require('node:async_hooks');
describe('Service', function () {
- let service, options;
+ let service, options, asyncLocalStorage;
let req, res, ctx;
beforeEach(function () {
+ asyncLocalStorage = new AsyncLocalStorage();
options = new Config('test');
- service = new Service(stubLogger, stubDb, options);
+ service = new Service(stubLogger, stubDb, options, asyncLocalStorage);
sinon.stub(service.manager);
sinon.stub(service.sessionManager);
sinon.stub(service.authenticator);
assert(service);
});
+ describe('preHandler', function () {
+ it('logs requestId', async () => {
+ sinon.stub(service.__proto__.__proto__, 'preHandler').resolves();
+ await service.asyncLocalStorage.run({}, async () => {
+ await service.preHandler(req, res, ctx);
+ const logObject = service.asyncLocalStorage.getStore();
+ assert('requestId' in logObject);
+ });
+ });
+ }); // preHandler
+
describe('maybeIngestBody', function () {
beforeEach(function () {
sinon.stub(service, 'bodyData');
stubCtx = {};
});
it('gets tasks', async function () {
+ /**
+ * In older versions, could just deepStrictEqual un-awaited promises for equality,
+ * but post 14 or so, async_id symbol properties are included in comparison, and
+ * in some executions of test suites these are somehow different in value so the test
+ * was failing. So now we settle everything prior to comparison.
+ */
const expected = [
Promise.resolve('first'),
Promise.reject('bad'),
];
worker.promiseGiver.resolves(expected);
const result = await worker._getWork(stubCtx);
- assert.deepStrictEqual(result, expected);
+
+ const expectedResolved = await Promise.allSettled(expected);
+ const resultResolved = await Promise.allSettled(result);
+ assert.deepStrictEqual(resultResolved, expectedResolved);
+
assert.strictEqual(worker.inFlight.length, expected.length);
});
it('covers none wanted', async function () {