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",
Co-authored-by: Sebastien Guillemot <[email protected]>
5018: Use ouroboros-network-0.3.0.2 and ouroboros-network-framework-0.2.0.1 r=dermetfan a=coot Co-authored-by: Marcin Szamotulski <[email protected]> Co-authored-by: Samuel Leathers <[email protected]>
Waiting for a day, at a pace of one block every 20 seconds would generate 4320 blocks which takes forever to be created and processes, even in IO sim. We don't really observe the issue now because we cheat in the way we generate the block. This commit helps preparing for a more realistic block generation.
Everyone collects after observing the last commit
That way, we try to get closer to an actual block production pattern.