Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions components/api-server/src/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ const userLocalDirectory = require('business').users.userLocalDirectory;
const { Extension, ExtensionLoader } = require('utils').extension;

const { getAPIVersion } = require('middleware/src/project_version');
const { pubsub } = require('messages');
const { tracingMiddleware } = require('tracing');

logger.debug('Loading app');
Expand Down
5 changes: 5 additions & 0 deletions components/api-server/src/expressApp.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ const { getAPIVersion } = require('middleware/src/project_version');

const { getConfig } = require('@pryv/boiler');

const { initExpressTracer } = require('tracing');

// ------------------------------------------------------------ express app init

// Creates and returns an express application with a standard set of middleware.
Expand All @@ -27,6 +29,9 @@ async function expressAppInit(logging) {
const version = await getAPIVersion();
const config = await getConfig();
const app = express(); // register common middleware

initExpressTracer(app);

const commonHeadersMiddleware = await middleware.commonHeaders();
const requestTraceMiddleware = middleware.requestTrace(app, logging);

Expand Down
4 changes: 2 additions & 2 deletions components/api-server/src/routes/auth/register.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ module.exports = function (expressApp: express$Application, app: Application) {
expressApp.get(path.join(regPath, '/:username/check_username'),
setMinimalMethodContext,
setMethodId('auth.usernameCheck'),
(req: express$Request, res, next) => {
function apiCall(req: express$Request, res, next) {
api.call(req.context, req.params, methodCallback(res, next, 200));
});
expressApp.get(path.join(regPath, '/:email/check_email'),
setMinimalMethodContext,
setMethodId('auth.emailCheck'),
(req: express$Request, res, next) => {
function apiCall(req: express$Request, res, next) {
api.call(req.context, req.params, methodCallback(res, next, 200));
});
expressApp.post(path.join(regPath, '/username/check'), (req: express$Request, res, next) => {
Expand Down
16 changes: 8 additions & 8 deletions components/api-server/src/routes/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ module.exports = async function(expressApp: express$Application, app: Applicatio
expressApp.get(Paths.Events + '/',
setMethodId('events.get'),
loadAccessMiddleware,
function (req: express$Request, res, next) {
function coerce(req: express$Request, res, next) {
const params = _.extend({}, req.query);
tryCoerceStringValues(params, {
fromTime: 'number',
Expand All @@ -56,7 +56,7 @@ module.exports = async function(expressApp: express$Application, app: Applicatio
expressApp.get(Paths.Events + '/:id',
setMethodId('events.getOne'),
loadAccessMiddleware,
function (req: express$Request, res, next) {
function coerce(req: express$Request, res, next) {
const params = _.extend({id: req.params.id}, req.query);
tryCoerceStringValues(params, {
includeHistory: 'boolean'
Expand Down Expand Up @@ -126,7 +126,7 @@ module.exports = async function(expressApp: express$Application, app: Applicatio
setMethodId('events.create'),
loadAccessMiddleware,
hasFileUpload,
function (req: express$Request, res, next) {
function apiCall(req: express$Request, res, next) {
const params = req.body;
if (req.files) {
params.files = req.files;
Expand All @@ -144,12 +144,12 @@ module.exports = async function(expressApp: express$Application, app: Applicatio
expressApp.put(Paths.Events + '/:id',
setMethodId('events.update'),
loadAccessMiddleware,
function (req: express$Request, res, next) {
function apiCall(req: express$Request, res, next) {
api.call(req.context, { id: req.params.id, update: req.body }, methodCallback(res, next, 200));
});

expressApp.post(Paths.Events + '/stop',
function (req: express$Request, res, next) {
function apiCall(req: express$Request, res, next) {
return next(errors.goneResource());
});

Expand All @@ -158,7 +158,7 @@ module.exports = async function(expressApp: express$Application, app: Applicatio
setMethodId('events.update'),
loadAccessMiddleware,
hasFileUpload,
function (req: express$Request, res, next) {
function apiCall(req: express$Request, res, next) {
const params = {
id: req.params.id,
update: {}
Expand All @@ -174,14 +174,14 @@ module.exports = async function(expressApp: express$Application, app: Applicatio
expressApp.delete(Paths.Events + '/:id',
setMethodId('events.delete'),
loadAccessMiddleware,
function (req: express$Request, res, next) {
function apiCall(req: express$Request, res, next) {
api.call(req.context, {id: req.params.id}, methodCallback(res, next, 200));
});

expressApp.delete(Paths.Events + '/:id/:fileId',
setMethodId('events.deleteAttachment'),
loadAccessMiddleware,
function (req: express$Request, res, next) {
function apiCall(req: express$Request, res, next) {
api.call(req.context, {id: req.params.id, fileId: req.params.fileId}, methodCallback(res, next, 200));
});

Expand Down
2 changes: 1 addition & 1 deletion components/api-server/src/routes/methodCallback.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import type Result from '../Result';
* @returns {Function}
*/
module.exports = function (res: express$Response, next: express$NextFunction, successCode: number) {
return function (err: ?Error, result: ?Result) {
return function methodCallBack(err: ?Error, result: ?Result) {

if (err != null) {
return next(err);
Expand Down
2 changes: 1 addition & 1 deletion components/api-server/src/routes/streams.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ module.exports = function (expressApp: express$Application, app: Application) {
expressApp.get(Paths.Streams,
loadAccessMiddleware,
setMethodId('streams.get'),
function (req: express$Request, res, next) {
function coerce (req: express$Request, res, next) {
const params = _.extend({}, req.query);
tryCoerceStringValues(params, {
includeDeletionsSince: 'number'
Expand Down
4 changes: 2 additions & 2 deletions components/middleware/src/commonHeaders.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ const { getAPIVersion } = require('middleware/src/project_version');
// Middleware to handle OPTIONS requests and to add CORS headers to all other
// requests.

module.exports = async function (): Promise<Function> {
module.exports = async function (): Promise<Function> {
const version = await getAPIVersion();
return function (req: express$Request, res: express$Response, next: express$NextFunction) {
return function commonHeaders(req: express$Request, res: express$Response, next: express$NextFunction) {
// allow cross-domain requests (CORS)
res.header('Access-Control-Allow-Origin', req.headers.origin || '*');
// *
Expand Down
2 changes: 1 addition & 1 deletion components/middleware/src/contentType.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ var errors = require('errors').factory;
function checkContentType(/* arguments */) {
var acceptedTypes = arguments,
count = acceptedTypes.length;
return function (req, res, next) {
return function checkContentType(req, res, next) {
if (count < 1) { return next(); }

var contentType = req.headers['content-type'];
Expand Down
2 changes: 1 addition & 1 deletion components/middleware/src/initContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import type { StorageLayer } from 'storage';
module.exports = function initContext(
storageLayer: StorageLayer, customAuthStepFn: ?CustomAuthFunction
) {
return function (
return function initContext(
req: express$Request, res: express$Response, next: express$NextFunction
) {
const authorizationHeader = req.headers['authorization'];
Expand Down
2 changes: 1 addition & 1 deletion components/middleware/src/loadAccess.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import type { StorageLayer } from 'storage';
// Also, it adds the corresponding access id as a specific response header.
//
module.exports = function loadAccess(storageLayer: StorageLayer) {
return async function (
return async function loadAccess(
req: express$Request, res: express$Response, next: express$NextFunction
) {

Expand Down
2 changes: 1 addition & 1 deletion components/middleware/src/notFound.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ const errors = require('errors').factory;
/**
* '404' handling to override Express' defaults. Must be set after the routes in the init sequence.
*/
module.exports = function (req, res, next) {
module.exports = function notFound(req, res, next) {
return next(errors.unknownResource());
};
2 changes: 1 addition & 1 deletion components/middleware/src/requestTrace.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
const morgan = require('morgan');
const { getLogger } = require('@pryv/boiler');

module.exports = function (express: any) {
module.exports = function requestTrace(express: any) {
const logger = getLogger('request-trace');
const morganLoggerStreamWrite = (msg: string) => logger.info(msg);

Expand Down
4 changes: 2 additions & 2 deletions components/middleware/src/setMethodId.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ module.exports = function (methodId: string) {
req: express$Request, res: express$Response, next: express$NextFunction
) {
if (req.context == null) {
const tracing = initRootSpan('express2');
const tracing = initRootSpan('expressX');
req.context = { tracing: tracing};
res.on('finish', () => { tracing.finishSpan('express2', 'e2:' + methodId)} )
res.on('finish', () => { tracing.finishSpan('expressX', 'e2:' + methodId)} )
}
req.context.methodId = methodId;

Expand Down
2 changes: 1 addition & 1 deletion components/middleware/src/subdomainToPath.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const { USERNAME_REGEXP_STR } = require('api-server/src/schema/helpers');
* @return {Function}
*/
module.exports = function (ignoredPaths: Array<string>) {
return function (req: express$Request, res: express$Response, next: express$NextFunction) {
return function subdomainToPath (req: express$Request, res: express$Response, next: express$NextFunction) {
if (isIgnoredPath(req.url)) { return next(); }

if (! req.headers.host) { return next(errors.missingHeader('Host')); }
Expand Down
66 changes: 66 additions & 0 deletions components/tracing/src/expressPatch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/**
* @license
* Copyright (C) 2012-2021 Pryv S.A. https://pryv.com - All Rights Reserved
* Unauthorized copying of this file, via any medium is strictly prohibited
* Proprietary and confidential
*/


module.exports = function patchApp(app, expressSpanName) {
if (app.legacy_use != null) throw new Error('Already patched');

app.legacy_use = app.use;
app.use = function () {
const newArgs = [];
for (let i = 0; i < arguments.length; i++) {
// !!!! doing nothing for now.. all attemp to patch "use" failed
newArgs.push(patchFunction0(arguments[i]));
}
//console.log(arguments, newArgs);
return app.legacy_use(...newArgs);
}

patch('get');
patch('post');
patch('put');
patch('delete');

function patch(key) {
app['legacy_' + key] = app[key];
app[key] = function () {
const newArgs = [arguments[0]];
for (let i = 1; i < arguments.length; i++) {
const fn = arguments[i];
const spanName = 'e:' + key + ':' + arguments[0] + ':' + (fn.name || ('unamed.' + i));
newArgs.push(patchFunction(fn, spanName));
}
return app['legacy_' + key](...newArgs);
}
}

function patchFunction(fn, spanName) {
return async function (req, res, next) {
req.tracing.startSpan(spanName, {}, expressSpanName);
return await fn(req, res, function nextCloseSpan(err) {
req.tracing.finishSpan(spanName);
next(err);
});
}
}

// doing nothing
function patchFunction0(fn) {
console.log('>>>> unpatched: ', fn.name);
return fn;
}

// kept for reference
function patchFunction2(fn) {
// return fn;
if (fn.constructor.name === 'AsyncFunction') {
return async () => { try { return await fn.apply(null, arguments); } catch (e) { console.log('XXXX', e) } }
}
return () => { try { return fn.apply(null, arguments); } catch (e) { console.log(e) } }
}

}
17 changes: 12 additions & 5 deletions components/tracing/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@



const { Tracing, DummyTracing } = require('./Tracing');
const { Tracing, DummyTracing } = require('./Tracing');
const { getHookerTracer } = require('./HookedTracer');


const expressPatch = require('./expressPatch');
const dataBaseTracer = require('./databaseTracer');
const { getConfigUnsafe } = require('@pryv/boiler');
const isTracingEnabled = getConfigUnsafe(true).get('trace:enable');
const launchTags = getConfigUnsafe(true).get('trace:tags');

module.exports.DummyTracing = DummyTracing;

module.exports.dataBaseTracer = dataBaseTracer;

module.exports.dataBaseTracer = dataBaseTracer;
module.exports.getHookerTracer = getHookerTracer;

/**
Expand All @@ -42,9 +42,9 @@ module.exports.initRootSpan = initRootSpan;
/**
* Returns an ExpressJS middleware that starts a span and attaches the "tracing" object to the request parameter.
*/
module.exports.tracingMiddleware = (name: string = 'express1', tags: ?{}): Function => {
function tracingMiddleware (name: string, tags: ?{}): Function {
return function (req: express$Request, res: express$Response, next: express$NextFunction): void {
if (req.tracing != null) { console.log('XXXXX tracing already set', new Error()); return next();}
if (req.tracing != null) { console.log('XXXXX tracing already set', new Error()); return next();}
const tracing = initRootSpan (name, tags);
res.on('close', () => {
const extra = req.context?.methodId || req.url;
Expand All @@ -54,3 +54,10 @@ module.exports.tracingMiddleware = (name: string = 'express1', tags: ?{}): Funct
next();
}
}
module.exports.tracingMiddleware = tracingMiddleware;

module.exports.initExpressTracer = function(app) {
const expressTraceName = 'express2';
app.use(tracingMiddleware(expressTraceName)); // anyway .. initRootSpan will retrun a dummytracer is not enabled
if (isTracingEnabled) expressPatch(app, expressTraceName);
}