From 76f9017482ab516034b0db553b5f74e13241db4b Mon Sep 17 00:00:00 2001 From: badrAZ Date: Mon, 14 Jan 2019 10:40:50 +0100 Subject: [PATCH] feat(xo-server/api): emit event on call/resolution of xo method (#3770) --- packages/xo-server/src/xo-mixins/api.js | 56 ++++++++++++++++++------- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/packages/xo-server/src/xo-mixins/api.js b/packages/xo-server/src/xo-mixins/api.js index 7666b4242..cb3659f36 100644 --- a/packages/xo-server/src/xo-mixins/api.js +++ b/packages/xo-server/src/xo-mixins/api.js @@ -210,6 +210,7 @@ export default class Api { } async callApiMethod(session, name, params = {}) { + const xo = this._xo const startTime = Date.now() const method = this._methods[name] @@ -219,7 +220,7 @@ export default class Api { // FIXME: it can cause issues if there any property assignments in // XO methods called from the API. - const context = Object.create(this._xo, { + const context = Object.create(xo, { api: { // Used by system.*(). value: this, @@ -231,9 +232,24 @@ export default class Api { // Fetch and inject the current user. const userId = session.get('user_id', undefined) - context.user = userId && (await this._xo.getUser(userId)) + context.user = userId && (await xo.getUser(userId)) const userName = context.user ? context.user.email : '(unknown user)' + const data = { + userId, + method: name, + params: sensitiveValues.replace(params, '* obfuscated *'), + } + + const callId = Math.random() + .toString(36) + .slice(2) + + xo.emit('xo:preCall', { + ...data, + callId, + }) + try { await checkPermission.call(context, method) @@ -271,23 +287,33 @@ export default class Api { )}] ==> ${kindOf(result)}` ) + xo.emit('xo:postCall', { + callId, + method: name, + result, + }) + return result } catch (error) { - params = sensitiveValues.replace(params, '* obfuscated *') - const data = { - userId, + const serializedError = serializeError(error) + + xo.emit('xo:postCall', { + callId, + error: serializedError, method: name, - params, + }) + + const message = `${userName} | ${name}(${JSON.stringify( + data.params + )}) [${ms(Date.now() - startTime)}] =!> ${error}` + + this._logger.error(message, { + ...data, duration: Date.now() - startTime, - error: serializeError(error), - } - const message = `${userName} | ${name}(${JSON.stringify(params)}) [${ms( - Date.now() - startTime - )}] =!> ${error}` + error: serializedError, + }) - this._logger.error(message, data) - - if (this._xo._config.verboseLogsOnErrors) { + if (xo._config.verboseLogsOnErrors) { log.warn(message, { error }) } else { log.warn( @@ -301,7 +327,7 @@ export default class Api { if (xoError) { throw xoError(error.params, ref => { try { - return this._xo.getObject(ref).id + return xo.getObject(ref).id } catch (e) { return ref }