Comparing version 0.7.2 to 0.8.0-beta.0
@@ -5,6 +5,8 @@ 'use strict' | ||
const tags = require('./tags') | ||
const formats = require('./formats') | ||
module.exports = { | ||
priority, | ||
tags | ||
tags, | ||
formats | ||
} |
@@ -1,1 +0,1 @@ | ||
module.exports = '0.7.2' | ||
module.exports = '0.8.0-beta.0' |
{ | ||
"name": "dd-trace", | ||
"version": "0.7.2", | ||
"version": "0.8.0-beta.0", | ||
"description": "Datadog APM tracing client for JavaScript", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -28,7 +28,7 @@ 'use strict' | ||
return { | ||
trace_id: spanContext.traceId, | ||
span_id: spanContext.spanId, | ||
parent_id: spanContext.parentId, | ||
name: String(spanContext.name), | ||
resource: String(spanContext.name), | ||
trace_id: spanContext._traceId, | ||
span_id: spanContext._spanId, | ||
parent_id: spanContext._parentId, | ||
name: String(spanContext._name), | ||
resource: String(spanContext._name), | ||
error: 0, | ||
@@ -43,3 +43,3 @@ meta: {}, | ||
function extractTags (trace, span) { | ||
const tags = span.context().tags | ||
const tags = span.context()._tags | ||
@@ -83,10 +83,10 @@ Object.keys(tags).forEach(tag => { | ||
Object.keys(spanContext.metrics).forEach(metric => { | ||
if (typeof spanContext.metrics[metric] === 'number') { | ||
trace.metrics[metric] = spanContext.metrics[metric] | ||
Object.keys(spanContext._metrics).forEach(metric => { | ||
if (typeof spanContext._metrics[metric] === 'number') { | ||
trace.metrics[metric] = spanContext._metrics[metric] | ||
} | ||
}) | ||
if (spanContext.sampling.priority !== undefined) { | ||
trace.metrics[SAMPLING_PRIORITY_KEY] = spanContext.sampling.priority | ||
if (spanContext._sampling.priority !== undefined) { | ||
trace.metrics[SAMPLING_PRIORITY_KEY] = spanContext._sampling.priority | ||
} | ||
@@ -93,0 +93,0 @@ } |
@@ -17,4 +17,4 @@ 'use strict' | ||
inject (spanContext, carrier) { | ||
carrier[traceKey] = spanContext.traceId.toString() | ||
carrier[spanKey] = spanContext.spanId.toString() | ||
carrier[traceKey] = spanContext.toTraceId() | ||
carrier[spanKey] = spanContext.toSpanId() | ||
@@ -46,3 +46,3 @@ this._injectSamplingPriority(spanContext, carrier) | ||
_injectSamplingPriority (spanContext, carrier) { | ||
const priority = spanContext.sampling.priority | ||
const priority = spanContext._sampling.priority | ||
@@ -55,4 +55,4 @@ if (Number.isInteger(priority)) { | ||
_injectBaggageItems (spanContext, carrier) { | ||
spanContext.baggageItems && Object.keys(spanContext.baggageItems).forEach(key => { | ||
carrier[baggagePrefix + key] = String(spanContext.baggageItems[key]) | ||
spanContext._baggageItems && Object.keys(spanContext._baggageItems).forEach(key => { | ||
carrier[baggagePrefix + key] = String(spanContext._baggageItems[key]) | ||
}) | ||
@@ -66,3 +66,3 @@ } | ||
if (match) { | ||
spanContext.baggageItems[match[1]] = carrier[key] | ||
spanContext._baggageItems[match[1]] = carrier[key] | ||
} | ||
@@ -76,3 +76,3 @@ }) | ||
if (Number.isInteger(priority)) { | ||
spanContext.sampling.priority = parseInt(carrier[samplingKey], 10) | ||
spanContext._sampling.priority = parseInt(carrier[samplingKey], 10) | ||
} | ||
@@ -79,0 +79,0 @@ } |
@@ -9,14 +9,14 @@ 'use strict' | ||
this.traceId = props.traceId | ||
this.spanId = props.spanId | ||
this.parentId = props.parentId || null | ||
this.name = props.name | ||
this.children = props.children || [] | ||
this.isFinished = props.isFinished || false | ||
this.tags = props.tags || {} | ||
this.metrics = props.metrics || {} | ||
this.sampled = props.sampled === undefined || props.sampled | ||
this.sampling = props.sampling || {} | ||
this.baggageItems = props.baggageItems || {} | ||
this.trace = props.trace || { | ||
this._traceId = props.traceId | ||
this._spanId = props.spanId | ||
this._parentId = props.parentId || null | ||
this._name = props.name | ||
this._children = props.children || [] | ||
this._isFinished = props.isFinished || false | ||
this._tags = props.tags || {} | ||
this._metrics = props.metrics || {} | ||
this._sampled = props.sampled === undefined || props.sampled | ||
this._sampling = props.sampling || {} | ||
this._baggageItems = props.baggageItems || {} | ||
this._trace = props.trace || { | ||
started: [], | ||
@@ -26,4 +26,12 @@ finished: [] | ||
} | ||
toTraceId () { | ||
return this._traceId.toString() | ||
} | ||
toSpanId () { | ||
return this._spanId.toString() | ||
} | ||
} | ||
module.exports = DatadogSpanContext |
@@ -32,5 +32,5 @@ 'use strict' | ||
this._spanContext = this._createContext(parent) | ||
this._spanContext.name = operationName | ||
this._spanContext.tags = tags | ||
this._spanContext.metrics = metrics | ||
this._spanContext._name = operationName | ||
this._spanContext._tags = tags | ||
this._spanContext._metrics = metrics | ||
} | ||
@@ -41,8 +41,8 @@ | ||
const json = JSON.stringify({ | ||
traceId: spanContext.traceId, | ||
spanId: spanContext.spanId, | ||
parentId: spanContext.parentId, | ||
service: spanContext.tags['service.name'], | ||
name: spanContext.name, | ||
resource: truncate(spanContext.tags['resource.name'], { length: 100 }) | ||
traceId: spanContext._traceId, | ||
spanId: spanContext._spanId, | ||
parentId: spanContext._parentId, | ||
service: spanContext._tags['service.name'], | ||
name: spanContext._name, | ||
resource: truncate(spanContext._tags['resource.name'], { length: 100 }) | ||
}) | ||
@@ -58,9 +58,9 @@ | ||
spanContext = new SpanContext({ | ||
traceId: parent.traceId, | ||
traceId: parent._traceId, | ||
spanId: platform.id(), | ||
parentId: parent.spanId, | ||
sampled: parent.sampled, | ||
sampling: parent.sampling, | ||
baggageItems: Object.assign({}, parent.baggageItems), | ||
trace: parent.trace.started.length !== parent.trace.finished.length ? parent.trace : null | ||
parentId: parent._spanId, | ||
sampled: parent._sampled, | ||
sampling: parent._sampling, | ||
baggageItems: parent._baggageItems, | ||
trace: parent._trace.started.length !== parent._trace.finished.length ? parent._trace : null | ||
}) | ||
@@ -76,3 +76,3 @@ } else { | ||
spanContext.trace.started.push(this) | ||
spanContext._trace.started.push(this) | ||
@@ -91,11 +91,11 @@ return spanContext | ||
_setOperationName (name) { | ||
this._spanContext.name = name | ||
this._spanContext._name = name | ||
} | ||
_setBaggageItem (key, value) { | ||
this._spanContext.baggageItems[key] = value | ||
this._spanContext._baggageItems[key] = value | ||
} | ||
_getBaggageItem (key) { | ||
return this._spanContext.baggageItems[key] | ||
return this._spanContext._baggageItems[key] | ||
} | ||
@@ -106,3 +106,3 @@ | ||
Object.keys(keyValuePairs).forEach(key => { | ||
this._spanContext.tags[key] = String(keyValuePairs[key]) | ||
this._spanContext._tags[key] = String(keyValuePairs[key]) | ||
}) | ||
@@ -122,12 +122,12 @@ } catch (e) { | ||
this._duration = finishTime - this._startTime | ||
this._spanContext.trace.finished.push(this) | ||
this._spanContext.isFinished = true | ||
this._spanContext._trace.finished.push(this) | ||
this._spanContext._isFinished = true | ||
this._prioritySampler.sample(this) | ||
if (this._spanContext.sampled) { | ||
if (this._spanContext._sampled) { | ||
this._recorder.record(this) | ||
} | ||
this._spanContext.children | ||
.filter(child => !child.context().isFinished) | ||
this._spanContext._children | ||
.filter(child => !child.context()._isFinished) | ||
.forEach(child => { | ||
@@ -134,0 +134,0 @@ log.error(`Parent span ${this} was finished before child span ${child}.`) |
@@ -15,2 +15,4 @@ 'use strict' | ||
const BinaryPropagator = require('./propagation/binary') | ||
const LogPropagator = require('./propagation/log') | ||
const formats = require('../../ext/formats') | ||
const log = require('../log') | ||
@@ -35,5 +37,6 @@ | ||
this._propagators = { | ||
[opentracing.FORMAT_TEXT_MAP]: new TextMapPropagator(), | ||
[opentracing.FORMAT_HTTP_HEADERS]: new HttpPropagator(), | ||
[opentracing.FORMAT_BINARY]: new BinaryPropagator() | ||
[formats.TEXT_MAP]: new TextMapPropagator(), | ||
[formats.HTTP_HEADERS]: new HttpPropagator(), | ||
[formats.BINARY]: new BinaryPropagator(), | ||
[formats.LOG]: new LogPropagator() | ||
} | ||
@@ -62,3 +65,3 @@ } | ||
if (parent && parent.type() === opentracing.REFERENCE_CHILD_OF) { | ||
parent.referencedContext().children.push(span) | ||
parent.referencedContext()._children.push(span) | ||
} | ||
@@ -65,0 +68,0 @@ |
@@ -9,6 +9,6 @@ 'use strict' | ||
return function wrapHandle (handle) { | ||
return function handleWithTracer (req) { | ||
return function handleWithTracer (req, res, done) { | ||
web.patch(req) | ||
return handle.apply(this, arguments) | ||
return handle.call(this, req, res, wrapDone(done, req)) | ||
} | ||
@@ -46,6 +46,8 @@ } | ||
if (this.stack) { | ||
wrapStack(this.stack, offset, extractMatchers(fn)) | ||
if (typeof this.stack === 'function') { | ||
this.stack = [{ handle: this.stack }] | ||
} | ||
wrapStack(this.stack, offset, extractMatchers(fn)) | ||
return router | ||
@@ -55,16 +57,17 @@ } | ||
function wrapLayerHandle (layer, handle) { | ||
if (handle.length === 4) { | ||
return function (error, req, res, next) { | ||
return callHandle(layer, handle, req, [error, req, res, wrapNext(layer, req, next)]) | ||
} | ||
} else { | ||
return function (req, res, next) { | ||
return callHandle(layer, handle, req, [req, res, wrapNext(layer, req, next)]) | ||
} | ||
} | ||
} | ||
function wrapStack (stack, offset, matchers) { | ||
[].concat(stack).slice(offset).forEach(layer => { | ||
const handle = layer.handle || layer | ||
if (handle.length === 4) { | ||
layer.handle = (error, req, res, next) => { | ||
return handle.call(layer, error, req, res, wrapNext(layer, req, next)) | ||
} | ||
} else { | ||
layer.handle = (req, res, next) => { | ||
return handle.call(layer, req, res, wrapNext(layer, req, next)) | ||
} | ||
} | ||
layer.handle = wrapLayerHandle(layer, layer.handle) | ||
layer._datadog_matchers = matchers | ||
@@ -74,2 +77,6 @@ | ||
METHODS.forEach(method => { | ||
if (typeof layer.route.stack === 'function') { | ||
layer.route.stack = [{ handle: layer.route.stack }] | ||
} | ||
layer.route[method] = wrapRouterMethod(layer.route[method]) | ||
@@ -82,10 +89,6 @@ }) | ||
function wrapNext (layer, req, next) { | ||
if (!web.active(req)) { | ||
return next | ||
} | ||
if (!next || !web.active(req)) return next | ||
const originalNext = next | ||
web.reactivate(req) | ||
return function (error) { | ||
@@ -96,2 +99,6 @@ if (!error && layer.path && !isFastStar(layer)) { | ||
addError(web.active(req), error) | ||
web.exitMiddleware(req) | ||
process.nextTick(() => { | ||
@@ -103,2 +110,22 @@ originalNext.apply(null, arguments) | ||
function wrapDone (original, req) { | ||
return function done (error) { | ||
const span = web.root(req) | ||
addError(span, error) | ||
return original.apply(this, arguments) | ||
} | ||
} | ||
function callHandle (layer, handle, req, args) { | ||
web.enterMiddleware(req, handle, 'express.middleware') | ||
try { | ||
return handle.apply(layer, args) | ||
} catch (e) { | ||
throw addError(web.active(req), e) | ||
} | ||
} | ||
function extractMatchers (fn) { | ||
@@ -129,2 +156,14 @@ const arg = flatten([].concat(fn)) | ||
function addError (span, error) { | ||
if (error) { | ||
span.addTags({ | ||
'error.type': error.name, | ||
'error.msg': error.message, | ||
'error.stack': error.stack | ||
}) | ||
} | ||
return error | ||
} | ||
module.exports = { | ||
@@ -131,0 +170,0 @@ name: 'router', |
@@ -23,3 +23,3 @@ 'use strict' | ||
span.setTag('service.name', config.service || `${span.context().tags['service.name']}-redis`) | ||
span.setTag('service.name', config.service || `${span.context()._tags['service.name']}-redis`) | ||
@@ -26,0 +26,0 @@ return span |
@@ -69,2 +69,34 @@ 'use strict' | ||
// Start a new middleware span and activate a new scope with the span. | ||
enterMiddleware (req, middleware, name) { | ||
if (!this.active(req)) return | ||
const tracer = req._datadog.tracer | ||
const childOf = this.active(req) | ||
const span = tracer.startSpan(name, { childOf }) | ||
const scope = tracer.scopeManager().activate(span) | ||
span.addTags({ | ||
[RESOURCE_NAME]: middleware.name || '<anonymous>' | ||
}) | ||
req._datadog.middleware.push(scope) | ||
return span | ||
}, | ||
// Close the active middleware scope and finish its span. | ||
exitMiddleware (req) { | ||
if (!this.active(req)) return | ||
const scope = req._datadog.middleware.pop() | ||
if (!scope) return | ||
const span = scope.span() | ||
span.finish() | ||
scope.close() | ||
}, | ||
// Register a callback to run before res.end() is called. | ||
@@ -84,2 +116,3 @@ beforeEnd (req, callback) { | ||
paths: [], | ||
middleware: [], | ||
beforeEnd: [] | ||
@@ -90,5 +123,13 @@ } | ||
// Return the active span. For now, this is always the request span. | ||
// Return the request root span. | ||
root (req) { | ||
return req._datadog ? req._datadog.span : null | ||
}, | ||
// Return the active span. | ||
active (req) { | ||
return req._datadog ? req._datadog.span : null | ||
if (!req._datadog) return null | ||
if (req._datadog.middleware.length === 0) return req._datadog.span || null | ||
return req._datadog.middleware.slice(-1)[0].span() | ||
} | ||
@@ -101,3 +142,3 @@ } | ||
if (req._datadog.span) { | ||
req._datadog.span.context().name = name | ||
req._datadog.span.context()._name = name | ||
return req._datadog.span | ||
@@ -134,2 +175,13 @@ } | ||
function finishMiddleware (req, res) { | ||
if (req._datadog.finished) return | ||
let scope | ||
while ((scope = req._datadog.middleware.pop())) { | ||
scope.span().finish() | ||
scope.close() | ||
} | ||
} | ||
function wrapEnd (req) { | ||
@@ -144,2 +196,4 @@ const res = req._datadog.res | ||
finishMiddleware(req, res) | ||
const returnValue = end.apply(this, arguments) | ||
@@ -185,3 +239,3 @@ | ||
const span = req._datadog.span | ||
const tags = span.context().tags | ||
const tags = span.context()._tags | ||
@@ -188,0 +242,0 @@ if (tags['resource.name']) return |
@@ -29,3 +29,3 @@ 'use strict' | ||
const context = this._getContext(span) | ||
const key = `service:${context.tags[SERVICE_NAME]},env:${this._env}` | ||
const key = `service:${context._tags[SERVICE_NAME]},env:${this._env}` | ||
const sampler = this._samplers[key] || this._samplers[DEFAULT_KEY] | ||
@@ -39,12 +39,12 @@ | ||
if (context.sampling.priority !== undefined) return | ||
if (context._sampling.priority !== undefined) return | ||
const tag = parseInt(context.tags[SAMPLING_PRIORITY], 10) | ||
const tag = parseInt(context._tags[SAMPLING_PRIORITY], 10) | ||
if (this.validate(tag)) { | ||
context.sampling.priority = tag | ||
context._sampling.priority = tag | ||
return | ||
} | ||
context.sampling.priority = this.isSampled(span) ? AUTO_KEEP : AUTO_REJECT | ||
context._sampling.priority = this.isSampled(span) ? AUTO_KEEP : AUTO_REJECT | ||
} | ||
@@ -51,0 +51,0 @@ |
@@ -22,3 +22,3 @@ 'use strict' | ||
append (span) { | ||
const trace = span.context().trace | ||
const trace = span.context()._trace | ||
@@ -25,0 +25,0 @@ if (trace.started.length === trace.finished.length) { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
131985
82
3755