<commit_before>/*
 * Copyright (C) 2013 salesforce.com, inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*jslint sub: true */


/**
 * @description The metrics service implementation
 * @constructor
 * @export
**/
Aura.Services.MetricsService = function MetricsService() {
    this.collector                 = { "default": [] };
    this.globalHandlers            = { "transactionEnd": [], "transactionsKilled": [] };
    this.bootstrap                 = {};
    this.registeredPlugins         = {};
    this.pluginInstances           = {};
    this.beaconProviders           = {};
    this.transactions              = {};
    this.doneBootstrap             = false;
    this.pluginsInitialized        = false;
    this.clearCompleteTransactions = true; // In PTEST Mode this is set to false (see initialize method)

    // #if {"excludeModes" : ["PRODUCTION"]}
    this["collector"] = this.collector; // Protected API to access the raw marks
    // #end
};

Aura.Services.MetricsService.PERFTIME = !!(window.performance && window.performance.now);
Aura.Services.MetricsService.TIMER    = Aura.Services.MetricsService.PERFTIME ? window.performance.now.bind(performance) : Date.now.bind(Date);
Aura.Services.MetricsService.START    = 'start';
Aura.Services.MetricsService.END      = 'end';
Aura.Services.MetricsService.STAMP    = 'stamp';
Aura.Services.MetricsService.DEFAULT  = 'default';
Aura.Services.MetricsService.MAXTIME  = 30000; // Max time for a transaction to finish

/**
 * Initialize function
 *@private
**/
Aura.Services.MetricsService.prototype.initialize = function () {
    // #if {"modes" : ["PTEST"]}
        this.setClearCompletedTransactions(false);
    // #end
    this.getPageStartTime();
    this.transactionStart('bootstrap','app');
    this.initializePlugins();
};

/**
 * Instrument a particular method (function) of an object, useful for AOP
 * @param {Object} instance Object that holds the method to hook
 * @param {string} method Method name
 * @param {string} ns Namespace
 * @param {boolean} async
 * @param {function(Object)} before
 * @param {function} after
 * @param {function} override
 * @export
**/
Aura.Services.MetricsService.prototype.instrument = function (instance, method, ns, async, before, after, override) {
    var self     = this,
        original = instance[method],
        beforeFn = typeof before === 'function',
        afterFn  = typeof after === 'function';

    instance[method] = function () {
        var mark = !override && self.markStart(ns, method),
            ret;

        if (beforeFn) {
            Array.prototype.unshift.call(arguments, mark);
            before.apply(this, arguments);
            Array.prototype.shift.call(arguments);
        }

        if (override) {
            Array.prototype.unshift.call(arguments, original);
            ret = override.apply(this, arguments);
            Array.prototype.shift.call(arguments);
        } else {
            ret = original.apply(this, arguments);
        }

        if (async) {
            return ret;
        }

        mark = !override && self.markEnd(ns, method);

        if (afterFn) {
            Array.prototype.unshift.call(arguments, mark);
            after.apply(this, arguments);
        }

        return ret;
    };

    instance[method]["__original"] = original;
};

/**
 * UnInstrument a particular method (function) of an object, useful for AOP
 * @param {Object} instance Object that holds the method to hook
 * @param {string} method Method name
 * @export
**/
Aura.Services.MetricsService.prototype.unInstrument = function (instance, method) {
    var original = instance[method]["__original"];
    delete instance[method]["__original"];
    instance[method] = original;
};

/**
 * Initialize registered plugins
 * @private
**/
Aura.Services.MetricsService.prototype.initializePlugins = function () {
    for (var plugin in this.registeredPlugins) {
        this.initializePlugin(plugin, this.registeredPlugins[plugin]);
    }
    this.pluginsInitialized = true;
};

