Skip to content

Commit

Permalink
feat(data-point): implement opentracing interface (#418)
Browse files Browse the repository at this point in the history
closes #414
  • Loading branch information
acatl authored Sep 10, 2019
1 parent 561aca5 commit e8065cd
Show file tree
Hide file tree
Showing 6 changed files with 269 additions and 0 deletions.
102 changes: 102 additions & 0 deletions documentation/examples/opentracing/opentracing-example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/* eslint-disable */

const DataPoint = require("@data-point/core");
const DPModel = require("@data-point/core/model");
const DPIfThenElse = require("@data-point/core/ifThenElse");
const DPMap = require("@data-point/core/map");

const DPOpenTracing = require("@data-point/tracers/opentracing");
const initTracer = require("jaeger-client").initTracer;

const fs = require("fs");

const myModel = DPModel({
name: "myModel",

uid: acc => `${acc.reducer.id}${acc.value.a.b}`,

value: [
"$a.b",
input => input.toUpperCase(),
DPIfThenElse({
if: input => input === "FOO",
then: () => {
// return "yes foo!!";
throw new Error("ohh");
},
else: input => `foo no! got ${input}`
})
],

catch(acc) {
console.log(acc);
return "its ok";
},

params: {
ttl: "20h"
}
});

async function main() {
const datapoint = DataPoint();

const store = new Map();

datapoint.cache.get = (uid, acc) => {
return store.get(uid);
};

datapoint.cache.set = (uid, acc) => {
return store.set(uid, acc.value);
};

const input = [
{
a: {
b: "foo"
}
},
{
a: {
b: "bar"
}
},
{
a: {
b: "baz"
}
}
];

const config = {
serviceName: "data-point-test",
reporter: {
logSpans: true,
agentHost: "localhost",
agentPort: 6832
},
sampler: {
type: "probabilistic",
param: 1.0
}
};

const options = {
tags: {
"data-point-test.version": "1.1.2"
}
};

const openTracer = initTracer(config, options);

const tracer = DPOpenTracing(openTracer);

result = await datapoint.resolve(input, DPMap(myModel), {
tracer
});

openTracer.close();
}

main();
11 changes: 11 additions & 0 deletions documentation/examples/opentracing/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "@data-point/opentracing-example",
"main": "opentracing-example.js",
"private": true,
"version": "1.0.0",
"devDependencies": {
"@data-point/core": "^6.0.0",
"@data-point/tracers": "^1.0.0",
"jaeger-client": "^3.15.0"
}
}
1 change: 1 addition & 0 deletions packages/data-point-tracers/opentracing/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require("./opentracing").OpenTracing.create;
46 changes: 46 additions & 0 deletions packages/data-point-tracers/opentracing/opentracing.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
class OpenTracing {
constructor(tracer) {
this.tracer = tracer;
}

static create(tracer) {
return new OpenTracing(tracer);
}

start(dpSpan) {
const isRoot = dpSpan.root === true;

let oTspan;

if (isRoot) {
oTspan = this.tracer.startSpan(dpSpan.name);
} else {
const parentSpan = dpSpan.parent;
oTspan = this.tracer.startSpan(dpSpan.name, {
childOf: parentSpan.data.span.context()
});
}

// eslint-disable-next-line no-param-reassign
dpSpan.data.span = oTspan;
}

// eslint-disable-next-line class-methods-use-this
error(dpSpan, error) {
// marks the span as an error
dpSpan.data.span.setTag("error", "true");
dpSpan.data.span.log({
"error.description": error.message,
"error.stack": error.stack
});
}

// eslint-disable-next-line class-methods-use-this
finish(dpSpan) {
dpSpan.data.span.finish();
}
}

module.exports = {
OpenTracing
};
103 changes: 103 additions & 0 deletions packages/data-point-tracers/opentracing/opentracing.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
const { OpenTracing } = require("./opentracing");

const mockOpenTraceSpan = {
context: jest.fn(() => "context"),
setTag: jest.fn(),
log: jest.fn(),
finish: jest.fn()
};

const mockOpenTrace = {
startSpan: jest.fn(() => mockOpenTraceSpan)
};

function createSpan() {
return {
name: "name",
parent: {},
data: {}
};
}

afterEach(() => {
jest.clearAllMocks();
});

describe("OpenTracing", () => {
describe("constructor", () => {
it("should set tracer", () => {
const result = new OpenTracing("tracer");
expect(result).toHaveProperty("tracer", "tracer");
});
});

describe("create", () => {
it("should create a new OpenTracing instance", () => {
const result = OpenTracing.create("tracer");
expect(result).toBeInstanceOf(OpenTracing);
expect(result).toHaveProperty("tracer", "tracer");
});
});

describe("start", () => {
it("should create a new root span", () => {
const result = new OpenTracing(mockOpenTrace);
const span = createSpan();
span.root = true;
result.start(span);
expect(mockOpenTrace.startSpan).toBeCalledTimes(1);
expect(mockOpenTrace.startSpan).toBeCalledWith("name");
// store span on `data` property
expect(span.data).toHaveProperty("span", mockOpenTraceSpan);
});

it("should create a new child span", () => {
const result = new OpenTracing(mockOpenTrace);
const span = createSpan();
span.parent = createSpan();
span.parent.data.span = mockOpenTraceSpan;

result.start(span);
expect(mockOpenTrace.startSpan).toBeCalledTimes(1);
expect(mockOpenTrace.startSpan).toBeCalledWith("name", {
childOf: mockOpenTraceSpan.context()
});
// store span on `data` property
expect(span.data).toHaveProperty("span", mockOpenTraceSpan);
});
});

describe("error", () => {
function callErrorAPI(error) {
const result = new OpenTracing(mockOpenTrace);
const span = createSpan();
span.data.span = mockOpenTraceSpan;
result.error(span, error);
return span;
}
it("should set tag with error === 'true'", () => {
const error = new Error("test");
const span = callErrorAPI(error);
expect(span.data.span.setTag).toBeCalledWith("error", "true");
});

it("should add error to log", () => {
const error = new Error("test");
const span = callErrorAPI(error);
expect(span.data.span.log).toBeCalledWith({
"error.description": error.message,
"error.stack": error.stack
});
});
});

describe("finish", () => {
it("should call span.finish()", () => {
const result = new OpenTracing(mockOpenTrace);
const span = createSpan();
span.data.span = mockOpenTraceSpan;
result.finish(span);
expect(span.data.span.finish).toBeCalled();
});
});
});
6 changes: 6 additions & 0 deletions packages/data-point-tracers/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "@data-point/tracers",
"main": "index.js",
"version": "1.0.0",
"private": true
}

0 comments on commit e8065cd

Please sign in to comment.