Merge pull request #3015 from Emurgo/denis/logging_improvement
Denis/logging improvement
Denis/logging improvement
const addressesLimit = 50;
const txsLimit = 20;
let logger;
function _validateAddressesReq({ addresses }: { addresses: Array<string>, ... } = {}): boolean {
logger.info(`mockCardanoServer: Validate Addresses request`);
function _validateAddressesReq(
{ addresses }: { addresses: Array<string>, ... } = {},
localLogger: LocalLogger
): boolean {
localLogger.logInfo(`Validate Addresses request`);
if (!addresses || addresses.length > addressesLimit || addresses.length === 0) {
throw new Error('Addresses request length should be (0, ' + addressesLimit + ']');
localLogger.logError(`Addresses request length should be (0, ${addressesLimit})`);
throw new Error(`Addresses request length should be (0, ${addressesLimit})`);
}
// TODO: Add address validation
return true;
}
function _defaultSignedTransaction(
req: { body: SignedRequestInternal, ... },
res: { send(arg: SignedResponse): any, ... }
res: { send(arg: SignedResponse): any, ... },
localLogger: LocalLogger
): void {
logger.info(`mockCardanoServer: Default Signed Transaction`);
logger.info(`mockCardanoServer: mockImporter.sendTx -> request`);
logger.info(JSON.stringify(req.body));
localLogger.logInfo(`Default Signed Transaction`);
localLogger.logInfo(`mockImporter.sendTx <- request\n ${JSON.stringify(req.body)}`);
const response = mockImporter.sendTx(req.body);
logger.info(`mockCardanoServer: mockImporter.sendTx -> response`);
logger.info(JSON.stringify(response));
localLogger.logInfo(`mockImporter.sendTx -> response\n ${JSON.stringify(response)}`);
res.send(response);
}
const expectedTxBase64 = [];
export function setExpectedTx(signedTx: void | string): void {
logger.info(`mockCardanoServer: Set expected transaction`);
if (signedTx == null) {
// remove all elements from the array
expectedTxBase64.splice(0, expectedTxBase64.length);
// TODO: no type from json-server
let MockServer: null | any = null;
class MethodLogger {
localLogger: LocalLogger;
method: string;
url: string;
constructor(localLogger: LocalLogger, method: string, url: string) {
this.localLogger = localLogger;
this.method = method;
this.url = url;
}
logRequest = (message?: string) => {
this.localLogger.logInfo(
`${this.method}: ${this.url} <- request${message ? `\n ${message}` : ''}`,
false
);
};
logResponseSuccess = (message: any) => {
this.localLogger.logInfo(
`${this.method}: ${this.url} -> response${JSON.stringify(message) ? `\n ${JSON.stringify(message)}` : ''}`,
false
);
};
logResponseError = (errorMessage: string) => {
this.localLogger.logError(`${this.method}: ${this.url} ->\n Error:\n${errorMessage}`, false);
};
}
class LocalLogger {
fileName: string;
logger: { info: string => void, error: string => void, ... };
constructor(fileName: string, logPath) {
this.fileName = fileName;
this.logger = simpleNodeLogger.createSimpleFileLogger(logPath);
}
getMethodLogger = (method: string, url: string) => {
return new MethodLogger(this, method, url);
};
logInfo = (message: string, spaceBefore: boolean = true) => {
this.logger.info(`${this.fileName}:${spaceBefore ? ' ' : ''}${message}`);
};
logError = (message: string, spaceAfter: boolean = true) => {
this.logger.error(`${this.fileName}:${spaceAfter ? ' ' : ''}${message}`);
};
}
export function getMockServer(settings: {
signedTransaction?: (
req: { body: SignedRequestInternal, ... },
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
const loggerPath = `${dir}/cardanoMockServerLog_${getLogDate()}.log`;
const logPath = `${dir}/cardanoMockServerLog_${getLogDate()}.log`;
const localLogger = new LocalLogger('mockCardanoServer', logPath);
logger = simpleNodeLogger.createSimpleFileLogger(loggerPath);
if (!MockServer) {
const middlewares = [...defaults({ logger: !!settings.outputLog }), bodyParser];
const server = create();
logger.info(`mockCardanoServer: JSON Server Created`);
localLogger.logInfo(`JSON Server Created`);
server.use(middlewares);
req: { body: AddressUtxoRequest, ... },
res: { send(arg: AddressUtxoResponse): any, ... }
): Promise<void> => {
chai.assert.isTrue(_validateAddressesReq(req.body));
logger.info(`mockCardanoServer: /api/txs/utxoForAddresses -> request`);
logger.info(JSON.stringify(req.body));
const methodLogger = localLogger.getMethodLogger('POST', '/api/txs/utxoForAddresses');
chai.assert.isTrue(_validateAddressesReq(req.body, localLogger));
methodLogger.logRequest(JSON.stringify(req.body));
const utxoForAddresses = await mockImporter.utxoForAddresses(req.body);
logger.info(`mockCardanoServer: /api/txs/utxoForAddresses -> response`);
logger.info(JSON.stringify(utxoForAddresses));
methodLogger.logResponseSuccess(JSON.stringify(utxoForAddresses));
res.send(utxoForAddresses);
}
);
req: { body: UtxoSumRequest, ... },
res: { send(arg: UtxoSumResponse): any, ... }
): Promise<void> => {
chai.assert.isTrue(_validateAddressesReq(req.body));
logger.info(`mockCardanoServer: /api/txs/utxoSumForAddresses -> request`);
logger.info(JSON.stringify(req.body));
const methodLogger = localLogger.getMethodLogger('POST', '/api/txs/utxoSumForAddresses');
chai.assert.isTrue(_validateAddressesReq(req.body, localLogger));
methodLogger.logRequest(JSON.stringify(req.body));
const utxoSumForAddresses = await mockImporter.utxoSumForAddresses(req.body);
logger.info(`mockCardanoServer: /api/txs/utxoSumForAddresses -> response`);
logger.info(JSON.stringify(utxoSumForAddresses));
methodLogger.logResponseSuccess(JSON.stringify(utxoSumForAddresses));
res.send(utxoSumForAddresses);
}
);
req: { body: HistoryRequest, ... },
res: { send(arg: HistoryResponse): any, ... }
): Promise<void> => {
chai.assert.isTrue(_validateAddressesReq(req.body));
logger.info(`mockCardanoServer: /api/v2/txs/history -> request`);
logger.info(JSON.stringify(req.body));
const methodLogger = localLogger.getMethodLogger('POST', '/api/v2/txs/history');
chai.assert.isTrue(_validateAddressesReq(req.body, localLogger));
methodLogger.logRequest(JSON.stringify(req.body));
const history = await mockImporter.history(req.body);
logger.info(`mockCardanoServer: /api/v2/txs/history -> response`);
logger.info(JSON.stringify(history));
methodLogger.logResponseSuccess(JSON.stringify(history));
// Returns a chunk of txs
res.send(history.slice(0, txsLimit));
}
req: { body: BestBlockRequest, ... },
res: { send(arg: BestBlockResponse): any, ... }
): Promise<void> => {
logger.info(`mockCardanoServer: /api/v2/getblock-> request`);
logger.info(JSON.stringify(req.body));
const methodLogger = localLogger.getMethodLogger('POST', '/api/v2/bestblock');
methodLogger.logRequest(JSON.stringify(req.body));
const bestBlock = await mockImporter.getBestBlock(req.body);
logger.info(`mockCardanoServer: /api/v2/getblock -> response`);
logger.info(JSON.stringify(bestBlock));
methodLogger.logResponseSuccess(JSON.stringify(bestBlock));
res.send(bestBlock);
}
);
...
}
): void => {
logger.info(`mockCardanoServer: /api/txs/signed-> request`);
const methodLogger = localLogger.getMethodLogger('POST', '/api/txs/signed');
// note: don't use this in practice because ttl makes the tx hash computer-time-sensitive
"dev": true
},
"chromedriver": {
"version": "108.0.0",
"resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-108.0.0.tgz",
"integrity": "sha512-/kb0rb0dlC4RfXh2BOT7RV87K6d+It3VV5YXebLzO5a8t2knNffiTE23XPJQCH+l1xmgoW8/sOX/NB9irskvOQ==",
"version": "109.0.0",
"resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-109.0.0.tgz",
"integrity": "sha512-jdmBq11IUwfThLFiygGTZ89qbROSQI4bICQjvOVQy2Bqr1LwC+MFkhwyZp3YG99eehQbZuTlQmmfCZBfpewTNA==",
"dev": true,
"requires": {
"@testim/chrome-version": "^1.1.3",
"axios": "^1.1.3",
"axios": "^1.2.1",
"compare-versions": "^5.0.1",
"extract-zip": "^2.0.1",
"https-proxy-agent": "^5.0.1",
},
"dependencies": {
"axios": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.2.1.tgz",
"integrity": "sha512-I88cFiGu9ryt/tfVEi4kX2SITsvDddTajXTOFmt2uK1ZVA8LytjtdeyefdQWEf5PU8w+4SSJDoYnggflB5tW4A==",
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.3.0.tgz",
"integrity": "sha512-oCye5nHhTypzkdLIvF9SaHfr8UAquqCn1KY3j8vsrjeol8yohAdGxIpRPbF1bOLsx33HOAatdfMX1yzsj2cHwg==",
"dev": true,
"requires": {
"follow-redirects": "^1.15.0",
A flaky test run was discovering this and we seemingly had forgotten to add this schema when introducing the IgnoredInitTx constructor.
Fixes #348
Fixes #347
Fixes #412
Fixes #347
Fixes #348
Fixes #347
From https://github.com/input-output-hk/ouroboros-network at ff2331f0d254944f7c375078e6a3eb8e4f8770db
From https://github.com/input-output-hk/ouroboros-network at ff2331f0d254944f7c375078e6a3eb8e4f8770db
Fixes #347
Fixes #347
Fixes #347