/**
 * Initialize a give plugin
 * @param {string} pluginName Plugin name
 * @param {Object|function} Construtor or Objecct for the plugin
 * @private
**/
Aura.Services.MetricsService.prototype.initializePlugin = function (pluginName, PluginContructor) {
    var pluginInstance = typeof PluginContructor === 'function' ? new PluginContructor() : PluginContructor;
    this.pluginInstances[pluginName] = pluginInstance;
    this.collector[pluginName] = [];
    pluginInstance["initialize"](this);
};

/**
 * Internal method called once the application is ready
 * @private
**/
Aura.Services.MetricsService.prototype.applicationReady = function () {
    this.bootstrapMark("applicationReady");
    this.doneBootstrap = true;

    var bootstrap = this.getBootstrapMetrics();
    var now = this.time();
    this.transactionEnd('bootstrap','app', function (transaction) {
        // We need to override manually the duration to add the time before aura was initialized
        var bootstrapStart = Aura.Services.MetricsService.PERFTIME ? 0 : transaction["pageStartTime"];
        transaction["marks"]["bootstrap"] = bootstrap;
        transaction["ts"] = bootstrapStart;
        transaction["duration"] = now - bootstrapStart;
    });

    // #if {"modes" : ["PRODUCTION"]}
    var beacons = this.beaconProviders;
    if ($A.util.isEmpty(beacons)) {
        this.disablePlugins();
        this.clearMarks();
    }
    // #end
};
/**
 * Add a callback everytime a transaction ends.
 * @param {function} callback Function to execute for every transaction
 * @public
 * @export
**/
Aura.Services.MetricsService.prototype.onTransactionEnd = function (callback) {
    this.globalHandlers["transactionEnd"].push(callback);
};

/**
 * Unbind a callback everytime a transaction ends.
 * @param {function} callback Function to detach for every transaction<commit_msg>adding synthetic transaction method<commit_after>/*
 * Copyright (C) 2013 salesforce.com, inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*jslint sub: true */


/**
 * @description The metrics service implementation
 * @constructor
 * @export
**/
Aura.Services.MetricsService = function MetricsService() {
    this.collector                 = { "default": [] };
    this.globalHandlers            = { "transactionEnd": [], "transactionsKilled": [] };
    this.bootstrap                 = {};
    this.registeredPlugins         = {};
    this.pluginInstances           = {};
    this.beaconProviders           = {};
    this.transactions              = {};
    this.doneBootstrap             = false;
    this.pluginsInitialized        = false;
    this.clearCompleteTransactions = true; // In PTEST Mode this is set to false (see initialize method)

    // #if {"excludeModes" : ["PRODUCTION"]}
    this["collector"] = this.collector; // Protected API to access the raw marks
    // #end
};

Aura.Services.MetricsService.PERFTIME = !!(window.performance && window.performance.now);
Aura.Services.MetricsService.TIMER    = Aura.Services.MetricsService.PERFTIME ? window.performance.now.bind(performance) : Date.now.bind(Date);
Aura.Services.MetricsService.START    = 'start';
Aura.Services.MetricsService.END      = 'end';
Aura.Services.MetricsService.STAMP    = 'stamp';
Aura.Services.MetricsService.DEFAULT  = 'default';
Aura.Services.MetricsService.MAXTIME  = 30000; // Max time for a transaction to finish

/**
 * Initialize function
 *@private
**/
Aura.Services.MetricsService.prototype.initialize = function () {
    // #if {"modes" : ["PTEST"]}
        this.setClearCompletedTransactions(false);
    // #end
    this.getPageStartTime();
    this.transactionStart('bootstrap','app');
    this.initializePlugins();
};

