<commit_before>'use strict';

/* eslint-env node, es6 */

/* eslint-disable global-require */

const assert = require('assert');
const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
const url = require('url');

const chalk = require('chalk');

const cosi = require(path.resolve(path.resolve(__dirname, '..', '..', '..', 'cosi')));
const Registration = require(path.resolve(cosi.lib_dir, 'registration'));
const Template = require(path.join(cosi.lib_dir, 'template'));
const Check = require(path.resolve(cosi.lib_dir, 'check'));

class Checks extends Registration {

    constructor(quiet) {
        super(quiet);

        const err = this.loadRegConfig();

        if (err !== null) {
            this.emit('error', err);
            return;
        }

        this.checks = {
            system: null,
            statsd: null
        };
    }

    create(cb) {
        console.log(chalk.bold('\nRegistration - checks'));

        const self = this;

        this.once('check.config', this.configSystemCheck);
        this.once('check.config.done', () => {
            self.emit('check.create');
        });

        this.once('check.create', this.createSystemCheck);
        this.once('check.create.done', (check) => {
            self._setCheckMeta('system', check);
            self.emit('check.finalize');
        });

        this.once('check.finalize', this.finalizeSystemCheck);
        this.once('check.finalize.done', () => {
            if (self.regConfig.statsd.enabled) {
                self.emit('statsd.config');
            } else {
                self.emit('checks.done');
            }
        });

        if (self.regConfig.statsd.enabled) {
            this.once('statsd.config', this.configStatsdCheck);
            this.once('statsd.config.done', () => {
                self.emit('statsd.create');
            });

            this.once('statsd.create', this.createStatsdCheck);
            this.once('statsd.create.done', (check) => {
                self._setCheckMeta('statsd', check);
                self.emit('statsd.finalize');
            });

            this.once('statsd.finalize', this.finalizeStatsdCheck);
            this.once('statsd.finalize.done', () => {
                self.emit('checks.done');
            });
        }

        this.once('checks.done', () => {
            if (typeof cb === 'function') {
                cb();
                return;
            }
        });

        this.emit('check.config');
    }

    update(cb) {
        console.log(chalk.blue(this.marker));
        console.log('Updating system check');

        const regFile = path.resolve(cosi.reg_dir, 'registration-check-system.json');

        if (!this._fileExists(regFile)) {
            this.emit('error', new Error(`System check registration file not found ${regFile}`));
            return;
        }

        console.log(chalk.bold('\tRegistration found'), `using ${regFile}`);

        const check = new Check(regFile);
        const checkMetrics = check.metrics;
        const visualMetrics = this._extractMetricsFromVisuals();
        let updateCheck = false;

        console.log(chalk.bold('\tChecking metrics'), 'from visuals against currently active metrics');
        for (let i = 0; i < visualMetrics.length; i++) {
            let active = false;

            for (let j = 0; j < checkMetrics.length; j++) {
                if (checkMetrics[j].name === visualMetrics[i].name) {
                    active = true;
                    break;
                }
            }
            if (!active) {
                console.log(chalk.bold('\t\tFound'), `new metric ${visualMetrics[i].name}`);
                updateCheck = true;
                // not breaking on first new metric, so we have a list in log of all new metrics
            }
        }

        if (updateCheck) {
            check.metrics = visualMetrics;
        }

        // check for new metric tags
        const metricTagFile = path.resolve(path.join(cosi.reg_dir, 'metric-tags.json'));

        if (this._fileExists(metricTagFile)) {
            let metricTags = {};

            try {
                metricTags = require(metricTagFile);
            } catch (err) {
                // ignore
            }

            console.log(chalk.bold('\tChecking metric tags'), `from ${metricTagFile}`);

            for (let i = 0; i < check.metrics.length; i++) {
                const metricName = check.metrics[i].name;

                if ({}.hasOwnProperty.call(metricTags, metricName)) {
                    const currTags = check.metrics[i].tags.join(',');

                    for (let j = 0; j < metricTags[metricName].length; j++) {
                        const tag = metricTags[metricName][j];

                        if (currTags.indexOf(tag) === -1) {
                            console.log('\t\tFound', `new tag for ${metricName}, adding ${tag}`);
                            check.metrics[i].tags.push(tag);
                            updateCheck = true;
                        }
                    }
                }
            }
        }

        if (!updateCheck) {
            console.log(chalk.green('\tSKIPPING'), 'check update, no new metrics or metric tags found');
            this.emit('check.update.done');
            cb();
            return;
        }

        const self = this;

        console.log(chalk.bold(`\tUpdating system check`), 'new metrics found');
        if (!{}.hasOwnProperty.call(check, 'metric_limit')) {<commit_msg>ensure check.metric.tags is an array when setting custom tags<commit_after>'use strict';

/* eslint-env node, es6 */

/* eslint-disable global-require */

const assert = require('assert');
const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
const url = require('url');

const chalk = require('chalk');

const cosi = require(path.resolve(path.resolve(__dirname, '..', '..', '..', 'cosi')));
const Registration = require(path.resolve(cosi.lib_dir, 'registration'));
const Template = require(path.join(cosi.lib_dir, 'template'));
const Check = require(path.resolve(cosi.lib_dir, 'check'));

class Checks extends Registration {

    constructor(quiet) {
        super(quiet);

        const err = this.loadRegConfig();

        if (err !== null) {
            this.emit('error', err);
            return;
        }

        this.checks = {
            system: null,
            statsd: null
        };
    }

    create(cb) {
        console.log(chalk.bold('\nRegistration - checks'));

        const self = this;

        this.once('check.config', this.configSystemCheck);
        this.once('check.config.done', () => {
            self.emit('check.create');
        });

        this.once('check.create', this.createSystemCheck);
        this.once('check.create.done', (check) => {
            self._setCheckMeta('system', check);
            self.emit('check.finalize');
        });

        this.once('check.finalize', this.finalizeSystemCheck);
        this.once('check.finalize.done', () => {
            if (self.regConfig.statsd.enabled) {
                self.emit('statsd.config');
            } else {
                self.emit('checks.done');
            }
        });

        if (self.regConfig.statsd.enabled) {
            this.once('statsd.config', this.configStatsdCheck);
            this.once('statsd.config.done', () => {
                self.emit('statsd.create');
            });

            this.once('statsd.create', this.createStatsdCheck);
            this.once('statsd.create.done', (check) => {
                self._setCheckMeta('statsd', check);
                self.emit('statsd.finalize');
            });

            this.once('statsd.finalize', this.finalizeStatsdCheck);
            this.once('statsd.finalize.done', () => {
                self.emit('checks.done');
            });
        }

        this.once('checks.done', () => {
            if (typeof cb === 'function') {
                cb();
                return;
            }
        });

        this.emit('check.config');
    }

    update(cb) {
        console.log(chalk.blue(this.marker));
        console.log('Updating system check');

        const regFile = path.resolve(cosi.reg_dir, 'registration-check-system.json');

        if (!this._fileExists(regFile)) {
            this.emit('error', new Error(`System check registration file not found ${regFile}`));
            return;
        }

        console.log(chalk.bold('\tRegistration found'), `using ${regFile}`);

        const check = new Check(regFile);
        const checkMetrics = check.metrics;
        const visualMetrics = this._extractMetricsFromVisuals();
        let updateCheck = false;

        console.log(chalk.bold('\tChecking metrics'), 'from visuals against currently active metrics');
        for (let i = 0; i < visualMetrics.length; i++) {
            let active = false;

            for (let j = 0; j < checkMetrics.length; j++) {
                if (checkMetrics[j].name === visualMetrics[i].name) {
                    active = true;
                    break;
                }
            }
            if (!active) {
                console.log(chalk.bold('\t\tFound'), `new metric ${visualMetrics[i].name}`);
                updateCheck = true;
                // not breaking on first new metric, so we have a list in log of all new metrics
            }
        }

        if (updateCheck) {
            check.metrics = visualMetrics;
        }

        // check for new metric tags
        const metricTagFile = path.resolve(path.join(cosi.reg_dir, 'metric-tags.json'));

        if (this._fileExists(metricTagFile)) {
            let metricTags = {};

            try {
                metricTags = require(metricTagFile);
            } catch (err) {
                // ignore
            }

            console.log(chalk.bold('\tChecking metric tags'), `from ${metricTagFile}`);

            for (let i = 0; i < check.metrics.length; i++) {
                const metricName = check.metrics[i].name;

                if (!Array.isArray(check.metrics[i].tags)) {
                    check.metrics[i].tags = [];
                }

                if ({}.hasOwnProperty.call(metricTags, metricName)) {
                    const currTags = check.metrics[i].tags.join(',');

                    for (let j = 0; j < metricTags[metricName].length; j++) {
                        const tag = metricTags[metricName][j];

                        if (currTags.indexOf(tag) === -1) {
                            console.log('\t\tFound', `new tag for ${metricName}, adding ${tag}`);
                            check.metrics[i].tags.push(tag);
                            updateCheck = true;
                        }
                    }
                }
            }
        }

        if (!updateCheck) {
            console.log(chalk.green('\tSKIPPING'), 'check update, no new metrics or metric tags found');
            this.emit('check.update.done');
            cb();
            return;
        }

        const self = this;

        console.log(chalk.bold(`\tUpdating system check`), 'new metrics found');
        if (!{}.hasOwnProperty.call(check, 'metric_limit')) {
{'fraction_non_alphanumeric': 0.14639800285306706, 'fraction_numerical': 0.0010699001426533524, 'mean_word_length': 1.7002888781896968, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '5099411', 'n_tokens_mistral': 3140, 'n_tokens_neox': 3014, 'n_words': 609}