Skip to content
This repository was archived by the owner on Mar 8, 2020. It is now read-only.

Commit 6d6a71a

Browse files
authored
Add performance logging to connector (#4434)
contributes to #4428 Signed-off-by: Dave Kelsey <[email protected]>
1 parent 0379752 commit 6d6a71a

File tree

11 files changed

+133
-47
lines changed

11 files changed

+133
-47
lines changed

packages/composer-common/lib/idcard.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,8 @@ class IdCard {
155155
*/
156156
setCredentials(credentials) {
157157
const method = 'setCredentials';
158-
LOG.entry(method, credentials);
158+
// Don't log the credentials
159+
LOG.entry(method);
159160

160161
this.credentials = credentials || { };
161162

packages/composer-common/lib/log/logger.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ class Logger {
280280
/**
281281
* @description Log a message at the _verbose_ level
282282
*
283-
* @param {String} method cupdateLoggerCfgalling method
283+
* @param {String} method calling method
284284
* @param {String} msg Text Message
285285
* @param {stuff} data Data to log at a verbose level
286286
*
@@ -299,6 +299,24 @@ class Logger {
299299
this.intlog.apply(this, args);
300300
}
301301

302+
/**
303+
* @description Log a performance message at the _verbose_ level
304+
*
305+
* @param {String} method calling method
306+
* @param {String} msg Text Message
307+
* @param {TransactionID} txId The node-sdk transaction id
308+
* @param {Date} startTime Date object representing the start of the timed block
309+
*
310+
* @private
311+
*/
312+
perf(method, msg, txId, startTime) {
313+
if (!(this.include && this.logLevel >= LOG_LEVEL_VERBOSE)) {
314+
return;
315+
}
316+
const timeTaken = (Date.now() - startTime).toFixed(2);
317+
this.intlog('verbose', method, `[${txId.getTransactionID().substring(0, 8)}] ${msg} ${timeTaken}ms`);
318+
}
319+
302320
/**
303321
* @description Log a message at the _error_ level
304322
*

packages/composer-common/lib/modelmanager.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ class ModelManager {
7878

7979
// add the system model
8080
SYSTEM_MODELS.forEach((SYSTEM_MODEL) => {
81-
LOG.info(method, SYSTEM_MODEL);
81+
LOG.debug(method, SYSTEM_MODEL);
8282
let m = new ModelFile(this, SYSTEM_MODEL.contents, SYSTEM_MODEL.fileName);
8383
this.modelFiles[m.getNamespace()] = m;
8484
});

packages/composer-common/test/log/logger.js

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -269,31 +269,38 @@ describe('Logger', () => {
269269
sinon.assert.calledWith(logger.intlog, 'debug', 'Method','Message','Data');
270270
});
271271

272-
it('info method should call debug level, no args', () => {
272+
it('info method should call info level, no args', () => {
273273
logger.info('Method', 'Message', 'Data');
274274
sinon.assert.calledOnce(logger.intlog);
275275
sinon.assert.calledWith(logger.intlog, 'info', 'Method','Message','Data');
276276
});
277277

278-
it('verbose method should call debug level, no args', () => {
278+
it('verbose method should call verbose level, no args', () => {
279279
logger.verbose('Method', 'Message', 'Data');
280280
sinon.assert.calledOnce(logger.intlog);
281281
sinon.assert.calledWith(logger.intlog, 'verbose', 'Method','Message','Data');
282282
});
283283

284-
it('error method should call debug level, no args', () => {
284+
it('perf method should call verbose level, no args', () => {
285+
logger.perf('Method', 'Perf message', {getTransactionID: () => {return 'txid';}}, new Date());
286+
sinon.assert.calledOnce(logger.intlog);
287+
sinon.assert.calledWith(logger.intlog, 'verbose', 'Method', sinon.match.string);
288+
});
289+
290+
291+
it('error method should call error level, no args', () => {
285292
logger.error('Method', 'Message', 'Data');
286293
sinon.assert.calledOnce(logger.intlog);
287294
sinon.assert.calledWith(logger.intlog, 'error', 'Method','Message','Data');
288295
});
289296

290-
it('entry method should call debug level, no args', () => {
297+
it('entry method should call entry level, no args', () => {
291298
logger.entry('Method', 'Message', 'Data');
292299
sinon.assert.calledOnce(logger.intlog);
293300
sinon.assert.calledWith(logger.intlog, 'debug', 'Method','>','Message','Data');
294301
});
295302

296-
it('exit method should call debug level, no args', () => {
303+
it('exit method should call exit level, no args', () => {
297304
logger.exit('Method', 'Message', 'Data');
298305
sinon.assert.calledOnce(logger.intlog);
299306
sinon.assert.calledWith(logger.intlog, 'debug', 'Method','<','Message','Data');
@@ -321,37 +328,42 @@ describe('Logger', () => {
321328
levelsandbox.restore();
322329
});
323330

324-
it('warn method should call warn level, no args', () => {
331+
it('warn method should not call warn level, no args', () => {
325332
logger.warn('Method', 'Message', 'Data');
326333
sinon.assert.notCalled(logger.intlog);
327334
});
328335

329-
it('debug method should call debug level, no args', () => {
336+
it('debug method should not call debug level, no args', () => {
330337
logger.debug('Method', 'Message', 'Data');
331338
sinon.assert.notCalled(logger.intlog);
332339
});
333340

334-
it('info method should call debug level, no args', () => {
341+
it('info method should not call info level, no args', () => {
335342
logger.info('Method', 'Message', 'Data');
336343
sinon.assert.notCalled(logger.intlog);
337344
});
338345

339-
it('verbose method should call debug level, no args', () => {
346+
it('verbose method should not call verbose level, no args', () => {
340347
logger.verbose('Method', 'Message', 'Data');
341348
sinon.assert.notCalled(logger.intlog);
342349
});
343350

344-
it('error method should call debug level, no args', () => {
351+
it('perf method should not call verbose level, no args', () => {
352+
logger.perf('Method', 'Perf message', {getTransactionID: () => {return 'txid';}}, new Date());
353+
sinon.assert.notCalled(logger.intlog);
354+
});
355+
356+
it('error method should not call error level, no args', () => {
345357
logger.error('Method', 'Message', 'Data');
346358
sinon.assert.notCalled(logger.intlog);
347359
});
348360

349-
it('entry method should call debug level, no args', () => {
361+
it('entry method should not call entry level, no args', () => {
350362
logger.entry('Method', 'Message', 'Data');
351363
sinon.assert.notCalled(logger.intlog);
352364
});
353365

354-
it('exit method should call debug level, no args', () => {
366+
it('exit method should not call exit level, no args', () => {
355367
logger.exit('Method', 'Message', 'Data');
356368
sinon.assert.notCalled(logger.intlog);
357369
});

packages/composer-connector-hlfv1/lib/hlfconnection.js

Lines changed: 49 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ class HLFConnection extends Connection {
9999
constructor(connectionManager, connectionProfile, businessNetworkIdentifier, connectOptions, client, channel, caClient) {
100100
super(connectionManager, connectionProfile, businessNetworkIdentifier);
101101
const method = 'constructor';
102-
LOG.entry(method, connectionManager, connectionProfile, businessNetworkIdentifier, connectOptions, client, channel, caClient);
102+
// don't log the client, channel, caClient objects here they're too big
103+
LOG.entry(method, connectionManager, connectionProfile, businessNetworkIdentifier, connectOptions);
103104

104105
// Validate all the arguments.
105106
if (!connectOptions) {
@@ -389,7 +390,8 @@ class HLFConnection extends Connection {
389390
};
390391
pollCCListener();
391392

392-
LOG.exit(method, result);
393+
// don't log the result object it's too large
394+
LOG.exit(method);
393395
return result;
394396

395397
})
@@ -412,7 +414,7 @@ class HLFConnection extends Connection {
412414
*/
413415
async install(securityContext, businessNetworkDefinition, installOptions) {
414416
const method = 'install';
415-
LOG.entry(method, securityContext, businessNetworkDefinition, installOptions);
417+
LOG.entry(method, businessNetworkDefinition, installOptions);
416418

417419
if (!businessNetworkDefinition) {
418420
throw new Error('businessNetworkDefinition not specified');
@@ -639,7 +641,7 @@ class HLFConnection extends Connection {
639641
*/
640642
async start(securityContext, businessNetworkName, businessNetworkVersion, startTransaction, startOptions) {
641643
const method = 'start';
642-
LOG.entry(method, securityContext, businessNetworkName, startTransaction, startOptions);
644+
LOG.entry(method, businessNetworkName, startTransaction, startOptions);
643645

644646
if (!businessNetworkName) {
645647
throw new Error('Business network name not specified');
@@ -785,7 +787,7 @@ class HLFConnection extends Connection {
785787
*/
786788
ping(securityContext) {
787789
const method = 'ping';
788-
LOG.entry(method, securityContext);
790+
LOG.entry(method);
789791

790792
// Check that a valid security context has been specified.
791793
HLFUtil.securityCheck(securityContext);
@@ -818,7 +820,7 @@ class HLFConnection extends Connection {
818820
*/
819821
_checkRuntimeVersions(securityContext) {
820822
const method = '_checkRuntimeVersions';
821-
LOG.entry(method, securityContext);
823+
LOG.entry(method);
822824

823825
return this.queryChainCode(securityContext, 'ping', [])
824826
.then((buffer) => {
@@ -846,7 +848,7 @@ class HLFConnection extends Connection {
846848
*/
847849
async queryChainCode(securityContext, functionName, args) {
848850
const method = 'queryChainCode';
849-
LOG.entry(method, securityContext, functionName, args);
851+
LOG.entry(method, functionName, args);
850852

851853
if (!this.businessNetworkIdentifier) {
852854
throw new Error('No business network has been specified for this connection');
@@ -872,7 +874,10 @@ class HLFConnection extends Connection {
872874
}
873875

874876
let txId = this.client.newTransactionID();
877+
878+
const t0 = Date.now();
875879
let result = await this.queryHandler.queryChaincode(txId, functionName, args);
880+
LOG.perf(method, 'Total duration for queryChaincode: ', txId, t0);
876881
LOG.exit(method, result ? result : null);
877882
return result ? result : null;
878883
}
@@ -889,7 +894,7 @@ class HLFConnection extends Connection {
889894
*/
890895
async invokeChainCode(securityContext, functionName, args, options = {}) {
891896
const method = 'invokeChainCode';
892-
LOG.entry(method, securityContext, functionName, args, options);
897+
LOG.entry(method, functionName, args, options);
893898

894899
// If commit has been set to false, we do not want to order the transaction or wait for any events.
895900
if (options.commit === false) {
@@ -928,6 +933,7 @@ class HLFConnection extends Connection {
928933
let eventHandler;
929934
let validResponses;
930935

936+
let t0 = Date.now();
931937
try {
932938

933939
// initialize the channel if it hasn't been initialized already otherwise verification will fail.
@@ -944,7 +950,18 @@ class HLFConnection extends Connection {
944950
fcn: functionName,
945951
args: args
946952
};
947-
const results = await this.channel.sendTransactionProposal(request); // node sdk will target all peers on the channel that are endorsingPeer
953+
LOG.perf(method, 'Total duration to initialize channel: ', txId, t0);
954+
t0 = Date.now();
955+
956+
let results;
957+
try {
958+
results = await this.channel.sendTransactionProposal(request); // node sdk will target all peers on the channel that are endorsingPeer
959+
} catch(error) {
960+
LOG.error(method, error);
961+
throw new Error(`Error received from sendTransactionProposal: ${error}`);
962+
}
963+
LOG.perf(method, 'Total duration for sendTransactionProposal: ', txId, t0);
964+
t0 = Date.now();
948965

949966
// Validate the endorsement results.
950967
LOG.debug(method, `Received ${results.length} result(s) from invoking the composer runtime chaincode`, results);
@@ -970,11 +987,22 @@ class HLFConnection extends Connection {
970987
eventHandler = HLFConnection.createTxEventHandler(this.eventHubs, txId.getTransactionID(), this.commitTimeout);
971988
eventHandler.startListening();
972989
LOG.debug(method, 'TxEventHandler started listening, sending valid responses to the orderer');
973-
const response = await this.channel.sendTransaction({
974-
proposalResponses: validResponses,
975-
proposal: proposal,
976-
header: header
977-
});
990+
LOG.perf(method, 'Total duration to prepare proposals for orderer: ', txId, t0);
991+
t0 = Date.now();
992+
993+
let response;
994+
try {
995+
response = await this.channel.sendTransaction({
996+
proposalResponses: validResponses,
997+
proposal: proposal,
998+
header: header
999+
});
1000+
} catch(error) {
1001+
LOG.error(method, error);
1002+
throw new Error(`Error received from sendTransaction: ${error} `);
1003+
}
1004+
LOG.perf(method, 'Total duration for sendTransaction: ', txId, t0);
1005+
t0 = Date.now();
9781006

9791007
// If the transaction was successful, wait for it to be committed.
9801008
LOG.debug(method, 'Received response from orderer', response);
@@ -984,21 +1012,23 @@ class HLFConnection extends Connection {
9841012
throw new Error(`Failed to send peer responses for transaction '${txId.getTransactionID()}' to orderer. Response status '${response.status}'`);
9851013
}
9861014
await eventHandler.waitForEvents();
1015+
LOG.perf(method, 'Total duration for commit notification : ', txId, t0);
9871016

9881017
LOG.exit(method, result);
9891018
return result;
9901019

9911020
} catch (error) {
9921021
// Log first in case anything below fails and masks the original error
1022+
LOG.error(method, `Failed to invoke business network with transaction id: ${txId.getTransactionID()}`);
9931023
LOG.error(method, error);
9941024

995-
// Investigate proposal response results and log if they differ and rethrow
1025+
// Investigate proposal response results and log if they differ
9961026
if (validResponses && validResponses.length >= 2 && !this.channel.compareProposalResponseResults(validResponses)) {
9971027
const warning = 'Peers did not agree, Read Write sets differed';
9981028
LOG.warn(method, warning);
9991029
}
10001030

1001-
const newError = new Error('Error trying invoke business network. ' + error);
1031+
const newError = new Error(`Error trying invoke business network with transaction id ${txId.getTransactionID()}. ${error}`);
10021032
throw newError;
10031033
}
10041034
}
@@ -1020,7 +1050,7 @@ class HLFConnection extends Connection {
10201050
*/
10211051
createIdentity(securityContext, userID, options) {
10221052
const method = 'createIdentity';
1023-
LOG.entry(method, securityContext, userID, options);
1053+
LOG.entry(method, userID, options);
10241054

10251055
// Check that a valid security context has been specified.
10261056
HLFUtil.securityCheck(securityContext);
@@ -1095,7 +1125,7 @@ class HLFConnection extends Connection {
10951125
*/
10961126
list(securityContext) {
10971127
const method = 'list';
1098-
LOG.entry(method, securityContext);
1128+
LOG.entry(method);
10991129

11001130
// Check that a valid security context has been specified.
11011131
HLFUtil.securityCheck(securityContext);
@@ -1140,7 +1170,7 @@ class HLFConnection extends Connection {
11401170
*/
11411171
async upgrade(securityContext, businessNetworkName, businessNetworkVersion, upgradeOptions) {
11421172
const method = 'upgrade';
1143-
LOG.entry(method, securityContext, businessNetworkName, upgradeOptions);
1173+
LOG.entry(method, businessNetworkName, upgradeOptions);
11441174

11451175
if (!businessNetworkName) {
11461176
throw new Error('Business network name not specified');

0 commit comments

Comments
 (0)