/**
 * Instrument a particular method (function) of an object, useful for AOP
 * @param {Object} instance Object that holds the method to hook
 * @param {string} method Method name
 * @param {string} ns Namespace
 * @param {boolean} async
 * @param {function(Object)} before
 * @param {function} after
 * @param {function} override
 * @export
**/
Aura.Services.MetricsService.prototype.instrument = function (instance, method, ns, async, before, after, override) {
    var self     = this,
        original = instance[method],
        beforeFn = typeof before === 'function',
        afterFn  = typeof after === 'function';

    instance[method] = function () {
        var mark = !override && self.markStart(ns, method),
            ret;

        if (beforeFn) {
            Array.prototype.unshift.call(arguments, mark);
            before.apply(this, arguments);
            Array.prototype.shift.call(arguments);
        }

        if (override) {
            Array.prototype.unshift.call(arguments, original);
            ret = override.apply(this, arguments);
            Array.prototype.shift.call(arguments);
        } else {
            ret = original.apply(this, arguments);
        }

        if (async) {
            return ret;
        }

        mark = !override && self.markEnd(ns, method);

        if (afterFn) {
            Array.prototype.unshift.call(arguments, mark);
            after.apply(this, arguments);
        }

        return ret;
    };

    instance[method]["__original"] = original;
};

/**
 * UnInstrument a particular method (function) of an object, useful for AOP
 * @param {Object} instance Object that holds the method to hook
 * @param {string} method Method name
 * @export
**/
Aura.Services.MetricsService.prototype.unInstrument = function (instance, method) {
    var original = instance[method]["__original"];
    delete instance[method]["__original"];
    instance[method] = original;
};

/**
 * Initialize registered plugins
 * @private
**/
Aura.Services.MetricsService.prototype.initializePlugins = function () {
    for (var plugin in this.registeredPlugins) {
        this.initializePlugin(plugin, this.registeredPlugins[plugin]);
    }
    this.pluginsInitialized = true;
};

/**
 * Initialize a give plugin
 * @param {string} pluginName Plugin name
 * @param {Object|function} Construtor or Objecct for the plugin
 * @private
**/
Aura.Services.MetricsService.prototype.initializePlugin = function (pluginName, PluginContructor) {
    var pluginInstance = typeof PluginContructor === 'function' ? new PluginContructor() : PluginContructor;
    this.pluginInstances[pluginName] = pluginInstance;
    this.collector[pluginName] = [];
    pluginInstance["initialize"](this);
};

/**
 * Internal method called once the application is ready
 * @private
**/
Aura.Services.MetricsService.prototype.applicationReady = function () {
    this.bootstrapMark("applicationReady");
    this.doneBootstrap = true;

    var bootstrap = this.getBootstrapMetrics();
    var now = this.time();
    this.transactionEnd('bootstrap','app', function (transaction) {
        // We need to override manually the duration to add the time before aura was initialized
        var bootstrapStart = Aura.Services.MetricsService.PERFTIME ? 0 : transaction["pageStartTime"];
        transaction["marks"]["bootstrap"] = bootstrap;
        transaction["ts"] = bootstrapStart;
        transaction["duration"] = now - bootstrapStart;
    });

    // #if {"modes" : ["PRODUCTION"]}
    var beacons = this.beaconProviders;
    if ($A.util.isEmpty(beacons)) {
        this.disablePlugins();
        this.clearMarks();
    }
    // #end
};

/**
 * Create a transaction based on a given configuration
 * @param {string} ns Namespace of the transaction
 * @param {string} name Name of the transaction
 * @param {Object} transaction Transaction
 * @public
 * @export
**/
Aura.Services.MetricsService.prototype.syntheticTransactionStart = function (ns, name, config) {
    var trx = this.createTransaction(ns, name, config);
    $A.util.apply(this.transactions[trx], config, true, true);
    return trx;
};


/**
 * Add a callback everytime a transaction ends.
 * @param {function} callback Function to execute for every transaction
 * @public
 * @export
**/
Aura.Services.MetricsService.prototype.onTransactionEnd = function (callback) {
    this.globalHandlers["transactionEnd"].push(callback);
};

/**
 * Unbind a callback everytime a transaction ends.
 * @param {function} callback Function to detach for every transaction
{'fraction_non_alphanumeric': 0.12229673724662798, 'fraction_numerical': 0.0021098636123879134, 'mean_word_length': 3.198671306548561, 'pattern_counts': {'":': 6, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '531484', 'n_tokens_mistral': 3629, 'n_tokens_neox': 3547, 'n_words': 986}