Skip to content

Commit a569bab

Browse files
authored
Merge pull request #1238 from harrider/users/harrider/add-heap-stats-logging
Add heap stats logging to Service
2 parents 8368325 + 574ed37 commit a569bab

File tree

6 files changed

+106
-4
lines changed

6 files changed

+106
-4
lines changed

app.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ function createApp(config) {
100100
crawlerSecret
101101
)
102102

103+
// enable heap stats logging at an interval if configured
104+
const trySetHeapLoggingAtInterval = require('./lib/heapLogger')
105+
trySetHeapLoggingAtInterval(config, logger)
106+
103107
const app = express()
104108
app.use(cors())
105109
app.options('*', cors())

bin/config.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,5 +100,9 @@ module.exports = {
100100
crawlerKey: config.get('APPINSIGHTS_CRAWLER_APIKEY')
101101
},
102102
appVersion: config.get('APP_VERSION'),
103-
buildsha: config.get('BUILD_SHA')
103+
buildsha: config.get('BUILD_SHA'),
104+
heapstats: {
105+
logHeapstats: config.get('LOG_NODE_HEAPSTATS'),
106+
logInverval: config.get('LOG_NODE_HEAPSTATS_INTERVAL_MS')
107+
}
104108
}

full.env.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,9 @@
4747
"CRAWLER_QUEUE_PROVIDER": "memory",
4848
"CRAWLER_SERVICE_PORT": "5000",
4949
"CRAWLER_GITHUB_TOKEN": "< GitHub PAT here >",
50-
"SCANCODE_HOME": "< ScanCode install location e.g., c:\\installs\\scancode-toolkit-2.2.1 >"
50+
"SCANCODE_HOME": "< ScanCode install location e.g., c:\\installs\\scancode-toolkit-2.2.1 >",
51+
52+
"========== Heapstats Logging settings (OPTIONAL) ==========": "",
53+
"LOG_NODE_HEAPSTATS": "<true|false>",
54+
"LOG_NODE_HEAPSTATS_INTERVAL_MS": "<time_in_milliseconds (e.g. '30000')>"
5155
}

lib/heapLogger.js

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
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

minimal.env.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,9 @@
88

99
"========== Service Curation settings ==========": "",
1010
"CURATION_GITHUB_REPO": "sample-curated-data",
11-
"CURATION_GITHUB_TOKEN": "<GitHub token here>"
11+
"CURATION_GITHUB_TOKEN": "<GitHub token here>",
12+
13+
"========== Heapstats Logging settings (OPTIONAL) ==========": "",
14+
"LOG_NODE_HEAPSTATS": "<true|false>",
15+
"LOG_NODE_HEAPSTATS_INTERVAL_MS": "<time_in_milliseconds (e.g. '30000')>"
1216
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"prettier:check": "prettier . --check",
1313
"prettier:write": "prettier . --write",
1414
"dev": "nodemon ./bin/www",
15-
"start": "node ./bin/www",
15+
"start": "node --max-old-space-size=8192 ./bin/www",
1616
"postinstall": "patch-package"
1717
},
1818
"license": "MIT",

0 commit comments

Comments
 (0)