@instana/shared-metrics 4.26.3 → 4.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/package.json +3 -3
- package/src/dependencies.js +26 -6
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,25 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [4.27.0](https://github.com/instana/nodejs/compare/v4.26.4...v4.27.0) (2025-10-23)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* **shared-metrics:** reduce memory consumption with many dependencies ([#2088](https://github.com/instana/nodejs/issues/2088)) ([7e0b029](https://github.com/instana/nodejs/commit/7e0b029331a6657c64b29e875a529d03952e7414))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## [4.26.4](https://github.com/instana/nodejs/compare/v4.26.3...v4.26.4) (2025-10-21)
|
|
18
|
+
|
|
19
|
+
**Note:** Version bump only for package @instana/shared-metrics
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
6
25
|
## [4.26.3](https://github.com/instana/nodejs/compare/v4.26.2...v4.26.3) (2025-10-21)
|
|
7
26
|
|
|
8
27
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@instana/shared-metrics",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.27.0",
|
|
4
4
|
"description": "Internal metrics plug-in package for Node.js monitoring with Instana",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Bastian Krol",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
},
|
|
60
60
|
"license": "MIT",
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@instana/core": "4.
|
|
62
|
+
"@instana/core": "4.27.0",
|
|
63
63
|
"detect-libc": "^2.1.2",
|
|
64
64
|
"event-loop-lag": "^1.4.0",
|
|
65
65
|
"semver": "^7.7.3",
|
|
@@ -72,5 +72,5 @@
|
|
|
72
72
|
"event-loop-stats": "1.4.1",
|
|
73
73
|
"gcstats.js": "1.0.0"
|
|
74
74
|
},
|
|
75
|
-
"gitHead": "
|
|
75
|
+
"gitHead": "dd557cc7ae7bd26a2399ffc821031969cdb8d5a1"
|
|
76
76
|
}
|
package/src/dependencies.js
CHANGED
|
@@ -27,6 +27,8 @@ exports.MAX_DEPENDENCIES = 750;
|
|
|
27
27
|
/** @type {string} */
|
|
28
28
|
exports.payloadPrefix = 'dependencies';
|
|
29
29
|
|
|
30
|
+
const MAX_DEPTH_NODE_MODULES = 2;
|
|
31
|
+
|
|
30
32
|
/** @type {Object.<string, string>} */
|
|
31
33
|
const preliminaryPayload = {};
|
|
32
34
|
|
|
@@ -87,7 +89,13 @@ exports.activate = function activate() {
|
|
|
87
89
|
* @param {string} packageJsonPath
|
|
88
90
|
*/
|
|
89
91
|
function addAllDependencies(dependencyDir, started, packageJsonPath) {
|
|
90
|
-
addDependenciesFromDir(dependencyDir, () => {
|
|
92
|
+
addDependenciesFromDir(dependencyDir, 0, () => {
|
|
93
|
+
// TODO: This check happens AFTER we have already collected the dependencies.
|
|
94
|
+
// This is quiet useless for a large dependency tree, because we consume resources to collect
|
|
95
|
+
// all the dependencies (fs.stats, fs.readFile etc), but then discard most of them here.
|
|
96
|
+
// This is only critical for a very large number of defined dependencies in package.json (vertical).
|
|
97
|
+
// NOTE: There is an extra protection in the `addDependenciesFromDir` fn to
|
|
98
|
+
// limit the depth of traversing node_modules.
|
|
91
99
|
if (Object.keys(preliminaryPayload).length <= exports.MAX_DEPENDENCIES) {
|
|
92
100
|
// @ts-ignore: Cannot redeclare exported variable 'currentPayload'
|
|
93
101
|
exports.currentPayload = preliminaryPayload;
|
|
@@ -114,7 +122,11 @@ function addAllDependencies(dependencyDir, started, packageJsonPath) {
|
|
|
114
122
|
* @param {string} dependencyDir
|
|
115
123
|
* @param {() => void} callback
|
|
116
124
|
*/
|
|
117
|
-
function addDependenciesFromDir(dependencyDir, callback) {
|
|
125
|
+
function addDependenciesFromDir(dependencyDir, currentDepth = 0, callback) {
|
|
126
|
+
if (currentDepth >= MAX_DEPTH_NODE_MODULES) {
|
|
127
|
+
return callback();
|
|
128
|
+
}
|
|
129
|
+
|
|
118
130
|
fs.readdir(dependencyDir, (readDirErr, dependencies) => {
|
|
119
131
|
if (readDirErr || !dependencies) {
|
|
120
132
|
logger.warn(`Cannot analyse dependencies due to ${readDirErr?.message}`);
|
|
@@ -140,11 +152,13 @@ function addDependenciesFromDir(dependencyDir, callback) {
|
|
|
140
152
|
|
|
141
153
|
filteredDependendencies.forEach(dependency => {
|
|
142
154
|
if (dependency.indexOf('@') === 0) {
|
|
143
|
-
|
|
155
|
+
// NOTE: We do not increase currentDepth because scoped packages are just a folder containing more packages.
|
|
156
|
+
addDependenciesFromDir(path.join(dependencyDir, dependency), currentDepth, () => {
|
|
144
157
|
countDownLatch.countDown();
|
|
145
158
|
});
|
|
146
159
|
} else {
|
|
147
160
|
const fullDirPath = path.join(dependencyDir, dependency);
|
|
161
|
+
|
|
148
162
|
// Only check directories. For example, yarn adds a .yarn-integrity file to /node_modules/ which we need to
|
|
149
163
|
// exclude, otherwise we get a confusing "Failed to identify version of .yarn-integrity dependency due to:
|
|
150
164
|
// ENOTDIR: not a directory, open '.../node_modules/.yarn-integrity/package.json'." in the logs.
|
|
@@ -159,7 +173,7 @@ function addDependenciesFromDir(dependencyDir, callback) {
|
|
|
159
173
|
return;
|
|
160
174
|
}
|
|
161
175
|
|
|
162
|
-
addDependency(dependency, fullDirPath, countDownLatch);
|
|
176
|
+
addDependency(dependency, fullDirPath, countDownLatch, currentDepth);
|
|
163
177
|
});
|
|
164
178
|
}
|
|
165
179
|
});
|
|
@@ -173,9 +187,11 @@ function addDependenciesFromDir(dependencyDir, callback) {
|
|
|
173
187
|
* @param {string} dependency
|
|
174
188
|
* @param {string} dependencyDirPath
|
|
175
189
|
* @param {import('./util/CountDownLatch')} countDownLatch
|
|
190
|
+
* @param {number} currentDepth
|
|
176
191
|
*/
|
|
177
|
-
function addDependency(dependency, dependencyDirPath, countDownLatch) {
|
|
192
|
+
function addDependency(dependency, dependencyDirPath, countDownLatch, currentDepth) {
|
|
178
193
|
const packageJsonPath = path.join(dependencyDirPath, 'package.json');
|
|
194
|
+
|
|
179
195
|
fs.readFile(packageJsonPath, { encoding: 'utf8' }, (err, contents) => {
|
|
180
196
|
if (err && err.code === 'ENOENT') {
|
|
181
197
|
// This directory does not contain a package json. This happens for example for node_modules/.cache etc.
|
|
@@ -198,19 +214,23 @@ function addDependency(dependency, dependencyDirPath, countDownLatch) {
|
|
|
198
214
|
preliminaryPayload[parsedPackageJson.name] = parsedPackageJson.version;
|
|
199
215
|
}
|
|
200
216
|
} catch (parseErr) {
|
|
217
|
+
// TODO: countDownLatch.countDown(); needs to be called here too?
|
|
218
|
+
// countDownLatch.countDown();
|
|
201
219
|
return logger.info(
|
|
202
220
|
`Failed to identify version of ${dependency} dependency due to: ${parseErr?.message}.
|
|
203
221
|
This means that you will not be able to see details about this dependency within Instana.`
|
|
204
222
|
);
|
|
205
223
|
}
|
|
206
224
|
|
|
225
|
+
// NOTE: The dependency metric collector does not respect if the node_modules are dev dependencies or production
|
|
226
|
+
// dependencies. It collects all dependencies that are installed in the node_modules folder.
|
|
207
227
|
const potentialNestedNodeModulesFolder = path.join(dependencyDirPath, 'node_modules');
|
|
208
228
|
fs.stat(potentialNestedNodeModulesFolder, (statErr, stats) => {
|
|
209
229
|
if (statErr || !stats.isDirectory()) {
|
|
210
230
|
countDownLatch.countDown();
|
|
211
231
|
return;
|
|
212
232
|
}
|
|
213
|
-
addDependenciesFromDir(potentialNestedNodeModulesFolder, () => {
|
|
233
|
+
addDependenciesFromDir(potentialNestedNodeModulesFolder, currentDepth + 1, () => {
|
|
214
234
|
countDownLatch.countDown();
|
|
215
235
|
});
|
|
216
236
|
});
|