Skip to content

Commit

Permalink
[0.19.x] Fix TxId logging for performance logging (hyperledger-archiv…
Browse files Browse the repository at this point in the history
…es#4536)

This doesn’t fix it for any other logging as all trace points
in composer-runtime will need to be changed, also somehow
the context would have to be passed to apis in composer-common
as well.

Signed-off-by: Dave Kelsey <[email protected]>
  • Loading branch information
Dave Kelsey authored Dec 4, 2018
1 parent 1e67fbf commit 4cc9d5a
Show file tree
Hide file tree
Showing 19 changed files with 155 additions and 105 deletions.
2 changes: 2 additions & 0 deletions packages/composer-common/lib/log/logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,8 @@ class Logger {
const timeTaken = (Date.now() - startTime).toFixed(2);
if (txId && txId.getTransactionID) {
this.intlog('verbose', method, `[${txId.getTransactionID().substring(0, 8)}] ${msg} ${timeTaken}ms`);
} else if (txId && txId.length > 0) {
this.intlog('verbose', method, `[${txId.substring(0, 8)}] ${msg} ${timeTaken}ms`);
} else {
this.intlog('verbose', method, `[NO TXID ] ${msg} ${timeTaken}ms`);
}
Expand Down
11 changes: 9 additions & 2 deletions packages/composer-common/test/log/logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -282,13 +282,20 @@ describe('Logger', () => {
sinon.assert.calledWith(logger.intlog, 'verbose', 'Method','Message','Data');
});

it('perf method should call verbose level, no args', () => {
it('perf method should call verbose level, handling a transaction id object', () => {
logger.perf('Method', 'Perf message', {getTransactionID: () => {return 'txid';}}, new Date());
sinon.assert.calledOnce(logger.intlog);
sinon.assert.calledWith(logger.intlog, 'verbose', 'Method', sinon.match.string);
});

it('perf method should call verbose level and work without a txid, no args', () => {
it('perf method should call verbose level, handling a transaction id string', () => {
logger.perf('Method', 'Perf message', 'A-TxId-value', new Date());
sinon.assert.calledOnce(logger.intlog);
sinon.assert.calledWith(logger.intlog, 'verbose', 'Method', sinon.match.string);
});


it('perf method should call verbose level and work without a txid', () => {
logger.perf('Method', 'Perf message', null, new Date());
sinon.assert.calledOnce(logger.intlog);
sinon.assert.calledWith(logger.intlog, 'verbose', 'Method', sinon.match.string);
Expand Down
10 changes: 5 additions & 5 deletions packages/composer-runtime-hlfv1/lib/composer.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,12 @@ class Composer {
let nodeContext = this._createContext(engine, stub);
await engine.init(nodeContext, fcn, params);
LOG.exit(method);
LOG.verbose('@PERF ' + method, 'Total (ms) duration for txnID [' + stub.getTxID() + ']: ' + (Date.now() - t0).toFixed(2));
LOG.perf(method, 'Total (ms) duration for txnID [' + stub.getTxID() + ']: ', stub.getTxID(), t0);
return shim.success();
}
catch(err) {
LOG.error(method, err);
LOG.verbose('@PERF ' + method, 'Total (ms) duration for txnID [' + stub.getTxID() + ']: ' + (Date.now() - t0).toFixed(2));
LOG.perf(method, 'Total (ms) duration for txnID [' + stub.getTxID() + ']: ', stub.getTxID(), t0);
return shim.error(err);
}
}
Expand All @@ -127,16 +127,16 @@ class Composer {
let payload = await engine.invoke(nodeContext, fcn, params);
if (payload !== null && payload !== undefined) {
LOG.exit(method, payload);
LOG.verbose('@PERF ' + method, 'Total (ms) duration for txnID [' + stub.getTxID() + ']: ' + (Date.now() - t0).toFixed(2));
LOG.perf(method, 'Total (ms) duration for txnID [' + stub.getTxID() + ']: ', stub.getTxID(), t0);
return shim.success(Buffer.from(JSON.stringify(payload)));
}
LOG.exit(method);
LOG.verbose('@PERF ' + method, 'Total (ms) duration for txnID [' + stub.getTxID() + ']: ' + (Date.now() - t0).toFixed(2));
LOG.perf(method, 'Total (ms) duration for txnID [' + stub.getTxID() + ']: ', stub.getTxID(), t0);
return shim.success();
}
catch(err) {
LOG.error(method, err);
LOG.verbose('@PERF ' + method, 'Total (ms) duration for txnID [' + stub.getTxID() + ']: ' + (Date.now() - t0).toFixed(2));
LOG.perf(method, 'Total (ms) duration for txnID [' + stub.getTxID() + ']: ', stub.getTxID(), t0);
return shim.error(err);
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/composer-runtime-hlfv1/lib/nodecontext.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class NodeContext extends Context {
this.stub = stub;
this.dataService = new NodeDataService(this.stub);
this.identityService = new NodeIdentityService(this.stub);
this.setContextId(stub.getTxID());
LOG.exit(method);
}

Expand Down
22 changes: 11 additions & 11 deletions packages/composer-runtime-hlfv1/lib/nodedatacollection.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ class NodeDataCollection extends DataCollection {
const t0 = Date.now();

let iterator = await this.stub.getStateByPartialCompositeKey(this.collectionID, []);
let results = await NodeUtils.getAllResults(iterator);
let results = await NodeUtils.getAllResults(iterator, this.stub);
LOG.exit(method, results);
LOG.verbose('@PERF ' + method, 'Total (ms) duration: ' + (Date.now() - t0).toFixed(2));
LOG.perf(method, 'Total (ms) duration: ', this.stub.getTxID(), t0);
return results;
}

Expand All @@ -72,12 +72,12 @@ class NodeDataCollection extends DataCollection {
if (value.length === 0) {
const newErr = new Error(`Object with ID '${id}' in collection with ID '${this.collectionID}' does not exist`);
LOG.error(method, newErr);
LOG.verbose('@PERF ' + method, 'Total (ms) duration: ' + (Date.now() - t0).toFixed(2));
LOG.perf(method, 'Total (ms) duration: ', this.stub.getTxID(), t0);
throw newErr;
}
let retVal = JSON.parse(value.toString('utf8'));
LOG.exit(method, retVal);
LOG.verbose('@PERF ' + method, 'Total (ms) duration: ' + (Date.now() - t0).toFixed(2));
LOG.perf(method, 'Total (ms) duration: ', this.stub.getTxID(), t0);
return retVal;
}

Expand All @@ -96,7 +96,7 @@ class NodeDataCollection extends DataCollection {
let value = await this.stub.getState(key);
let retVal = value.length !== 0;
LOG.exit(method, retVal);
LOG.verbose('@PERF ' + method, 'Total (ms) duration: ' + (Date.now() - t0).toFixed(2));
LOG.perf(method, 'Total (ms) duration: ', this.stub.getTxID(), t0);
return retVal;
}

Expand All @@ -120,14 +120,14 @@ class NodeDataCollection extends DataCollection {
if (value.length !== 0) {
const newErr = new Error(`Failed to add object with ID '${id}' in collection with ID '${this.collectionID}' as the object already exists`);
LOG.error(method, newErr);
LOG.verbose('@PERF ' + method, 'Total (ms) duration: ' + (Date.now() - t0).toFixed(2));
LOG.perf(method, 'Total (ms) duration: ', this.stub.getTxID(), t0);
throw newErr;
}
}
await this.stub.putState(key, Buffer.from(JSON.stringify(object)));

LOG.exit(method);
LOG.verbose('@PERF ' + method, 'Total (ms) duration: ' + (Date.now() - t0).toFixed(2));
LOG.perf(method, 'Total (ms) duration: ', this.stub.getTxID(), t0);
}

/**
Expand All @@ -148,12 +148,12 @@ class NodeDataCollection extends DataCollection {
if (value.length === 0) {
const newErr = new Error(`Failed to update object with ID '${id}' in collection with ID '${this.collectionID}' as the object does not exist`);
LOG.error(method, newErr);
LOG.verbose('@PERF ' + method, 'Total (ms) duration: ' + (Date.now() - t0).toFixed(2));
LOG.perf(method, 'Total (ms) duration: ', this.stub.getTxID(), t0);
throw newErr;
}
await this.stub.putState(key, Buffer.from(JSON.stringify(object)));
LOG.exit(method);
LOG.verbose('@PERF ' + method, 'Total (ms) duration: ' + (Date.now() - t0).toFixed(2));
LOG.perf(method, 'Total (ms) duration: ', this.stub.getTxID(), t0);
}

/**
Expand All @@ -170,12 +170,12 @@ class NodeDataCollection extends DataCollection {
if (value.length === 0) {
const newErr = new Error(`Failed to delete object with ID '${id}' in collection with ID '${this.collectionID}' as the object does not exist`);
LOG.error(method, newErr);
LOG.verbose('@PERF ' + method, 'Total (ms) duration: ' + (Date.now() - t0).toFixed(2));
LOG.perf(method, 'Total (ms) duration: ', this.stub.getTxID(), t0);
throw newErr;
}
await this.stub.deleteState(key);
LOG.exit(method);
LOG.verbose('@PERF ' + method, 'Total (ms) duration: ' + (Date.now() - t0).toFixed(2));
LOG.perf(method, 'Total (ms) duration: ', this.stub.getTxID(), t0);
}
}

Expand Down
26 changes: 13 additions & 13 deletions packages/composer-runtime-hlfv1/lib/nodedataservice.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,17 @@ class NodeDataService extends DataService {
if (value.length === 0) {
let result = await this._storeCollection(key, id);
LOG.exit(method, result);
LOG.verbose('@PERF ' + method, 'Total (ms) duration: ' + (Date.now() - t0).toFixed(2));
LOG.perf(method, 'Total (ms) duration: ', this.stub.getTxID(), t0);
return result;
}
else {
LOG.verbose('@PERF ' + method, 'Total (ms) duration: ' + (Date.now() - t0).toFixed(2));
LOG.perf(method, 'Total (ms) duration: ', this.stub.getTxID(), t0);
throw new Error(`Failed to create collection with ID ${id} as it already exists`);
}
} else {
let result = await this._storeCollection(key, id);
LOG.exit(method, result);
LOG.verbose('@PERF ' + method, 'Total (ms) duration: ' + (Date.now() - t0).toFixed(2));
LOG.perf(method, 'Total (ms) duration: ', this.stub.getTxID(), t0);
return result;
}
}
Expand All @@ -88,7 +88,7 @@ class NodeDataService extends DataService {
await this.stub.putState(key, Buffer.from(JSON.stringify({'id': id})));
let retVal = new NodeDataCollection(this, this.stub, id);
LOG.exit(method, retVal);
LOG.verbose('@PERF ' + method, 'Total (ms) duration: ' + (Date.now() - t0).toFixed(2));
LOG.perf(method, 'Total (ms) duration: ', this.stub.getTxID(), t0);
return retVal;
}

Expand All @@ -104,13 +104,13 @@ class NodeDataService extends DataService {
let key = this.stub.createCompositeKey(collectionObjectType, [id]);
let exists = await this.existsCollection(id);
if (!exists) {
LOG.verbose('@PERF ' + method, 'Total (ms) duration: ' + (Date.now() - t0).toFixed(2));
LOG.perf(method, 'Total (ms) duration: ', this.stub.getTxID(), t0);
throw new Error(`Collection with ID ${id} does not exist`);
}
await this.clearCollection(id);
await this.stub.deleteState(key);
LOG.exit(method);
LOG.verbose('@PERF ' + method, 'Total (ms) duration: ' + (Date.now() - t0).toFixed(2));
LOG.perf(method, 'Total (ms) duration: ', this.stub.getTxID(), t0);
}

/**
Expand All @@ -128,18 +128,18 @@ class NodeDataService extends DataService {
if (bypass) {
let retVal = new NodeDataCollection(this, this.stub, id);
LOG.exit(method, retVal);
LOG.verbose('@PERF ' + method, 'Total (ms) duration: ' + (Date.now() - t0).toFixed(2));
LOG.perf(method, 'Total (ms) duration: ', this.stub.getTxID(), t0);
return retVal;
} else {
let key = this.stub.createCompositeKey(collectionObjectType, [id]);
let value = await this.stub.getState(key);
if (value.length === 0) {
LOG.verbose('@PERF ' + method, 'Total (ms) duration: ' + (Date.now() - t0).toFixed(2));
LOG.perf(method, 'Total (ms) duration: ', this.stub.getTxID(), t0);
throw new Error(`Collection with ID ${id} does not exist`);
}
let retVal = new NodeDataCollection(this, this.stub, id);
LOG.exit(method, retVal);
LOG.verbose('@PERF ' + method, 'Total (ms) duration: ' + (Date.now() - t0).toFixed(2));
LOG.perf(method, 'Total (ms) duration: ', this.stub.getTxID(), t0);
return retVal;
}
}
Expand All @@ -159,7 +159,7 @@ class NodeDataService extends DataService {
let value = await this.stub.getState(key);
let retVal = value.length !== 0;
LOG.exit(method, retVal);
LOG.verbose('@PERF ' + method, 'Total (ms) duration: ' + (Date.now() - t0).toFixed(2));
LOG.perf(method, 'Total (ms) duration: ', this.stub.getTxID(), t0);
return retVal;
}

Expand All @@ -176,9 +176,9 @@ class NodeDataService extends DataService {
const t0 = Date.now();

let iterator = await this.stub.getQueryResult(query);
let results = await NodeUtils.getAllResults(iterator);
let results = await NodeUtils.getAllResults(iterator, this.stub);
LOG.exit(method, results);
LOG.verbose('@PERF ' + method, 'Total (ms) duration: ' + (Date.now() - t0).toFixed(2));
LOG.perf(method, 'Total (ms) duration: ', this.stub.getTxID(), t0);
return results;
}

Expand All @@ -194,7 +194,7 @@ class NodeDataService extends DataService {
let iterator = await this.stub.getStateByPartialCompositeKey(id, []);
await NodeUtils.deleteAllResults(iterator, this.stub);
LOG.exit(method);
LOG.verbose('@PERF ' + method, 'Total (ms) duration: ' + (Date.now() - t0).toFixed(2));
LOG.perf(method, 'Total (ms) duration: ', this.stub.getTxID(), t0);
}
}

Expand Down
40 changes: 26 additions & 14 deletions packages/composer-runtime-hlfv1/lib/nodeloggingservice.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@
const LoggingService = require('composer-runtime').LoggingService;
const LOGLEVEL_KEY = 'ComposerLogCfg';
const Logger = require('composer-common').Logger;

Logger.setCallBack(function(logLevel) {
const timestamp = new Date().toISOString();
return `${timestamp} ${logLevel.toUpperCase().padEnd(8)} `;
});


/**
* Base class representing the logging service provided by a {@link Container}.
* @protected
Expand All @@ -29,6 +36,7 @@ class NodeLoggingService extends LoggingService {
constructor() {
super();
this.stub = null;
this.loggerInitialized = false;
}

/**
Expand All @@ -41,15 +49,19 @@ class NodeLoggingService extends LoggingService {
async initLogging(stub) {
this.stub = stub;

let logCFG = await this.getLoggerCfg();
Logger.setLoggerCfg(logCFG, true);

Logger.setCallBack(function(logLevel) {
const timestamp = new Date().toISOString();
const shortTxId = stub.getTxID().substring(0, 8);
return `${timestamp} [${shortTxId}] ${logLevel.toUpperCase().padEnd(8)} `;
});

// we only want to do this once for the first request that comes
// in so we can look at the initial state of the logger and set it
// appropriately. Any change to the logger state is handled so doesn't
// need to be checked at initLogging. The theory is that as this is
// called constantly in interleaved requests it stops some log points
// being logged.
if (!this.loggerInitialized) {
// set the initialized flag first to stop another interleaved request
// coming in trying to do the same thing.
this.loggerInitialized = true;
let logCFG = await this.getLoggerCfg();
Logger.setLoggerCfg(logCFG, true);
}
}

/**
Expand All @@ -66,14 +78,14 @@ class NodeLoggingService extends LoggingService {
*
* @returns {Object} configuration
*/
async getLoggerCfg(){
async getLoggerCfg() {
let result = await this.stub.getState(LOGLEVEL_KEY);
if (result.length === 0) {
let defCfg = this.getDefaultCfg();
return defCfg;
} else {
let json = JSON.parse(result.toString());
if( json.origin && json.origin==='default-logger-module'){
if( json.origin && json.origin === 'default-logger-module'){
json = this.getDefaultCfg();
}
return json;
Expand All @@ -83,7 +95,7 @@ class NodeLoggingService extends LoggingService {
/**
* @return {Object} the default cfg
*/
getDefaultCfg(){
getDefaultCfg() {

let envVariable = process.env.CORE_CHAINCODE_LOGGING_LEVEL;
let debugString = this.mapFabricDebug(envVariable);
Expand All @@ -97,7 +109,7 @@ class NodeLoggingService extends LoggingService {
},
'debug' : debugString,
'logger': './consolelogger.js',
'origin':'default-runtime-hlfv1'
'origin': 'default-runtime-hlfv1'
};
}

Expand All @@ -109,7 +121,7 @@ class NodeLoggingService extends LoggingService {
* @param {String} string input value to process
* @return {String} clean string that can be used for setting up logging.
*/
mapCfg(string){
mapCfg(string) {
let DEFAULT = 'composer[warn]:*';
// first split it up into elements based on ,
let details = string.split(/[\s,]+/);
Expand Down
7 changes: 4 additions & 3 deletions packages/composer-runtime-hlfv1/lib/nodeutils.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ class NodeUtils {
*
* @static
* @param {any} iterator the chaincode iterator
* @param {any} stub the stub for this invocation
* @returns {promise} a promise that is resolved with the results or rejected or error
*/
static async getAllResults(iterator) {
static async getAllResults(iterator, stub) {
const method = 'getAllResults';
LOG.entry(method, iterator);
const t0 = Date.now();
Expand All @@ -56,7 +57,7 @@ class NodeUtils {
LOG.warn(warnMsg);
}
LOG.exit(method);
LOG.verbose('@PERF ' + method, 'Total (ms) duration: ' + (Date.now() - t0).toFixed(2));
LOG.perf(method, 'Total (ms) duration: ', stub.getTxID(), t0);
return results;
}
}
Expand Down Expand Up @@ -94,7 +95,7 @@ class NodeUtils {
LOG.warn(warnMsg);
}
LOG.exit(method);
LOG.verbose('@PERF ' + method, 'Total (ms) duration: ' + (Date.now() - t0).toFixed(2));
LOG.perf(method, 'Total (ms) duration: ', stub.getTxID(), t0);
return results;
}
}
Expand Down
Loading

0 comments on commit 4cc9d5a

Please sign in to comment.