Comparing version 0.5.6 to 0.6.0-beta.0
@@ -288,2 +288,3 @@ <h1 id="home">Datadog JavaScript Tracer API</h1> | ||
| ------------- | ---------------------------- | --------- | ----------- | | ||
| enabled | DD_TRACE_ENABLED | true | Whether to enable the tracer. | | ||
| debug | DD_TRACE_DEBUG | false | Enable debug logging in the tracer. | | ||
@@ -290,0 +291,0 @@ | service | DD_SERVICE_NAME | | The service name to be used for this program. | |
@@ -1,1 +0,1 @@ | ||
module.exports = '0.5.6' | ||
module.exports = '0.6.0-beta.0' |
{ | ||
"name": "dd-trace", | ||
"version": "0.5.6", | ||
"version": "0.6.0-beta.0", | ||
"description": "Datadog APM tracing client for JavaScript", | ||
@@ -56,2 +56,3 @@ "main": "index.js", | ||
"devDependencies": { | ||
"amqp10": "^3.6.0", | ||
"amqplib": "^0.5.2", | ||
@@ -58,0 +59,0 @@ "axios": "^0.18.0", |
@@ -42,3 +42,3 @@ # dd-trace-js | ||
```sh | ||
$ docker-compose up -d | ||
$ docker-compose up -d -V --remove-orphans --force-recreate | ||
``` | ||
@@ -45,0 +45,0 @@ |
@@ -8,2 +8,3 @@ 'use strict' | ||
exec('npm whoami') | ||
exec('git checkout master') | ||
@@ -16,3 +17,3 @@ exec('git pull') | ||
exec(`git push origin refs/tags/v${pkg.version}`) | ||
exec('yarn publish') | ||
exec('npm publish') | ||
exec(`node scripts/publish_docs.js "v${pkg.version}"`) |
@@ -13,3 +13,2 @@ 'use strict' | ||
const debug = coalesce(options.debug, platform.env('DD_TRACE_DEBUG'), false) | ||
const service = coalesce(options.service, platform.env('DD_SERVICE_NAME'), platform.service(), 'node') | ||
const env = coalesce(options.env, platform.env('DD_ENV')) | ||
@@ -25,3 +24,2 @@ const protocol = 'http' | ||
this.debug = String(debug) === 'true' | ||
this.service = service | ||
this.env = env | ||
@@ -35,2 +33,14 @@ this.url = new URL(`${protocol}://${hostname}:${port}`) | ||
this.plugins = !!plugins | ||
Object.defineProperty(this, 'service', { | ||
get () { | ||
const service = coalesce(options.service, platform.env('DD_SERVICE_NAME')) | ||
if (service) { | ||
return service | ||
} | ||
return platform.service() || 'node' | ||
} | ||
}) | ||
} | ||
@@ -37,0 +47,0 @@ } |
@@ -7,3 +7,2 @@ 'use strict' | ||
const env = require('./env') | ||
const load = require('./load') | ||
const service = require('./service') | ||
@@ -26,3 +25,2 @@ const request = require('./request') | ||
env, | ||
load, | ||
service, | ||
@@ -29,0 +27,0 @@ request, |
'use strict' | ||
function service (key) { | ||
return this._service | ||
const path = require('path') | ||
const readPkgUp = require('read-pkg-up') | ||
const parentModule = require('parent-module') | ||
const semver = require('semver') | ||
const SUPPORTED_VERSIONS = '^4.7 || ^6.9 || >=8' | ||
function service () { | ||
if (!semver.satisfies(process.versions.node, SUPPORTED_VERSIONS)) { | ||
throw new Error([ | ||
`Node ${process.versions.node} is not supported.`, | ||
`Only versions of Node matching "${SUPPORTED_VERSIONS}" are supported.`, | ||
`Tracing has been disabled.` | ||
].join(' ')) | ||
} | ||
const callerPath = parentModule() | ||
const parentPath = parentModule(callerPath) | ||
const cwd = path.dirname(parentPath || callerPath) | ||
const pkg = readPkgUp.sync({ cwd }).pkg || {} | ||
return pkg.name | ||
} | ||
module.exports = service |
@@ -17,2 +17,4 @@ 'use strict' | ||
function ddTrace (req, res, next) { | ||
if (req._datadog.span) return next() | ||
const url = `${req.protocol}://${req.get('host')}${req.originalUrl}` | ||
@@ -33,2 +35,4 @@ const childOf = tracer.extract(FORMAT_HTTP_HEADERS, req.headers) | ||
res.end = function () { | ||
if (req._datadog.finished) return originalEnd.apply(this, arguments) | ||
const returned = originalEnd.apply(this, arguments) | ||
@@ -50,2 +54,3 @@ const path = req._datadog.paths.join('') | ||
req._datadog.scope && req._datadog.scope.close() | ||
req._datadog.finished = true | ||
@@ -52,0 +57,0 @@ return returned |
@@ -247,3 +247,3 @@ 'use strict' | ||
const types = ['query', 'mutation'] | ||
const types = ['query', 'mutation', 'subscription'] | ||
const definition = document.definitions.find(def => types.indexOf(def.operation) !== -1) | ||
@@ -250,0 +250,0 @@ |
@@ -10,3 +10,9 @@ 'use strict' | ||
return function queryTrace () { | ||
const pgQuery = query.apply(this, arguments) | ||
const retval = query.apply(this, arguments) | ||
const pgQuery = this.queryQueue[this.queryQueue.length - 1] || this.activeQuery | ||
if (!pgQuery) { | ||
return retval | ||
} | ||
const originalCallback = pgQuery.callback | ||
@@ -58,3 +64,3 @@ const statement = pgQuery.text | ||
return pgQuery | ||
return retval | ||
} | ||
@@ -72,5 +78,5 @@ } | ||
name: 'pg', | ||
versions: ['6.x'], | ||
versions: ['6.x', '7.x'], | ||
patch, | ||
unpatch | ||
} |
@@ -36,2 +36,3 @@ 'use strict' | ||
* @param {Object} [options] Configuration options. | ||
* @param {boolean} [options.enabled=true] Whether to enable the tracer. | ||
* @param {boolean} [options.debug=false] Enable debug logging in the tracer. | ||
@@ -52,10 +53,10 @@ * @param {string} [options.service] The service name to be used for this program. | ||
try { | ||
platform.load() | ||
const config = new Config(options) | ||
platform.configure(config) | ||
if (config.enabled) { | ||
platform.configure(config) | ||
this._tracer = new DatadogTracer(config) | ||
this._instrumenter.patch(config) | ||
this._tracer = new DatadogTracer(config) | ||
this._instrumenter.patch(config) | ||
} | ||
} catch (e) { | ||
@@ -62,0 +63,0 @@ log.error(e) |
@@ -122,5 +122,5 @@ 'use strict' | ||
describe('load', () => { | ||
describe('service', () => { | ||
let current | ||
let service | ||
let load | ||
let readPkgUp | ||
@@ -134,17 +134,17 @@ | ||
platform = require('../../../src/platform/node') | ||
load = proxyquire('../src/platform/node/load', { | ||
service = proxyquire('../src/platform/node/service', { | ||
'read-pkg-up': readPkgUp | ||
}) | ||
service = platform._service | ||
current = platform._service | ||
}) | ||
afterEach(() => { | ||
platform._service = service | ||
platform._service = current | ||
}) | ||
it('should load the service name from the user module', () => { | ||
require('./load/direct') | ||
const name = require('./load/direct') | ||
expect(platform._service).to.equal('foo') | ||
expect(name).to.equal('foo') | ||
}) | ||
@@ -155,3 +155,3 @@ | ||
load.call(platform) | ||
service.call(platform) | ||
@@ -162,5 +162,5 @@ expect(platform._service).to.be.undefined | ||
it('should work even in subfolders', () => { | ||
require('./load/indirect') | ||
const name = require('./load/indirect') | ||
expect(platform._service).to.have.equal('foo') | ||
expect(name).to.equal('foo') | ||
}) | ||
@@ -167,0 +167,0 @@ }) |
@@ -5,2 +5,2 @@ 'use strict' | ||
caller() | ||
module.exports = caller() |
@@ -5,2 +5,2 @@ 'use strict' | ||
foo() | ||
module.exports = foo() |
@@ -5,2 +5,2 @@ 'use strict' | ||
module.exports = () => platform.load() | ||
module.exports = () => platform.service() |
@@ -370,2 +370,18 @@ 'use strict' | ||
it('should instrument subscriptions', done => { | ||
const source = `subscription { human { name } }` | ||
agent | ||
.use(traces => { | ||
const spans = sort(traces[0]) | ||
expect(spans).to.have.length(3) | ||
expect(spans[0]).to.have.property('name', 'graphql.subscription') | ||
}) | ||
.then(done) | ||
.catch(done) | ||
graphql.graphql(schema, source).catch(done) | ||
}) | ||
it('should handle a circular schema', done => { | ||
@@ -372,0 +388,0 @@ const source = `{ human { pets { owner { name } } } }` |
@@ -63,2 +63,20 @@ 'use strict' | ||
it('should do automatic instrumentation when using promises', done => { | ||
agent.use(traces => { | ||
expect(traces[0][0]).to.have.property('service', 'test-postgres') | ||
expect(traces[0][0]).to.have.property('resource', 'SELECT $1::text as message') | ||
expect(traces[0][0]).to.have.property('type', 'sql') | ||
expect(traces[0][0].meta).to.have.property('db.name', 'postgres') | ||
expect(traces[0][0].meta).to.have.property('db.user', 'postgres') | ||
expect(traces[0][0].meta).to.have.property('db.type', 'postgres') | ||
expect(traces[0][0].meta).to.have.property('span.kind', 'client') | ||
done() | ||
}) | ||
client.query('SELECT $1::text as message', ['Hello world!']) | ||
.then(() => client.end()) | ||
.catch(done) | ||
}) | ||
it('should handle errors', done => { | ||
@@ -96,13 +114,2 @@ agent.use(traces => { | ||
}) | ||
it('should work without a callback', done => { | ||
agent.use(traces => { | ||
done() | ||
}) | ||
client.query('SELECT $1::text as message', ['Hello World!']) | ||
client.end((err) => { | ||
if (err) throw err | ||
}) | ||
}) | ||
}) | ||
@@ -109,0 +116,0 @@ |
@@ -46,3 +46,3 @@ 'use strict' | ||
config = {} | ||
config = { enabled: true } | ||
Config = sinon.stub().returns(config) | ||
@@ -89,10 +89,2 @@ | ||
it('should load the platform', () => { | ||
const options = {} | ||
proxy.init(options) | ||
expect(platform.load).to.have.been.called | ||
}) | ||
it('should not initialize twice', () => { | ||
@@ -105,2 +97,10 @@ proxy.init() | ||
it('should not initialize when disabled', () => { | ||
config.enabled = false | ||
proxy.init() | ||
expect(DatadogTracer).to.not.have.been.called | ||
}) | ||
it('should set up automatic instrumentation', () => { | ||
@@ -107,0 +107,0 @@ proxy.init() |
@@ -10,2 +10,3 @@ 'use strict' | ||
const retry = require('retry') | ||
const RetryOperation = require('retry/lib/retry_operation') | ||
const pg = require('pg') | ||
@@ -17,2 +18,3 @@ const mysql = require('mysql') | ||
const amqplib = require('amqplib/callback_api') | ||
const amqp = require('amqp10') | ||
const platform = require('../src/platform') | ||
@@ -60,3 +62,4 @@ const node = require('../src/platform/node') | ||
waitForElasticsearch(), | ||
waitForRabbitMQ() | ||
waitForRabbitMQ(), | ||
waitForQpid() | ||
]) | ||
@@ -67,3 +70,3 @@ } | ||
return new Promise((resolve, reject) => { | ||
const operation = retry.operation(retryOptions) | ||
const operation = createOperation('postgres') | ||
@@ -79,11 +82,11 @@ operation.attempt(currentAttempt => { | ||
client.connect((err) => { | ||
if (operation.retry(err)) return | ||
if (retryOperation(operation, err)) return | ||
if (err) return reject(err) | ||
client.query('SELECT version()', (err, result) => { | ||
if (operation.retry(err)) return | ||
if (retryOperation(operation, err)) return | ||
if (err) return reject(err) | ||
client.end((err) => { | ||
if (operation.retry(err)) return | ||
if (retryOperation(operation, err)) return | ||
if (err) return reject(err) | ||
@@ -101,3 +104,3 @@ | ||
return new Promise((resolve, reject) => { | ||
const operation = retry.operation(retryOptions) | ||
const operation = createOperation('mysql') | ||
@@ -112,4 +115,4 @@ operation.attempt(currentAttempt => { | ||
connection.connect(err => { | ||
if (operation.retry(err)) return | ||
if (err) reject(err) | ||
if (retryOperation(operation, err)) return | ||
if (err) return reject(err) | ||
@@ -128,2 +131,4 @@ connection.end(() => resolve()) | ||
return reject(options.error) | ||
} else { | ||
logAttempt('redis', 'failed to connect') | ||
} | ||
@@ -144,3 +149,3 @@ | ||
return new Promise((resolve, reject) => { | ||
const operation = retry.operation(retryOptions) | ||
const operation = createOperation('mongo') | ||
@@ -160,3 +165,3 @@ operation.attempt(currentAttempt => { | ||
server.on('error', err => { | ||
if (!operation.retry(err)) { | ||
if (!retryOperation(operation, err)) { | ||
reject(err) | ||
@@ -173,3 +178,3 @@ } | ||
return new Promise((resolve, reject) => { | ||
const operation = retry.operation(retryOptions) | ||
const operation = createOperation('elasticsearch') | ||
@@ -182,4 +187,4 @@ operation.attempt(currentAttempt => { | ||
client.ping((err) => { | ||
if (operation.retry(err)) return | ||
if (err) reject(err) | ||
if (retryOperation(operation, err)) return | ||
if (err) return reject(err) | ||
@@ -194,3 +199,3 @@ resolve() | ||
return new Promise((resolve, reject) => { | ||
const operation = retry.operation(retryOptions) | ||
const operation = createOperation('rabbitmq') | ||
@@ -200,4 +205,4 @@ operation.attempt(currentAttempt => { | ||
.connect((err, conn) => { | ||
if (operation.retry(err)) return | ||
if (err) reject(err) | ||
if (retryOperation(operation, err)) return | ||
if (err) return reject(err) | ||
@@ -210,2 +215,22 @@ conn.close(() => resolve()) | ||
function waitForQpid () { | ||
return new Promise((resolve, reject) => { | ||
const operation = retry.operation(retryOptions) | ||
operation.attempt(currentAttempt => { | ||
const client = new amqp.Client(amqp.Policy.merge({ | ||
reconnect: null | ||
})) | ||
client.connect('amqp://admin:admin@localhost:5673') | ||
.then(() => client.disconnect()) | ||
.then(() => resolve()) | ||
.catch(err => { | ||
if (operation.retry(err)) return | ||
reject(err) | ||
}) | ||
}) | ||
}) | ||
} | ||
function withoutScope (fn) { | ||
@@ -266,3 +291,2 @@ return function () { | ||
instrumentation.versions | ||
.filter(version => !range || semver.satisfies(version, range)) | ||
.forEach(version => { | ||
@@ -278,2 +302,3 @@ const min = semver.coerce(version).version | ||
Array.from(testVersions) | ||
.filter(v => !range || semver.satisfies(v[0], range)) | ||
.sort(v => v[0].localeCompare(v[0])) | ||
@@ -285,1 +310,19 @@ .map(v => Object.assign({}, v[1], { version: v[0] })) | ||
} | ||
function createOperation (service) { | ||
const timeouts = retry.timeouts(retryOptions) | ||
return new RetryOperation(timeouts, Object.assign({ service }, retryOptions)) | ||
} | ||
function retryOperation (operation, err) { | ||
const shouldRetry = operation.retry(err) | ||
if (shouldRetry) { | ||
logAttempt(operation._options.service, err.message) | ||
} | ||
return shouldRetry | ||
} | ||
function logAttempt (service, message) { | ||
// eslint-disable-next-line no-console | ||
console.error(`[Retrying connection to ${service}] ${message}`) | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
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
327713
143
9200
35
33