kayvee 3.17.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +147 -202
  2. package/dist/index.d.ts +4 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +29 -0
  5. package/dist/kayvee.d.ts +12 -0
  6. package/dist/kayvee.d.ts.map +1 -0
  7. package/dist/kayvee.js +50 -0
  8. package/dist/logger/logger.d.ts +49 -0
  9. package/dist/logger/logger.d.ts.map +1 -0
  10. package/dist/logger/logger.js +237 -0
  11. package/dist/middleware.d.ts +23 -0
  12. package/dist/middleware.d.ts.map +1 -0
  13. package/dist/middleware.js +196 -0
  14. package/dist/package.json +89 -0
  15. package/dist/router/index.d.ts +23 -0
  16. package/dist/router/index.d.ts.map +1 -0
  17. package/dist/router/index.js +184 -0
  18. package/package.json +64 -24
  19. package/.circleci/config.yml +0 -25
  20. package/.eslintrc.yml +0 -44
  21. package/.nvmrc +0 -1
  22. package/.prettierrc.json +0 -1
  23. package/Makefile +0 -56
  24. package/benchmarks/data/.keep +0 -1
  25. package/benchmarks/data/corpus-basic.json +0 -22
  26. package/benchmarks/data/corpus-pathological.json +0 -22
  27. package/benchmarks/data/corpus-realistic.json +0 -22
  28. package/benchmarks/data/kvconfig-basic.yml +0 -7
  29. package/benchmarks/data/kvconfig-pathological.yml +0 -222
  30. package/benchmarks/data/kvconfig-realistic.yml +0 -39
  31. package/benchmarks/routing.js +0 -116
  32. package/build/lib/kayvee.js +0 -67
  33. package/build/lib/logger/helpers.js +0 -0
  34. package/build/lib/logger/logger.js +0 -221
  35. package/build/lib/middleware.js +0 -302
  36. package/build/lib/router/index.js +0 -198
  37. package/build/package.json +0 -49
  38. package/build/test/context_logger.js +0 -77
  39. package/build/test/kayvee.js +0 -36
  40. package/build/test/logger_test.js +0 -334
  41. package/build/test/middleware.js +0 -557
  42. package/build/test/router.js +0 -311
  43. package/index.js +0 -7
  44. package/lib/kayvee.ts +0 -73
  45. package/lib/logger/helpers.ts +0 -0
  46. package/lib/logger/logger.ts +0 -296
  47. package/lib/middleware.ts +0 -317
  48. package/lib/router/index.ts +0 -234
  49. package/lib/router/schema_definitions.json +0 -158
  50. package/test/context_logger.ts +0 -76
  51. package/test/kayvee.ts +0 -50
  52. package/test/kvconfig.yml +0 -14
  53. package/test/logger_test.ts +0 -378
  54. package/test/middleware.ts +0 -632
  55. package/test/router.ts +0 -558
  56. package/test/static/empty.css +0 -0
  57. package/test/static/js/empty.js +0 -0
  58. package/test/tests.json +0 -100
  59. package/tsconfig.json +0 -10
  60. package/tslint.json +0 -134
  61. /package/{build/lib → dist}/router/schema_definitions.json +0 -0
