Skip to content

Commit 158cb42

Browse files
committed
feat(data-point): implement opentracing interface
closes ViacomInc#414
1 parent dc81612 commit 158cb42

File tree

6 files changed

+269
-0
lines changed

6 files changed

+269
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"name": "@data-point/opentracing-example",
3+
"main": "playground-opentracing.js",
4+
"private": true,
5+
"version": "1.0.0",
6+
"devDependencies": {
7+
"@data-point/core": "^6.0.0",
8+
"@data-point/tracers": "^1.0.0",
9+
"jaeger-client": "^3.15.0"
10+
}
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/* eslint-disable */
2+
3+
const DataPoint = require("@data-point/core");
4+
const DPModel = require("@data-point/core/model");
5+
const DPIfThenElse = require("@data-point/core/ifThenElse");
6+
const DPMap = require("@data-point/core/map");
7+
8+
const DPOpenTracing = require("@data-point/tracers/opentracing");
9+
const initTracer = require("jaeger-client").initTracer;
10+
11+
const fs = require("fs");
12+
13+
const myModel = DPModel({
14+
name: "myModel",
15+
16+
uid: acc => `${acc.reducer.id}${acc.value.a.b}`,
17+
18+
value: [
19+
"$a.b",
20+
input => input.toUpperCase(),
21+
DPIfThenElse({
22+
if: input => input === "FOO",
23+
then: () => {
24+
// return "yes foo!!";
25+
throw new Error("ohh");
26+
},
27+
else: input => `foo no! got ${input}`
28+
})
29+
],
30+
31+
catch(acc) {
32+
console.log(acc);
33+
return "its ok";
34+
},
35+
36+
params: {
37+
ttl: "20h"
38+
}
39+
});
40+
41+
async function main() {
42+
const datapoint = DataPoint();
43+
44+
const store = new Map();
45+
46+
datapoint.cache.get = (uid, acc) => {
47+
return store.get(uid);
48+
};
49+
50+
datapoint.cache.set = (uid, acc) => {
51+
return store.set(uid, acc.value);
52+
};
53+
54+
const input = [
55+
{
56+
a: {
57+
b: "foo"
58+
}
59+
},
60+
{
61+
a: {
62+
b: "bar"
63+
}
64+
},
65+
{
66+
a: {
67+
b: "baz"
68+
}
69+
}
70+
];
71+
72+
const config = {
73+
serviceName: "data-point-test",
74+
reporter: {
75+
logSpans: true,
76+
agentHost: "localhost",
77+
agentPort: 6832
78+
},
79+
sampler: {
80+
type: "probabilistic",
81+
param: 1.0
82+
}
83+
};
84+
85+
const options = {
86+
tags: {
87+
"data-point-test.version": "1.1.2"
88+
}
89+
};
90+
91+
const openTracer = initTracer(config, options);
92+
93+
const tracer = DPOpenTracing(openTracer);
94+
95+
result = await datapoint.resolve(input, DPMap(myModel), {
96+
tracer
97+
});
98+
99+
openTracer.close();
100+
}
101+
102+
main();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require("./opentracing").OpenTracing.create;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
class OpenTracing {
2+
constructor(tracer) {
3+
this.tracer = tracer;
4+
}
5+
6+
static create(tracer) {
7+
return new OpenTracing(tracer);
8+
}
9+
10+
start(dpSpan) {
11+
const isRoot = dpSpan.root === true;
12+
13+
let oTspan;
14+
15+
if (isRoot) {
16+
oTspan = this.tracer.startSpan(dpSpan.name);
17+
} else {
18+
const parentSpan = dpSpan.parent;
19+
oTspan = this.tracer.startSpan(dpSpan.name, {
20+
childOf: parentSpan.data.span.context()
21+
});
22+
}
23+
24+
// eslint-disable-next-line no-param-reassign
25+
dpSpan.data.span = oTspan;
26+
}
27+
28+
// eslint-disable-next-line class-methods-use-this
29+
error(dpSpan, error) {
30+
// marks the span as an error
31+
dpSpan.data.span.setTag("error", "true");
32+
dpSpan.data.span.log({
33+
"error.description": error.message,
34+
"error.stack": error.stack
35+
});
36+
}
37+
38+
// eslint-disable-next-line class-methods-use-this
39+
finish(dpSpan) {
40+
dpSpan.data.span.finish();
41+
}
42+
}
43+
44+
module.exports = {
45+
OpenTracing
46+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
const { OpenTracing } = require("./opentracing");
2+
3+
const mockOpenTraceSpan = {
4+
context: jest.fn(() => "context"),
5+
setTag: jest.fn(),
6+
log: jest.fn(),
7+
finish: jest.fn()
8+
};
9+
10+
const mockOpenTrace = {
11+
startSpan: jest.fn(() => mockOpenTraceSpan)
12+
};
13+
14+
function createSpan() {
15+
return {
16+
name: "name",
17+
parent: {},
18+
data: {}
19+
};
20+
}
21+
22+
afterEach(() => {
23+
jest.clearAllMocks();
24+
});
25+
26+
describe("OpenTracing", () => {
27+
describe("constructor", () => {
28+
it("should set tracer", () => {
29+
const result = new OpenTracing("tracer");
30+
expect(result).toHaveProperty("tracer", "tracer");
31+
});
32+
});
33+
34+
describe("create", () => {
35+
it("should create a new OpenTracing instance", () => {
36+
const result = OpenTracing.create("tracer");
37+
expect(result).toBeInstanceOf(OpenTracing);
38+
expect(result).toHaveProperty("tracer", "tracer");
39+
});
40+
});
41+
42+
describe("start", () => {
43+
it("should create a new root span", () => {
44+
const result = new OpenTracing(mockOpenTrace);
45+
const span = createSpan();
46+
span.root = true;
47+
result.start(span);
48+
expect(mockOpenTrace.startSpan).toBeCalledTimes(1);
49+
expect(mockOpenTrace.startSpan).toBeCalledWith("name");
50+
// store span on `data` property
51+
expect(span.data).toHaveProperty("span", mockOpenTraceSpan);
52+
});
53+
54+
it("should create a new child span", () => {
55+
const result = new OpenTracing(mockOpenTrace);
56+
const span = createSpan();
57+
span.parent = createSpan();
58+
span.parent.data.span = mockOpenTraceSpan;
59+
60+
result.start(span);
61+
expect(mockOpenTrace.startSpan).toBeCalledTimes(1);
62+
expect(mockOpenTrace.startSpan).toBeCalledWith("name", {
63+
childOf: mockOpenTraceSpan.context()
64+
});
65+
// store span on `data` property
66+
expect(span.data).toHaveProperty("span", mockOpenTraceSpan);
67+
});
68+
});
69+
70+
describe("error", () => {
71+
function callErrorAPI(error) {
72+
const result = new OpenTracing(mockOpenTrace);
73+
const span = createSpan();
74+
span.data.span = mockOpenTraceSpan;
75+
result.error(span, error);
76+
return span;
77+
}
78+
it("should set tag with error === 'true'", () => {
79+
const error = new Error("test");
80+
const span = callErrorAPI(error);
81+
expect(span.data.span.setTag).toBeCalledWith("error", "true");
82+
});
83+
84+
it("should add error to log", () => {
85+
const error = new Error("test");
86+
const span = callErrorAPI(error);
87+
expect(span.data.span.log).toBeCalledWith({
88+
"error.description": error.message,
89+
"error.stack": error.stack
90+
});
91+
});
92+
});
93+
94+
describe("finish", () => {
95+
it("should call span.finish()", () => {
96+
const result = new OpenTracing(mockOpenTrace);
97+
const span = createSpan();
98+
span.data.span = mockOpenTraceSpan;
99+
result.finish(span);
100+
expect(span.data.span.finish).toBeCalled();
101+
});
102+
});
103+
});
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "@data-point/tracers",
3+
"main": "index.js",
4+
"version": "1.0.0",
5+
"private": true
6+
}

0 commit comments

Comments
 (0)