rulesChecker.js 3.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. var debug = require('debug')('ylt:ruleschecker');
  2. var RulesChecker = function() {
  3. 'use strict';
  4. this.check = function(data, policies) {
  5. /*jshint loopfunc:true */
  6. var results = {};
  7. debug('Starting checking rules');
  8. for (var metricName in policies) {
  9. var policy = policies[metricName];
  10. var rule;
  11. if (policy.tool &&
  12. data.toolsResults[policy.tool] &&
  13. data.toolsResults[policy.tool].metrics &&
  14. (data.toolsResults[policy.tool].metrics[metricName] || data.toolsResults[policy.tool].metrics[metricName] === 0)) {
  15. rule = {
  16. value: data.toolsResults[policy.tool].metrics[metricName],
  17. policy: policy
  18. };
  19. // Take DOMqueriesAvoidable's offenders from DOMqueriesDuplicated, for example.
  20. if (policy.takeOffendersFrom) {
  21. var fromList = policy.takeOffendersFrom;
  22. var offenders = [];
  23. // takeOffendersFrom option can be a string or an array of strings.
  24. if (typeof fromList === 'string') {
  25. fromList = [fromList];
  26. }
  27. fromList.forEach(function(from) {
  28. offenders = offenders.concat(data.toolsResults[policy.tool].offenders[from]);
  29. });
  30. data.toolsResults[policy.tool].offenders[metricName] = offenders;
  31. }
  32. if (data.toolsResults[policy.tool].offenders &&
  33. data.toolsResults[policy.tool].offenders[metricName] &&
  34. data.toolsResults[policy.tool].offenders[metricName].length > 0) {
  35. rule.offenders = data.toolsResults[policy.tool].offenders[metricName];
  36. }
  37. rule.bad = rule.value > policy.isOkThreshold;
  38. rule.abnormal = policy.isAbnormalThreshold && rule.value >= policy.isAbnormalThreshold;
  39. // A value between 0 (bad) and 100 (very good).
  40. var score = (policy.isBadThreshold - rule.value) * 100 / (policy.isBadThreshold - policy.isOkThreshold);
  41. rule.score = Math.min(Math.max(Math.round(score), 0), 100);
  42. // A value between 0 (abnormal) and negative-infinity (your website is a blackhole)
  43. var abnormalityScore = (policy.isAbnormalThreshold - rule.value) * 100 / (policy.isAbnormalThreshold - policy.isOkThreshold);
  44. rule.abnormalityScore = Math.min(Math.round(abnormalityScore), 0);
  45. results[metricName] = rule;
  46. debug('Metric %s calculated. Score: %d', metricName, rule.score);
  47. } else if (policy.scoreFn) {
  48. debug('Custom score function for %s', metricName);
  49. // Custom score function
  50. rule = policy.scoreFn(data);
  51. // Check returned values (if the result is null, just don't save)
  52. if (rule) {
  53. rule.policy = {
  54. label: policy.label,
  55. message: policy.message
  56. };
  57. results[metricName] = rule;
  58. debug('Metric %s calculated. Score: %d', metricName, rule.score);
  59. } else {
  60. debug('Metric %s is null. Ignored.', metricName);
  61. }
  62. } else {
  63. debug('Metric %s not found for tool %s', metricName, policy.tool);
  64. }
  65. }
  66. debug('Rules checking finished');
  67. return results;
  68. };
  69. };
  70. module.exports = new RulesChecker();