Skip to content

Commit

Permalink
fix: logging
Browse files Browse the repository at this point in the history
  • Loading branch information
zetxx committed Nov 19, 2019
1 parent 9f8a360 commit 5565b57
Showing 1 changed file with 46 additions and 42 deletions.
88 changes: 46 additions & 42 deletions lib/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class Brid {
}

getApiRequestId() {
this.log('debug', {in: 'base.getApiRequestId'});
this.log('trace', {in: 'base.getApiRequestId'});
return this.apiRequestId++;
}

Expand All @@ -28,7 +28,7 @@ class Brid {
}

findMethod({method, channel, direction = 'out'} = {}) {
this.log('trace', {in: 'base.findMethod', description: `try find method ${channel}.${method}.${direction || ''}`, args: {method, channel, direction}});
this.log('debug', {in: 'base.findMethod', description: `try find method ${channel}.${method}.${direction || ''}`, method, channel, direction});
let found = ((direction && [`${method}.${direction}`, direction, method]) || [method]).find((v) => this.apiMethods[channel] && this.apiMethods[channel][v]);

if (!found) {
Expand All @@ -38,48 +38,48 @@ class Brid {
}

findApiMethod({method, direction = 'out'} = {}) {
this.log('debug', {in: 'base.findApiMethod', args: {method, direction}});
this.log('trace', {in: 'base.findApiMethod', method, direction});
return this.findMethod({method, direction, channel: 'api'});
}

findExternalMethod({method} = {}) {
this.log('debug', {in: 'base.findExternalMethod', args: {method}});
this.log('trace', {in: 'base.findExternalMethod', method});
return this.findMethod({method, direction: false, channel: 'external'});
}

registerMethod({method, channel, fn, meta}) {
this.log('trace', {in: 'base.registerMethod', description: `register method: ${channel}.${method}`, args: {method, channel, meta}});
this.log('debug', {in: 'base.registerMethod', description: `register method: ${channel}.${method}`, method, channel, meta});
!this.apiMethods[channel] && (this.apiMethods[channel] = {});
this.apiMethods[channel][method] = async(ctx, ...args) => {
let [message, meta] = args;
this.log('trace', {in: 'base.registerMethod', description: `exec method: ${channel}.${method}`, args: {message, meta}});
this.log('trace', {in: 'base.registerMethod', description: `exec method: ${channel}.${method}`, message, meta});
return fn.call(ctx, ...args);
};
}

registerApiMethod({method, fn, meta = {}}) {
this.log('debug', {in: 'base.registerApiMethod', args: {method, meta}});
this.log('debug', {in: 'base.registerApiMethod', method, meta});
this.registerMethod({method, fn, channel: 'api', meta});
}

registerExternalMethod({method, fn, meta = {}}) {
this.log('debug', {in: 'base.registerExternalMethod', args: {method, meta}});
this.log('debug', {in: 'base.registerExternalMethod', method, meta});
this.registerMethod({method, fn, channel: 'external', meta});
}

isApiRequest(apiRequestId) {
this.log('trace', {in: 'base.isApiRequest', args: {apiRequestId}});
this.log('trace', {in: 'base.isApiRequest', apiRequestId});
return this.apiRequestsPool.findIndex(({meta} = {}) => meta.apiRequestId === apiRequestId);
}

isApiRequestByMatchKey({result}) {
this.log('trace', {in: 'base.isApiRequestByMatchKey', args: {result}});
this.log('trace', {in: 'base.isApiRequestByMatchKey', result});
var [apiRequestId] = (this.apiRequestMatchKeys || []).map((key) => result[key]).filter((el) => el);
return apiRequestId;
}

findApiRequest(apiRequestId) {
this.log('debug', {in: 'base.findApiRequest', description: `search api request with id: ${apiRequestId}`});
this.log('trace', {in: 'base.findApiRequest', description: `search api request with id: ${apiRequestId}`});
var idx = this.isApiRequest(apiRequestId);

var {meta, message} = this.apiRequestsPool[idx];
Expand Down Expand Up @@ -108,22 +108,26 @@ class Brid {
}

getInternalCommunicationContext(meta, extraContext = {}) {
this.log('debug', {in: 'base.getInternalCommunicationContext', args: {meta}});
this.log('debug', {in: 'base.getInternalCommunicationContext', meta});
return {
sharedContext: extraContext || {},
request: async(destination, message, metaParams = {}) => {
this.log('trace', {in: 'base.getInternalCommunicationContext.request', args: {destination, message, metaParams, meta}});
this.log('trace', {in: 'base.getInternalCommunicationContext.request', destination, message, metaParams, meta});
var globTraceId = this.getGlobTraceId(meta);
return this.remoteApiRequest({destination, message, meta: Object.assign({}, meta, {globTraceId}, metaParams, {isNotification: 0})});
},
notification: async(destination, message, metaParams = {}) => {
this.log('trace', {in: 'base.getInternalCommunicationContext.notification', args: {destination, message, metaParams, meta}});
this.log('trace', {in: 'base.getInternalCommunicationContext.notification', destination, message, metaParams, meta});
var globTraceId = this.getGlobTraceId(meta);
this.remoteApiRequest({destination, message, meta: Object.assign({}, meta, {globTraceId}, metaParams, {isNotification: 1})})
.catch((error) => this.log('error', {
in: 'base.getInternalCommunicationContext.notification.response',
description: 'error should be handled correctly',
args: {destination, error, message, metaParams, meta}
destination,
error,
message,
metaParams,
meta
}));
return {};
},
Expand All @@ -133,13 +137,13 @@ class Brid {
}

async remoteApiRequest({destination, message, meta}) {
this.log('trace', {in: 'base.remoteApiRequest', description: `try to call microservice: ${destination}`, args: {destination, message, meta}});
this.log('trace', {in: 'base.remoteApiRequest', description: `try to call micro-service: ${destination}`, destination, message, meta});
throw errors.notImplemented();
}

// when someone hits api method
apiRequestReceived({message, meta}) {
this.log('trace', {in: 'base.apiRequestReceived', count: 1, args: {message, meta}});
this.log('debug', {in: 'base.apiRequestReceived', count: 1, message, meta});
return new Promise(async(resolve, reject) => {
// create meta
const m = Object.assign({}, meta, {resolve, reject, apiRequestId: this.getApiRequestId()});
Expand All @@ -149,9 +153,9 @@ class Brid {
try {
// find api request method (method.in)
let apiMethodFn = this.findApiMethod({method: meta.method, direction: 'in'});
this.log('debug', {in: 'base.apiRequestReceived', count: 2, description: 'api "in" method found', args: {message, meta: m, pack}});
if (meta.isNotification) { // respond if notification, dont wait for anything to be executed
this.log('debug', {in: 'base.apiRequestReceived', count: 3, description: 'api "in" method found, but notification', args: {message, meta: m, pack}});
this.log('trace', {in: 'base.apiRequestReceived', count: 2, description: 'api "in" method found', message, meta: m, pack});
if (meta.isNotification) { // respond if notification, don't wait for anything to be executed
this.log('trace', {in: 'base.apiRequestReceived', count: 3, description: 'api "in" method found, but notification', message, meta: m, pack});
this.apiResponseReceived({result: {}, meta: m});
}
// call found method
Expand All @@ -162,26 +166,26 @@ class Brid {
}
// send it to external only if result from api method call is full
if (apiMethodFnResult) {
this.log('info', {in: 'base.apiRequestReceived > send to external', count: 4, args: {message, meta: m, pack, apiMethodFnResult}});
this.log('trace', {in: 'base.apiRequestReceived > send to external', count: 4, message, meta: m, pack, apiMethodFnResult});
let extOutResP = this.externalOut({result: apiMethodFnResult, meta: m});
// start timer if request is not notification
if (!meta.isNotification && m && (m.apiRequestId || m.apiRequestId >= 0) && this.isApiRequest(m.apiRequestId) >= 0) {
this.log('info', {in: 'base.apiRequestReceived > timeout started', count: 5, args: {message, meta: m, pack, apiMethodFnResult, extOutResP}});
// timeout external, do timeout if it is notification, timeout means, that request to external didnt receive response that marks external call as finished
this.log('trace', {in: 'base.apiRequestReceived > timeout started', count: 5, message, meta: m, pack, apiMethodFnResult, extOutResP});
// timeout external, do timeout if it is notification, timeout means, that request to external didn't receive response that marks external call as finished
// for call to bi finished it should go trough apiResponseReceived
var timeoutId = setTimeout(() => {
this.log('info', {in: 'base.apiRequestReceived > method timeout', count: 6, args: {message, meta: m, pack, apiMethodFnResult, extOutResP}});
this.log('info', {in: 'base.apiRequestReceived > method timeout', count: 6, message, meta: m, pack, apiMethodFnResult, extOutResP});
return this.apiResponseReceived({error: errors.methodTimedOut(m), meta: m});
}, meta.timeout || 30000);
m.timeoutId = timeoutId;
return await extOutResP;
}
return {};
}
this.log('info', {in: 'base.apiRequestReceived > skip external, result from api fn call is false', count: 7, args: {message, meta: m, pack, apiMethodFnResult}});
this.log('info', {in: 'base.apiRequestReceived > skip external, result from api fn call is false', count: 7, message, meta: m, pack, apiMethodFnResult});
return (!meta.isNotification && this.apiResponseReceived({result: apiMethodFnResult, meta: m}));
} catch (e) {
this.log('error', {in: 'base.apiRequestReceived', count: 8, args: {message, meta: m, pack, error: e}});
this.log('error', {in: 'base.apiRequestReceived', count: 8, message, meta: m, pack, error: e});
return this.apiResponseReceived({error: e, meta: m});
}
});
Expand All @@ -190,32 +194,32 @@ class Brid {
// when external response received, response to previously api request, its is called when response from external are matched
async apiResponseReceived({result, error, meta: {apiRequestId = -1}} = {}) {
const message = (result && {result}) || (error && {error}) || undefined;
this.log('trace', {in: 'base.apiResponseReceived', args: {result, error, apiRequestId}});
this.log('debug', {in: 'base.apiResponseReceived', result, error, apiRequestId});
if (this.isApiRequest(apiRequestId) >= 0) { // request exists
var {meta} = this.findApiRequest(apiRequestId); // find request
if (meta.timeoutId) { // clear timeout if any
this.log('debug', {in: 'base.apiResponseReceived', timeout: 'cleared', args: {result, error, apiRequestId}});
this.log('trace', {in: 'base.apiResponseReceived', timeout: 'cleared', result, error, apiRequestId});
clearTimeout(meta.timeoutId); // clear timeout
}
if (meta.isNotification) { // notification case
this.log('debug', {in: 'base.apiResponseReceived', description: 'api "in" method found, but notification, returning notification: 1', args: {result, error, apiRequestId}});
this.log('trace', {in: 'base.apiResponseReceived', description: 'api "in" method found, but notification, returning notification: 1', result, error, apiRequestId});
return meta.resolve({notification: 1});
}
try {
let fn = this.findApiMethod({method: meta.method, direction: 'out'}); // find api method
let fnResult = await fn(this.getInternalCommunicationContext(meta), message, Object.assign({}, meta)); // execute api method
this.log('debug', {in: 'base.apiResponseReceived', description: 'resolve request', args: {result, error, apiRequestId}});
this.log('debug', {in: 'base.apiResponseReceived', description: 'resolve request', result, error, apiRequestId});
return meta.resolve(fnResult);
} catch (e) {
this.log('error', {in: 'base.apiResponseReceived', args: {result, error, apiRequestId}});
this.log('error', {in: 'base.apiResponseReceived', result, error, apiRequestId});
return meta.reject(e);
}
}
return undefined;
}
// when someone hits external
async externalIn({result, error, meta = {}} = {}) {
this.log('trace', {in: 'base.externalIn', args: {result, error, meta}});
this.log('debug', {in: 'base.externalIn', result, error, meta});
var {method, apiRequestId, isNotification} = meta;
const message = (result && {result}) || (error && {error}) || undefined;
// find if there is api request pending by id
Expand All @@ -226,50 +230,50 @@ class Brid {
let fnExt = this.findExternalMethod({method});
// call external method
let fnExtResult = await fnExt(this.getInternalCommunicationContext(Object.assign({direction: 'in'}, meta)), message, Object.assign({}, meta));
this.log('debug', {in: 'base.externalIn', description: 'external request is response of api request', args: {result, error, meta, fnExtResult}});
this.log('trace', {in: 'base.externalIn', description: 'external request is response of api request', result, error, meta, fnExtResult});
// call api response
return this.apiResponseReceived({result: fnExtResult, meta});
} catch (e) {
this.log('error', {in: 'base.externalIn:userDefinedTransformation', args: {result, error, meta}});
this.log('error', {in: 'base.externalIn:userDefinedTransformation', result, error, meta});
// call api response with error
return this.apiResponseReceived({error: e, meta});
}
// there is apiRequestId but no info in api queue, this means that message is probably timeouts
} else if (!isNotification) {
this.log('warn', {in: 'base.externalIn', error: 'message timed out', args: {result, error, meta}});
this.log('warn', {in: 'base.externalIn', errorMessage: 'message timed out', result, error, meta});
return {...message, meta: Object.assign({deadIn: 1}, meta)};
}
return {...message, meta: Object.assign({deadIn: 1}, meta)};
} else {
var apiRequestIdByMatchKey = this.isApiRequestByMatchKey(message); // try to match api key by matchKeys
if (apiRequestIdByMatchKey > 0) {
this.log('debug', {in: 'base.externalIn', description: 'external request is response of api request, matched by "apiRequestIdByMatchKey"', args: {result, error, meta}});
this.log('trace', {in: 'base.externalIn', description: 'external request is response of api request, matched by "apiRequestIdByMatchKey"', result, error, meta});
return this.externalIn({result, error, meta: Object.assign({}, meta, {apiRequestId: apiRequestIdByMatchKey})});
} else if (method) { // try to execute method and return it to caller
this.log('debug', {in: 'base.externalIn', description: 'external request is NOT response of api request', args: {result, error, meta}});
this.log('trace', {in: 'base.externalIn', description: 'external request is NOT response of api request', result, error, meta});
try {
let fnExt = this.findExternalMethod({method});
let transformedMsg = await fnExt(this.getInternalCommunicationContext(meta), message, Object.assign({}, meta));
if (transformedMsg) { // respond to external if result from transform function is not false.
this.log('debug', {in: 'base.externalIn', description: 'external request is NOT response of api request > send response to external', args: {result, error, meta}});
this.log('debug', {in: 'base.externalIn', description: 'external request is NOT response of api request > send response to external', result, error, meta});
return this.externalOut({result: transformedMsg, meta});
}
this.log('debug', {in: 'base.externalIn', description: 'external request is NOT response of api request > dont send response to external because user transofrm function returned false', args: {result, error, meta, transformedMsg}});
this.log('debug', {in: 'base.externalIn', description: 'external request is NOT response of api request > don\'t send response to external because user transform function returned false', result, error, meta, transformedMsg});
return {...message, meta: Object.assign({deadIn: 1}, meta)};
} catch (e) {
this.log('error', {in: 'base.externalIn', args: {result, error, meta}});
this.log('error', {in: 'base.externalIn', result, error, meta});
return this.externalOut({error: e, meta});
}
} else {
this.log('warn', {in: 'base.externalIn', error: 'message missing: apiRequestId, method', args: {result, error, meta}});
this.log('warn', {in: 'base.externalIn', errorMessage: 'message missing: apiRequestId, method', result, error, meta});
return {...message, meta: {deadIn: 1}};
}
}
}

// when request or response goes to external
async externalOut({result, meta}) {
this.log('trace', {in: 'base.externalOut', args: {result, meta}});
this.log('trace', {in: 'base.externalOut', result, meta});
return {result, meta};
}

Expand Down

0 comments on commit 5565b57

Please sign in to comment.