Repository: honeycombio/beeline-nodejs
Pull request #64 (2018-07-17 23:05:44)

get rid of source/name position arguments in favor of a map
both startRequest and startEvent switch from positional args for name/source to a map.

This has a couple of pleasant side-effects.

1. more self-documenting at the use-site.
2. allows us to collapse multiple addContext calls into the startEvent/startRequest call itself.



Patch:
diff --git a/lib/async_tracker.js b/lib/async_tracker.js
index fc7a02d..ebf468d 100644
--- a/lib/async_tracker.js
+++ b/lib/async_tracker.js
@@ -1,4 +1,4 @@
-/* global require module */
+/* eslint-env node */
 const async_hooks = require("async_hooks");
 
 class AsyncTracker {
diff --git a/lib/deterministic_sampler.js b/lib/deterministic_sampler.js
index a5ad464..af12f64 100644
--- a/lib/deterministic_sampler.js
+++ b/lib/deterministic_sampler.js
@@ -1,4 +1,4 @@
-/* global require module */
+/* eslint-env node */
 const createHash = require("crypto").createHash;
 
 const MAX_UINT32 = Math.pow(2, 32) - 1;
diff --git a/lib/event.js b/lib/event.js
index a18da03..70d1fbd 100644
--- a/lib/event.js
+++ b/lib/event.js
@@ -1,4 +1,4 @@
-/* global require exports __dirname */
+/* eslint-env node */
 const libhoney = require("libhoney").default,
   os = require("os"),
   process = require("process"),
@@ -55,25 +55,22 @@ class MockEventAPI {
     this.traceId = 0;
   }
 
-  startRequest(source, name, traceId) {
+  startRequest(metadataContext, traceId) {
     let id = this.traceId++;
-    let requestContext = { id: traceId || id };
-    tracker.setTracked(requestContext);
-    return this.startEvent(source, name);
+    tracker.setTracked({ id: traceId || id });
+    return this.startEvent(metadataContext);
   }
   finishRequest(ev) {
     this.finishEvent(ev);
     tracker.deleteTracked();
   }
-  startEvent(source, name) {
+  startEvent(metadataContext) {
     let context = tracker.getTracked();
-    const eventPayload = {
+    const eventPayload = Object.assign({}, metadataContext, {
       [schema.TRACE_ID]: context.id,
-      [schema.TRACE_SPAN_NAME]: name,
-      [schema.EVENT_TYPE]: source,
       startTime: Date.now(),
       startTimeHR: process.hrtime(),
-    };
+    });
     this.eventStack.push(eventPayload);
     return eventPayload;
   }
@@ -126,7 +123,7 @@ class LibhoneyEventAPI {
     this.honey.addField(schema.HOSTNAME, os.hostname());
   }
 
-  startRequest(source, name, traceId) {
+  startRequest(metadataContext, traceId) {
     let id = traceId || uuidv4();
 
     if (this.ds && !this.ds.sample(id)) {
@@ -134,13 +131,12 @@ class LibhoneyEventAPI {
       return null;
     }
 
-    const requestContext = {
+    tracker.setTracked({
       id,
       customContext: {},
       stack: [],
-    };
-    tracker.setTracked(requestContext);
-    return this.startEvent(source, name, id);
+    });
+    return this.startEvent(metadataContext, id);
   }
 
   finishRequest(ev) {
@@ -148,21 +144,19 @@ class LibhoneyEventAPI {
     tracker.deleteTracked();
   }
 
-  startEvent(source, name, spanId = uuidv4()) {
+  startEvent(metadataContext, spanId = uuidv4()) {
     let context = tracker.getTracked();
     let parentId;
     if (context.stack.length > 0) {
       parentId = context.stack[context.stack.length - 1][schema.TRACE_SPAN_ID];
     }
-    const eventPayload = {
-      [schema.EVENT_TYPE]: source,
+    const eventPayload = Object.assign({}, metadataContext, {
       [schema.TRACE_ID]: context.id,
       [schema.TRACE_SPAN_ID]: spanId,
-      [schema.TRACE_SERVICE_NAME]: source,
-      [schema.TRACE_SPAN_NAME]: name,
+      [schema.TRACE_SERVICE_NAME]: "XXX(toshok)",
       startTime: Date.now(),
       startTimeHR: process.hrtime(),
-    };
+    });
     if (parentId) {
       eventPayload[schema.TRACE_PARENT_ID] = parentId;
     }
@@ -286,8 +280,8 @@ exports.resetForTesting = resetForTesting;
 exports.traceActive = function traceActive() {
   return !!tracker.getTracked();
 };
-exports.startRequest = function startRequest(source, name, traceId) {
-  return eventAPI.startRequest(source, name, traceId);
+exports.startRequest = function startRequest(metadataContext, traceId) {
+  return eventAPI.startRequest(metadataContext, traceId);
 };
 exports.finishRequest = function finishRequest(ev) {
   return eventAPI.finishRequest(ev);
@@ -295,8 +289,8 @@ exports.finishRequest = function finishRequest(ev) {
 exports.addContext = function addContext(map) {
   return eventAPI.addContext(map);
 };
-exports.startEvent = function startEvent(source, name) {
-  return eventAPI.startEvent(source, name);
+exports.startEvent = function startEvent(metadataContext, spanId) {
+  return eventAPI.startEvent(metadataContext, spanId);
 };
 exports.finishEvent = function finishEvent(ev, rollup) {
   return eventAPI.finishEvent(ev, rollup);
diff --git a/lib/index.js b/lib/index.js
index 2c90eac..cb469dc 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -1,4 +1,4 @@
-/* global require module */
+/* eslint-env node */
 const event = require("./event"),
   instrumentation = require("./instrumentation");
 
diff --git a/lib/instrumentation.js b/lib/instrumentation.js
index a976b72..9ce9c22 100644
--- a/lib/instrumentation.js
+++ b/lib/instrumentation.js
@@ -1,4 +1,4 @@
-/* global require exports __dirname global console */
+/* eslint-env node */
 const shimmer = require("shimmer"),
   tracker = require("./async_tracker"),
   Module = require("module"),
diff --git a/lib/instrumentation/bluebird.js b/lib/instrumentation/bluebird.js
index 721f2fd..053b0b0 100644
--- a/lib/instrumentation/bluebird.js
+++ b/lib/instrumentation/bluebird.js
@@ -1,4 +1,4 @@
-/* global require, module */
+/* eslint-env node */
 const shimmer = require("shimmer"),
   tracker = require("../async_tracker");
 
diff --git a/lib/instrumentation/child_process.js b/lib/instrumentation/child_process.js
index 7134965..cdcb46c 100644
--- a/lib/instrumentation/child_process.js
+++ b/lib/instrumentation/child_process.js
@@ -1,4 +1,4 @@
-/* global require, module */
+/* eslint-env node */
 const shimmer = require("shimmer"),
   event = require("../event"),
   schema = require("../schema");
@@ -10,8 +10,15 @@ function wrapExecLike(name, packageVersion) {
         return original.apply(this, arguments);
       }
 
-      // filled in below the callback
-      let ev;
+      let ev = event.startEvent({
+        [schema.EVENT_TYPE]: "child_process",
+        [schema.PACKAGE_VERSION]: packageVersion,
+        [schema.TRACE_SPAN_NAME]: name,
+        "exec.file": file,
+      });
+      if (Array.isArray(args)) {
+        event.addContext({ "exec.args": args });
+      }
 
       let argsArray = Array.from(arguments);
       argsArray.slice(1).forEach((arg, idx) => {
@@ -19,19 +26,10 @@ function wrapExecLike(name, packageVersion) {
           return;
         }
         argsArray[idx + 1] = function(error, stdout, stderr) {
-          event.addContext({ "exec.file": file });
-          if (Array.isArray(args)) {
-            event.addContext({ "exec.args": args });
-          }
           event.finishEvent(ev, name);
           arg(error, stdout, stderr);
         };
       });
-
-      ev = event.startEvent("child_process", name);
-      event.addContext({
-        [schema.PACKAGE_VERSION]: packageVersion,
-      });
       return original.apply(this, argsArray);
     };
   };
diff --git a/lib/instrumentation/express.js b/lib/instrumentation/express.js
index 09d0433..2736c2b 100644
--- a/lib/instrumentation/express.js
+++ b/lib/instrumentation/express.js
@@ -1,4 +1,4 @@
-/* global require, module, __dirname */
+/* eslint-env node */
 const onHeaders = require("on-headers"),
   tracker = require("../async_tracker"),
   schema = require("../schema"),
@@ -83,7 +83,28 @@ const getUserContext = (userContext, req) => {
 
 const getMagicMiddleware = ({ userContext, traceIdSource, packageVersion }) => (req, res, next) => {
   let traceIdContext = getTraceId(traceIdSource, req);
-  let ev = event.startRequest("express", "request", traceIdContext.traceId);
+  let ev = event.startRequest(
+    {
+      [schema.EVENT_TYPE]: "express",
+      [schema.PACKAGE_VERSION]: packageVersion,
+      [schema.TRACE_SPAN_NAME]: "request",
+      [schema.TRACE_ID_SOURCE]: traceIdContext.source,
+      "request.host": req.hostname,
+      "request.base_url": req.baseUrl,
+      "request.original_url": req.originalUrl,
+      "request.remote_addr": req.ip,
+      "request.secure": req.secure,
+      "request.method": req.method,
+      "request.route": req.route ? req.route.path : undefined,
+      "request.scheme": req.protocol,
+      "request.path": req.path,
+      "request.query": req.query,
+      "request.http_version": `HTTP/${req.httpVersion}`,
+      "request.fresh": req.fresh,
+      "request.xhr": req.xhr,
+    },
+    traceIdContext.traceId
+  );
 
   if (!ev) {
     // sampler has decided that we shouldn't trace this request
@@ -91,24 +112,6 @@ const getMagicMiddleware = ({ userContext, traceIdSource, packageVersion }) => (
     return;
   }
 
-  event.addContext({
-    [schema.TRACE_ID_SOURCE]: traceIdContext.source,
-    [schema.PACKAGE_VERSION]: packageVersion,
-    "request.host": req.hostname,
-    "request.base_url": req.baseUrl,
-    "request.original_url": req.originalUrl,
-    "request.remote_addr": req.ip,
-    "request.secure": req.secure,
-    "request.method": req.method,
-    "request.route": req.route ? req.route.path : undefined,
-    "request.scheme": req.protocol,
-    "request.path": req.path,
-    "request.query": req.query,
-    "request.http_version": `HTTP/${req.httpVersion}`,
-    "request.fresh": req.fresh,
-    "request.xhr": req.xhr,
-  });
-
   // we bind the method that finishes the request event so that we're guaranteed to get an event
   // regardless of any lapses in context propagation.  Doing it this way also allows us to _detect_
   // if there was a lapse, since `context` will be undefined in that case.
diff --git a/lib/instrumentation/http.js b/lib/instrumentation/http.js
index 6cd53da..753328f 100644
--- a/lib/instrumentation/http.js
+++ b/lib/instrumentation/http.js
@@ -1,4 +1,4 @@
-/* global require, module */
+/* eslint-env node */
 const url = require("url"),
   shimmer = require("shimmer"),
   event = require("../event"),
@@ -21,21 +21,19 @@ let instrumentHTTP = (http, opts = {}) => {
         return original.apply(this, [options, cb]);
       }
 
-      // filled in below the callback
-      let ev;
+      let ev = event.startEvent({
+        [schema.EVENT_TYPE]: "http",
+        [schema.PACKAGE_VERSION]: opts.packageVersion,
+        [schema.TRACE_SPAN_NAME]: "request",
+        url: typeof options === "string" ? options : url.format(options),
+      });
 
       let wrapped_cb = function(res) {
-        event.addContext({ url: typeof options === "string" ? options : url.format(options) });
         event.finishEvent(ev, "request");
         if (cb) {
           return cb.apply(this, [res]);
         }
       };
-
-      ev = event.startEvent("http", "request");
-      event.addContext({
-        [schema.PACKAGE_VERSION]: opts.packageVersion,
-      });
       if (cb) {
         return original.apply(this, [options, wrapped_cb]);
       } else {
diff --git a/lib/instrumentation/https.js b/lib/instrumentation/https.js
index 086e922..e646bc2 100644
--- a/lib/instrumentation/https.js
+++ b/lib/instrumentation/https.js
@@ -1,4 +1,4 @@
-/* global require, module */
+/* eslint-env node */
 const url = require("url"),
   shimmer = require("shimmer"),
   event = require("../event"),
@@ -21,21 +21,20 @@ let instrumentHTTPS = (https, opts = {}) => {
         return original.apply(this, [options, cb]);
       }
 
-      // filled in below the callback
-      let ev;
+      let ev = event.startEvent({
+        [schema.EVENT_TYPE]: "https",
+        [schema.PACKAGE_VERSION]: opts.packageVersion,
+        [schema.TRACE_SPAN_NAME]: "request",
+        url: typeof options === "string" ? options : url.format(options),
+      });
 
       let wrapped_cb = function(res) {
-        event.addContext({ url: typeof options === "string" ? options : url.format(options) });
         event.finishEvent(ev, "request");
         if (cb) {
           return cb.apply(this, [res]);
         }
       };
 
-      ev = event.startEvent("https", "request");
-      event.addContext({
-        [schema.PACKAGE_VERSION]: opts.packageVersion,
-      });
       if (cb) {
         return original.apply(this, [options, wrapped_cb]);
       } else {
diff --git a/lib/instrumentation/mongodb.js b/lib/instrumentation/mongodb.js
index 9d80c98..bf54de0 100644
--- a/lib/instrumentation/mongodb.js
+++ b/lib/instrumentation/mongodb.js
@@ -1,21 +1,9 @@
-/* global require, module */
+/* eslint-env node */
 const shimmer = require("shimmer"),
   tracker = require("../async_tracker"),
   event = require("../event"),
   schema = require("../schema");
 
-function startCollectionEvent(packageVersion, name) {
-  let ev = event.startEvent("mongodb", `collection.${name}`);
-  event.addContext({
-    [schema.PACKAGE_VERSION]: packageVersion,
-  });
-  return ev;
-}
-
-function finishCollectionEvent(ev, name) {
-  event.finishEvent(ev, `collection.${name}`);
-}
-
 function prefixKeys(prefix, map = {}) {
   let prefixed = {};
   Object.keys(map).forEach(k => {
@@ -52,21 +40,25 @@ function instrumentMongodb(mongodb, opts = {}) {
         let callback = populatedArgs.pop(); // we'll put this back on (wrapped) when we original.apply below
         let options = populatedArgs[populatedArgs.length - 1];
 
-        // filled in below the callback
-        let ev;
+        let eventName = `collection.${name}`;
+        let ev = event.startEvent({
+          [schema.EVENT_TYPE]: "mongodb",
+          [schema.PACKAGE_VERSION]: opts.packageVersion,
+          [schema.TRACE_SPAN_NAME]: eventName,
+        });
+
+        event.addContext(prefixKeys("db.options", options));
+        if (additionalContext) {
+          event.addContext(prefixKeys("db", additionalContext(...populatedArgs)));
+        }
 
         let wrapped_cb = tracker.bindFunction(function(...cb_args) {
-          finishCollectionEvent(ev, name);
+          event.finishEvent(ev, eventName);
           if (callback) {
             return callback(...cb_args);
           }
         });
 
-        ev = startCollectionEvent(opts.packageVersion, name);
-        event.addContext(prefixKeys("db.options", options));
-        if (additionalContext) {
-          event.addContext(prefixKeys("db", additionalContext(...populatedArgs)));
-        }
         return original.apply(this, [...populatedArgs, wrapped_cb]);
       };
     });
diff --git a/lib/instrumentation/mongoose.js b/lib/instrumentation/mongoose.js
index 5e55198..c1b160d 100644
--- a/lib/instrumentation/mongoose.js
+++ b/lib/instrumentation/mongoose.js
@@ -1,4 +1,4 @@
-/* global require, module */
+/* eslint-env node */
 const shimmer = require("shimmer"),
   tracker = require("../async_tracker");
 
diff --git a/lib/instrumentation/mpromise.js b/lib/instrumentation/mpromise.js
index 50f9baf..5f328f2 100644
--- a/lib/instrumentation/mpromise.js
+++ b/lib/instrumentation/mpromise.js
@@ -1,4 +1,4 @@
-/* global require, module */
+/* eslint-env node */
 const shimmer = require("shimmer"),
   tracker = require("../async_tracker");
 
diff --git a/lib/instrumentation/mysql2.js b/lib/instrumentation/mysql2.js
index b7499ef..aef84e9 100644
--- a/lib/instrumentation/mysql2.js
+++ b/lib/instrumentation/mysql2.js
@@ -1,4 +1,4 @@
-/* global require, module */
+/* eslint-env node */
 const shimmer = require("shimmer"),
   tracker = require("../async_tracker"),
   event = require("../event"),
@@ -14,24 +14,20 @@ let instrumentConnection = function(conn, packageVersion) {
         return original.apply(this, args);
       }
 
-      // filled in below the callback
-      let ev;
+      let ev = event.startEvent({
+        [schema.EVENT_TYPE]: "mysql2",
+        [schema.PACKAGE_VERSION]: packageVersion,
+        [schema.TRACE_SPAN_NAME]: "query",
+        "db.query": args[0].sql,
+      });
 
       let cb = args[args.length - 1];
       let wrapped_cb = function(...cb_args) {
-        event.addContext({
-          "db.query": args[0].sql,
-        });
         event.finishEvent(ev, "query");
         return cb(...cb_args);
       };
-      args = args.slice(0, -1).concat(wrapped_cb);
 
-      ev = event.startEvent("mysql2", "query");
-      event.addContext({
-        [schema.PACKAGE_VERSION]: packageVersion,
-      });
-      return original.apply(this, args);
+      return original.apply(this, args.slice(0, -1).concat(wrapped_cb));
     };
   });
 
@@ -45,26 +41,22 @@ let instrumentConnection = function(conn, packageVersion) {
         return original.apply(this, args);
       }
 
-      // filled in below the callback
-      let ev;
+      let ev = event.startEvent({
+        [schema.EVENT_TYPE]: "mysql2",
+        [schema.PACKAGE_VERSION]: packageVersion,
+        [schema.TRACE_SPAN_NAME]: "query",
+        "db.query": args[0].sql,
+      });
 
       let cb = args[args.length - 1];
       // XXX(toshok) this bindFunction shouldn't be necessary, but we aren't
       // finishing the event properly without it.
       let wrapped_cb = tracker.bindFunction(function(...cb_args) {
-        event.addContext({
-          "db.query": args[0].sql,
-        });
         event.finishEvent(ev, "query");
         return cb(...cb_args);
       });
-      args = args.slice(0, -1).concat(wrapped_cb);
 
-      ev = event.startEvent("mysql2", "query");
-      event.addContext({
-        [schema.PACKAGE_VERSION]: packageVersion,
-      });
-      return original.apply(this, args);
+      return original.apply(this, args.slice(0, -1).concat(wrapped_cb));
     };
   });
   return conn;
diff --git a/lib/instrumentation/react-dom-server.js b/lib/instrumentation/react-dom-server.js
index a00cb63..bb9d4aa 100644
--- a/lib/instrumentation/react-dom-server.js
+++ b/lib/instrumentation/react-dom-server.js
@@ -1,4 +1,4 @@
-/* global require, module */
+/* eslint-env node */
 const shimmer = require("shimmer"),
   event = require("../event"),
   schema = require("../schema");
@@ -10,18 +10,17 @@ function shimRenderMethod(reactDOMServer, name, packageVersion) {
         return original.apply(this, args);
       }
 
-      let ev = event.startEvent("react", name);
-      event.addContext({
+      let ev = event.startEvent({
+        [schema.EVENT_TYPE]: "react",
         [schema.PACKAGE_VERSION]: packageVersion,
+        [schema.TRACE_SPAN_NAME]: name,
       });
-      let rv;
       try {
-        rv = original.apply(this, args);
+        return original.apply(this, args);
       } finally {
         // do we want to include anything else?  the resulting string (might be huge)?
         event.finishEvent(ev, name);
       }
-      return rv;
     };
   });
 }
diff --git a/lib/instrumentation/sequelize.js b/lib/instrumentation/sequelize.js
index 33db793..9c99418 100644
--- a/lib/instrumentation/sequelize.js
+++ b/lib/instrumentation/sequelize.js
@@ -1,4 +1,4 @@
-/* global require, module */
+/* eslint-env node */
 const instrumentBluebird = require("./bluebird");
 
 let instrumentSequelize = sequelize => {
diff --git a/lib/schema.js b/lib/schema.js
index 5095b1a..07a4e2a 100644
--- a/lib/schema.js
+++ b/lib/schema.js
@@ -1,4 +1,4 @@
-/* global exports */
+/* eslint-env node */
 
 exports.EVENT_TYPE = "meta.type"; // XXX(toshok) rename "type" to "source"?
 exports.NODE_VERSION = "meta.node_version";


Test patch:
diff --git a/lib/async_tracker.test.js b/lib/async_tracker.test.js
index 399e799..6af9b4f 100644
--- a/lib/async_tracker.test.js
+++ b/lib/async_tracker.test.js
@@ -1,4 +1,4 @@
-/* global require test expect setTimeout */
+/* eslint-env node, jest */
 const tracker = require("./async_tracker");
 
 test("local (non-continuation-based) tracked access", () => {
diff --git a/lib/deterministic_sampler.test.js b/lib/deterministic_sampler.test.js
index 6f436a5..0ab0bbe 100644
--- a/lib/deterministic_sampler.test.js
+++ b/lib/deterministic_sampler.test.js
@@ -1,4 +1,4 @@
-/* global require test expect */
+/* eslint-env node, jest */
 const DeterministicSampler = require("./deterministic_sampler");
 
 test("it works (sample datapoints)", () => {
diff --git a/lib/event.test.js b/lib/event.test.js
index 32118ea..75f97af 100644
--- a/lib/event.test.js
+++ b/lib/event.test.js
@@ -1,4 +1,4 @@
-/* global require beforeEach afterEach describe test expect __dirname */
+/* eslint-env node, jest */
 const path = require("path"),
   event = require("./event"),
   schema = require("./schema"),
@@ -22,26 +22,29 @@ test("startRequest starts tracking and creates an initial event, finishRequest s
   const honey = event.apiForTesting().honey;
   expect(tracker.getTracked()).toBeUndefined(); // context should be empty initially
 
-  let eventPayload = event.startRequest("source", "name");
+  let requestPayload = event.startRequest({
+    [schema.EVENT_TYPE]: "source",
+    [schema.TRACE_SPAN_NAME]: "name",
+  });
 
   // starting a request creates a context
   let context = tracker.getTracked();
   expect(context).not.toBeUndefined();
 
   // the stack consists solely of the request's event
-  expect(context.stack).toEqual([eventPayload]);
+  expect(context.stack).toEqual([requestPayload]);
   // and it should have these properties
-  expect(eventPayload[schema.EVENT_TYPE]).toBe("source");
-  let traceId = eventPayload[schema.TRACE_ID];
+  expect(requestPayload[schema.EVENT_TYPE]).toBe("source");
+  let traceId = requestPayload[schema.TRACE_ID];
   expect(traceId).not.toBeUndefined();
-  let startTime = eventPayload.startTime;
+  let startTime = requestPayload.startTime;
   expect(startTime).not.toBeUndefined();
 
   // libhoney shouldn't have been told to send anything yet
   expect(honey.transmission.events).toEqual([]);
 
   // finish the request
-  event.finishRequest(eventPayload);
+  event.finishRequest(requestPayload);
   expect(tracker.getTracked()).toBeUndefined(); // context should be cleared
 
   // libhoney should have been told to send one event
@@ -58,28 +61,43 @@ test("startRequest starts tracking and creates an initial event, finishRequest s
 });
 
 test("ending events out of order isn't allowed", () => {
-  let eventPayload = event.startRequest("source", "name");
+  let requestPayload = event.startRequest({
+    [schema.EVENT_TYPE]: "source",
+    [schema.TRACE_SPAN_NAME]: "name",
+  });
   let context = tracker.getTracked();
 
-  expect(context.stack).toEqual([eventPayload]);
+  expect(context.stack).toEqual([requestPayload]);
 
-  let event2Payload = event.startEvent("source2", "name2");
-  let event3Payload = event.startEvent("source3", "name3");
-  expect(context.stack).toEqual([eventPayload, event2Payload, event3Payload]);
+  let event2Payload = event.startEvent({
+    [schema.EVENT_TYPE]: "source2",
+    [schema.TRACE_SPAN_NAME]: "name2",
+  });
+  let event3Payload = event.startEvent({
+    [schema.EVENT_TYPE]: "source3",
+    [schema.TRACE_SPAN_NAME]: "name3",
+  });
+  expect(context.stack).toEqual([requestPayload, event2Payload, event3Payload]);
 
   // if we end event2Payload from the stack, we should also remove event3Payload.
   event.finishEvent(event2Payload);
-  expect(context.stack).toEqual([eventPayload]);
+  expect(context.stack).toEqual([requestPayload]);
 
   // if we finish event3 now, nothing should happen to the stack
   event.finishEvent(event3Payload);
-  expect(context.stack).toEqual([eventPayload]);
+  expect(context.stack).toEqual([requestPayload]);
 });
 
 test("sub-events can opt to rollup count/duration into request events", () => {
-  let requestPayload = event.startRequest("source", "name");
+  let requestPayload = event.startRequest({
+    [schema.EVENT_TYPE]: "source",
+    [schema.TRACE_SPAN_NAME]: "name",
+  });
 
-  let eventPayload = event.startEvent("source2", "name2");
+  let eventPayload = event.startEvent({
+    [schema.EVENT_TYPE]: "source2",
+    [schema.TRACE_SPAN_NAME]: "name2",
+  });
   event.finishEvent(eventPayload, "rollup");
 
   let durationMS = eventPayload[schema.DURATION_MS];
@@ -87,7 +105,10 @@ test("sub-events can opt to rollup count/duration into request events", () => {
   expect(requestPayload["totals.source2.rollup.duration_ms"]).toBe(durationMS);
 
   // another event from the same source
-  let event2Payload = event.startEvent("source2", "name2");
+  let event2Payload = event.startEvent({
+    [schema.EVENT_TYPE]: "source2",
+    [schema.TRACE_SPAN_NAME]: "name2",
+  });
   event.finishEvent(event2Payload, "rollup");
 
   let duration2MS = event2Payload[schema.DURATION_MS];
@@ -99,7 +120,9 @@ test("sub-events can opt to rollup count/duration into request events", () => {
   expect(requestPayload["totals.source2.duration_ms"]).toBe(durationMS + duration2MS);
 
   // one more event from the same source but a different name
-  let event3Payload = event.startEvent("source2");
+  let event3Payload = event.startEvent({
+    [schema.EVENT_TYPE]: "source2",
+  });
   event.finishEvent(event3Payload, "rollup2");
 
   let duration3MS = event3Payload[schema.DURATION_MS];
@@ -118,9 +141,15 @@ test("sub-events can opt to rollup count/duration into request events", () => {
 test("sub-events will get manual tracing fields", () => {
   const honey = event.apiForTesting().honey;
 
-  let requestPayload = event.startRequest("source", "name");
+  let requestPayload = event.startRequest({
+    [schema.EVENT_TYPE]: "source",
+    [schema.TRACE_SPAN_NAME]: "name",
+  });
 
-  let eventPayload = event.startEvent("source2", "name2");
+  let eventPayload = event.startEvent({
+    [schema.EVENT_TYPE]: "source2",
+    [schema.TRACE_SPAN_NAME]: "name2",
+  });
   event.finishEvent(eventPayload);
 
   // finish the request
@@ -141,7 +170,10 @@ describe("custom context", () => {
   test("it should be added to request events", () => {
     const honey = event.apiForTesting().honey;
 
-    let requestPayload = event.startRequest("source", "name");
+    let requestPayload = event.startRequest({
+      [schema.EVENT_TYPE]: "source",
+      [schema.TRACE_SPAN_NAME]: "name",
+    });
 
     event.customContext.add("testKey", "testVal");
 
@@ -155,7 +187,10 @@ describe("custom context", () => {
   test("removing it works too", () => {
     const honey = event.apiForTesting().honey;
 
-    let requestPayload = event.startRequest("source", "name");
+    let requestPayload = event.startRequest({
+      [schema.EVENT_TYPE]: "source",
+      [schema.TRACE_SPAN_NAME]: "name",
+    });
 
     event.customContext.add("testKey", "testVal");
 
@@ -171,14 +206,23 @@ describe("custom context", () => {
   test("it should be added to subevents sent after it was added", () => {
     const honey = event.apiForTesting().honey;
 
-    let requestPayload = event.startRequest("source", "name");
+    let requestPayload = event.startRequest({
+      [schema.EVENT_TYPE]: "source",
+      [schema.TRACE_SPAN_NAME]: "name",
+    });
 
-    let eventPayload = event.startEvent("source2", "name2");
+    let eventPayload = event.startEvent({
+      [schema.EVENT_TYPE]: "source2",
+      [schema.TRACE_SPAN_NAME]: "name2",
+    });
     event.finishEvent(eventPayload);
 
     event.customContext.add("testKey", "testVal");
 
-    let eventPayload2 = event.startEvent("source3", "name3");
+    let eventPayload2 = event.startEvent({
+      [schema.EVENT_TYPE]: "source3",
+      [schema.TRACE_SPAN_NAME]: "name3",
+    });
     event.finishEvent(eventPayload2);
 
     // finish the request
diff --git a/lib/index.test.js b/lib/index.test.js
index 3f27874..777b548 100644
--- a/lib/index.test.js
+++ b/lib/index.test.js
@@ -1,4 +1,4 @@
-/* global require test expect */
+/* eslint-env node, jest */
 test("the default export from the package has asyncTracker and customContext properties", () => {
   const beeline = require("./");
   expect(beeline.asyncTracker).toBeDefined();
diff --git a/lib/instrumentation.test.js b/lib/instrumentation.test.js
index 5f0b9d0..1bd9c13 100644
--- a/lib/instrumentation.test.js
+++ b/lib/instrumentation.test.js
@@ -1,4 +1,4 @@
-/* global require test expect */
+/* eslint-env node, jest */
 const instrumentation = require("./instrumentation");
 
 test("preload shims Promise.then", () => {
diff --git a/lib/instrumentation/child_process.test.js b/lib/instrumentation/child_process.test.js
index 993d708..776aa92 100644
--- a/lib/instrumentation/child_process.test.js
+++ b/lib/instrumentation/child_process.test.js
@@ -1,4 +1,4 @@
-/* global require expect test beforeAll */
+/* eslint-env node, jest */
 const child_process = require("child_process"),
   instrumentChildProcess = require("./child_process"),
   tracker = require("../async_tracker"),
diff --git a/lib/instrumentation/express.test.js b/lib/instrumentation/express.test.js
index a3f5354..9d4c21b 100644
--- a/lib/instrumentation/express.test.js
+++ b/lib/instrumentation/express.test.js
@@ -1,4 +1,4 @@
-/* global __dirname require expect describe test beforeEach afterEach */
+/* eslint-env node, jest */
 const request = require("supertest"),
   path = require("path"),
   instrumentExpress = require("./express"),
diff --git a/lib/instrumentation/http.test.js b/lib/instrumentation/http.test.js
index db96cb3..42086f4 100644
--- a/lib/instrumentation/http.test.js
+++ b/lib/instrumentation/http.test.js
@@ -1,4 +1,4 @@
-/* global require expect test beforeAll afterAll */
+/* eslint-env node, jest */
 const http = require("http"),
   instrumentHttp = require("./http"),
   schema = require("../schema"),
@@ -28,12 +28,12 @@ test("GET http://localhost:9009/ works", done => {
 
   http.get("http://localhost:9009", _res => {
     expect(tracker.getTracked()).toBe(context);
-    expect(event.apiForTesting().sentEvents).toEqual([
-      expect.objectContaining({
+    expect(event.apiForTesting().sentEvents).toMatchObject([
+      {
         [schema.EVENT_TYPE]: "http",
-        name: "request",
+        [schema.TRACE_SPAN_NAME]: "request",
         url: "http://localhost:9009",
-      }),
+      },
     ]);
     done();
   });
diff --git a/lib/instrumentation/https.test.js b/lib/instrumentation/https.test.js
index e28322a..0b4ed09 100644
--- a/lib/instrumentation/https.test.js
+++ b/lib/instrumentation/https.test.js
@@ -1,4 +1,4 @@
-/* global require expect beforeAll test */
+/* eslint-env node, jest */
 const https = require("https"),
   instrumentHttps = require("./https"),
   schema = require("../schema"),
@@ -19,12 +19,12 @@ test("GET https://google.com works", done => {
 
   https.get("https://google.com", _res => {
     expect(tracker.getTracked()).toBe(context);
-    expect(event.apiForTesting().sentEvents).toEqual([
-      expect.objectContaining({
+    expect(event.apiForTesting().sentEvents).toMatchObject([
+      {
         [schema.EVENT_TYPE]: "https",
-        name: "request",
+        [schema.TRACE_SPAN_NAME]: "request",
         url: "https://google.com",
-      }),
+      },
     ]);
     done();
   });
diff --git a/lib/instrumentation/react-dom-server.test.js b/lib/instrumentation/react-dom-server.test.js
index 4aa30fa..83c85c8 100644
--- a/lib/instrumentation/react-dom-server.test.js
+++ b/lib/instrumentation/react-dom-server.test.js
@@ -1,4 +1,4 @@
-/* global require expect test beforeAll describe */
+/* eslint-env node, jest */
 const ReactDOMServer = require("react-dom/server"),
   React = require("react"),
   instrumentReactDOMServer = require("./react-dom-server"),