Current File : //lib/node_modules/pm2/node_modules/@pm2/io/build/main/src/pmx.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const notify_1 = require("./features/notify");
const metrics_1 = require("./features/metrics");
const actions_1 = require("./features/actions");
const events_1 = require("./features/events");
const merge = require("deepmerge");
const configuration_1 = require("./configuration");
const metricConfig_1 = require("./utils/metricConfig");
const debug_1 = require("debug");
const fs = require("fs");
const cluster = require("cluster");
const serviceManager_1 = require("./serviceManager");
const transport_1 = require("./services/transport");
const debug = debug_1.default('PM2-IO-APM');
class TransactionConfig {
}
class MetricsConfig {
}
class ActionsConfig {
}
class IOConfig {
}
class PMX {
    constructor() {
        this.notifyFeature = new notify_1.NotifyFeature();
        this.metricsFeature = new metrics_1.default();
        this.actionsFeature = new actions_1.default(!cluster.isWorker);
        this.eventsFeature = new events_1.default();
        const eventLoopInspector = require('event-loop-inspector')(true);
        serviceManager_1.ServiceManager.set('eventLoopService', {
            inspector: eventLoopInspector
        });
        serviceManager_1.ServiceManager.set('transport', new transport_1.default());
    }
    getInitialConfig() {
        return this.initialConfig;
    }
    init(config, force) {
        let notifyOptions = notify_1.NotifyOptionsDefault;
        let configMetrics = {};
        if (!config) {
            config = new IOConfig();
        }
        if (process.env.PMX_FORCE_UPDATE) {
            const IO_KEY = Symbol.for('@pm2/io');
            const globalSymbols = Object.getOwnPropertySymbols(global);
            const alreadyInstanciated = (globalSymbols.indexOf(IO_KEY) > -1);
            if (alreadyInstanciated) {
                global[IO_KEY].destroy();
            }
            global[IO_KEY] = this;
        }
        if (config.level) {
            notifyOptions.level = config.level;
        }
        if (config.catchExceptions) {
            notifyOptions.catchExceptions = config.catchExceptions;
        }
        if (config.metrics) {
            configMetrics = config.metrics;
        }
        ((_) => tslib_1.__awaiter(this, void 0, void 0, function* () {
            // Transport
            if (config.standalone && config.publicKey && config.secretKey && config.appName) {
                yield serviceManager_1.ServiceManager.get('transport').initStandalone({
                    publicKey: config.publicKey,
                    secretKey: config.secretKey,
                    appName: config.appName,
                    serverName: config.serverName,
                    sendLogs: config.sendLogs
                });
            }
            else {
                serviceManager_1.ServiceManager.get('transport').init();
            }
            // Configuration
            this.backwardConfigConversion(config);
            this.notifyFeature.init(notifyOptions);
            this.metricsFeature.init(config.metrics, force);
            this.actionsFeature.init(config.actions, force);
            this.actionsFeature.initListener();
            configuration_1.default.init(config);
            this.initialConfig = config;
        }))();
        return this;
    }
    destroy() {
        if (this.metricsFeature)
            this.metricsFeature.destroy();
        if (this.actionsFeature)
            this.actionsFeature.destroy();
        if (this.notifyFeature)
            this.notifyFeature.destroy();
    }
    notifyError(err, context) {
        let level = 'info';
        if (context && context.level) {
            level = context.level;
        }
        this.notifyFeature.notifyError(err, level);
    }
    metrics(metrics) {
        const res = {};
        let allMetrics = [];
        if (!Array.isArray(metrics)) {
            allMetrics[0] = metrics;
        }
        else {
            allMetrics = metrics;
        }
        for (let i = 0; i < allMetrics.length; i++) {
            const currentMetric = allMetrics[i];
            if (!currentMetric || !currentMetric.hasOwnProperty('name') || !currentMetric.hasOwnProperty('type')) {
                console.warn(`Metric can't be initialized : missing some properties !`);
                console.warn('name => required');
                console.warn('type => required');
                console.warn('id => optional');
                console.warn('unit => optional');
                console.warn('value => optional');
                console.warn('historic => optional');
                console.warn('agg_type => optional');
                console.warn('measurement => optional');
                continue;
            }
            // escape spaces and special characters from metric's name
            const metricKey = currentMetric.name.replace(/ /g, '_').replace(/[^\w\s]/gi, '');
            const type = currentMetric.type;
            currentMetric.type = currentMetric.id;
            delete currentMetric.id;
            if (typeof this.metricsFeature[type] !== 'function') {
                console.warn(`Metric ${currentMetric.name} cant be initialized : unknown type ${type} !`);
                continue;
            }
            res[metricKey] = this.metricsFeature[type](currentMetric);
        }
        return res;
    }
    histogram(config) {
        config = metricConfig_1.default.buildConfig(config);
        return this.metricsFeature['histogram'](config);
    }
    metric(config) {
        config = metricConfig_1.default.buildConfig(config);
        return this.metricsFeature['metric'](config);
    }
    counter(config) {
        config = metricConfig_1.default.buildConfig(config);
        return this.metricsFeature['counter'](config);
    }
    meter(config) {
        config = metricConfig_1.default.buildConfig(config);
        return this.metricsFeature['meter'](config);
    }
    action(name, opts, fn) {
        if (typeof name === 'object') {
            opts = name.opts;
            fn = name.action;
            name = name.name;
        }
        this.actionsFeature.action(name, opts, fn);
        // Only listen if transporter wasn't initiated (no pmx.init())
        if (!serviceManager_1.ServiceManager.get('transport').initiated) {
            this.actionsFeature.initListener();
        }
    }
    scopedAction(name, fn) {
        this.actionsFeature.scopedAction(name, fn);
        // Only listen if transporter wasn't initiated (no pmx.init())
        if (!serviceManager_1.ServiceManager.get('transport').initiated) {
            this.actionsFeature.initListener();
        }
    }
    transpose(variableName, reporter) {
        this.metricsFeature.transpose(variableName, reporter);
    }
    onExit(callback) {
        if (callback && typeof callback === 'function') {
            const onExit = require('signal-exit');
            return onExit(callback);
        }
    }
    // -----------------------------------------------------------
    // Retro compatibility
    // -----------------------------------------------------------
    probe() {
        return {
            histogram: (histogram) => {
                return this.genericBackwardConversion(histogram, 'histogram');
            },
            meter: (meter) => {
                return this.genericBackwardConversion(meter, 'meter');
            },
            metric: (metric) => {
                return this.genericBackwardConversion(metric, 'metric');
            },
            counter: (counter) => {
                return this.genericBackwardConversion(counter, 'counter');
            },
            transpose: (variableName, reporter) => {
                this.transpose(variableName, reporter);
            }
        };
    }
    emit(name, data) {
        this.eventsFeature.emit(name, data);
    }
    emitEvent(name, data) {
        this.eventsFeature.emit(name, data);
    }
    notify(notification) {
        if (!(notification instanceof Error)) {
            notification = new Error(notification);
        }
        this.notifyFeature.notifyError(notification);
    }
    getPID(file) {
        if (typeof (file) === 'number')
            return file;
        return parseInt(fs.readFileSync(file).toString(), 10);
    }
    initModule(opts, cb) {
        if (!opts)
            opts = {};
        if (opts.reference) {
            opts.name = opts.reference;
            delete opts.reference;
        }
        opts = merge({
            widget: {}
        }, opts);
        opts.widget = merge({
            type: 'generic',
            logo: 'https://app.keymetrics.io/img/logo/keymetrics-300.png',
            theme: ['#111111', '#1B2228', '#807C7C', '#807C7C']
        }, opts.widget);
        opts.isModule = true;
        opts = configuration_1.default.init(opts);
        if (cb && typeof (cb) === 'function')
            return cb(null, opts);
        return opts;
    }
    expressErrorHandler() {
        return this.notifyFeature.expressErrorHandler();
    }
    genericBackwardConversion(object, type) {
        if (typeof object !== 'object') {
            console.error('Parameter should be an object');
            return null;
        }
        object.type = type;
        // escape spaces and special characters from metric's name
        const metricKey = object.name.replace(/ /g, '_').replace(/[^\w\s]/gi, '');
        return this.metrics(object)[metricKey];
    }
    backwardConfigConversion(config) {
        // ------------------------------------------
        // Network
        // ------------------------------------------
        if (config.hasOwnProperty('network') || config.hasOwnProperty('ports')) {
            const networkConf = {};
            if (config.hasOwnProperty('network')) {
                networkConf.traffic = Boolean(config.network);
                delete config.network;
            }
            if (config.hasOwnProperty('ports')) {
                networkConf.ports = Boolean(config.ports);
                delete config.ports;
            }
            this.initMetricsConf(config);
            config.metrics.network = networkConf;
        }
        // ------------------------------------------
        // V8
        // ------------------------------------------
        if (config.hasOwnProperty('v8')) {
            this.initMetricsConf(config);
            config.metrics.v8 = config.v8;
            delete config.v8;
        }
        // ------------------------------------------
        // transactions
        // ------------------------------------------
        if (config.hasOwnProperty('transactions') || config.hasOwnProperty('http')) {
            this.initMetricsConf(config);
            config.metrics.transaction = new TransactionConfig();
            if (config.hasOwnProperty('transactions')) {
                config.metrics.transaction.tracing = config.transactions;
                delete config.transactions;
            }
            if (config.hasOwnProperty('http')) {
                config.metrics.transaction.http = config.http;
                delete config.http;
            }
        }
        // ------------------------------------------
        // Deep metrics
        // ------------------------------------------
        if (config.hasOwnProperty('deep_metrics')) {
            this.initMetricsConf(config);
            config.metrics.deepMetrics = config.deep_metrics;
            delete config.deep_metrics;
        }
        // ------------------------------------------
        // Event Loop action
        // ------------------------------------------
        if (config.hasOwnProperty('event_loop_dump')) {
            this.initActionsConf(config);
            config.actions.eventLoopDump = config.event_loop_dump;
            delete config.event_loop_dump;
        }
        // ------------------------------------------
        // Profiling action
        // ------------------------------------------
        if (config.hasOwnProperty('profiling')) {
            this.initActionsConf(config);
            config.actions.profilingHeap = config.profiling;
            config.actions.profilingHeap = config.profiling;
            delete config.profiling;
        }
    }
    initMetricsConf(config) {
        if (!config.metrics) {
            config.metrics = new MetricsConfig();
        }
    }
    initActionsConf(config) {
        if (!config.actions) {
            config.actions = new ActionsConfig();
        }
    }
}
exports.default = PMX;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG14LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3BteC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw4Q0FBc0Y7QUFDdEYsZ0RBQStDO0FBQy9DLGdEQUErQztBQUMvQyw4Q0FBNEM7QUFDNUMsbUNBQWtDO0FBQ2xDLG1EQUEyQztBQUMzQyx1REFBOEM7QUFDOUMsaUNBQXlCO0FBQ3pCLHlCQUF3QjtBQUN4QixtQ0FBa0M7QUFDbEMscURBQWlEO0FBRWpELG9EQUFtRDtBQUVuRCxNQUFNLEtBQUssR0FBRyxlQUFLLENBQUMsWUFBWSxDQUFDLENBQUE7QUFFakM7Q0FHQztBQUVEO0NBS0M7QUFFRDtDQUlDO0FBRUQ7Q0FtQkM7QUFpQkQ7SUFTRTtRQUNFLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxzQkFBYSxFQUFFLENBQUE7UUFDeEMsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLGlCQUFjLEVBQUUsQ0FBQTtRQUMxQyxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksaUJBQWMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQTtRQUMzRCxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksZ0JBQVksRUFBRSxDQUFBO1FBRXZDLE1BQU0sa0JBQWtCLEdBQUcsT0FBTyxDQUFDLHNCQUFzQixDQUFDLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDaEUsK0JBQWMsQ0FBQyxHQUFHLENBQUMsa0JBQWtCLEVBQUU7WUFDckMsU0FBUyxFQUFFLGtCQUFrQjtTQUM5QixDQUFDLENBQUE7UUFDRiwrQkFBYyxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsSUFBSSxtQkFBZ0IsRUFBRSxDQUFDLENBQUE7SUFDekQsQ0FBQztJQUVELGdCQUFnQjtRQUNkLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQTtJQUMzQixDQUFDO0lBRUQsSUFBSSxDQUFFLE1BQWlCLEVBQUUsS0FBZTtRQUN0QyxJQUFJLGFBQWEsR0FBa0IsNkJBQW9C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