Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Environment & Services support #551

Merged
merged 11 commits into from
Mar 17, 2022
6 changes: 5 additions & 1 deletion lib/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ const process = require("process"),
pkg = require("../../package.json"),
debug = require("debug")(`${pkg.name}:event`),
LibhoneyImpl = require("./libhoney"),
MockImpl = require("./mock");
MockImpl = require("./mock"),
utils = require("../util");

const { honeycomb, aws, w3c, util } = propagation;

Expand Down Expand Up @@ -38,6 +39,9 @@ module.exports = {
}
debug(`using impl: ${impl == LibhoneyImpl ? "libhoney-event" : "mock"}`);
apiImpl = new impl(opts);

// tell honeycomb propagator whether we should propagate dataset
honeycomb.setPropagateDataset(utils.isClassic(opts.writeKey));
},

traceActive() {
Expand Down
29 changes: 26 additions & 3 deletions lib/api/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,40 @@ jest.mock("../deterministic_sampler");

beforeEach(() => {
api._resetForTesting();
api.configure({ impl: "libhoney-event", transmission: "mock", writeKey: "abc123" });
api.configure({
impl: "libhoney-event",
transmission: "mock",
writeKey: "e38be416d0d68f9ed1e96432ac1a3380",
});
});

test("libhoney default config", () => {
test("libhoney default config - classic", () => {
const honey = api._apiForTesting().honey;
expect(honey.transmission.constructorArg.apiHost).toBe("https://api.honeycomb.io");
expect(honey.transmission.constructorArg.dataset).toBe("nodejs");
expect(honey.transmission.constructorArg.writeKey).toBe("abc123");
expect(honey.transmission.constructorArg.writeKey).toBe("e38be416d0d68f9ed1e96432ac1a3380");
expect(honey.transmission.constructorArg.userAgentAddition).toBe(
`honeycomb-beeline/${pkg.version}`
);
expect(honey._builder._fields["service_name"]).toBe("unknown_service:nodejs");
});

test("libhoney default config - non-classoc", () => {
MikeGoldsmith marked this conversation as resolved.
Show resolved Hide resolved
api._resetForTesting();
api.configure({
impl: "libhoney-event",
transmission: "mock",
writeKey: "d68f9ed1e96432ac1a3380",
});

const honey = api._apiForTesting().honey;
expect(honey.transmission.constructorArg.apiHost).toBe("https://api.honeycomb.io");
expect(honey.transmission.constructorArg.dataset).toBe("unknown_service");
expect(honey.transmission.constructorArg.writeKey).toBe("d68f9ed1e96432ac1a3380");
expect(honey.transmission.constructorArg.userAgentAddition).toBe(
`honeycomb-beeline/${pkg.version}`
);
expect(honey._builder._fields["service_name"]).toBe("unknown_service:nodejs");
});

test("startTrace starts tracking and creates an initial event, finishTrace sends it", () => {
Expand Down
36 changes: 34 additions & 2 deletions lib/api/libhoney.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ const libhoney = require("libhoney"),
schema = require("../schema"),
Span = require("./span"),
pkg = require("../../package.json"),
debug = require("debug")(`${pkg.name}:event`);
debug = require("debug")(`${pkg.name}:event`),
util = require("../util");

const defaultName = "nodejs";

Expand Down Expand Up @@ -81,7 +82,38 @@ module.exports = class LibhoneyEventAPI {
debug(`using proxy ${proxy}`);
}

this.defaultDataset = opts.dataset || process.env["HONEYCOMB_DATASET"] || defaultName;
if (opts.serviceName) {
opts.serviceName.trim();
MikeGoldsmith marked this conversation as resolved.
Show resolved Hide resolved
} else {
console.warn("empty serviceName configuration option");
opts.serviceName = ["unknown_service", process.name ? process.name.trim() : "nodejs"].join(
":"
);
}

if (!opts.writeKey) {
console.warn("empty writeKey configuration option");
}

if (util.isClassic(opts.writeKey)) {
let dataset = opts.dataset || process.env["HONEYCOMB_DATASET"];
if (!dataset) {
console.warn("empty dataset configuration option");
} else {
dataset = dataset.trim();
}

this.defaultDataset = dataset ? dataset : defaultName;
} else {
if (opts.dataset) {
console.warn("dataset should be empty - using service name instead");
}

// don't use process name for unknown services
this.defaultDataset = opts.serviceName.startsWith("unknown_service")
? "unknown_service"
: opts.serviceName;
}

const libhoneyOpts = getFilteredOptions(opts);

Expand Down
13 changes: 11 additions & 2 deletions lib/propagation/honeycomb.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ exports.TRACE_HTTP_HEADER = TRACE_HTTP_HEADER;
const VERSION = "1";
exports.VERSION = VERSION;

let propagateDataset = true;

exports.setPropagateDataset = setPropagateDataset;
function setPropagateDataset(enabled) {
propagateDataset = enabled;
}

// assumes a header of the form:

// VERSION;PAYLOAD
Expand Down Expand Up @@ -38,7 +45,7 @@ function marshalTraceContextv1(context) {
let dataset = context.dataset;

let datasetClause = "";
if (dataset) {
if (propagateDataset && dataset) {
datasetClause = `dataset=${encodeURIComponent(dataset)},`;
}

Expand Down Expand Up @@ -84,7 +91,9 @@ function unmarshalTraceContextv1(payload) {
parentSpanId = v;
break;
case "dataset":
dataset = decodeURIComponent(v);
if (propagateDataset) {
dataset = decodeURIComponent(v);
}
break;
case "context":
contextb64 = v;
Expand Down
16 changes: 15 additions & 1 deletion lib/propagation/honeycomb.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ cases(
);

describe("roundtrip", () => {
test("works", () => {
test("classic", () => {
let contextStr = honeycomb.marshalTraceContext(testContext);
expect(honeycomb.unmarshalTraceContext(contextStr)).toEqual({
traceId: "abcdef123456",
Expand All @@ -93,4 +93,18 @@ describe("roundtrip", () => {
},
});
});

test("non-classic", () => {
honeycomb.setPropagateDataset(false);
let contextStr = honeycomb.marshalTraceContext(testContext);
expect(honeycomb.unmarshalTraceContext(contextStr)).toEqual({
traceId: "abcdef123456",
parentSpanId: "0102030405",
customContext: {
userID: 1,
errorMsg: "failed to sign on",
toRetry: true,
},
});
});
});
6 changes: 6 additions & 0 deletions lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,9 @@ function captureStackTrace(skipFrames = 0, limitFrames = 10) {
// the +1 here to get rid of the `Error\n` line at the top of the stacktrace.
return frames.slice(1 + skipFrames).join("\n");
}

exports.isClassic = isClassic;

function isClassic(writeKey) {
return !writeKey || writeKey.length == 32;
}