Socket
Socket
Sign inDemoInstall

dd-trace

Package Overview
Dependencies
20
Maintainers
3
Versions
558
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.6.1-beta.5 to 0.7.0-beta.0

1

docs/API.md

@@ -183,2 +183,3 @@ <h1 id="home">Datadog JavaScript Tracer API</h1>

| depth | -1 | The maximum depth of fields/resolvers to instrument. Set to `0` to only instrument the operation or to -1 to instrument all fields/resolvers. |
| collapse | false | Whether to collapse list items into a single element. (i.e. single `users.*.name` span instead of `users.0.name`, `users.1.name`, etc) |

@@ -185,0 +186,0 @@ <h3 id="hapi">hapi</h3>

2

lib/version.js

@@ -1,1 +0,1 @@

module.exports = '0.6.1-beta.5'
module.exports = '0.7.0-beta.0'
{
"name": "dd-trace",
"version": "0.6.1-beta.5",
"version": "0.7.0-beta.0",
"description": "Datadog APM tracing client for JavaScript",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -100,2 +100,5 @@ 'use strict'

if (resolve._datadog_patched) return resolve
if (config.collapse) {
responsePathAsArray = withCollapse(responsePathAsArray)
}

@@ -106,5 +109,5 @@ function resolveWithTrace (source, args, contextValue, info) {

const depth = path.filter(item => typeof item === 'string').length
const fieldParent = getFieldParent(operation, path)
if (config.depth >= 0 && config.depth < depth) {
const fieldParent = getFieldParent(operation, path)
const scope = tracer.scopeManager().activate(fieldParent)

@@ -118,12 +121,5 @@

const childOf = createPathSpan(tracer, config, 'field', fieldParent, path)
const field = assertField(tracer, config, operation, path)
const scope = tracer.scopeManager().activate(field.resolveSpan)
operation._datadog_fields[path.join('.')] = {
span: childOf,
parent: fieldParent
}
const span = createPathSpan(tracer, config, 'resolve', childOf, path)
const scope = tracer.scopeManager().activate(span)
return call(resolve, this, arguments, err => finish(scope, operation, path, err))

@@ -172,2 +168,25 @@ }

function assertField (tracer, config, operation, path) {
let field = getField(operation, path)
if (!field) {
field = operation._datadog_fields[path.join('.')] = {
pending: 0,
error: null
}
const fieldParent = getFieldParent(operation, path)
const childOf = createPathSpan(tracer, config, 'field', fieldParent, path)
const span = createPathSpan(tracer, config, 'resolve', childOf, path)
field.parent = fieldParent
field.span = childOf
field.resolveSpan = span
}
field.pending++
return field
}
function getFieldParent (operation, path) {

@@ -249,5 +268,9 @@ for (let i = path.length - 1; i > 0; i--) {

'service.name': getService(tracer, config),
'resource.name': [type, name].filter(val => val).join(' '),
'graphql.document': source
'resource.name': [type, name].filter(val => val).join(' ')
}
if (source) {
tags['graphql.document'] = source
}
if (variableValues && config.variables) {

@@ -259,2 +282,3 @@ const variables = config.variables(variableValues)

}
const span = tracer.startSpan(`graphql.${operation.operation}`, {

@@ -291,2 +315,10 @@ tags,

function finish (scope, operation, path, error) {
const field = getField(operation, path)
field.pending--
if (field.error || field.pending > 0) return
field.error = error
const span = scope.span()

@@ -323,2 +355,9 @@

function withCollapse (responsePathAsArray) {
return function () {
return responsePathAsArray.apply(this, arguments)
.map(segment => typeof segment === 'number' ? '*' : segment)
}
}
function getField (operation, path) {

@@ -325,0 +364,0 @@ return operation._datadog_fields[path.join('.')]

@@ -8,22 +8,4 @@ 'use strict'

return function internalSendCommandWithTrace (options) {
const scope = tracer.scopeManager().active()
const span = tracer.startSpan('redis.command', {
childOf: scope && scope.span(),
tags: {
[Tags.SPAN_KIND]: Tags.SPAN_KIND_RPC_CLIENT,
[Tags.DB_TYPE]: 'redis',
'service.name': config.service || `${tracer._service}-redis`,
'resource.name': options.command,
'span.type': 'redis',
'db.name': this.selected_db || '0'
}
})
const span = startSpan(tracer, config, this, options.command)
if (this.connection_options) {
span.addTags({
'out.host': String(this.connection_options.host),
'out.port': String(this.connection_options.port)
})
}
options.callback = wrapCallback(tracer, span, options.callback)

@@ -36,2 +18,49 @@

function createWrapSendCommand (tracer, config) {
return function wrapSendCommand (sendCommand) {
return function sendCommandWithTrace (command, args, callback) {
const span = startSpan(tracer, config, this, command)
if (callback) {
callback = wrapCallback(tracer, span, callback)
} else if (args) {
args[(args.length || 1) - 1] = wrapCallback(tracer, span, args[args.length - 1])
} else {
args = [wrapCallback(tracer, span)]
}
return sendCommand.call(this, command, args, callback)
}
}
}
function startSpan (tracer, config, client, command) {
const scope = tracer.scopeManager().active()
const span = tracer.startSpan('redis.command', {
childOf: scope && scope.span(),
tags: {
[Tags.SPAN_KIND]: Tags.SPAN_KIND_RPC_CLIENT,
[Tags.DB_TYPE]: 'redis',
'service.name': config.service || `${tracer._service}-redis`,
'resource.name': command,
'span.type': 'redis',
'db.name': client.selected_db || '0'
}
})
const connectionOptions = client.connection_options || client.connection_option || {
host: client.options.host || '127.0.0.1',
port: client.options.port || 6379
}
if (connectionOptions) {
span.addTags({
'out.host': String(connectionOptions.host),
'out.port': String(connectionOptions.port)
})
}
return span
}
function wrapCallback (tracer, span, done) {

@@ -49,3 +78,3 @@ return (err, res) => {

if (done) {
if (typeof done === 'function') {
done(err, res)

@@ -56,15 +85,23 @@ }

function patch (redis, tracer, config) {
this.wrap(redis.RedisClient.prototype, 'internal_send_command', createWrapInternalSendCommand(tracer, config))
}
function unpatch (redis) {
this.unwrap(redis.RedisClient.prototype, 'internal_send_command')
}
module.exports = {
name: 'redis',
versions: ['^2.6'],
patch,
unpatch
}
module.exports = [
{
name: 'redis',
versions: ['^2.6'],
patch (redis, tracer, config) {
this.wrap(redis.RedisClient.prototype, 'internal_send_command', createWrapInternalSendCommand(tracer, config))
},
unpatch (redis) {
this.unwrap(redis.RedisClient.prototype, 'internal_send_command')
}
},
{
name: 'redis',
versions: ['>=0.12 <2.6'],
patch (redis, tracer, config) {
this.wrap(redis.RedisClient.prototype, 'send_command', createWrapSendCommand(tracer, config))
},
unpatch (redis) {
this.unwrap(redis.RedisClient.prototype, 'send_command')
}
}
]

@@ -959,2 +959,58 @@ 'use strict'

describe('with collapsing enabled', () => {
before(() => {
tracer = require('../..')
return agent.load(plugin, 'graphql', { collapse: true })
})
after(() => {
return agent.close()
})
beforeEach(() => {
graphql = require(`../../versions/graphql@${version}`).get()
buildSchema()
})
it('should collapse list field resolvers', done => {
const source = `{ friends { name } }`
agent
.use(traces => {
const spans = sort(traces[0])
expect(spans).to.have.length(8)
const execute = spans[3]
const friendsField = spans[4]
const friendsResolve = spans[5]
const friendNameField = spans[6]
const friendNameResolve = spans[7]
expect(execute).to.have.property('name', 'graphql.execute')
expect(friendsField).to.have.property('name', 'graphql.field')
expect(friendsField).to.have.property('resource', 'friends')
expect(friendsField.parent_id.toString()).to.equal(execute.span_id.toString())
expect(friendsResolve).to.have.property('name', 'graphql.resolve')
expect(friendsResolve).to.have.property('resource', 'friends')
expect(friendsResolve.parent_id.toString()).to.equal(friendsField.span_id.toString())
expect(friendNameField).to.have.property('name', 'graphql.field')
expect(friendNameField).to.have.property('resource', 'friends.*.name')
expect(friendNameField.parent_id.toString()).to.equal(friendsField.span_id.toString())
expect(friendNameResolve).to.have.property('name', 'graphql.resolve')
expect(friendNameResolve).to.have.property('resource', 'friends.*.name')
expect(friendNameResolve.parent_id.toString()).to.equal(friendNameField.span_id.toString())
})
.then(done)
.catch(done)
graphql.graphql(schema, source).catch(done)
})
})
withVersions(plugin, 'apollo-server-core', apolloVersion => {

@@ -994,2 +1050,3 @@ let runQuery

expect(spans[0]).to.have.property('resource', 'query MyQuery')
expect(spans[0].meta).to.have.property('graphql.document')

@@ -1010,2 +1067,3 @@ expect(spans[1]).to.have.property('name', 'graphql.parse')

expect(spans[6]).to.have.property('resource', 'query MyQuery')
expect(spans[6].meta).to.not.have.property('graphql.document')

@@ -1012,0 +1070,0 @@ expect(spans[7]).to.have.property('name', 'graphql.validate')

@@ -40,3 +40,2 @@ 'use strict'

agent.use(() => client.get('foo')) // wait for initial info command
agent

@@ -56,2 +55,4 @@ .use(traces => {

.catch(done)
client.get('foo', () => {})
})

@@ -58,0 +59,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc