Logging and Pretty-Printing Data for Debugging


#1

Hi,

Is there a recommended way to log data of any type on the server, in order to get readable contents in c3_server.log?
I came up with the following:

if (!String.prototype.format) {
 String.prototype.format = function() {
   var args = arguments;
   return this.replace(/{(\d+)}/g, function(match, number) {
     return typeof args[number] != ‘undefined’
       ? JSON.stringify(args[number])
       : ‘undefined’
     ;
   });
 };
}

which, when called like this:

logger.info(“@@@ scoreConfigs: {0}, end: {1}, interval: {2}, anomalyPeriodStartDate: {3}, start: {4}“.format(scoreConfigs, end, interval, anomalyPeriodStartDate, start));

produces in c3_server.log:

@@@ scoreConfigs: [{"type":"AnomalyScoreConfig","scoreName":"General","equipmentType":"Asset","expressions":["CasingPressure","GasProduction","WaterProduction","BottomHolePressure","FluidLevel","GasFlowLinePressure","GasRate","Wat
erRate","PumpSpeed","Torque","ReservoirPressure","SeparatorPressure","TubingPressure","WaterFlowLinePressure"],"referenceAnalytics":["'8'","'9'"],"predictedAnalytics":["'0'","'1'","'2'","'3'","'4'","'5'","'6'","'7'","'10'","'11'",
"'12'","'13'"],"applySmoothing":true,"id":"AssetAnomalyScoreConfig","version":87},{"type":"AnomalyScoreConfig","scoreName":"General","equipmentType":"TestPumpAsset","expressions":["PreviousPumpTempA","PreviousPumpTempB","PreviousP
umpTempC"],"referenceAnalytics":["'2'"],"predictedAnalytics":["'0'","'1'"],"applySmoothing":true,"id":"TestPumpAssetAnomalyScoreConfig","version":87},{"type":"AnomalyScoreConfig","scoreName":"General","equipmentType":"TestTurbineA
sset","expressions":["PreviousTurbineTempA","PreviousTurbineTempB","PreviousTurbineTempC"],"referenceAnalytics":["'2'"],"predictedAnalytics":["'0'","'1'"],"applySmoothing":true,"id":"TestTurbineAssetAnomalyScoreConfig","version":8
7}], end: "2018-02-23T00:00:00.000-08:00", interval: "HOUR", anomalyPeriodStartDate: undefined, start: undefined

#2

C3.logger already supports interpolation :slight_smile: Just use empty curly braces in your template string and pass extra parameters to the logger function, like this:

logger.info("@@@ scoreConfigs: {}, end: {}, interval: {}, anomalyPeriodStartDate: {}, start: {}", JSON.stringify(scoreConfigs), JSON.stringify(end), JSON.stringify(interval), JSON.stringify(anomalyPeriodStartDate), JSON.stringify(start));

If you really wanted to, you could write a wrapper function that automatically calls JSON.stringify on the arguments after the template string, but by default .toString should be called as part of interpolation.


#3

Thanks, it would be good to document it as “interpolated string” type.
BTW, toString does not work for undefined.