datadog-tracer
Advanced tools
Comparing version 0.3.0 to 0.3.1
@@ -1,15 +0,30 @@ | ||
const Tracer = require('../src') | ||
var express = require('express') | ||
var Tracer = require('../src') | ||
const tracer = new Tracer({ service: 'test' }) | ||
var app = express() | ||
var tracer = new Tracer({ service: 'example' }) | ||
const span = tracer.startSpan('someOperation') | ||
tracer.on('error', function (e) { | ||
console.log(e) | ||
}) | ||
span.addTags({ | ||
'resource': '/user/:id', // required by Datadog | ||
'type': 'web', // required by Datadog | ||
'span.kind': 'server', | ||
'http.method': 'GET', | ||
'http.url': '/user/123', | ||
'http.status_code': '200' | ||
app.get('/hello/:name', function (req, res) { | ||
var span = tracer.startSpan('say_hello') | ||
res.status(200) | ||
span.addTags({ | ||
'resource': req.route.path, | ||
'type': 'web', | ||
'span.kind': 'server', | ||
'http.method': req.method, | ||
'http.url': req.url, | ||
'http.status_code': res.statusCode | ||
}) | ||
span.finish() | ||
res.send('Hello, ' + req.params.name + '!') | ||
}) | ||
span.finish() | ||
app.listen(3000) |
@@ -5,3 +5,3 @@ # Datadog Tracer Example | ||
**Note: Don't forget to replace <Your API Key> with your actual API key from Datadog.** | ||
**Note: Don't forget to replace `<Your API Key>` with your actual API key from Datadog.** | ||
@@ -15,9 +15,9 @@ ```sh | ||
```sh | ||
node ./example | ||
node example | ||
``` | ||
This will start the server on port `31337`. You can then make requests on the server to generate traces: | ||
This will start the server on port `3000`. You can then make requests on the server to generate traces: | ||
```sh | ||
curl http://localhost:31337/hello/world | ||
curl http://localhost:3000/hello/World | ||
``` |
{ | ||
"name": "datadog-tracer", | ||
"version": "0.3.0", | ||
"version": "0.3.1", | ||
"description": "OpenTracing Tracer implementation for Datadog in JavaScript", | ||
@@ -34,6 +34,3 @@ "main": "src/index.js", | ||
"performance-now": "^2.1.0", | ||
"protobufjs": "^6.7.3", | ||
"safe-buffer": "^5.0.1", | ||
"superagent": "^3.5.2", | ||
"uuid": "^3.0.1" | ||
"protobufjs": "^6.7.3" | ||
}, | ||
@@ -49,2 +46,3 @@ "devDependencies": { | ||
"eslint-plugin-standard": "^3.0.1", | ||
"express": "^4.15.2", | ||
"mocha": "^3.2.0", | ||
@@ -51,0 +49,0 @@ "nock": "^9.0.13", |
@@ -45,3 +45,4 @@ # Datadog Tracer | ||
var tracer = new Tracer({ service: 'my service' }) | ||
var app = express() | ||
var tracer = new Tracer({ service: 'example' }) | ||
@@ -53,25 +54,25 @@ // handle errors from Datadog agent. omit this if you want to ignore errors | ||
var app = express() | ||
app.get('/hello/:name', function (req, res) { | ||
var span = tracer.startSpan('say_hello') | ||
app.get('/user/:id', function (req, res) { | ||
var span = tracer.startSpan('someOperation') | ||
res.status(200) | ||
// do stuff | ||
span.addTags({ | ||
'resource': '/user/:id', // required by Datadog | ||
'resource': req.route.path, // required by Datadog | ||
'type': 'web', // required by Datadog | ||
'span.kind': 'server', | ||
'http.method': 'GET', | ||
'http.url': '/user/123', | ||
'http.status_code': '200' | ||
'http.method': req.method, | ||
'http.url': req.url, | ||
'http.status_code': res.statusCode | ||
}) | ||
span.finish() | ||
res.send() | ||
res.send('Hello, ' + req.params.name + '!') | ||
}) | ||
app.listen(3000) | ||
``` | ||
See the [semantic conventions](https://github.com/opentracing/specification/blob/master/semantic_conventions.md) for | ||
more information about tags. | ||
See the [example](example) folder to run this example. | ||
@@ -81,1 +82,6 @@ ## API Documentation | ||
See the OpenTracing JavaScript [API](https://doc.esdoc.org/github.com/opentracing/opentracing-javascript/) | ||
## Additional Resources | ||
* [OpenTracing Specification](https://github.com/opentracing/specification/blob/master/specification.md) | ||
* [OpenTracing Semantic Conventions](https://github.com/opentracing/specification/blob/master/semantic_conventions.md) |
'use strict' | ||
const http = require('http') | ||
const now = require('performance-now') | ||
const Long = require('long') | ||
const loadNs = now() | ||
@@ -10,3 +12,57 @@ const loadMs = Date.now() | ||
return Math.round((loadMs + now() - loadNs) * 100000) / 100000 | ||
}, | ||
id () { | ||
return new Long(random(), random(), true) | ||
}, | ||
request (options) { | ||
options = Object.assign({ | ||
headers: {} | ||
}, options) | ||
options.headers['Content-Type'] = 'application/json' | ||
options.headers['Content-Length'] = Buffer.byteLength(options.data || '', 'utf8') | ||
return new Promise((resolve, reject) => { | ||
const req = http.request(options, (res) => { | ||
let body = '' | ||
res.setEncoding('utf8') | ||
res.on('data', (chunk) => { | ||
body += chunk | ||
}) | ||
res.on('end', () => { | ||
if (res.statusCode >= 200 && res.statusCode <= 299) { | ||
resolve() | ||
} else { | ||
const error = new Error(http.STATUS_CODES[res.statusCode]) | ||
error.status = res.statusCode | ||
error.response = { | ||
body, headers: res.rawHeaders | ||
} | ||
reject(error) | ||
} | ||
}) | ||
}) | ||
req.on('error', e => reject(e)) | ||
req.write(options.data) | ||
req.end() | ||
}) | ||
} | ||
} | ||
function random () { | ||
let number = 0 | ||
for (let i = 0; i < 4; i++) { | ||
number += Math.floor(Math.random() * 255) << (i * 8) | ||
} | ||
return number | ||
} |
'use strict' | ||
const request = require('superagent') | ||
const bignumJSON = require('json-bignum') | ||
const platform = require('./platform') | ||
@@ -11,3 +11,3 @@ class DatadogRecorder { | ||
const body = bignumJSON.stringify([[{ | ||
const data = bignumJSON.stringify([[{ | ||
trace_id: new bignumJSON.BigNumber(spanContext.traceId.toString()), | ||
@@ -26,6 +26,10 @@ span_id: new bignumJSON.BigNumber(spanContext.spanId.toString()), | ||
return request | ||
.put(`${tracer._endpoint}/v0.3/traces`) | ||
.set('Content-Type', 'application/json') | ||
.send(body) | ||
return platform.request({ | ||
protocol: tracer._endpoint.protocol, | ||
hostname: tracer._endpoint.hostname, | ||
port: tracer._endpoint.port, | ||
path: '/v0.3/traces', | ||
method: 'PUT', | ||
data | ||
}) | ||
} | ||
@@ -32,0 +36,0 @@ } |
'use strict' | ||
const uuid = require('uuid') | ||
const Long = require('long') | ||
const Buffer = require('safe-buffer').Buffer | ||
const opentracing = require('opentracing') | ||
@@ -32,3 +29,3 @@ const Span = opentracing.Span | ||
traceId: parent.traceId, | ||
spanId: generateUUID(), | ||
spanId: platform.id(), | ||
sampled: parent.sampled, | ||
@@ -41,4 +38,4 @@ baggageItems: Object.assign({}, parent.baggageItems) | ||
this._spanContext = new SpanContext({ | ||
traceId: generateUUID(), | ||
spanId: generateUUID(), | ||
traceId: platform.id(), | ||
spanId: platform.id(), | ||
sampled: this._sampler.isSampled(this), | ||
@@ -82,2 +79,3 @@ baggageItems: {} | ||
this._duration = finishTime - this._startTime | ||
this._recorder.record(this) | ||
@@ -90,8 +88,2 @@ .catch(e => { | ||
function generateUUID () { | ||
const buffer = Buffer.alloc(8) | ||
uuid.v4(null, buffer) | ||
return new Long(buffer.readUInt32LE(), buffer.readUInt32LE(4), true) | ||
} | ||
module.exports = DatadogSpan |
@@ -9,2 +9,3 @@ 'use strict' | ||
const BinaryPropagator = require('./propagation/binary') | ||
const Endpoint = require('./endpoint') | ||
@@ -14,2 +15,3 @@ class DatadogTracer extends Tracer { | ||
super() | ||
EventEmitter.call(this) | ||
@@ -23,4 +25,3 @@ const service = config.service | ||
this._service = service | ||
this._endpoint = endpoint || `${protocol}://${hostname}:${port}` | ||
this._emitter = new EventEmitter() | ||
this._endpoint = new Endpoint(endpoint || `${protocol}://${hostname}:${port}`) | ||
} | ||
@@ -47,2 +48,4 @@ | ||
Object.assign(DatadogTracer.prototype, EventEmitter.prototype) | ||
function getPropagator (format) { | ||
@@ -84,8 +87,2 @@ let propagator | ||
Object.keys(EventEmitter.prototype).forEach(method => { | ||
DatadogTracer.prototype[method] = function () { | ||
this._emitter[method].apply(this._emitter, arguments) | ||
} | ||
}) | ||
module.exports = DatadogTracer |
'use strict' | ||
const proxyquire = require('proxyquire') | ||
const nock = require('nock') | ||
@@ -11,2 +12,3 @@ describe('Platform', () => { | ||
sinon.stub(Date, 'now').returns(1000000000) | ||
sinon.stub(Math, 'random') | ||
now = sinon.stub().returns(100.11111) | ||
@@ -18,2 +20,3 @@ platform = proxyquire('../src/platform', { 'performance-now': now }) | ||
Date.now.restore() | ||
Math.random.restore() | ||
}) | ||
@@ -26,2 +29,57 @@ | ||
}) | ||
it('should return a random 64bit ID', () => { | ||
Math.random.onCall(0).returns(0) | ||
Math.random.onCall(1).returns(1) | ||
Math.random.onCall(2).returns(0) | ||
Math.random.onCall(3).returns(0) | ||
expect(platform.id().toString()).to.equal(String(255 << 8)) | ||
}) | ||
it('should send an http request', () => { | ||
nock('http://test:123', { | ||
reqheaders: { | ||
'content-type': 'application/json', | ||
'content-length': '13' | ||
} | ||
}) | ||
.put('/path', { foo: 'bar' }) | ||
.reply(200) | ||
return platform.request({ | ||
protocol: 'http:', | ||
hostname: 'test', | ||
port: 123, | ||
path: '/path', | ||
method: 'PUT', | ||
data: JSON.stringify({ foo: 'bar' }) | ||
}) | ||
}) | ||
it('should handle an http error response', () => { | ||
nock('http://localhost:80') | ||
.put('/path') | ||
.reply(400) | ||
return platform.request({ | ||
path: '/path', | ||
method: 'PUT' | ||
}) | ||
.then(() => setImmediate(() => { throw new Error() })) | ||
.catch(e => { | ||
expect(e).to.be.instanceof(Error) | ||
}) | ||
}) | ||
it('should handle an http network error', () => { | ||
return platform.request({ | ||
path: '/path', | ||
method: 'PUT' | ||
}) | ||
.then(() => setImmediate(() => { throw new Error() })) | ||
.catch(e => { | ||
expect(e).to.be.instanceof(Error) | ||
}) | ||
}) | ||
}) |
'use strict' | ||
const Long = require('long') | ||
const Endpoint = require('../src/endpoint') | ||
@@ -18,3 +19,3 @@ describe('Recorder', () => { | ||
_service: 'service', | ||
_endpoint: 'http://localhost:8080' | ||
_endpoint: new Endpoint('https://localhost:8080') | ||
} | ||
@@ -65,3 +66,3 @@ | ||
reqheaders: { | ||
'Content-Type': 'application/json' | ||
'content-type': 'application/json' | ||
} | ||
@@ -72,6 +73,3 @@ }) | ||
return recorder.record(span).then(response => { | ||
expect(response.status).to.equal(200) | ||
expect(response.text).to.equal(expected) | ||
}) | ||
return recorder.record(span) | ||
}) | ||
@@ -92,3 +90,3 @@ | ||
reqheaders: { | ||
'Content-Type': 'application/json' | ||
'content-type': 'application/json' | ||
} | ||
@@ -99,7 +97,4 @@ }) | ||
return recorder.record(span).then(response => { | ||
expect(response.status).to.equal(200) | ||
expect(response.text).to.equal(expected) | ||
}) | ||
return recorder.record(span) | ||
}) | ||
}) |
@@ -13,6 +13,6 @@ 'use strict' | ||
let recorder | ||
let uuid | ||
let platform | ||
beforeEach(() => { | ||
uuid = { v4: sinon.stub() } | ||
platform = { id: sinon.stub().returns(new Long(0, 0, true)) } | ||
tracer = new EventEmitter() | ||
@@ -23,3 +23,3 @@ recorder = { record: sinon.stub() } | ||
Span = proxyquire('../src/span', { | ||
'uuid': uuid, | ||
'./platform': platform, | ||
'./tracer': tracer, | ||
@@ -26,0 +26,0 @@ './recorder': Recorder |
@@ -6,2 +6,3 @@ 'use strict' | ||
const Reference = opentracing.Reference | ||
const Endpoint = require('../src/endpoint') | ||
@@ -46,4 +47,2 @@ describe('Tracer', () => { | ||
it('should support host configuration', () => { | ||
const endpoint = 'https://test:7777' | ||
tracer = new Tracer({ | ||
@@ -56,11 +55,11 @@ service: 'service', | ||
expect(tracer._endpoint).to.equal(endpoint) | ||
expect(tracer._endpoint).to.deep.equal(new Endpoint('https://test:7777')) | ||
}) | ||
it('should support endpoint configuration', () => { | ||
const endpoint = 'test' | ||
const endpoint = 'http://test:123' | ||
tracer = new Tracer({ service: 'service', endpoint }) | ||
expect(tracer._endpoint).to.equal(endpoint) | ||
expect(tracer._endpoint).to.deep.equal(new Endpoint('http://test:123')) | ||
}) | ||
@@ -67,0 +66,0 @@ |
Sorry, the diff of this file is not supported yet
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
36046
6
36
951
85
16
1
- Removedsafe-buffer@^5.0.1
- Removedsuperagent@^3.5.2
- Removeduuid@^3.0.1
- Removedasynckit@0.4.0(transitive)
- Removedcall-bind-apply-helpers@1.0.2(transitive)
- Removedcall-bound@1.0.3(transitive)
- Removedcombined-stream@1.0.8(transitive)
- Removedcomponent-emitter@1.3.1(transitive)
- Removedcookiejar@2.1.4(transitive)
- Removedcore-util-is@1.0.3(transitive)
- Removeddebug@3.2.7(transitive)
- Removeddelayed-stream@1.0.0(transitive)
- Removeddunder-proto@1.0.1(transitive)
- Removedes-define-property@1.0.1(transitive)
- Removedes-errors@1.3.0(transitive)
- Removedes-object-atoms@1.1.1(transitive)
- Removedextend@3.0.2(transitive)
- Removedform-data@2.5.2(transitive)
- Removedformidable@1.2.6(transitive)
- Removedfunction-bind@1.1.2(transitive)
- Removedget-intrinsic@1.2.7(transitive)
- Removedget-proto@1.0.1(transitive)
- Removedgopd@1.2.0(transitive)
- Removedhas-symbols@1.1.0(transitive)
- Removedhasown@2.0.2(transitive)
- Removedinherits@2.0.4(transitive)
- Removedisarray@1.0.0(transitive)
- Removedmath-intrinsics@1.1.0(transitive)
- Removedmethods@1.1.2(transitive)
- Removedmime@1.6.0(transitive)
- Removedmime-db@1.52.0(transitive)
- Removedmime-types@2.1.35(transitive)
- Removedms@2.1.3(transitive)
- Removedobject-inspect@1.13.4(transitive)
- Removedprocess-nextick-args@2.0.1(transitive)
- Removedqs@6.14.0(transitive)
- Removedreadable-stream@2.3.8(transitive)
- Removedsafe-buffer@5.1.25.2.1(transitive)
- Removedside-channel@1.1.0(transitive)
- Removedside-channel-list@1.0.0(transitive)
- Removedside-channel-map@1.0.1(transitive)
- Removedside-channel-weakmap@1.0.2(transitive)
- Removedstring_decoder@1.1.1(transitive)
- Removedsuperagent@3.8.3(transitive)
- Removedutil-deprecate@1.0.2(transitive)
- Removeduuid@3.4.0(transitive)