Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

zipkin-instrumentation-fetch

Package Overview
Dependencies
Maintainers
1
Versions
57
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

zipkin-instrumentation-fetch - npm Package Compare versions

Comparing version 0.19.0-alpha.4 to 0.19.0

2

lib/wrapFetch.js

@@ -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});
});
SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc