zipkin-instrumentation-fetch
Advanced tools
Comparing version 0.19.0-alpha.4 to 0.19.0
@@ -28,3 +28,3 @@ "use strict"; | ||
resolve(res); | ||
}).catch(function (err) { | ||
})["catch"](function (err) { | ||
tracer.scoped(function () { | ||
@@ -31,0 +31,0 @@ instrumentation.recordError(traceId, err); |
{ | ||
"name": "zipkin-instrumentation-fetch", | ||
"version": "0.19.0-alpha.4+723a033", | ||
"version": "0.19.0", | ||
"description": "Interceptor for HTTP clients using the 'fetch' API", | ||
@@ -8,3 +8,5 @@ "main": "lib/index.js", | ||
"build": "babel src -d lib", | ||
"test": "mocha --exit --require ../../test/helper.js", | ||
"test": "mocha --exit --require ../../test/helper.js --require @babel/register && karma start --single-run --browsers ChromeHeadless,FirefoxHeadless ../../karma.conf.js", | ||
"test-browser": "karma start --single-run --browsers ChromeHeadless ../../karma.conf.js", | ||
"test-debug": "mocha --inspect-brk --exit --require ../../test/helper.js", | ||
"prepublish": "npm run build" | ||
@@ -15,11 +17,9 @@ }, | ||
"repository": "https://github.com/openzipkin/zipkin-js", | ||
"dependencies": { | ||
"zipkin": "^0.19.0" | ||
}, | ||
"devDependencies": { | ||
"@babel/cli": "7.1.5", | ||
"@babel/core": "7.1.5", | ||
"express": "^4.13.4", | ||
"mocha": "^5.2.0", | ||
"node-fetch": "^1.5.3", | ||
"zipkin": "^0.19.0-alpha.4+723a033" | ||
"node-fetch": "^1.5.3" | ||
}, | ||
"gitHead": "723a033d90aa4dcf894625244bb2c4c5ef6b484f" | ||
"gitHead": "579e12b642b7e0b486dd2b78193ec0a798e82a7a" | ||
} |
# zipkin-instrumentation-fetch | ||
![npm](https://img.shields.io/npm/dm/zipkin-instrumentation-fetch.svg) | ||
This library will wrap the [fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API). | ||
@@ -4,0 +6,0 @@ You need to provide your own `fetch` implementation; it could for example come from `window.fetch` (in the browser), |
@@ -12,7 +12,6 @@ const { | ||
const method = opts.method || 'GET'; | ||
const zipkinOpts = | ||
instrumentation.recordRequest(opts, url, method); | ||
const zipkinOpts = instrumentation.recordRequest(opts, url, method); | ||
const traceId = tracer.id; | ||
fetch(url, zipkinOpts).then(res => { | ||
fetch(url, zipkinOpts).then((res) => { | ||
tracer.scoped(() => { | ||
@@ -22,3 +21,3 @@ instrumentation.recordResponse(traceId, res.status); | ||
resolve(res); | ||
}).catch(err => { | ||
}).catch((err) => { | ||
tracer.scoped(() => { | ||
@@ -25,0 +24,0 @@ instrumentation.recordError(traceId, err); |
@@ -1,170 +0,31 @@ | ||
const {Tracer, ExplicitContext, createNoopTracer} = require('zipkin'); | ||
const express = require('express'); | ||
const nodeFetch = require('node-fetch'); | ||
const sinon = require('sinon'); | ||
// defer lookup of node fetch until we know if we are node | ||
const wrapFetch = require('../src/wrapFetch'); | ||
describe('wrapFetch', () => { | ||
before(function(done) { | ||
const app = express(); | ||
app.post('/user', (req, res) => res.status(202).json({ | ||
traceId: req.header('X-B3-TraceId') || '?', | ||
spanId: req.header('X-B3-SpanId') || '?' | ||
})); | ||
app.get('/user', (req, res) => res.status(202).json({})); | ||
this.server = app.listen(0, () => { | ||
this.port = this.server.address().port; | ||
done(); | ||
}); | ||
}); | ||
const {inBrowser} = require('../../../test/testFixture'); | ||
const clientFixture = require('../../../test/httpClientTestFixture'); | ||
after(function(done) { | ||
this.server.close(done); | ||
}); | ||
describe('fetch instrumentation - integration test', () => { | ||
function clientFunction({tracer, remoteServiceName}) { | ||
let fetch; | ||
if (inBrowser()) { | ||
fetch = window.fetch; // eslint-disable-line | ||
} else { // defer loading node-fetch | ||
fetch = require('node-fetch'); // eslint-disable-line global-require | ||
} | ||
it('should add instrumentation to "fetch"', function(done) { | ||
const record = sinon.spy(); | ||
const recorder = {record}; | ||
const ctxImpl = new ExplicitContext(); | ||
const tracer = new Tracer({recorder, ctxImpl}); | ||
const fetch = wrapFetch(nodeFetch, { | ||
tracer, | ||
serviceName: 'caller', | ||
remoteServiceName: 'callee' | ||
const wrapped = wrapFetch(fetch, {tracer, remoteServiceName}); | ||
return ({ | ||
get(url) { | ||
return wrapped(url, {redirect: 'manual'}); | ||
}, | ||
getOptions(url) { | ||
return wrapped({url}); | ||
}, | ||
getJson(url) { | ||
return wrapped(url).then(response => response.json()); | ||
} | ||
}); | ||
} | ||
ctxImpl.scoped(() => { | ||
const id = tracer.createChildId(); | ||
tracer.setId(id); | ||
const host = '127.0.0.1'; | ||
const urlPath = '/user'; | ||
const url = `http://${host}:${this.port}${urlPath}`; | ||
fetch(url, {method: 'post'}) | ||
.then(res => res.json()) | ||
.then(data => { | ||
const annotations = record.args.map(args => args[0]); | ||
// All annotations should have the same trace id and span id | ||
const traceId = annotations[0].traceId.traceId; | ||
const spanId = annotations[0].traceId.spanId; | ||
annotations.forEach(ann => expect(ann.traceId.traceId).to.equal(traceId)); | ||
annotations.forEach(ann => expect(ann.traceId.spanId).to.equal(spanId)); | ||
expect(annotations[0].annotation.annotationType).to.equal('ServiceName'); | ||
expect(annotations[0].annotation.serviceName).to.equal('caller'); | ||
expect(annotations[1].annotation.annotationType).to.equal('Rpc'); | ||
expect(annotations[1].annotation.name).to.equal('POST'); | ||
expect(annotations[2].annotation.annotationType).to.equal('BinaryAnnotation'); | ||
expect(annotations[2].annotation.key).to.equal('http.path'); | ||
expect(annotations[2].annotation.value).to.equal(urlPath); | ||
expect(annotations[3].annotation.annotationType).to.equal('ClientSend'); | ||
expect(annotations[4].annotation.annotationType).to.equal('ServerAddr'); | ||
expect(annotations[4].annotation.serviceName).to.equal('callee'); | ||
expect(annotations[5].annotation.annotationType).to.equal('BinaryAnnotation'); | ||
expect(annotations[5].annotation.key).to.equal('http.status_code'); | ||
expect(annotations[5].annotation.value).to.equal('202'); | ||
expect(annotations[6].annotation.annotationType).to.equal('ClientRecv'); | ||
const traceIdOnServer = data.traceId; | ||
expect(traceIdOnServer).to.equal(traceId); | ||
const spanIdOnServer = data.spanId; | ||
expect(spanIdOnServer).to.equal(spanId); | ||
}) | ||
.then(done) | ||
.catch(done); | ||
}); | ||
}); | ||
it('should not throw when using fetch without options', function(done) { | ||
const tracer = createNoopTracer(); | ||
const fetch = wrapFetch(nodeFetch, {serviceName: 'user-service', tracer}); | ||
const path = `http://127.0.0.1:${this.port}/user`; | ||
fetch(path) | ||
.then(res => res.json()) | ||
.then(() => { | ||
done(); | ||
}) | ||
.catch(done); | ||
}); | ||
it('should not throw when using fetch with a request object', function(done) { | ||
const tracer = createNoopTracer(); | ||
const fetch = wrapFetch(nodeFetch, {serviceName: 'user-service', tracer}); | ||
const path = `http://127.0.0.1:${this.port}/user`; | ||
const request = {url: path}; | ||
fetch(request) | ||
.then(res => res.json()) | ||
.then(() => { | ||
done(); | ||
}) | ||
.catch(done); | ||
}); | ||
it('should record error', (done) => { | ||
const record = sinon.spy(); | ||
const recorder = {record}; | ||
const ctxImpl = new ExplicitContext(); | ||
const tracer = new Tracer({recorder, ctxImpl}); | ||
const fetch = wrapFetch(nodeFetch, { | ||
tracer, | ||
serviceName: 'caller', | ||
remoteServiceName: 'callee' | ||
}); | ||
ctxImpl.scoped(() => { | ||
const id = tracer.createChildId(); | ||
tracer.setId(id); | ||
const host = 'domain.invalid'; | ||
const url = `http://${host}`; | ||
fetch(url, {method: 'post'}) | ||
.then(() => expect.fail()) | ||
.catch(() => { | ||
const annotations = record.args.map(args => args[0]); | ||
// All annotations should have the same trace id and span id | ||
const traceId = annotations[0].traceId.traceId; | ||
const spanId = annotations[0].traceId.spanId; | ||
annotations.forEach(ann => expect(ann.traceId.traceId).to.equal(traceId)); | ||
annotations.forEach(ann => expect(ann.traceId.spanId).to.equal(spanId)); | ||
expect(annotations[0].annotation.annotationType).to.equal('ServiceName'); | ||
expect(annotations[0].annotation.serviceName).to.equal('caller'); | ||
expect(annotations[1].annotation.annotationType).to.equal('Rpc'); | ||
expect(annotations[1].annotation.name).to.equal('POST'); | ||
expect(annotations[2].annotation.annotationType).to.equal('BinaryAnnotation'); | ||
expect(annotations[2].annotation.key).to.equal('http.path'); | ||
expect(annotations[2].annotation.value).to.equal('/'); | ||
expect(annotations[3].annotation.annotationType).to.equal('ClientSend'); | ||
expect(annotations[4].annotation.annotationType).to.equal('ServerAddr'); | ||
expect(annotations[4].annotation.serviceName).to.equal('callee'); | ||
expect(annotations[5].annotation.annotationType).to.equal('BinaryAnnotation'); | ||
expect(annotations[5].annotation.key).to.equal('error'); | ||
expect(annotations[5].annotation.value) | ||
.to.contain('getaddrinfo ENOTFOUND domain.invalid'); | ||
expect(annotations[6].annotation.annotationType).to.equal('ClientRecv'); | ||
expect(annotations[7]).to.be.undefined; // eslint-disable-line no-unused-expressions | ||
done(); | ||
}); | ||
}); | ||
}); | ||
clientFixture.setupAllHttpClientTests({clientFunction}); | ||
}); |
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
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
1
24
3
5156
1
92
+ Addedzipkin@^0.19.0
+ Addedbase64-js@1.5.1(transitive)
+ Addedis-promise@2.2.2(transitive)
+ Addedzipkin@0.19.2(transitive)