Current File : //lib/node_modules/pm2/node_modules/@pm2/io/build/main/src/metrics/v8.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const v8 = require("v8");
const module_1 = require("../utils/module");
const metricConfig_1 = require("../utils/metricConfig");
const debug_1 = require("debug");
const debug = debug_1.default('axm:v8');
class V8Metric {
    constructor(metricFeature) {
        this.unitKB = 'kB';
        this.allPossibleMetrics = {
            new_space: {
                name: 'New space used size',
                type: 'internal/v8/heap/space/new',
                unit: this.unitKB,
                historic: true
            },
            old_space: {
                name: 'Old space used size',
                type: 'internal/v8/heap/space/old',
                unit: this.unitKB,
                historic: true
            },
            map_space: {
                name: 'Map space used size',
                type: 'internal/v8/heap/space/map',
                unit: this.unitKB,
                historic: false
            },
            code_space: {
                name: 'Code space used size',
                type: 'internal/v8/heap/space/code',
                unit: this.unitKB,
                historic: false
            },
            large_object_space: {
                name: 'Large object space used size',
                type: 'internal/v8/heap/space/large',
                unit: this.unitKB,
                historic: false
            },
            total_physical_size: {
                name: 'Heap physical size',
                type: 'internal/v8/heap/physical',
                unit: 'kB',
                historic: false
            },
            total_heap_size: {
                name: 'Heap size',
                type: 'internal/v8/heap/used',
                unit: 'kB',
                historic: true
            },
            total_available_size: {
                name: 'Heap available size',
                type: 'internal/v8/heap/available',
                unit: 'kB',
                historic: true
            },
            total_heap_size_executable: {
                name: 'Heap size executable',
                type: 'internal/v8/heap/executable',
                unit: this.unitKB,
                historic: false
            },
            used_heap_size: {
                name: 'Used heap size',
                type: 'internal/v8/heap/used',
                unit: this.unitKB,
                historic: true
            },
            heap_size_limit: {
                name: 'Heap size limit',
                type: 'internal/v8/heap/limit',
                unit: this.unitKB,
                historic: true
            },
            malloced_memory: {
                name: 'Malloced memory',
                type: 'internal/v8/heap/malloced',
                unit: this.unitKB,
                historic: false
            },
            peak_malloced_memory: {
                name: 'Peak malloced memory',
                type: 'internal/v8/heap/peakmalloced',
                unit: this.unitKB,
                historic: false
            },
            does_zap_garbage: {
                name: 'Zap garbage',
                type: 'internal/v8/heap/zapgarbage',
                unit: '',
                historic: false
            }
        };
        this.allPossibleMetricsGC = {
            totalHeapSize: {
                name: 'GC Heap size',
                type: 'internal/v8/gc/heap/size',
                unit: this.unitKB,
                historic: true
            },
            totalHeapExecutableSize: {
                name: 'GC Executable heap size',
                type: 'internal/v8/gc/heap/executable',
                unit: this.unitKB,
                historic: false
            },
            usedHeapSize: {
                name: 'GC Used heap size',
                type: 'internal/v8/gc/heap/used',
                unit: this.unitKB,
                historic: true
            },
            heapSizeLimit: {
                name: 'GC heap size limit',
                type: 'internal/v8/gc/heap/limit',
                unit: this.unitKB,
                historic: false
            },
            totalPhysicalSize: {
                name: 'GC physical size',
                type: 'internal/v8/gc/heap/physical',
                unit: this.unitKB,
                historic: false
            },
            totalAvailableSize: {
                name: 'GC available size',
                type: 'internal/v8/gc/heap/available',
                unit: this.unitKB,
                historic: false
            },
            mallocedMemory: {
                name: 'GC malloced memory',
                type: 'internal/v8/gc/heap/malloced',
                unit: this.unitKB,
                historic: false
            },
            peakMallocedMemory: {
                name: 'GC peak malloced memory',
                type: 'internal/v8/gc/heap/peakmalloced',
                unit: this.unitKB,
                historic: false
            },
            gcType: {
                name: 'GC Type',
                type: 'internal/v8/gc/type',
                historic: false
            },
            gcPause: {
                name: 'GC Pause',
                type: 'internal/v8/gc/pause',
                unit: 'ms',
                historic: false
            }
        };
        this.defaultConf = {
            new_space: true,
            old_space: true,
            map_space: true,
            code_space: true,
            large_object_space: true,
            total_heap_size: true,
            total_heap_size_executable: true,
            used_heap_size: true,
            heap_size_limit: true,
            GC: {
                totalHeapSize: true,
                totalHeapExecutableSize: true,
                usedHeapSize: true,
                gcType: true,
                gcPause: true
            }
        };
        this.TIME_INTERVAL = 1000;
        this.metricFeature = metricFeature;
    }
    init(config) {
        config = metricConfig_1.default.getConfig(config, this.defaultConf);
        let heapProbes;
        const self = this;
        if (v8.hasOwnProperty('getHeapSpaceStatistics') && v8.hasOwnProperty('getHeapStatistics')) {
            heapProbes = metricConfig_1.default.initProbes(this.allPossibleMetrics, config, this.metricFeature);
        }
        this.timer = setInterval(function () {
            if (v8.hasOwnProperty('getHeapSpaceStatistics')) {
                const data = v8.getHeapSpaceStatistics();
                for (let i = 0; i < data.length; i++) {
                    const item = data[i];
                    if (heapProbes.hasOwnProperty(item.space_name)) {
                        heapProbes[item.space_name].set(Math.round(item.space_used_size / 1000));
                    }
                }
            }
            if (v8.hasOwnProperty('getHeapStatistics')) {
                const heapStats = v8.getHeapStatistics();
                metricConfig_1.default.setProbesValue(this.allPossibleMetrics, heapStats, heapProbes, self.unitKB);
            }
        }.bind(this), this.TIME_INTERVAL);
        this.timer.unref();
        module_1.default.detectModule('gc-stats', (err, gcPath) => {
            if (err) {
                return false;
            }
            return this._sendGCStats(gcPath, config.GC);
        });
    }
    destroy() {
        clearInterval(this.timer);
    }
    _sendGCStats(gcPath, config) {
        let gc;
        try {
            gc = (require(gcPath))();
        }
        catch (e) {
            debug('error when requiring gc-stats on path', gcPath);
            debug(e);
            return false;
        }
        config = metricConfig_1.default.getConfig(config, this.defaultConf.GC);
        const gcProbes = metricConfig_1.default.initProbes(this.allPossibleMetricsGC, config, this.metricFeature);
        const self = this;
        gc.on('stats', (stats) => {
            metricConfig_1.default.setProbesValue(this.allPossibleMetricsGC, stats.after, gcProbes, self.unitKB);
            gcProbes['gcType'].set(stats.gctype);
            gcProbes['gcPause'].set(Math.round(stats.pause / 1000000)); // convert to milliseconds (cause pauseMs seems to use Math.floor)
        });
    }
}
exports.default = V8Metric;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidjguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbWV0cmljcy92OC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHlCQUF3QjtBQUN4Qiw0Q0FBbUM7QUFHbkMsd0RBQWdEO0FBRWhELGlDQUF5QjtBQUN6QixNQUFNLEtBQUssR0FBRyxlQUFLLENBQUMsUUFBUSxDQUFDLENBQUE7QUFFN0I7SUFnTEUsWUFBYSxhQUE2QjtRQTFLbEMsV0FBTSxHQUFHLElBQUksQ0FBQTtRQUViLHVCQUFrQixHQUFHO1lBQzNCLFNBQVMsRUFBRTtnQkFDVCxJQUFJLEVBQUUscUJBQXFCO2dCQUMzQixJQUFJLEVBQUUsNEJBQTRCO2dCQUNsQyxJQUFJLEVBQUUsSUFBSSxDQUFDLE1BQU07Z0JBQ2pCLFFBQVEsRUFBRSxJQUFJO2FBQ2Y7WUFDRCxTQUFTLEVBQUU7Z0JBQ1QsSUFBSSxFQUFFLHFCQUFxQjtnQkFDM0IsSUFBSSxFQUFFLDRCQUE0QjtnQkFDbEMsSUFBSSxFQUFFLElBQUksQ0FBQyxNQUFNO2dCQUNqQixRQUFRLEVBQUUsSUFBSTthQUNmO1lBQ0QsU0FBUyxFQUFFO2dCQUNULElBQUksRUFBRSxxQkFBcUI7Z0JBQzNCLElBQUksRUFBRSw0QkFBNEI7Z0JBQ2xDLElBQUksRUFBRSxJQUFJLENBQUMsTUFBTTtnQkFDakIsUUFBUSxFQUFFLEtBQUs7YUFDaEI7WUFDRCxVQUFVLEVBQUU7Z0JBQ1YsSUFBSSxFQUFFLHNCQUFzQjtnQkFDNUIsSUFBSSxFQUFFLDZCQUE2QjtnQkFDbkMsSUFBSSxFQUFFLElBQUksQ0FBQyxNQUFNO2dCQUNqQixRQUFRLEVBQUUsS0FBSzthQUNoQjtZQUNELGtCQUFrQixFQUFFO2dCQUNsQixJQUFJLEVBQUUsOEJBQThCO2dCQUNwQyxJQUFJLEVBQUUsOEJBQThCO2dCQUNwQyxJQUFJLEVBQUUsSUFBSSxDQUFDLE1BQU07Z0JBQ2pCLFFBQVEsRUFBRSxLQUFLO2FBQ2hCO1lBQ0QsbUJBQW1C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