@@ -1,198 +0,0 @@
1
- var fs = require("fs");
2
- var jsonschema = require("jsonschema");
3
- var schema = require("./schema_definitions");
4
- var yaml = require("js-yaml");
5
- var _ = require("underscore");
6
- var packageJson = require("../../package.json");
7
- var kvVersion = packageJson.version;
8
- var teamName = process.env._TEAM_OWNER || "UNSET";
9
- var reEnvvarTokens = new RegExp("\\$\\{(.+?)\\}", "g");
10
- var reFieldTokens = new RegExp("%\\{(.+?)\\}", "g");
11
- // For performance reason this code is intentionally redundant and not-inlined.
12
- // Removing redundancy and inlining this function some how makes performance worst.
13
- function substituteEnvVars(obj, subber) {
14
- var rtn = {};
15
- var replacer = function (s) { return s.replace(reEnvvarTokens, function (__, p1) { return subber(p1); }); };
16
- for (var key in obj) {
17
- var val = obj[key];
18
- if (Array.isArray(val)) {
19
- var updatedVals = Array(val.length);
20
- for (var i = 0; i < val.length; i++) {
21
- updatedVals[i] = replacer(val[i]);
22
- }
23
- rtn[key] = updatedVals;
24
- }
25
- else {
26
- rtn[key] = replacer(val);
27
- }
28
- }
29
- return rtn;
30
- }
31
- function deepKey(obj, key) {
32
- var path = key.split(".");
33
- var idx = 0;
34
- var val = obj;
35
- do {
36
- val = val[path[idx++]];
37
- } while (val && idx < path.length);
38
- return val;
39
- }
40
- function fieldMatches(obj, field, values) {
41
- var val = obj[field] || deepKey(obj, field);
42
- if (val == null || val === "") {
43
- return false;
44
- }
45
- if (values[0] === "*") {
46
- return true;
47
- }
48
- for (var i = 0; i < values.length; i++) {
49
- if (values[i] === val) {
50
- return true;
51
- }
52
- }
53
- return false;
54
- }
55
- var Rule = /** @class */ (function () {
56
- function Rule(name, matchers, output) {
57
- this.name = null;
58
- this.matchers = null;
59
- this.output = null;
60
- this.name = name;
61
- this.matchers = matchers;
62
- var envMissing = [];
63
- this.output = substituteEnvVars(output, function (k) {
64
- var val = process.env[k];
65
- if (val == null) {
66
- envMissing.push(k);
67
- }
68
- return val;
69
- });
70
- if (envMissing.length > 0) {
71
- throw new Error("Missing env var(s): " + envMissing.join(", "));
72
- }
73
- Object.keys(matchers).forEach(function (field) {
74
- var fieldVals = matchers[field];
75
- if (fieldVals.indexOf("*") !== -1 && fieldVals.length > 1) {
76
- throw new Error("Invalid matcher values in " + name + "." + field + ".\n" +
77
- "Wildcard matcher can't co-exist with other matchers.");
78
- }
79
- });
80
- if (this.output.type === "alerts" || this.output.type === "metrics") {
81
- this.output.value_field = this.output.value_field || "value";
82
- }
83
- this.output.rule = this.name;
84
- }
85
- // matches returns true if `msg` matches against this rule
86
- Rule.prototype.matches = function (msg) {
87
- for (var field in this.matchers) {
88
- if (!fieldMatches(msg, field, this.matchers[field])) {
89
- return false;
90
- }
91
- }
92
- return true;
93
- };
94
- // returns the output with kv substitutions performed
95
- Rule.prototype.outputFor = function (msg) {
96
- var rtn = {};
97
- var subst = function (__, k) { return msg[k] || deepKey(msg, k) || "KEY_NOT_FOUND"; };
98
- var replacer = function (s) { return s.replace(reFieldTokens, subst); };
99
- for (var key in this.output) {
100
- var val = this.output[key];
101
- if (Array.isArray(val)) {
102
- var updatedVals = Array(val.length);
103
- for (var i = 0; i < val.length; i++) {
104
- updatedVals[i] = replacer(val[i]);
105
- }
106
- rtn[key] = updatedVals;
107
- }
108
- else {
109
- rtn[key] = replacer(val);
110
- }
111
- }
112
- return rtn;
113
- };
114
- return Rule;
115
- }());
116
- // validateKVConfig ensures that `routes` matches the config schema. We have this
117
- // function instead of just doing a plain jsonschema.validate in order to get
118
- // better error messages for the "output" object (by default jsonschema would
119
- // just tell you that the output block doesn't match any of the known output
120
- // formats, but won't tell you what's wrong because it doesn't let you
121
- // condition on the output.type property).
122
- function validateKVConfig(config) {
123
- var validator = new jsonschema.Validator();
124
- var results = validator.validate(config, schema);
125
- return {
126
- valid: results.valid,
127
- errors: results.errors.map(function (err) { return err.stack; }),
128
- };
129
- }
130
- // parseConfig parses and validates the configuration passed as a string. It
131
- // returns an object of the form {valid, rules, errors}, where valid is true if
132
- // it was successfully parsed, rules is an array of rules, and errors is an
133
- // array of errors.
134
- function parseConfig(fileString) {
135
- var config;
136
- try {
137
- config = yaml.safeLoad(fileString);
138
- }
139
- catch (e) {
140
- return { valid: false, rules: [], errors: [e] };
141
- }
142
- var validateRes = validateKVConfig(config);
143
- if (!validateRes.valid) {
144
- return _.assign(validateRes, { rules: [] });
145
- }
146
- try {
147
- var rulesObj = _.mapObject(config.routes, function (elem, name) { return new Rule(name, elem.matchers, elem.output); });
148
- var rules = _.values(rulesObj);
149
- return { valid: true, rules: rules, errors: [] };
150
- }
151
- catch (e) {
152
- return { valid: false, rules: [], errors: [e] };
153
- }
154
- }
155
- var Router = /** @class */ (function () {
156
- function Router(rules) {
157
- this.rules = null;
158
- this.rules = rules || [];
159
- }
160
- // loadConfig reads in the config located at `filename` and sets the routing
161
- // rules to what it finds there. It should be a YAML-formatted file with
162
- // routing rules placed under the `routes` key on the root object.
163
- Router.prototype.loadConfig = function (filename) {
164
- var data = fs.readFileSync(filename, "utf8");
165
- this._loadConfigString(data);
166
- };
167
- Router.prototype._loadConfigString = function (configStr) {
168
- var parsedRules = parseConfig(configStr);
169
- if (!parsedRules.valid) {
170
- throw new Error(parsedRules.errors);
171
- }
172
- this.rules = parsedRules.rules;
173
- };
174
- // route matches the log line `msg` against all loaded rules and returns a
175
- // metadata object describing the outputs it should be sent to based on that
176
- // matching. logger.ts will attach this to log lines under the `_kvmeta`
177
- // property.
178
- Router.prototype.route = function (msg) {
179
- var outputs = [];
180
- for (var i = 0; i < this.rules.length; i++) {
181
- var rule = this.rules[i];
182
- if (rule.matches(msg)) {
183
- outputs.push(rule.outputFor(msg));
184
- }
185
- }
186
- return {
187
- team: teamName,
188
- kv_version: kvVersion,
189
- kv_language: "js",
190
- routes: outputs,
191
- };
192
- };
193
- return Router;
194
- }());
195
- module.exports = {
196
- Router: Router,
197
- Rule: Rule,
198
- };
@@ -1,49 +0,0 @@
1
- {
2
- "name": "kayvee",
3
- "description": "Write data to key=val pairs, for human and machine readability",
4
- "version": "3.17.0",
5
- "main": "index.js",
6
- "repository": {
7
- "type": "git",
8
- "url": "git://github.com/Clever/kayvee-js"
9
- },
10
- "dependencies": {
11
- "js-yaml": "^3.6.1",
12
- "jsonschema": "^1.1.0",
13
- "morgan": "^1.7.0",
14
- "qs": "^6.9.4",
15
- "split": "^1.0.0",
16
- "underscore": "^1.8.3"
17
- },
18
- "devDependencies": {
19
- "@clever/prettier-config": "1.0.0",
20
- "@types/mocha": "^8.0.3",
21
- "@types/node": "^12.12.68",
22
- "babel-eslint": "^6.0.2",
23
- "benchmark": "^2.1.1",
24
- "eslint": "^2.7.0",
25
- "eslint-config-airbnb": "^7.0.0",
26
- "eslint-plugin-jsx-a11y": "^0.6.2",
27
- "eslint-plugin-react": "^4.3.0",
28
- "express": "^4.13.4",
29
- "mocha": "^3.5.3",
30
- "prettier": "2.1.2",
31
- "sinon": "^1.17.4",
32
- "supertest": "^1.2.0",
33
- "ts-node": "^9.0.0",
34
- "tslint": "^3.7.4",
35
- "typescript": "^4.0.3"
36
- },
37
- "scripts": {
38
- "test": "make -Br test",
39
- "prepublish": "make build"
40
- },
41
- "author": "Clever <tech-notify@clever.com>",
42
- "license": "BSD-2-Clause",
43
- "bugs": {
44
- "url": "https://github.com/Clever/kayvee-js/issues"
45
- },
46
- "publishConfig": {
47
- "registry": "https://registry.npmjs.org"
48
- }
49
- }
@@ -1,77 +0,0 @@
1
- var assert = require("assert");
2
- var sinon = require("sinon");
3
- var middleware = require("../lib/middleware");
4
- var KayveeLogger = require("../lib/logger/logger");
5
- describe("ContextLogger", function () {
6
- var fake_req = { key1: "val1" };
7
- var fake_handler = function (req) { return ({ log_key1: req.key1, key2: "val2" }); };
8
- var _loop_1 = function (level) {
9
- it("correctly adds context to " + level + " calls", function () {
10
- var spy = sinon.spy();
11
- var stub_logger = {};
12
- stub_logger[level + "D"] = spy;
13
- var log = new middleware.ContextLogger(stub_logger, [fake_handler], fake_req);
14
- log[level]("test_title");
15
- var expected_context = { log_key1: "val1", key2: "val2" };
16
- assert(spy.calledWithExactly("test_title", expected_context));
17
- assert.equal(spy.callCount, 1);
18
- });
19
- it("correctly adds context to " + level + "D calls", function () {
20
- var spy = sinon.spy();
21
- var stub_logger = {};
22
- stub_logger[level + "D"] = spy;
23
- var log = new middleware.ContextLogger(stub_logger, [fake_handler], fake_req);
24
- log[level + "D"]("test_title", { key2: "new_value", key3: "val3" });
25
- var expected_data = {
26
- log_key1: "val1",
27
- key2: "new_value",
28
- key3: "val3",
29
- };
30
- assert(spy.calledWithExactly("test_title", expected_data));
31
- assert.equal(spy.callCount, 1);
32
- });
33
- };
34
- for (var _i = 0, _a = KayveeLogger.LEVELS; _i < _a.length; _i++) {
35
- var level = _a[_i];
36
- _loop_1(level);
37
- }
38
- var _loop_2 = function (metric) {
39
- it("correctly adds context to " + metric + " calls", function () {
40
- var spy = sinon.spy();
41
- var stub_logger = {};
42
- stub_logger[metric + "D"] = spy;
43
- var log = new middleware.ContextLogger(stub_logger, [fake_handler], fake_req);
44
- log[metric]("test_title", 3);
45
- var expected_context = { log_key1: "val1", key2: "val2" };
46
- assert(spy.calledWithExactly("test_title", 3, expected_context));
47
- assert.equal(spy.callCount, 1);
48
- });
49
- it("correctly adds context to " + metric + "D calls", function () {
50
- var spy = sinon.spy();
51
- var stub_logger = {};
52
- stub_logger[metric + "D"] = spy;
53
- var log = new middleware.ContextLogger(stub_logger, [fake_handler], fake_req);
54
- log[metric + "D"]("test_title", 3, { key2: "new_value", key3: "val3" });
55
- var expected_data = {
56
- log_key1: "val1",
57
- key2: "new_value",
58
- key3: "val3",
59
- };
60
- assert(spy.calledWithExactly("test_title", 3, expected_data));
61
- assert.equal(spy.callCount, 1);
62
- });
63
- };
64
- for (var _b = 0, _c = KayveeLogger.METRICS; _b < _c.length; _b++) {
65
- var metric = _c[_b];
66
- _loop_2(metric);
67
- }
68
- it("correctly handles being instantiated with empty list of handlers", function () {
69
- var spy = sinon.spy();
70
- var stub_logger = { infoD: spy };
71
- var log = new middleware.ContextLogger(stub_logger, [], fake_req);
72
- log.info("test_title");
73
- var expected_context = {};
74
- assert(spy.calledWithExactly("test_title", expected_context));
75
- assert.equal(spy.callCount, 1);
76
- });
77
- });
@@ -1,36 +0,0 @@
1
- var kv = require("../lib/kayvee");
2
- var assert = require("assert");
3
- var _ = require("underscore");
4
- var fs = require("fs");
5
- describe("kayvee", function () {
6
- var tests = JSON.parse(fs.readFileSync("test/tests.json"));
7
- describe(".format", function () {
8
- _.each(tests.format, function (spec) {
9
- it(spec.title, function () {
10
- var actual = kv.format(spec.input.data);
11
- var expected = spec.output;
12
- assert.deepEqual(JSON.parse(actual), _.extend({ deploy_env: "testing", wf_id: "abc" }, JSON.parse(expected)));
13
- });
14
- });
15
- });
16
- describe(".format with Errors", function () {
17
- it("encodes Error objects", function () {
18
- var actual = kv.format({ err: Error("An Error Message") });
19
- var expected = {
20
- deploy_env: "testing",
21
- wf_id: "abc",
22
- err: "Error: An Error Message",
23
- };
24
- assert.deepEqual(JSON.parse(actual), expected);
25
- });
26
- });
27
- describe(".formatLog", function () {
28
- _.each(tests.formatLog, function (spec) {
29
- it(spec.title, function () {
30
- var actual = kv.formatLog(spec.input.source, spec.input.level, spec.input.title, spec.input.data);
31
- var expected = spec.output;
32
- assert.deepEqual(JSON.parse(actual), _.extend({ deploy_env: "testing", wf_id: "abc" }, JSON.parse(expected)));
33
- });
34
- });
35
- });
36
- });