diff --git a/package.json b/package.json index 187c9e5..9abbf35 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "compile_commands": "node-gyp configure --release -- -f gyp.generator.compile_commands_json.py && mv Release/compile_commands.json ./", "rebuild": "node-gyp rebuild -j max", "lint": "node scripts/check_licenses.js && eslint .", - "test": "mocha 'test/**/*.spec.js' && node test/main" + "test": "mocha -n expose-gc 'test/**/*.spec.js' && node test/main" }, "keywords": [ "datadog", @@ -34,7 +34,6 @@ "eslint-plugin-node": "^11.1.0", "eslint-plugin-promise": "^5.1.0", "eslint-plugin-standard": "^5.0.0", - "mocha": "^9.0.3", - "nan": "^2.17.0" + "mocha": "^9.0.3" } } diff --git a/src/metrics/GarbageCollection.hpp b/src/metrics/GarbageCollection.hpp index c3f5cab..42d158e 100644 --- a/src/metrics/GarbageCollection.hpp +++ b/src/metrics/GarbageCollection.hpp @@ -13,6 +13,7 @@ using Napi::Env; using Napi::Object; using Napi::Value; +using Napi::VersionManagement; namespace datadog { class GarbageCollection { @@ -27,28 +28,14 @@ namespace datadog { Value ToJSON(Env env); private: std::map pause_; + Histogram pause_all_; std::map types_; uint64_t start_time_; + + const char* ToType(Env env, v8::GCType); }; GarbageCollection::GarbageCollection() { -#if NODE_MODULE_VERSION >= 108 - types_[1] = "scavenge"; - types_[2] = "minor_mark_compact"; - types_[4] = "mark_sweep_compact"; - types_[8] = "incremental_marking"; - types_[16] = "process_weak_callbacks"; - types_[31] = "all"; -#else - types_[1] = "scavenge"; - types_[2] = "mark_sweep_compact"; - types_[3] = "all"; - types_[4] = "incremental_marking"; - types_[8] = "process_weak_callbacks"; - types_[15] = "all"; -#endif - - pause_[v8::GCType::kGCTypeAll] = Histogram(); start_time_ = uv_hrtime(); } @@ -86,15 +73,56 @@ namespace datadog { } pause_[type].add(usage); - pause_[v8::GCType::kGCTypeAll].add(usage); + pause_all_.add(usage); } Value GarbageCollection::ToJSON(Env env) { Object gc = Object::New(env); + for (auto &it : pause_) { - gc.Set(types_[it.first], it.second.ToJSON(env)); + auto type = this->ToType(env, it.first); + gc.Set(type, it.second.ToJSON(env)); it.second.reset(); } + + gc.Set("all", pause_all_.ToJSON(env)); + pause_all_.reset(); + return gc; } + + const char* GarbageCollection::ToType(Env env, v8::GCType type) { + auto version = VersionManagement::GetNodeVersion(env); + auto type_bit = static_cast(type); + + if (version->major >= 22) { + switch (type_bit) { + case 1: return "scavenge"; + case 2: return "minor_mark_sweep"; + case 4: return "mark_sweep_compact"; // Deprecated, might be removed soon. + case 8: return "incremental_marking"; + case 16: return "process_weak_callbacks"; + case 31: return "all"; + } + } else if (version->major >= 18) { + switch (type_bit) { + case 1: return "scavenge"; + case 2: return "minor_mark_compact"; + case 4: return "mark_sweep_compact"; + case 8: return "incremental_marking"; + case 16: return "process_weak_callbacks"; + case 31: return "all"; + } + } else { + switch (type_bit) { + case 1: return "scavenge"; + case 2: return "mark_sweep_compact"; + case 4: return "incremental_marking"; + case 8: return "process_weak_callbacks"; + case 15: return "all"; + } + } + + return "unknown"; + } } diff --git a/test/main.js b/test/main.js index 1ff6ea7..b4bfad7 100644 --- a/test/main.js +++ b/test/main.js @@ -3,8 +3,10 @@ const path = require('path') const { Worker } = require('worker_threads') -const worker = new Worker(path.join(__dirname, 'worker.js')) +for (let i = 0; i < 100; i++) { + const worker = new Worker(path.join(__dirname, 'worker.js')) -setTimeout(() => { - worker.terminate() -}, 1000) + setTimeout(() => { + worker.terminate() + }, 1000) +} diff --git a/test/metrics.spec.js b/test/metrics.spec.js index 4463ad7..5ff7ac1 100644 --- a/test/metrics.spec.js +++ b/test/metrics.spec.js @@ -27,6 +27,8 @@ describe('metrics', () => { }) it('should collect stats', () => { + globalThis.gc() + const stats = nativeMetrics.stats() expect(stats).to.have.property('cpu') @@ -53,6 +55,7 @@ describe('metrics', () => { expect(stats).to.have.property('gc') expect(stats.gc).to.have.property('all') + expect(stats.gc).to.not.have.property('unknown') expect(stats.gc.all).to.have.property('min') expect(stats.gc.all.min).to.be.a('number') expect(stats.gc.all).to.have.property('max') diff --git a/yarn.lock b/yarn.lock index 7f2d862..fac24a2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1178,11 +1178,6 @@ ms@2.1.3: resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -nan@^2.17.0: - version "2.17.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb" - integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ== - nanoid@3.3.1: version "3.3.1" resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz"