From ff4b895e48c7e0c0ba57aa9e811ece2a9877340f Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Sun, 3 Oct 2021 01:08:37 +0200 Subject: [PATCH] Use a map to store OCPP command statistics MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- src/performance/PerformanceStatistics.ts | 55 +++++++++------------- src/performance/storage/JSONFileStorage.ts | 14 +++++- src/types/Statistics.ts | 2 +- 3 files changed, 36 insertions(+), 35 deletions(-) diff --git a/src/performance/PerformanceStatistics.ts b/src/performance/PerformanceStatistics.ts index 56f8c042..9f3b9482 100644 --- a/src/performance/PerformanceStatistics.ts +++ b/src/performance/PerformanceStatistics.ts @@ -22,7 +22,7 @@ export default class PerformanceStatistics { public constructor(objId: string, URI: URL) { this.objId = objId; this.initializePerformanceObserver(); - this.statistics = { id: this.objId ?? 'Object id not specified', URI: URI.toString(), createdAt: new Date(), statisticsData: {} }; + this.statistics = { id: this.objId ?? 'Object id not specified', URI: URI.toString(), createdAt: new Date(), statisticsData: new Map>() }; } public static beginMeasure(id: string): string { @@ -39,35 +39,24 @@ export default class PerformanceStatistics { public addRequestStatistic(command: RequestCommand | IncomingRequestCommand, messageType: MessageType): void { switch (messageType) { case MessageType.CALL_MESSAGE: - if (this.statistics.statisticsData[command] && this.statistics.statisticsData[command].countRequest) { - this.statistics.statisticsData[command].countRequest++; + if (this.statistics.statisticsData.has(command) && this.statistics.statisticsData.get(command)?.countRequest) { + this.statistics.statisticsData.get(command).countRequest++; } else { - this.statistics.statisticsData[command] = {} as StatisticsData; - this.statistics.statisticsData[command].countRequest = 1; + this.statistics.statisticsData.set(command, Object.assign({ countRequest: 1 }, this.statistics.statisticsData.get(command))); } break; case MessageType.CALL_RESULT_MESSAGE: - if (this.statistics.statisticsData[command]) { - if (this.statistics.statisticsData[command].countResponse) { - this.statistics.statisticsData[command].countResponse++; - } else { - this.statistics.statisticsData[command].countResponse = 1; - } + if (this.statistics.statisticsData.has(command) && this.statistics.statisticsData.get(command)?.countResponse) { + this.statistics.statisticsData.get(command).countResponse++; } else { - this.statistics.statisticsData[command] = {} as StatisticsData; - this.statistics.statisticsData[command].countResponse = 1; + this.statistics.statisticsData.set(command, Object.assign({ countResponse: 1 }, this.statistics.statisticsData.get(command))); } break; case MessageType.CALL_ERROR_MESSAGE: - if (this.statistics.statisticsData[command]) { - if (this.statistics.statisticsData[command].countError) { - this.statistics.statisticsData[command].countError++; - } else { - this.statistics.statisticsData[command].countError = 1; - } + if (this.statistics.statisticsData.has(command) && this.statistics.statisticsData.get(command)?.countError) { + this.statistics.statisticsData.get(command).countError++; } else { - this.statistics.statisticsData[command] = {} as StatisticsData; - this.statistics.statisticsData[command].countError = 1; + this.statistics.statisticsData.set(command, Object.assign({ countError: 1 }, this.statistics.statisticsData.get(command))); } break; default: @@ -176,21 +165,21 @@ export default class PerformanceStatistics { entryName = MAP_NAME[entryName]; } // Initialize command statistics - if (!this.statistics.statisticsData[entryName]) { - this.statistics.statisticsData[entryName] = {} as StatisticsData; + if (!this.statistics.statisticsData.has(entryName)) { + this.statistics.statisticsData.set(entryName, {}); } // Update current statistics this.statistics.updatedAt = new Date(); - this.statistics.statisticsData[entryName].countTimeMeasurement = this.statistics.statisticsData[entryName].countTimeMeasurement ? this.statistics.statisticsData[entryName].countTimeMeasurement + 1 : 1; - this.statistics.statisticsData[entryName].currentTimeMeasurement = entry.duration; - this.statistics.statisticsData[entryName].minTimeMeasurement = this.statistics.statisticsData[entryName].minTimeMeasurement ? (this.statistics.statisticsData[entryName].minTimeMeasurement > entry.duration ? entry.duration : this.statistics.statisticsData[entryName].minTimeMeasurement) : entry.duration; - this.statistics.statisticsData[entryName].maxTimeMeasurement = this.statistics.statisticsData[entryName].maxTimeMeasurement ? (this.statistics.statisticsData[entryName].maxTimeMeasurement < entry.duration ? entry.duration : this.statistics.statisticsData[entryName].maxTimeMeasurement) : entry.duration; - this.statistics.statisticsData[entryName].totalTimeMeasurement = this.statistics.statisticsData[entryName].totalTimeMeasurement ? this.statistics.statisticsData[entryName].totalTimeMeasurement + entry.duration : entry.duration; - this.statistics.statisticsData[entryName].avgTimeMeasurement = this.statistics.statisticsData[entryName].totalTimeMeasurement / this.statistics.statisticsData[entryName].countTimeMeasurement; - Array.isArray(this.statistics.statisticsData[entryName].timeMeasurementSeries) ? this.statistics.statisticsData[entryName].timeMeasurementSeries.push(entry.duration) : this.statistics.statisticsData[entryName].timeMeasurementSeries = new CircularArray(DEFAULT_CIRCULAR_ARRAY_SIZE, entry.duration); - this.statistics.statisticsData[entryName].medTimeMeasurement = this.median(this.statistics.statisticsData[entryName].timeMeasurementSeries); - this.statistics.statisticsData[entryName].ninetyFiveThPercentileTimeMeasurement = this.percentile(this.statistics.statisticsData[entryName].timeMeasurementSeries, 95); - this.statistics.statisticsData[entryName].stdDevTimeMeasurement = this.stdDeviation(this.statistics.statisticsData[entryName].timeMeasurementSeries); + this.statistics.statisticsData.get(entryName).countTimeMeasurement = this.statistics.statisticsData.get(entryName)?.countTimeMeasurement ? this.statistics.statisticsData.get(entryName).countTimeMeasurement + 1 : 1; + this.statistics.statisticsData.get(entryName).currentTimeMeasurement = entry.duration; + this.statistics.statisticsData.get(entryName).minTimeMeasurement = this.statistics.statisticsData.get(entryName)?.minTimeMeasurement ? (this.statistics.statisticsData.get(entryName).minTimeMeasurement > entry.duration ? entry.duration : this.statistics.statisticsData.get(entryName).minTimeMeasurement) : entry.duration; + this.statistics.statisticsData.get(entryName).maxTimeMeasurement = this.statistics.statisticsData.get(entryName)?.maxTimeMeasurement ? (this.statistics.statisticsData.get(entryName).maxTimeMeasurement < entry.duration ? entry.duration : this.statistics.statisticsData.get(entryName).maxTimeMeasurement) : entry.duration; + this.statistics.statisticsData.get(entryName).totalTimeMeasurement = this.statistics.statisticsData.get(entryName)?.totalTimeMeasurement ? this.statistics.statisticsData.get(entryName).totalTimeMeasurement + entry.duration : entry.duration; + this.statistics.statisticsData.get(entryName).avgTimeMeasurement = this.statistics.statisticsData.get(entryName).totalTimeMeasurement / this.statistics.statisticsData.get(entryName).countTimeMeasurement; + Array.isArray(this.statistics.statisticsData.get(entryName).timeMeasurementSeries) ? this.statistics.statisticsData.get(entryName).timeMeasurementSeries.push(entry.duration) : this.statistics.statisticsData.get(entryName).timeMeasurementSeries = new CircularArray(DEFAULT_CIRCULAR_ARRAY_SIZE, entry.duration); + this.statistics.statisticsData.get(entryName).medTimeMeasurement = this.median(this.statistics.statisticsData.get(entryName).timeMeasurementSeries); + this.statistics.statisticsData.get(entryName).ninetyFiveThPercentileTimeMeasurement = this.percentile(this.statistics.statisticsData.get(entryName).timeMeasurementSeries, 95); + this.statistics.statisticsData.get(entryName).stdDevTimeMeasurement = this.stdDeviation(this.statistics.statisticsData.get(entryName).timeMeasurementSeries); if (Configuration.getPerformanceStorage().enabled) { parentPort.postMessage({ id: ChargingStationWorkerMessageEvents.PERFORMANCE_STATISTICS, data: this.statistics }); } diff --git a/src/performance/storage/JSONFileStorage.ts b/src/performance/storage/JSONFileStorage.ts index 92b4faae..4eb5680d 100644 --- a/src/performance/storage/JSONFileStorage.ts +++ b/src/performance/storage/JSONFileStorage.ts @@ -23,7 +23,19 @@ export class JSONFileStorage extends Storage { const fileData = fs.readFileSync(this.dbName, 'utf8'); const performanceRecords: Statistics[] = fileData ? JSON.parse(fileData) as Statistics[] : []; performanceRecords.push(performanceStatistics); - fs.writeFileSync(this.dbName, JSON.stringify(performanceRecords, null, 2), 'utf8'); + fs.writeFileSync(this.dbName, + JSON.stringify(performanceRecords, + (key, value) => { + if (value instanceof Map) { + return { + dataType: 'Map', + value: [...value] + }; + } + return value as Statistics; + }, + 2), + 'utf8'); } catch (error) { FileUtils.handleFileException(this.logPrefix, Constants.PERFORMANCE_RECORDS_FILETYPE, this.dbName, error); } diff --git a/src/types/Statistics.ts b/src/types/Statistics.ts index 120f258e..00c73052 100644 --- a/src/types/Statistics.ts +++ b/src/types/Statistics.ts @@ -21,5 +21,5 @@ export default interface Statistics { URI: string; createdAt: Date; updatedAt?: Date; - statisticsData: Record; + statisticsData: Map>; } -- 2.34.1