deep-framework
Version:
99 lines (72 loc) • 2.66 kB
JavaScript
var _ = require('underscore');
var fs = require('fs');
var path = require('path');
var Sampler = require('./sampler');
var Utils = require('../utils');
var rulesLocation = path.join(__dirname, '..', 'resources', 'default_sampling_rules.json');
var DEFAULT = 'Default';
/**
* Represents a set of matchers and rules in regards to sampling rates.
* @constructor
* @param {string} [location] - The location of the custom sampling rules file. If none is provided, the default file will be used.
*/
function SamplingRules(location) {
this.init(location);
}
SamplingRules.prototype.init = function init(location) {
var loc = location ? location : rulesLocation;
this.rules = addRulesConfig(loc);
};
SamplingRules.prototype.shouldSample = function shouldSample(serviceName, httpMethod, urlPath) {
var matchedRule;
_.each(this.rules, function(ruleEntry) {
var rule = ruleEntry.rule;
if (ruleEntry.id === DEFAULT || (Utils.wildcardMatch(rule.service_name, serviceName)
&& Utils.wildcardMatch(rule.http_method, httpMethod) && Utils.wildcardMatch(rule.url_path, urlPath))) {
matchedRule = rule;
return;
}
}, this);
if (!_.isUndefined(matchedRule))
return matchedRule.sampler.isSampled();
else
return false;
};
function addRulesConfig(location) {
var doc = loadRules(location);
var rules = [];
var defaultRule = doc.rules.Default;
_.each(_.omit(doc.rules, DEFAULT), function(rawRule, id) {
if (!_.isNaN(parseInt(id))) {
var rule = parseIntoRuleParams(rawRule);
rule.sampler = new Sampler(rawRule.fixed_target, rawRule.rate);
rules.push({ id: id, rule: rule });
} else {
throw new Error('Invalid rule identifier: ' + id + '. Must be an integer or "Default".');
}
}, this);
_.sortBy(rules, function(rule) { return parseInt(rule.key); });
if (defaultRule) {
rules.push({ id: DEFAULT, rule: {
sampler: new Sampler(defaultRule.fixed_target, defaultRule.rate)
}});
}
return rules;
}
function parseIntoRuleParams(rule) {
var params = _.omit(rule, 'fixed_target');
params = _.omit(params, 'rate');
_.each(params, function(matcher, attribute) {
if (attribute != 'service_name' && attribute != 'http_method' && attribute != 'url_path')
throw new Error('Unknown rule attribute "' + attribute + '".');
params[attribute] = matcher;
}, this);
return params;
}
function loadRules(location) {
var doc = JSON.parse(fs.readFileSync(location, 'utf8'));
if (_.isUndefined(doc.rules))
throw new Error('Document formatting is incorrect. Expecting "rules" param.');
return doc;
}
module.exports = SamplingRules;