|
| 1 | +// (c) Copyright 2024, Microsoft and ClearlyDefined contributors. Licensed under the MIT license. |
| 2 | +// SPDX-License-Identifier: MIT |
| 3 | + |
| 4 | +// =================================================== |
| 5 | +// Log the heap statistics at regular intervals |
| 6 | +// =================================================== |
| 7 | +// NOTE: set 'LOG_NODE_HEAPSTATS' env var to 'true' to log heap stats |
| 8 | +// NOTE: set 'LOG_NODE_HEAPSTATS_INTERVAL_MS' env var to '<time_in_milliseconds>' for logging interval |
| 9 | +// NOTE: To better understand heap stats being logged, check: |
| 10 | +// - https://nodejs.org/docs/v22.12.0/api/v8.html#v8getheapspacestatistics |
| 11 | +// - https://nodejs.org/docs/v22.12.0/api/v8.html#v8getheapstatistics |
| 12 | +function trySetHeapLoggingAtInterval(config, logger) { |
| 13 | + logger.debug('heapLogger.js :: Entered "trySetHeapLoggingAtInterval"...') |
| 14 | + |
| 15 | + const shouldLogHeapstats = config.heapstats.logHeapstats |
| 16 | + ? config.heapstats.logHeapstats.toLowerCase() === 'true' |
| 17 | + : false |
| 18 | + |
| 19 | + logger.debug(`heapLogger.js :: "shouldLogHeapstats" set to "${shouldLogHeapstats}"`) |
| 20 | + |
| 21 | + if (shouldLogHeapstats) { |
| 22 | + const v8 = require('v8') |
| 23 | + |
| 24 | + const addCommas = num => Number(num).toLocaleString() |
| 25 | + const isNumeric = num => !isNaN(Number(num)) |
| 26 | + |
| 27 | + // Set the heapstats logging interval |
| 28 | + const maybeInterval = config.heapstats.logInverval |
| 29 | + const heapStatsInverval = maybeInterval && isNumeric(maybeInterval) ? maybeInterval : 30000 |
| 30 | + |
| 31 | + logger.debug(`heapLogger.js :: heap stats logging interval will be "${heapStatsInverval}" ms`) |
| 32 | + |
| 33 | + // Function to log the heap space statistics |
| 34 | + const logHeapSpaceStats = () => { |
| 35 | + // Get the current timestamp |
| 36 | + const currentTimestamp = new Date().toISOString() |
| 37 | + |
| 38 | + // Get the heap space statistics |
| 39 | + const heapSpaceStats = v8.getHeapSpaceStatistics() |
| 40 | + |
| 41 | + heapSpaceStats.forEach(space => { |
| 42 | + const heapStatsMessage = |
| 43 | + `[${currentTimestamp}] Heap Space Statistics: ` + |
| 44 | + `Space Name: '${space.space_name}', ` + |
| 45 | + `Space Size: '${addCommas(space.space_size)}' bytes, ` + |
| 46 | + `Space Used Size: '${addCommas(space.space_used_size)}' bytes, ` + |
| 47 | + `Space Available Size: '${addCommas(space.space_available_size)}' bytes, ` + |
| 48 | + `Physical Space Size: '${addCommas(space.physical_space_size)}' bytes` + |
| 49 | + '\n--------------------------' |
| 50 | + |
| 51 | + logger.info(heapStatsMessage) |
| 52 | + }) |
| 53 | + |
| 54 | + // Get the heap statistics |
| 55 | + const heapStats = v8.getHeapStatistics() |
| 56 | + |
| 57 | + const heapStatsMessage = |
| 58 | + `[${currentTimestamp}] Heap Statistics: ` + |
| 59 | + `Total Heap Size: '${addCommas(heapStats.total_heap_size)}' bytes, ` + |
| 60 | + `Total Heap Size Executable: '${addCommas(heapStats.total_heap_size_executable)}' bytes, ` + |
| 61 | + `Total Physical Size: '${addCommas(heapStats.total_physical_size)}' bytes, ` + |
| 62 | + `Total Available Size: '${addCommas(heapStats.total_available_size)}' bytes, ` + |
| 63 | + `Used Heap Size: '${addCommas(heapStats.used_heap_size)}' bytes, ` + |
| 64 | + `Heap Size Limit: '${addCommas(heapStats.heap_size_limit)}' bytes` + |
| 65 | + '\n--------------------------' |
| 66 | + |
| 67 | + logger.info(heapStatsMessage) |
| 68 | + } |
| 69 | + |
| 70 | + // Only run if not in a test environment |
| 71 | + if (process.argv.every(arg => !arg.includes('mocha'))) { |
| 72 | + logger.debug(`heapLogger.js :: setting heap stats logging at "${heapStatsInverval}" ms interval...`) |
| 73 | + |
| 74 | + // Set the interval to log the heap space statistics |
| 75 | + setInterval(logHeapSpaceStats, heapStatsInverval) |
| 76 | + |
| 77 | + logger.debug(`heapLogger.js :: set heap stats logging at "${heapStatsInverval}" ms interval.`) |
| 78 | + } |
| 79 | + } else { |
| 80 | + logger.debug('heapLogger.js :: heap stats logging not enabled.') |
| 81 | + } |
| 82 | + |
| 83 | + logger.debug('heapLogger.js :: Exiting "trySetHeapLoggingAtInterval".') |
| 84 | +} |
| 85 | + |
| 86 | +module.exports = trySetHeapLoggingAtInterval |
0 commit comments