kayvee 3.16.0 → 3.18.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.
@@ -1,23 +1,22 @@
1
- var _ = require("underscore");
2
- var kv = require("../kayvee");
1
+ var _ = require("underscore");
2
+ var kv = require("../kayvee");
3
3
  var router = require("../router");
4
4
 
5
-
6
5
  var LEVELS = {
7
- Trace: "trace",
8
- Debug: "debug",
9
- Info: "info",
10
- Warning: "warning",
11
- Error: "error",
6
+ Trace: "trace",
7
+ Debug: "debug",
8
+ Info: "info",
9
+ Warning: "warning",
10
+ Error: "error",
12
11
  Critical: "critical",
13
12
  };
14
13
 
15
14
  var LOG_LEVEL_ENUM = {
16
- trace: 0,
17
- debug: 1,
18
- info: 2,
19
- warning: 3,
20
- error: 4,
15
+ trace: 0,
16
+ debug: 1,
17
+ info: 2,
18
+ warning: 3,
19
+ error: 4,
21
20
  critical: 5,
22
21
  };
23
22
 
@@ -41,13 +40,20 @@ class Logger {
41
40
  globals = null;
42
41
  logWriter = null;
43
42
  logRouter = null;
44
-
45
- constructor(source, logLvl = process.env.KAYVEE_LOG_LEVEL, formatter = kv.format, output = console.error) {
43
+ asyncLocalStorage = null;
44
+
45
+ constructor(
46
+ source,
47
+ logLvl = process.env.KAYVEE_LOG_LEVEL,
48
+ formatter = kv.format,
49
+ output = console.error,
50
+ ) {
46
51
  this.formatter = formatter;
47
52
  this.logLvl = this._validateLogLvl(logLvl);
48
53
  this.globals = {};
49
54
  this.globals.source = source;
50
55
  this.logWriter = output;
56
+ this.asyncLocalStorage = null;
51
57
 
52
58
  if (process.env._TEAM_OWNER) {
53
59
  this.globals.team = process.env._TEAM_OWNER;
@@ -72,6 +78,10 @@ class Logger {
72
78
  }
73
79
  }
74
80
 
81
+ setAsyncLocalStorage(asyncLocalStorage) {
82
+ this.asyncLocalStorage = asyncLocalStorage;
83
+ }
84
+
75
85
  setRouter(r) {
76
86
  this.logRouter = r;
77
87
  }
@@ -147,62 +157,104 @@ class Logger {
147
157
  }
148
158
 
149
159
  traceD(title, data) {
150
- this._logWithLevel(LEVELS.Trace, {
151
- title,
152
- }, data);
160
+ this._logWithLevel(
161
+ LEVELS.Trace,
162
+ {
163
+ title,
164
+ },
165
+ data,
166
+ );
153
167
  }
154
168
 
155
169
  debugD(title, data) {
156
- this._logWithLevel(LEVELS.Debug, {
157
- title,
158
- }, data);
170
+ this._logWithLevel(
171
+ LEVELS.Debug,
172
+ {
173
+ title,
174
+ },
175
+ data,
176
+ );
159
177
  }
160
178
 
161
179
  infoD(title, data) {
162
- this._logWithLevel(LEVELS.Info, {
163
- title,
164
- }, data);
180
+ this._logWithLevel(
181
+ LEVELS.Info,
182
+ {
183
+ title,
184
+ },
185
+ data,
186
+ );
165
187
  }
166
188
 
167
189
  warnD(title, data) {
168
- this._logWithLevel(LEVELS.Warning, {
169
- title,
170
- }, data);
190
+ this._logWithLevel(
191
+ LEVELS.Warning,
192
+ {
193
+ title,
194
+ },
195
+ data,
196
+ );
171
197
  }
172
198
 
173
199
  errorD(title, data) {
174
- this._logWithLevel(LEVELS.Error, {
175
- title,
176
- }, data);
200
+ this._logWithLevel(
201
+ LEVELS.Error,
202
+ {
203
+ title,
204
+ },
205
+ data,
206
+ );
177
207
  }
178
208
 
179
209
  criticalD(title, data) {
180
- this._logWithLevel(LEVELS.Critical, {
181
- title,
182
- }, data);
210
+ this._logWithLevel(
211
+ LEVELS.Critical,
212
+ {
213
+ title,
214
+ },
215
+ data,
216
+ );
183
217
  }
184
218
 
185
219
  counterD(title, value, data) {
186
- this._logWithLevel(LEVELS.Info, {
187
- title,
188
- value,
189
- type: "counter",
190
- }, data);
220
+ this._logWithLevel(
221
+ LEVELS.Info,
222
+ {
223
+ title,
224
+ value,
225
+ type: "counter",
226
+ },
227
+ data,
228
+ );
191
229
  }
192
230
 
193
231
  gaugeD(title, value, data) {
194
- this._logWithLevel(LEVELS.Info, {
195
- title,
196
- value,
197
- type: "gauge",
198
- }, data);
232
+ this._logWithLevel(
233
+ LEVELS.Info,
234
+ {
235
+ title,
236
+ value,
237
+ type: "gauge",
238
+ },
239
+ data,
240
+ );
199
241
  }
200
242
 
201
243
  _logWithLevel(logLvl, metadata, userdata) {
202
244
  if (LOG_LEVEL_ENUM[logLvl] < LOG_LEVEL_ENUM[this.logLvl]) {
203
245
  return;
204
246
  }
205
- const data = assign({level: logLvl}, this.globals, metadata, userdata);
247
+ // I'm not clever enough to want to do these in one line without extra vars.
248
+ // We're on a REALLY old version of TS compiling to ES5. So I don't get a lot of the fancy tools
249
+ // like ?. and ??.
250
+ const store = this.asyncLocalStorage && this.asyncLocalStorage.getStore();
251
+ const storeData = store || { get: () => ({}) };
252
+ const contextData = storeData.get("context") ? storeData.get("context") : {};
253
+ const plainContextData =
254
+ contextData instanceof Map ? Object.fromEntries(contextData) : contextData;
255
+
256
+ var data = assign({ level: logLvl }, this.globals, metadata, plainContextData, userdata);
257
+
206
258
  if (this.logRouter) {
207
259
  data._kvmeta = this.logRouter.route(data);
208
260
  } else if (globalRouter) {
@@ -228,11 +280,13 @@ module.exports.mockRouting = (cb) => {
228
280
  const formatter = this.formatter;
229
281
  const logWriter = this.logWriter;
230
282
 
231
- this.formatter = msg => msg;
283
+ this.formatter = (msg) => msg;
232
284
  this.logWriter = (msg) => {
233
- if (!msg._kvmeta) { return; }
285
+ if (!msg._kvmeta) {
286
+ return;
287
+ }
234
288
 
235
- msg._kvmeta.routes.forEach(route => {
289
+ msg._kvmeta.routes.forEach((route) => {
236
290
  ruleMatches[route.rule] = (ruleMatches[route.rule] || []).concat(route);
237
291
  });
238
292
  };
package/lib/middleware.ts CHANGED
@@ -38,7 +38,9 @@ function walkDirSync(dir, files = []) {
38
38
  function skip_path(dir, base_path = "/") {
39
39
  let files = walkDirSync(dir);
40
40
  files = files.map((file) => path.join(base_path, file));
41
- console.error(`KayveeMiddleware: Skipping successful requests for files in ${dir} at ${base_path}`);
41
+ console.error(
42
+ `KayveeMiddleware: Skipping successful requests for files in ${dir} at ${base_path}`,
43
+ );
42
44
  return (req, res) => _(files).contains(req.path) && res.statusCode < 400;
43
45
  }
44
46
 
@@ -59,7 +61,10 @@ function getBaseUrl(req) {
59
61
  function getQueryParams(req) {
60
62
  var url = req.originalUrl || req.url;
61
63
  var parsed = require("url").parse(url, true);
62
- var parsedQueryString = require("qs").parse(parsed.search, {allowPrototypes: false, ignoreQueryPrefix: true});
64
+ var parsedQueryString = require("qs").parse(parsed.search, {
65
+ allowPrototypes: false,
66
+ ignoreQueryPrefix: true,
67
+ });
63
68
  return `?${require("qs").stringify(parsedQueryString)}`;
64
69
  }
65
70
 
@@ -89,8 +94,7 @@ function getResponseTimeNs(req, res) {
89
94
  }
90
95
 
91
96
  // calculate diff
92
- var ns = (res._startAt[0] - req._startAt[0]) * 1e9
93
- + (res._startAt[1] - req._startAt[1]);
97
+ var ns = (res._startAt[0] - req._startAt[0]) * 1e9 + (res._startAt[1] - req._startAt[1]);
94
98
  return ns;
95
99
  }
96
100
 
@@ -118,44 +122,34 @@ function getLogLevel(req, res) {
118
122
  return result;
119
123
  }
120
124
 
121
- /**
122
- * Get canary status
123
- */
124
- function isCanary() {
125
- return (process.env._CANARY === "1") || ("_POD_SHORTNAME" in process.env && process.env._POD_SHORTNAME.includes("-canary"));
126
- }
127
-
128
125
  /*
129
126
  * Default handlers
130
127
  */
131
128
  var defaultHandlers = [
132
129
  // Request method
133
- (req) => ({method: req.method}),
130
+ (req) => ({ method: req.method }),
134
131
  // Path (URL without query params)
135
- (req) => ({path: getBaseUrl(req)}),
132
+ (req) => ({ path: getBaseUrl(req) }),
136
133
  // Query params
137
- (req) => ({params: getQueryParams(req)}),
134
+ (req) => ({ params: getQueryParams(req) }),
138
135
  // Response size
139
- (req, res) => ({"response-size": getResponseSize(res)}),
136
+ (req, res) => ({ "response-size": getResponseSize(res) }),
140
137
  // Response time (ns)
141
- (req, res) => ({"response-time": getResponseTimeNs(req, res)}),
138
+ (req, res) => ({ "response-time": getResponseTimeNs(req, res) }),
142
139
  // Status code
143
- (req, res) => ({"status-code": res.statusCode}),
140
+ (req, res) => ({ "status-code": res.statusCode }),
144
141
  // Ip address
145
- (req) => ({ip: getIp(req)}),
142
+ (req) => ({ ip: getIp(req) }),
146
143
  // Via -- what library/code produced this log?
147
- () => ({via: "kayvee-middleware"}),
144
+ () => ({ via: "kayvee-middleware" }),
148
145
 
149
146
  // Kayvee's reserved fields
150
147
  // Log level
151
- (req, res) => ({level: getLogLevel(req, res)}),
148
+ (req, res) => ({ level: getLogLevel(req, res) }),
152
149
  // Source -- which app emitted this log?
153
150
  // -> Gets passed in among `options` during library initialization
154
151
  // Title
155
- () => ({title: "request-finished"}),
156
- // During the transition to pods, let's keep the canary field accurate
157
- // whether it's in the canary pod or a canary container in homepod
158
- () => ({canary: isCanary()}),
152
+ () => ({ title: "request-finished" }),
159
153
  ];
160
154
 
161
155
  const defaultContextHandlers = [];
@@ -167,7 +161,7 @@ function handlerData(handlers, ...args) {
167
161
  const handler_data = h(...args);
168
162
  _.extend(data, handler_data);
169
163
  } catch (e) {
170
- // ignore invalid handler
164
+ // swallow invalid handler
171
165
  }
172
166
  });
173
167
  return data;
@@ -236,14 +230,14 @@ var formatLine = (options_arg) => {
236
230
 
237
231
  // `source` is the one required field
238
232
  if (!options.source) {
239
- throw (Error("Missing required config for 'source' in Kayvee middleware 'options'"));
233
+ throw Error("Missing required config for 'source' in Kayvee middleware 'options'");
240
234
  }
241
235
 
242
236
  const router = KayveeLogger.getGlobalRouter();
243
237
 
244
238
  return (tokens, req, res) => {
245
239
  // Build a dict of data to log
246
- var data = {_kvmeta: undefined}; // Adding _kvmeta here to make typescript compile happy
240
+ var data = { _kvmeta: undefined }; // Adding _kvmeta here to make typescript compile happy
247
241
 
248
242
  // Add user-configured request headers
249
243
  var custom_headers = options.headers || [];
@@ -260,7 +254,7 @@ var formatLine = (options_arg) => {
260
254
 
261
255
  // Allow user to override `base_handlers`; provide sane default set of handlers
262
256
  var base_handlers = options.base_handlers || defaultHandlers;
263
- base_handlers = base_handlers.concat([() => ({source: options.source})]);
257
+ base_handlers = base_handlers.concat([() => ({ source: options.source })]);
264
258
 
265
259
  // Execute custom-handlers THEN base-handlers
266
260
  const all_handlers = custom_handlers.concat(base_handlers);
@@ -285,9 +279,12 @@ const defaultContextLoggerOpts = {
285
279
  */
286
280
 
287
281
  if (process.env.NODE_ENV === "test") {
288
- module.exports = (clever_options, morgan_options = {skip: null}) => {
282
+ module.exports = (clever_options, morgan_options = { skip: null }) => {
289
283
  if (clever_options.ignore_dir) {
290
- morgan_options.skip = skip_path(clever_options.ignore_dir.directory, clever_options.ignore_dir.path);
284
+ morgan_options.skip = skip_path(
285
+ clever_options.ignore_dir.directory,
286
+ clever_options.ignore_dir.path,
287
+ );
291
288
  }
292
289
  return morgan(formatLine(clever_options), morgan_options);
293
290
  };
@@ -304,7 +301,10 @@ if (process.env.NODE_ENV === "test") {
304
301
  skip: null,
305
302
  };
306
303
  if (clever_options.ignore_dir) {
307
- morgan_options.skip = skip_path(clever_options.ignore_dir.directory, clever_options.ignore_dir.path);
304
+ morgan_options.skip = skip_path(
305
+ clever_options.ignore_dir.directory,
306
+ clever_options.ignore_dir.path,
307
+ );
308
308
  }
309
309
  const morgan_logger = morgan(formatLine(clever_options), morgan_options);
310
310
  return (req, res, next) => {
@@ -1,8 +1,8 @@
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");
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
6
 
7
7
  var packageJson = require("../../package.json");
8
8
  const kvVersion = packageJson.version;
@@ -58,7 +58,9 @@ function fieldMatches(obj, field, values) {
58
58
  }
59
59
 
60
60
  for (let i = 0; i < values.length; i++) {
61
- if (values[i] === val) { return true; }
61
+ if (values[i] === val) {
62
+ return true;
63
+ }
62
64
  }
63
65
 
64
66
  return false;
@@ -91,7 +93,7 @@ class Rule {
91
93
  if (fieldVals.indexOf("*") !== -1 && fieldVals.length > 1) {
92
94
  throw new Error(
93
95
  `Invalid matcher values in ${name}.${field}.\n` +
94
- "Wildcard matcher can't co-exist with other matchers."
96
+ "Wildcard matcher can't co-exist with other matchers.",
95
97
  );
96
98
  }
97
99
  });
@@ -106,7 +108,9 @@ class Rule {
106
108
  // matches returns true if `msg` matches against this rule
107
109
  matches(msg) {
108
110
  for (const field in this.matchers) {
109
- if (!fieldMatches(msg, field, this.matchers[field])) { return false; }
111
+ if (!fieldMatches(msg, field, this.matchers[field])) {
112
+ return false;
113
+ }
110
114
  }
111
115
 
112
116
  return true;
@@ -161,20 +165,21 @@ function parseConfig(fileString) {
161
165
  try {
162
166
  config = yaml.safeLoad(fileString);
163
167
  } catch (e) {
164
- return {valid: false, rules: [], errors: [e]};
168
+ return { valid: false, rules: [], errors: [e] };
165
169
  }
166
170
  const validateRes = validateKVConfig(config);
167
171
  if (!validateRes.valid) {
168
- return _.assign(validateRes, {rules: []});
172
+ return _.assign(validateRes, { rules: [] });
169
173
  }
170
174
  try {
171
175
  const rulesObj = _.mapObject(
172
- config.routes, (elem, name) => new Rule(name, elem.matchers, elem.output)
176
+ config.routes,
177
+ (elem, name) => new Rule(name, elem.matchers, elem.output),
173
178
  );
174
179
  const rules = _.values(rulesObj);
175
- return {valid: true, rules, errors: []};
180
+ return { valid: true, rules, errors: [] };
176
181
  } catch (e) {
177
- return {valid: false, rules: [], errors: [e]};
182
+ return { valid: false, rules: [], errors: [e] };
178
183
  }
179
184
  }
180
185
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kayvee",
3
3
  "description": "Write data to key=val pairs, for human and machine readability",
4
- "version": "3.16.0",
4
+ "version": "3.18.0",
5
5
  "main": "index.js",
6
6
  "repository": {
7
7
  "type": "git",
@@ -16,19 +16,27 @@
16
16
  "underscore": "^1.8.3"
17
17
  },
18
18
  "devDependencies": {
19
+ "@clever/prettier-config": "1.0.0",
20
+ "@types/mocha": "^8.0.3",
21
+ "@types/node": "^12.12.68",
22
+ "@typescript-eslint/eslint-plugin": "^5.2.0",
23
+ "@typescript-eslint/parser": "^5.2.0",
19
24
  "babel-eslint": "^6.0.2",
20
25
  "benchmark": "^2.1.1",
21
- "eslint": "^2.7.0",
26
+ "eslint": "^7.11.0",
22
27
  "eslint-config-airbnb": "^7.0.0",
23
- "eslint-plugin-jsx-a11y": "^0.6.2",
24
- "eslint-plugin-react": "^4.3.0",
28
+ "eslint-config-prettier": "^6.12.0",
29
+ "eslint-formatter-summary": "^1.1.0",
30
+ "eslint-plugin-jsx-a11y": "^6.3.1",
31
+ "eslint-plugin-react": "^7.21.5",
32
+ "eslint-plugin-react-hooks": "^4.1.2",
25
33
  "express": "^4.13.4",
26
- "mocha": "^2.5.3",
34
+ "mocha": "^3.5.3",
35
+ "prettier": "2.1.2",
27
36
  "sinon": "^1.17.4",
28
37
  "supertest": "^1.2.0",
29
- "ts-node": "^0.7.1",
30
- "tslint": "^3.7.4",
31
- "typescript": "^1.8.9"
38
+ "ts-node": "^9.0.0",
39
+ "typescript": "^3.9.10"
32
40
  },
33
41
  "scripts": {
34
42
  "test": "make -Br test",
@@ -5,8 +5,8 @@ var middleware = require("../lib/middleware");
5
5
  var KayveeLogger = require("../lib/logger/logger");
6
6
 
7
7
  describe("ContextLogger", () => {
8
- const fake_req = {key1: "val1"};
9
- const fake_handler = (req) => ({log_key1: req.key1, key2: "val2"});
8
+ const fake_req = { key1: "val1" };
9
+ const fake_handler = (req) => ({ log_key1: req.key1, key2: "val2" });
10
10
 
11
11
  for (const level of KayveeLogger.LEVELS) {
12
12
  it(`correctly adds context to ${level} calls`, () => {
@@ -15,7 +15,7 @@ describe("ContextLogger", () => {
15
15
  stub_logger[`${level}D`] = spy;
16
16
  const log = new middleware.ContextLogger(stub_logger, [fake_handler], fake_req);
17
17
  log[level]("test_title");
18
- const expected_context = {log_key1: "val1", key2: "val2"};
18
+ const expected_context = { log_key1: "val1", key2: "val2" };
19
19
  assert(spy.calledWithExactly("test_title", expected_context));
20
20
  assert.equal(spy.callCount, 1);
21
21
  });
@@ -25,7 +25,7 @@ describe("ContextLogger", () => {
25
25
  const stub_logger = {};
26
26
  stub_logger[`${level}D`] = spy;
27
27
  const log = new middleware.ContextLogger(stub_logger, [fake_handler], fake_req);
28
- log[`${level}D`]("test_title", {key2: "new_value", key3: "val3"});
28
+ log[`${level}D`]("test_title", { key2: "new_value", key3: "val3" });
29
29
  const expected_data = {
30
30
  log_key1: "val1",
31
31
  key2: "new_value",
@@ -43,7 +43,7 @@ describe("ContextLogger", () => {
43
43
  stub_logger[`${metric}D`] = spy;
44
44
  const log = new middleware.ContextLogger(stub_logger, [fake_handler], fake_req);
45
45
  log[metric]("test_title", 3);
46
- const expected_context = {log_key1: "val1", key2: "val2"};
46
+ const expected_context = { log_key1: "val1", key2: "val2" };
47
47
  assert(spy.calledWithExactly("test_title", 3, expected_context));
48
48
  assert.equal(spy.callCount, 1);
49
49
  });
@@ -53,7 +53,7 @@ describe("ContextLogger", () => {
53
53
  const stub_logger = {};
54
54
  stub_logger[`${metric}D`] = spy;
55
55
  const log = new middleware.ContextLogger(stub_logger, [fake_handler], fake_req);
56
- log[`${metric}D`]("test_title", 3, {key2: "new_value", key3: "val3"});
56
+ log[`${metric}D`]("test_title", 3, { key2: "new_value", key3: "val3" });
57
57
  const expected_data = {
58
58
  log_key1: "val1",
59
59
  key2: "new_value",
@@ -66,7 +66,7 @@ describe("ContextLogger", () => {
66
66
 
67
67
  it("correctly handles being instantiated with empty list of handlers", () => {
68
68
  const spy = sinon.spy();
69
- const stub_logger = {infoD: spy};
69
+ const stub_logger = { infoD: spy };
70
70
  const log = new middleware.ContextLogger(stub_logger, [], fake_req);
71
71
  log.info("test_title");
72
72
  const expected_context = {};
package/test/kayvee.ts CHANGED
@@ -1,4 +1,4 @@
1
- var kv = require("../lib/kayvee");
1
+ var kv = require("../lib/kayvee");
2
2
  var assert = require("assert");
3
3
  var _ = require("underscore");
4
4
  var fs = require("fs");
@@ -10,15 +10,17 @@ describe("kayvee", () => {
10
10
  it(spec.title, () => {
11
11
  const actual = kv.format(spec.input.data);
12
12
  const expected = spec.output;
13
- assert.deepEqual(JSON.parse(actual), _.extend({deploy_env: "testing", wf_id: "abc"},
14
- JSON.parse(expected)));
13
+ assert.deepEqual(
14
+ JSON.parse(actual),
15
+ _.extend({ deploy_env: "testing", wf_id: "abc" }, JSON.parse(expected)),
16
+ );
15
17
  });
16
18
  });
17
19
  });
18
20
 
19
21
  describe(".format with Errors", () => {
20
22
  it("encodes Error objects", () => {
21
- const actual = kv.format({err: Error("An Error Message")});
23
+ const actual = kv.format({ err: Error("An Error Message") });
22
24
  const expected = {
23
25
  deploy_env: "testing",
24
26
  wf_id: "abc",
@@ -31,10 +33,17 @@ describe("kayvee", () => {
31
33
  describe(".formatLog", () => {
32
34
  _.each(tests.formatLog, (spec) => {
33
35
  it(spec.title, () => {
34
- const actual = kv.formatLog(spec.input.source, spec.input.level, spec.input.title, spec.input.data);
36
+ const actual = kv.formatLog(
37
+ spec.input.source,
38
+ spec.input.level,
39
+ spec.input.title,
40
+ spec.input.data,
41
+ );
35
42
  const expected = spec.output;
36
- assert.deepEqual(JSON.parse(actual), _.extend({deploy_env: "testing", wf_id: "abc"},
37
- JSON.parse(expected)));
43
+ assert.deepEqual(
44
+ JSON.parse(actual),
45
+ _.extend({ deploy_env: "testing", wf_id: "abc" }, JSON.parse(expected)),
46
+ );
38
47
  });
39
48
  });
40
49
  });