Commit d05e75946eba1441ff17cb0fb026d634a3f1cbc8

Authored by Adhidarma Hadiwinoto
1 parent 12f6d059c5
Exists in master and in 1 other branch dev

CORE-CALLBACK dumper

Showing 4 changed files with 189 additions and 1 deletions Side-by-side Diff

lib/core-callback/dumper/req.js
... ... @@ -0,0 +1,82 @@
  1 +const MODULE_NAME = 'CORE-CALLBACK.DUMPER.REQ';
  2 +
  3 +const fs = require('fs');
  4 +const fsPromise = require('fs').promises;
  5 +const path = require('path');
  6 +const config = require('komodo-sdk/config');
  7 +const logger = require('komodo-sdk/logger');
  8 +const moment = require('moment');
  9 +
  10 +const baseDumpDir = 'dump';
  11 +const subBaseDumpDir = path.join(baseDumpDir, 'core-callback');
  12 +const lastSymbolicLinkName = path.join(subBaseDumpDir, 'last-req');
  13 +
  14 +if (!fs.existsSync(baseDumpDir)) {
  15 + logger.verbose(`${MODULE_NAME} B5785525: Creating base dump dir`);
  16 + fs.mkdirSync(baseDumpDir);
  17 +}
  18 +
  19 +if (!fs.existsSync(subBaseDumpDir)) {
  20 + logger.verbose(`${MODULE_NAME} 13BD289A: Creating dump dir`);
  21 + fs.mkdirSync(subBaseDumpDir);
  22 +}
  23 +
  24 +module.exports = async (req, res, next) => {
  25 + if (
  26 + !config
  27 + || !config.listener
  28 + || !config.listener.core
  29 + || !config.listener.core.dump
  30 + ) {
  31 + next();
  32 + return;
  33 + }
  34 +
  35 + const { xid } = res.locals;
  36 +
  37 + const data = `--------
  38 +XID: ${xid}
  39 +PID: ${process.pid}
  40 +DATE: ${moment().format('YYYY-MM-DD HH:mm:ss.SSS')}
  41 +
  42 +REQ-CONTENT-TYPE: ${req.get('content-type')}
  43 +
  44 +REQ QUERY-STRING:
  45 +${JSON.stringify(req.query, null, 2)}
  46 +
  47 +REQ BODY:
  48 +${JSON.stringify(req.body, null, 2)}
  49 +`;
  50 +
  51 + const dumpDir = path.join(
  52 + subBaseDumpDir,
  53 + moment().format('YYYY-MM-DD'),
  54 + );
  55 +
  56 + try {
  57 + await fsPromise.stat(dumpDir);
  58 + } catch (e) {
  59 + await fsPromise.mkdir(dumpDir, { recursive: true });
  60 + }
  61 +
  62 + const dumpFileName = path.join(
  63 + dumpDir,
  64 + [
  65 + 'req',
  66 + moment().format('YYMMDD_HHmmss_SSS'),
  67 + xid,
  68 + ].join('_'),
  69 + );
  70 +
  71 + await fsPromise.writeFile(dumpFileName, data);
  72 +
  73 + try {
  74 + await fsPromise.unlink(lastSymbolicLinkName);
  75 + } catch (e) {
  76 + //
  77 + }
  78 +
  79 + await fs.symlink(dumpFileName, lastSymbolicLinkName);
  80 +
  81 + next();
  82 +};
lib/core-callback/dumper/sender.js
... ... @@ -0,0 +1,87 @@
  1 +const MODULE_NAME = 'CORE-CALLBACK.DUMPER.SENDER';
  2 +
  3 +const fs = require('fs');
  4 +const fsPromise = require('fs').promises;
  5 +const path = require('path');
  6 +const config = require('komodo-sdk/config');
  7 +const logger = require('komodo-sdk/logger');
  8 +const moment = require('moment');
  9 +
  10 +const baseDumpDir = 'dump';
  11 +const subBaseDumpDir = path.join(baseDumpDir, 'core-callback');
  12 +const lastSymbolicLinkName = path.join(subBaseDumpDir, 'last-sent');
  13 +
  14 +if (!fs.existsSync(baseDumpDir)) {
  15 + logger.verbose(`${MODULE_NAME} CE7EA06A: Creating base dump dir`);
  16 + fs.mkdirSync(baseDumpDir);
  17 +}
  18 +
  19 +if (!fs.existsSync(subBaseDumpDir)) {
  20 + logger.verbose(`${MODULE_NAME} A9807434: Creating dump dir`);
  21 + fs.mkdirSync(subBaseDumpDir);
  22 +}
  23 +
  24 +module.exports = async (xid, httpMethod, endpointUrl, params, axiosResponse, axiosError) => {
  25 + if (
  26 + !config
  27 + || !config.listener
  28 + || !config.listener.core
  29 + || !config.listener.core.dump
  30 + ) {
  31 + return;
  32 + }
  33 +
  34 + const data = `--------
  35 +XID: ${xid}
  36 +PID: ${process.pid}
  37 +DATE: ${moment().format('YYYY-MM-DD HH:mm:ss.SSS')}
  38 +
  39 +HTTP METHOD: ${httpMethod}
  40 +ENDPOINT URL: ${endpointUrl}
  41 +
  42 +REQ PARAMS:
  43 +${JSON.stringify(params, null, 2)}
  44 +
  45 +ERROR CODE: ${(axiosError && axiosError.code) || ''}
  46 +ERROR MESSAGE: ${(axiosError && axiosError.message) || ''}
  47 +
  48 +RES HTTP STATUS: ${axiosResponse && axiosResponse.status}
  49 +RES BODY:
  50 +${
  51 + axiosResponse && axiosResponse.data && (
  52 + ((typeof axiosResponse.data === 'string') && axiosResponse.data)
  53 + || JSON.stringify(axiosResponse.data, null, 2)
  54 + )
  55 +}
  56 +`;
  57 +
  58 + const dumpDir = path.join(
  59 + subBaseDumpDir,
  60 + moment().format('YYYY-MM-DD'),
  61 + );
  62 +
  63 + try {
  64 + await fsPromise.stat(dumpDir);
  65 + } catch (e) {
  66 + await fsPromise.mkdir(dumpDir, { recursive: true });
  67 + }
  68 +
  69 + const dumpFileName = path.join(
  70 + dumpDir,
  71 + [
  72 + 'sent',
  73 + moment().format('YYMMDD_HHmmss_SSS'),
  74 + xid,
  75 + ].join('_'),
  76 + );
  77 +
  78 + await fsPromise.writeFile(dumpFileName, data);
  79 +
  80 + try {
  81 + await fsPromise.unlink(lastSymbolicLinkName);
  82 + } catch (e) {
  83 + //
  84 + }
  85 +
  86 + await fs.symlink(dumpFileName, lastSymbolicLinkName);
  87 +};
lib/core-callback/index.js
... ... @@ -7,9 +7,9 @@ const config = require('komodo-sdk/config');
7 7 const logger = require('komodo-sdk/logger');
8 8 const middlewareCommon = require('../middlewares/common');
9 9 const sender = require('./sender');
  10 +const dumperReq = require('./dumper/req');
10 11 const matrix = require('../matrix');
11 12  
12   -
13 13 const app = express();
14 14  
15 15 app.use(express.json({ extended: true }));
... ... @@ -21,6 +21,7 @@ app.use((req, res, next) => {
21 21 });
22 22  
23 23 app.use(middlewareCommon);
  24 +app.use(dumperReq);
24 25  
25 26 app.use((req, res) => {
26 27 matrix.core.received += 1;
lib/core-callback/sender.js
... ... @@ -4,6 +4,7 @@ const axios = require('axios').default;
4 4 const config = require('komodo-sdk/config');
5 5 const logger = require('komodo-sdk/logger');
6 6  
  7 +const dumper = require('./dumper/sender');
7 8 const matrix = require('../matrix');
8 9  
9 10 const HTTP_TIMEOUT = Number(
... ... @@ -89,6 +90,9 @@ const sender = async (data, xid, retry) => {
89 90 endpointUrl,
90 91 });
91 92  
  93 + let responseToDump;
  94 + let errorResponseToDump;
  95 +
92 96 try {
93 97 const response = isHttpPost
94 98 ? await axios.post(data.reverse_url, params, {
... ... @@ -101,6 +105,8 @@ const sender = async (data, xid, retry) => {
101 105 headers: axiosHeaders,
102 106 });
103 107  
  108 + responseToDump = response;
  109 +
104 110 matrix.callback_sender.sent += 1;
105 111 matrix.callback_sender.active_count += 1;
106 112 matrix.callback_sender.active_sending[xid] = {
... ... @@ -134,6 +140,9 @@ const sender = async (data, xid, retry) => {
134 140 responseBody: e.response && e.response.data,
135 141 };
136 142  
  143 + responseToDump = e.response && e.response.data;
  144 + errorResponseToDump = e;
  145 +
137 146 logger.warn(`${MODULE_NAME} A1EC9E70: Failed on sending to PARTNER`, {
138 147 xid,
139 148 retry,
... ... @@ -158,6 +167,15 @@ const sender = async (data, xid, retry) => {
158 167 if (matrix.callback_sender.active_sending[xid]) {
159 168 delete matrix.callback_sender.active_sending[xid];
160 169 }
  170 +
  171 + dumper(
  172 + xid,
  173 + isHttpPost ? 'POST' : 'GET',
  174 + endpointUrl,
  175 + params,
  176 + responseToDump,
  177 + errorResponseToDump,
  178 + );
161 179 }
162 180 };
163 181