Skip to content

Commit

Permalink
feat: improve logging (quite a bit) (#73)
Browse files Browse the repository at this point in the history
* Improve logging

* Bump package ver. Improve README slightly.

* Package versions, vuln fixes

* Some minor fixes
  • Loading branch information
partiallyordered authored Jun 29, 2021
1 parent 36c46a7 commit 56a4567
Show file tree
Hide file tree
Showing 18 changed files with 689 additions and 326 deletions.
29 changes: 5 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@

The backend service to support the admin portal web ui. Essentially a thin wrapper around SQL queries.

Run in development with `npm run dev`.

You can filter logs through `pino-pretty`, or another ndjson viewer such as `jq` to obtain
pretty-printed output. This also works with `kubectl log`.

## TODO
* Make sure app.env is 'production' in production. See: https://koajs.com/ 'Settings' section.
* In development mode check for divergence between .env.template and .env and warn the user
Expand All @@ -16,18 +21,6 @@ The backend service to support the admin portal web ui. Essentially a thin wrapp
* Check all mandatory environment and secrets are present before beginning operation. Print a
useful error message informing that operation cannot continue if they are not.

## Deploying to DEV environment
* Make a PR to this repo and have it merged
* Make a release on the repo with the release version of the form vX.Y.Z where X is the product
increment, Y is the sprint number, Z is an zero-based incrementing integer that is reset each
time Y is changed.

## Installing
```bash
cd ./src
npm install
```

## External dependencies
This service relies on external APIs in order to perform some operations regarding Forex transactions and delegation of the "commit settlement window" action.

Expand All @@ -36,18 +29,6 @@ Their endpoints are defined by these configuration values:
* FXP_ENDPOINT
* EXTERNAL_SETTLEMENTS_ENDPOINT

## Push to the repo
Follow the instructions from the Building section above, then:
```bash
make push
```

## Running containerised
Follow the instructions from the Building section above, then:
```bash
make run
```

## Running locally
You'll need access to a mysql instance containing some central_ledger data, and a mojaloop deployment.

Expand Down
8 changes: 2 additions & 6 deletions src/handlers/emailAddress.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
const casaLib = require('@mojaloop/finance-portal-lib');

const { getParticipantEmailAddresses, updateEmailAddress } = casaLib.admin.api;
const { getParticipantEmailAddresses, updateEmailAddress } = require('@mojaloop/finance-portal-lib').admin.api;

const handler = (router, routesContext) => {
router.get('/emailAddress/:participantName', async (ctx, next) => {
const emailAddresses = await getParticipantEmailAddresses(
routesContext.config.centralLedgerEndpoint, ctx.params.participantName,
routesContext.log,
);
ctx.response.body = emailAddresses;
ctx.response.status = 200;
Expand All @@ -21,10 +18,9 @@ const handler = (router, routesContext) => {
participantName,
emailType,
ctx.request.body.newValue,
routesContext.log,
);
const emailAddresses = await getParticipantEmailAddresses(
routesContext.config.centralLedgerEndpoint, participantName, routesContext.log,
routesContext.config.centralLedgerEndpoint, participantName,
);
const emailAddress = emailAddresses.filter((a) => a.type === emailType);
[ctx.response.body] = emailAddress;
Expand Down
5 changes: 2 additions & 3 deletions src/handlers/forex.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
const casaLib = require('@mojaloop/finance-portal-lib');
const util = require('util');

const { getFxpRatesPerCurrencyChannel, createFxpRateForCurrencyChannel } = casaLib.admin.api;

Expand All @@ -15,7 +14,7 @@ const handler = (router, routesContext) => {

await next();
} catch (error) {
routesContext.log('Error', util.inspect(error, { depth: 10 }));
ctx.log.error(error);
ctx.response.body = { msg: 'FXP API Error' };
ctx.response.status = 502;

Expand All @@ -35,7 +34,7 @@ const handler = (router, routesContext) => {

await next();
} catch (error) {
routesContext.log('Error', util.inspect(error, { depth: 10 }));
ctx.log.error(error);
ctx.response.body = { msg: 'FXP API Error' };
ctx.response.status = 502;

Expand Down
1 change: 0 additions & 1 deletion src/handlers/funds-out.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ const handler = (router, routesContext) => {
ctx.request.body.amount,
ctx.request.body.currency,
'Admin portal funds out request',
routesContext.log,
);
ctx.response.status = 200;
} catch (err) {
Expand Down
2 changes: 1 addition & 1 deletion src/handlers/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const handler = (router, routesContext) => {

router.post('/login', async (ctx, next) => {
if (routesContext.config.auth.bypass) {
routesContext.log('authentication bypassed');
ctx.log.warn('authentication bypassed');
ctx.response.body = {
expiresIn: '3600',
};
Expand Down
2 changes: 1 addition & 1 deletion src/handlers/logout.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const selfSignedAgent = new https.Agent({ rejectUnauthorized: false });
const handler = (router, routesContext) => {
router.put('/logout', async (ctx, next) => {
const accessToken = ctx.request.get('Cookie').split('=').splice(1).join('');
routesContext.log(`revoking token - ${accessToken}- onlogout`);
ctx.log.info(`revoking token - ${accessToken}- onlogout`);
const opts = {
method: 'POST',
headers: {
Expand Down
3 changes: 0 additions & 3 deletions src/handlers/netdebitcap.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ const handler = (router, routesContext) => {
routesContext.config.centralLedgerEndpoint,
ctx.params.participantName,
acc.currency,
routesContext.log,
);
acc.netDebitCap = limit.limit.value;
return acc;
Expand All @@ -30,7 +29,6 @@ const handler = (router, routesContext) => {
ctx.params.participantName,
ctx.request.body.currency,
ctx.request.body.newValue,
routesContext.log,
);
const accounts = await getParticipantAccounts(
routesContext.config.centralLedgerEndpoint, ctx.params.participantName,
Expand All @@ -42,7 +40,6 @@ const handler = (router, routesContext) => {
routesContext.config.centralLedgerEndpoint,
ctx.params.participantName,
acc.currency,
routesContext.log,
);
acc.netDebitCap = limit.limit.value;
return acc;
Expand Down
4 changes: 1 addition & 3 deletions src/handlers/participants.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ const { getParticipants, setParticipantIsActiveFlag } = casaLib.admin.api;

const handler = (router, routesContext) => {
router.get('/participants', async (ctx, next) => {
ctx.response.body = await getParticipants(routesContext.config.centralLedgerEndpoint,
routesContext.log);
ctx.response.body = await getParticipants(routesContext.config.centralLedgerEndpoint);
ctx.response.status = 200;
await next();
});
Expand All @@ -23,7 +22,6 @@ const handler = (router, routesContext) => {
routesContext.config.centralLedgerEndpoint,
ctx.request.body.participantName,
ctx.request.body.isActive !== 0,
routesContext.log,
);
} catch (err) {
ctx.response.body = await routesContext.db
Expand Down
4 changes: 2 additions & 2 deletions src/handlers/report.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ const handler = (router, routesContext) => {
};

const reportUrl = new URL(routesContext.config.reportUrls[reportId]);
routesContext.log(`Found report URL: ${reportUrl}`);
ctx.log.info(`Found report URL: ${reportUrl}`);
const completeUrl = await generateReportUrl(ctx.request, reportUrl, reportId);
routesContext.log(`Generated report request: ${completeUrl}`);
ctx.log.info(`Generated report request: ${completeUrl}`);

try {
const response = await fetch(completeUrl, opts);
Expand Down
5 changes: 2 additions & 3 deletions src/handlers/settlement-window-commit.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
const portalLib = require('@mojaloop/finance-portal-lib');
const util = require('util');
const sleep = require('sleep-promise');

const { commitSettlementWindow } = portalLib.admin.api;
Expand All @@ -16,7 +15,7 @@ const handler = (router, routesContext) => {
Number(settlementId),
);
} catch (error) {
routesContext.log('Settlement API Error', util.inspect(error, { depth: 10 }));
ctx.log.child({ error }).error('Settlement API Error');
ctx.response.body = { msg: 'Settlement API Error' };
ctx.response.status = 502;

Expand All @@ -41,7 +40,7 @@ const handler = (router, routesContext) => {

[mostRecentSettlementWindow] = settlementWindows;
} catch (error) {
routesContext.log(`An error occurred during getSettlementWindow: ${error.message}`);
ctx.log.child({ error }).error('An error occurred during getSettlementWindow');
}

ctx.response.body = mostRecentSettlementWindow || {};
Expand Down
2 changes: 1 addition & 1 deletion src/handlers/settlement-windows.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const handler = (router, routesContext) => {
});
settlementWindow.settlement = (settlement.length === 1 ? settlement[0] : {});
} catch (error) {
routesContext.log(error);
ctx.log.error(error);
settlementWindow.settlement = {};
}
ctx.response.body = settlementWindow;
Expand Down
4 changes: 2 additions & 2 deletions src/handlers/validate-transfer.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const handler = (router, routesContext) => {
const validMessage = await AzureLog
.getTransferMessageWithJWSSignature(routesContext.config.azureLog,
ctx.params.transferId,
routesContext.log);
ctx.log);
let isValidTransfer = false;

if (validMessage != null) {
Expand All @@ -32,7 +32,7 @@ const handler = (router, routesContext) => {
try {
isValidTransfer = pubKeys.some((pubKey) => JWT.verify(token, pubKey));
} catch (err) {
routesContext.log(`Error validating JWS token: ${err.stack || util.inspect(err)}`);
ctx.log.error(`Error validating JWS token: ${err.stack || util.inspect(err)}`);
}
}

Expand Down
33 changes: 24 additions & 9 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,58 @@
const pino = require('pino');
const createServer = require('./server');
const Database = require('./db');
const config = require('./config/config');
const log = require('./lib/log');
const { version } = require('./package.json');

// /////////////////////////////////////////////////////////////////////////////
// Config
// /////////////////////////////////////////////////////////////////////////////

const logger = pino({
serializers: {
// return the body for any HTTPResponseError types we receive from finance-portal-lib
err: pino.stdSerializers.wrapErrorSerializer((e) => {
if (e.type !== 'HTTPResponseError') {
return e;
}
return {
...e,
body: e.raw.getData().resp,
request: e.raw.getData().request,
};
}),
},
});

// Log development/production status
log('Running portal version ', version);
log('Running in ', process.env.NODE_ENV);
logger.child({ version, env: process.env.NODE_ENV }).info('Running portal backend service');

// Set up the db
const db = new Database(config.db);

// Warnings for certain environment var settings
if (config.cors.reflectOrigin && process.env.NODE_ENV !== 'development') {
log('WARNING: NODE_ENV != \'development\' and CORS origin being reflected in Access-Control-Allow-Origin header. '
logger.warn('WARNING: NODE_ENV != \'development\' and CORS origin being reflected in Access-Control-Allow-Origin header. '
+ 'Changing CORS_ACCESS_CONTROL_REFLECT_ORIGIN to false is important for preventing CSRF.');
}
if (config.auth.bypass) {
log('WARNING: auth bypass enabled- all login requests will be approved');
logger.warn('WARNING: auth bypass enabled- all login requests will be approved');
}

// /////////////////////////////////////////////////////////////////////////////
// Start app
// /////////////////////////////////////////////////////////////////////////////

log('Config:', config);
const server = createServer(config, db, log, Database);
logger.child({ config }).info('Config:');
const server = createServer(config, db, logger, Database);
const listener = server.listen(config.server.listenPort);

const handle = async (signal) => {
log(`Received signal ${signal}. Shutting down..`);
logger.info(`Received signal ${signal}. Shutting down..`);
listener.close();
process.exit();
};
process.on('SIGINT', handle);
process.on('SIGTERM', handle);

log(`Listening on port ${config.server.listenPort}`);
logger.info(`Listening on port ${config.server.listenPort}`);
9 changes: 0 additions & 9 deletions src/lib/log.js

This file was deleted.

Loading

0 comments on commit 56a4567

Please sign in to comment.