Comparing version
@@ -1,1 +0,1 @@ | ||
module.exports = '0.5.2' | ||
module.exports = '0.5.3' |
{ | ||
"name": "dd-trace", | ||
"version": "0.5.2", | ||
"version": "0.5.3", | ||
"description": "Datadog APM tracing client for JavaScript", | ||
@@ -36,5 +36,2 @@ "main": "index.js", | ||
"async-hook-jl": "^1.7.6", | ||
"cls-bluebird": "^2.1.0", | ||
"cls-hooked": "^4.2.2", | ||
"continuation-local-storage": "^3.2.1", | ||
"int64-buffer": "^0.1.9", | ||
@@ -72,2 +69,3 @@ "koalas": "^1.0.2", | ||
"eslint-plugin-standard": "^3.0.1", | ||
"eventemitter3": "^3.1.0", | ||
"express": "^4.16.2", | ||
@@ -74,0 +72,0 @@ "get-port": "^3.2.0", |
'use strict' | ||
const EventEmitter = require('events') | ||
const id = require('./id') | ||
@@ -11,3 +12,5 @@ const now = require('./now') | ||
module.exports = { | ||
const emitter = new EventEmitter() | ||
const platform = { | ||
_config: {}, | ||
@@ -26,3 +29,10 @@ name: () => 'nodejs', | ||
request, | ||
msgpack | ||
msgpack, | ||
on: emitter.on.bind(emitter), | ||
once: emitter.once.bind(emitter), | ||
off: emitter.removeListener.bind(emitter) | ||
} | ||
process.once('beforeExit', () => emitter.emit('exit')) | ||
module.exports = platform |
@@ -77,5 +77,4 @@ 'use strict' | ||
const matchers = layer._datadog_matchers | ||
const scope = tracer.scopeManager().active() | ||
if (matchers && scope) { | ||
if (matchers) { | ||
const paths = req._datadog_paths || [] | ||
@@ -127,13 +126,14 @@ | ||
if (req._datadog_trace_patched) { | ||
const scope = tracer.scopeManager().active() | ||
const originalNext = next | ||
return function () { | ||
const scope = tracer.scopeManager().active() | ||
const paths = req._datadog_paths | ||
if (scope) { | ||
const paths = req._datadog_paths | ||
if (paths && layer.path && !layer.regexp.fast_star) { | ||
paths.pop() | ||
} | ||
if (paths && layer.path && !layer.regexp.fast_star) { | ||
paths.pop() | ||
} | ||
if (!tracer.scopeManager().active() && scope) { | ||
tracer.scopeManager().activate(scope.span()) | ||
} | ||
@@ -140,0 +140,0 @@ |
@@ -22,4 +22,2 @@ 'use strict' | ||
let isFinish = false | ||
options = typeof options === 'string' ? url.parse(uri) : Object.assign({}, options) | ||
@@ -42,12 +40,17 @@ options.headers = options.headers || {} | ||
tracer.inject(span, FORMAT_HTTP_HEADERS, options.headers) | ||
if (!hasAmazonSignature(options)) { | ||
tracer.inject(span, FORMAT_HTTP_HEADERS, options.headers) | ||
} | ||
const req = request.call(this, options, res => { | ||
const req = request.call(this, options, callback) | ||
req.on('response', res => { | ||
span.setTag(Tags.HTTP_STATUS_CODE, res.statusCode) | ||
res.on('end', finish) | ||
callback && callback(res) | ||
}) | ||
req.on('socket', socket => { | ||
socket.on('close', finish) | ||
res.on('end', () => span.finish()) | ||
// empty the data stream when no other listener exists to consume it | ||
if (req.listenerCount('response') === 1) { | ||
res.resume() | ||
} | ||
}) | ||
@@ -65,9 +68,2 @@ | ||
function finish () { | ||
if (!isFinish) { | ||
isFinish = true | ||
span.finish() | ||
} | ||
} | ||
return req | ||
@@ -111,2 +107,22 @@ } | ||
function hasAmazonSignature (options) { | ||
if (!options) { | ||
return false | ||
} | ||
if (options.headers) { | ||
const headers = Object.keys(options.headers) | ||
.reduce((prev, next) => Object.assign(prev, { | ||
[next.toLowerCase()]: options.headers[next] | ||
}), {}) | ||
if (headers['x-amz-signature'] || | ||
(headers['authorization'] && headers['authorization'].startsWith('AWS4-HMAC-SHA256'))) { | ||
return true | ||
} | ||
} | ||
return options.path && options.path.toLowerCase().indexOf('x-amz-signature=') !== -1 | ||
} | ||
function unpatch (http) { | ||
@@ -113,0 +129,0 @@ this.unwrap(http, 'request') |
'use strict' | ||
// TODO: flush on process exit | ||
const platform = require('./platform') | ||
@@ -15,2 +15,4 @@ class Scheduler { | ||
this._timer.unref && this._timer.unref() | ||
platform.on('exit', this._callback) | ||
} | ||
@@ -20,2 +22,4 @@ | ||
clearInterval(this._timer) | ||
platform.off('exit', this._callback) | ||
} | ||
@@ -22,0 +26,0 @@ |
@@ -271,2 +271,36 @@ 'use strict' | ||
it('should not lose the current path without a scope', done => { | ||
const app = express() | ||
const router = express.Router() | ||
router.use((req, res, next) => { | ||
const scope = tracer.scopeManager().active() | ||
scope.close() | ||
next() | ||
}) | ||
router.get('/user/:id', (req, res) => { | ||
res.status(200).send() | ||
}) | ||
app.use('/app', router) | ||
getPort().then(port => { | ||
agent | ||
.use(traces => { | ||
expect(traces[0][0]).to.have.property('resource', 'GET /app/user/:id') | ||
}) | ||
.then(done) | ||
.catch(done) | ||
appListener = app.listen(port, 'localhost', () => { | ||
axios | ||
.get(`http://localhost:${port}/app/user/123`) | ||
.catch(done) | ||
}) | ||
}) | ||
}) | ||
it('should fallback to the the verb if a path pattern could not be found', done => { | ||
@@ -318,2 +352,37 @@ const app = express() | ||
it('should reactivate the span when the active scope is closed', done => { | ||
const app = express() | ||
let span | ||
let scope | ||
app.use((req, res, next) => { | ||
scope = tracer.scopeManager().active() | ||
span = scope.span() | ||
scope.close() | ||
next() | ||
}) | ||
app.get('/user', (req, res) => { | ||
const scope = tracer.scopeManager().active() | ||
res.status(200).send() | ||
try { | ||
expect(scope).to.not.be.null | ||
expect(scope.span()).to.equal(span) | ||
done() | ||
} catch (e) { | ||
done(e) | ||
} | ||
}) | ||
getPort().then(port => { | ||
appListener = app.listen(port, 'localhost', () => { | ||
axios.get(`http://localhost:${port}/user`) | ||
.catch(done) | ||
}) | ||
}) | ||
}) | ||
it('should only include paths for routes that matched', done => { | ||
@@ -320,0 +389,0 @@ const app = express() |
@@ -178,2 +178,90 @@ 'use strict' | ||
it('should skip injecting if the Authorization header contains an AWS signature', done => { | ||
const app = express() | ||
app.get('/', (req, res) => { | ||
try { | ||
expect(req.get('x-datadog-trace-id')).to.be.undefined | ||
expect(req.get('x-datadog-parent-id')).to.be.undefined | ||
res.status(200).send() | ||
done() | ||
} catch (e) { | ||
done(e) | ||
} | ||
}) | ||
getPort().then(port => { | ||
appListener = app.listen(port, 'localhost', () => { | ||
const req = http.request({ | ||
port, | ||
headers: { | ||
Authorization: 'AWS4-HMAC-SHA256 ...' | ||
} | ||
}) | ||
req.end() | ||
}) | ||
}) | ||
}) | ||
it('should skip injecting if the X-Amz-Signature header is set', done => { | ||
const app = express() | ||
app.get('/', (req, res) => { | ||
try { | ||
expect(req.get('x-datadog-trace-id')).to.be.undefined | ||
expect(req.get('x-datadog-parent-id')).to.be.undefined | ||
res.status(200).send() | ||
done() | ||
} catch (e) { | ||
done(e) | ||
} | ||
}) | ||
getPort().then(port => { | ||
appListener = app.listen(port, 'localhost', () => { | ||
const req = http.request({ | ||
port, | ||
headers: { | ||
'X-Amz-Signature': 'abc123' | ||
} | ||
}) | ||
req.end() | ||
}) | ||
}) | ||
}) | ||
it('should skip injecting if the X-Amz-Signature query param is set', done => { | ||
const app = express() | ||
app.get('/', (req, res) => { | ||
try { | ||
expect(req.get('x-datadog-trace-id')).to.be.undefined | ||
expect(req.get('x-datadog-parent-id')).to.be.undefined | ||
res.status(200).send() | ||
done() | ||
} catch (e) { | ||
done(e) | ||
} | ||
}) | ||
getPort().then(port => { | ||
appListener = app.listen(port, 'localhost', () => { | ||
const req = http.request({ | ||
port, | ||
path: '/?X-Amz-Signature=abc123' | ||
}) | ||
req.end() | ||
}) | ||
}) | ||
}) | ||
it('should run the callback in the parent context', done => { | ||
@@ -180,0 +268,0 @@ const app = express() |
'use strict' | ||
const EventEmitter = require('eventemitter3') | ||
const proxyquire = require('proxyquire').noCallThru() | ||
describe('Scheduler', () => { | ||
let Scheduler | ||
let clock | ||
let platform | ||
beforeEach(() => { | ||
Scheduler = require('../src/scheduler') | ||
platform = new EventEmitter() | ||
Scheduler = proxyquire('../src/scheduler', { | ||
'./platform': platform | ||
}) | ||
clock = sinon.useFakeTimers() | ||
@@ -30,2 +39,12 @@ }) | ||
}) | ||
it('should call the callback when the process exits gracefully', () => { | ||
const spy = sinon.spy() | ||
const scheduler = new Scheduler(spy, 5000) | ||
scheduler.start() | ||
platform.emit('exit') | ||
expect(spy).to.have.been.called | ||
}) | ||
}) | ||
@@ -44,2 +63,13 @@ | ||
}) | ||
it('should stop calling the callback when the process exits gracefully', () => { | ||
const spy = sinon.spy() | ||
const scheduler = new Scheduler(spy, 5000) | ||
scheduler.start() | ||
scheduler.stop() | ||
platform.emit('exit') | ||
expect(spy).to.not.have.been.called | ||
}) | ||
}) | ||
@@ -46,0 +76,0 @@ |
Sorry, the diff of this file is not supported yet
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
291605
1.86%18
-14.29%8277
2.05%32
3.23%- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed