Comparing version
@@ -1,1 +0,1 @@ | ||
module.exports = '0.6.1-beta.2' | ||
module.exports = '0.6.1-beta.3' |
{ | ||
"name": "dd-trace", | ||
"version": "0.6.1-beta.2", | ||
"version": "0.6.1-beta.3", | ||
"description": "Datadog APM tracing client for JavaScript", | ||
@@ -42,2 +42,3 @@ "main": "index.js", | ||
"lodash.pick": "^4.4.0", | ||
"lodash.truncate": "^4.4.2", | ||
"lodash.uniq": "^4.5.0", | ||
@@ -44,0 +45,0 @@ "methods": "^1.1.2", |
@@ -12,2 +12,5 @@ 'use strict' | ||
this.parentId = props.parentId || null | ||
this.name = props.name | ||
this.children = props.children || [] | ||
this.isFinished = props.isFinished || false | ||
this.tags = props.tags || {} | ||
@@ -14,0 +17,0 @@ this.metrics = props.metrics || {} |
@@ -5,2 +5,3 @@ 'use strict' | ||
const Span = opentracing.Span | ||
const truncate = require('lodash.truncate') | ||
const SpanContext = require('./span_context') | ||
@@ -33,2 +34,3 @@ const platform = require('../platform') | ||
this._spanContext = this._createContext(parent) | ||
this._spanContext.name = operationName | ||
this._spanContext.tags = tags | ||
@@ -38,2 +40,16 @@ this._spanContext.metrics = metrics | ||
toString () { | ||
const spanContext = this.context() | ||
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 }) | ||
}) | ||
return `Span${json}` | ||
} | ||
_createContext (parent) { | ||
@@ -105,2 +121,3 @@ let spanContext | ||
this._spanContext.trace.finished.push(this) | ||
this._spanContext.isFinished = true | ||
this._prioritySampler.sample(this) | ||
@@ -111,2 +128,8 @@ | ||
} | ||
this._spanContext.children | ||
.filter(child => !child.isFinished) | ||
.forEach(child => { | ||
log.error(`Parent span ${this} was finished before child span ${child}.`) | ||
}) | ||
} | ||
@@ -113,0 +136,0 @@ } |
@@ -40,3 +40,6 @@ 'use strict' | ||
// TODO: move references handling to the Span class | ||
_startSpan (name, fields) { | ||
const references = getReferences(fields.references) | ||
const parent = getParent(references) | ||
const tags = { | ||
@@ -52,8 +55,14 @@ 'resource.name': name | ||
return new Span(this, this._recorder, this._sampler, this._prioritySampler, { | ||
const span = new Span(this, this._recorder, this._sampler, this._prioritySampler, { | ||
operationName: fields.operationName || name, | ||
parent: getParent(fields.references), | ||
parent: parent && parent.referencedContext(), | ||
tags: Object.assign(tags, this._tags, fields.tags), | ||
startTime: fields.startTime | ||
}) | ||
if (parent && parent.type() === opentracing.REFERENCE_CHILD_OF) { | ||
parent.referencedContext().children.push(span) | ||
} | ||
return span | ||
} | ||
@@ -82,28 +91,34 @@ | ||
function getParent (references) { | ||
let parent = null | ||
function getReferences (references) { | ||
if (!references) return [] | ||
if (references) { | ||
for (let i = 0; i < references.length; i++) { | ||
const ref = references[i] | ||
return references.filter(ref => { | ||
if (!(ref instanceof Reference)) { | ||
log.error(() => `Expected ${ref} to be an instance of opentracing.Reference`) | ||
return false | ||
} | ||
if (!(ref instanceof Reference)) { | ||
log.error(() => `Expected ${ref} to be an instance of opentracing.Reference`) | ||
break | ||
} | ||
const spanContext = ref.referencedContext() | ||
const spanContext = ref.referencedContext() | ||
if (!(spanContext instanceof SpanContext)) { | ||
log.error(() => `Expected ${spanContext} to be an instance of SpanContext`) | ||
return false | ||
} | ||
if (!(spanContext instanceof SpanContext)) { | ||
log.error(() => `Expected ${spanContext} to be an instance of SpanContext`) | ||
break | ||
} | ||
return true | ||
}) | ||
} | ||
if (ref.type() === opentracing.REFERENCE_CHILD_OF) { | ||
parent = ref.referencedContext() | ||
break | ||
} else if (ref.type() === opentracing.REFERENCE_FOLLOWS_FROM) { | ||
if (!parent) { | ||
parent = ref.referencedContext() | ||
} | ||
function getParent (references) { | ||
let parent = null | ||
for (let i = 0; i < references.length; i++) { | ||
const ref = references[i] | ||
if (ref.type() === opentracing.REFERENCE_CHILD_OF) { | ||
parent = ref | ||
break | ||
} else if (ref.type() === opentracing.REFERENCE_FOLLOWS_FROM) { | ||
if (!parent) { | ||
parent = ref | ||
} | ||
@@ -110,0 +125,0 @@ } |
@@ -22,12 +22,9 @@ 'use strict' | ||
args.contextValue = contextValue | ||
args.fieldResolver = wrapFieldResolver(fieldResolver, tracer, config, responsePathAsArray) | ||
if (config.depth !== 0) { | ||
args.fieldResolver = wrapFieldResolver(fieldResolver, tracer, config, responsePathAsArray) | ||
if (!schema._datadog_patched) { | ||
wrapFields(schema._queryType, tracer, config, responsePathAsArray) | ||
wrapFields(schema._mutationType, tracer, config, responsePathAsArray) | ||
if (!schema._datadog_patched) { | ||
wrapFields(schema._queryType, tracer, config, responsePathAsArray) | ||
wrapFields(schema._mutationType, tracer, config, responsePathAsArray) | ||
schema._datadog_patched = true | ||
} | ||
schema._datadog_patched = true | ||
} | ||
@@ -143,9 +140,13 @@ | ||
const depth = path.filter(item => typeof item === 'string').length | ||
const fieldParent = getFieldParent(contextValue, path) | ||
if (config.depth > 0 && config.depth < depth) { | ||
return call(resolve, this, arguments, () => updateFinishTime(contextValue, path)) | ||
if (config.depth >= 0 && config.depth < depth) { | ||
const scope = tracer.scopeManager().activate(fieldParent) | ||
return call(resolve, this, arguments, () => { | ||
scope.close() | ||
updateFinishTime(contextValue, path) | ||
}) | ||
} | ||
const fieldParent = getFieldParent(contextValue, path) | ||
const childOf = createPathSpan(tracer, config, 'field', fieldParent, path) | ||
@@ -152,0 +153,0 @@ |
@@ -15,2 +15,5 @@ 'use strict' | ||
parentId: '789', | ||
name: 'test', | ||
children: ['span'], | ||
isFinished: true, | ||
tags: {}, | ||
@@ -36,2 +39,5 @@ metrics: {}, | ||
parentId: null, | ||
name: undefined, | ||
children: [], | ||
isFinished: false, | ||
tags: {}, | ||
@@ -38,0 +44,0 @@ metrics: {}, |
@@ -145,2 +145,3 @@ 'use strict' | ||
parent.children = [] | ||
fields.references = [ | ||
@@ -151,3 +152,3 @@ new Reference(opentracing.REFERENCE_CHILD_OF, parent) | ||
tracer = new Tracer(config) | ||
tracer.startSpan('name', fields) | ||
const span = tracer.startSpan('name', fields) | ||
@@ -158,2 +159,3 @@ expect(Span).to.have.been.calledWithMatch(tracer, recorder, sampler, prioritySampler, { | ||
}) | ||
expect(parent.children).to.include(span) | ||
}) | ||
@@ -160,0 +162,0 @@ |
@@ -876,2 +876,30 @@ 'use strict' | ||
}) | ||
it('should run the resolvers in the execution scope', done => { | ||
if (process.env.DD_CONTEXT_PROPAGATION === 'false') return done() | ||
const schema = graphql.buildSchema(` | ||
type Query { | ||
hello: String | ||
} | ||
`) | ||
const source = `{ hello }` | ||
const rootValue = { | ||
hello () { | ||
const scope = tracer.scopeManager().active() | ||
try { | ||
expect(scope).to.not.be.null | ||
expect(scope.span()).to.have.property('_operationName', 'graphql.execute') | ||
done() | ||
} catch (e) { | ||
done(e) | ||
} | ||
} | ||
} | ||
graphql.graphql({ schema, source, rootValue }).catch(done) | ||
}) | ||
}) | ||
@@ -878,0 +906,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
2429864
0.1%12283
0.54%20
5.26%95
1.06%+ Added
+ Added