From f7c0d85209c9e96f7812c4a2996f000a2667770d Mon Sep 17 00:00:00 2001 From: hui Date: Sun, 10 Sep 2017 11:41:34 +0800 Subject: [PATCH] feat: support app.httpclient and agent.httpclient auto set tracer (#1393) --- lib/core/httpclient.js | 15 ++ package.json | 1 + test/fixtures/apps/httpclient-tracer/app.js | 6 + .../apps/httpclient-tracer/config/plugin.js | 8 + .../apps/httpclient-tracer/package.json | 3 + test/lib/core/httpclient.test.js | 211 ++++++++++++++++++ 6 files changed, 244 insertions(+) create mode 100644 test/fixtures/apps/httpclient-tracer/app.js create mode 100644 test/fixtures/apps/httpclient-tracer/config/plugin.js create mode 100644 test/fixtures/apps/httpclient-tracer/package.json diff --git a/lib/core/httpclient.js b/lib/core/httpclient.js index 6896167c6a..89c86b327d 100644 --- a/lib/core/httpclient.js +++ b/lib/core/httpclient.js @@ -18,6 +18,21 @@ class HttpClient extends urllib.HttpClient { }); this.app = app; } + + request(url, args, callback) { + if (typeof args === 'function') { + callback = args; + args = null; + } + + args = args || {}; + + if (!args.ctx && !args.tracer) { + args.tracer = this.app.tracer; + } + + return super.request(url, args, callback); + } } function normalizeConfig(app) { diff --git a/package.json b/package.json index 83feaff29c..77176b8103 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "egg-doctools": "^2.0.1", "egg-mock": "^3.8.0", "egg-plugin-puml": "^2.4.0", + "egg-tracer": "^1.1.0", "egg-view-nunjucks": "^2.1.3", "eslint": "^4.1.1", "eslint-config-egg": "^5.0.0", diff --git a/test/fixtures/apps/httpclient-tracer/app.js b/test/fixtures/apps/httpclient-tracer/app.js new file mode 100644 index 0000000000..9159c26c97 --- /dev/null +++ b/test/fixtures/apps/httpclient-tracer/app.js @@ -0,0 +1,6 @@ +'use strict'; + +module.exports = app => { + const done = app.readyCallback('ready'); + setTimeout(done, 5000); +}; \ No newline at end of file diff --git a/test/fixtures/apps/httpclient-tracer/config/plugin.js b/test/fixtures/apps/httpclient-tracer/config/plugin.js new file mode 100644 index 0000000000..2e2c7e6ad0 --- /dev/null +++ b/test/fixtures/apps/httpclient-tracer/config/plugin.js @@ -0,0 +1,8 @@ +'use strict'; + +module.exports = { + tracer: { + enable: true, + package: 'egg-tracer', + }, +} diff --git a/test/fixtures/apps/httpclient-tracer/package.json b/test/fixtures/apps/httpclient-tracer/package.json new file mode 100644 index 0000000000..7365a534a8 --- /dev/null +++ b/test/fixtures/apps/httpclient-tracer/package.json @@ -0,0 +1,3 @@ +{ + "name": "httpclient-tracer" +} diff --git a/test/lib/core/httpclient.test.js b/test/lib/core/httpclient.test.js index 7b4a2bd6f0..60dd1da919 100644 --- a/test/lib/core/httpclient.test.js +++ b/test/lib/core/httpclient.test.js @@ -177,4 +177,215 @@ describe('test/lib/core/httpclient.test.js', () => { }); }); }); + + describe('httpclient tracer', () => { + let app; + before(() => { + app = utils.app('apps/httpclient-tracer'); + return app.ready(); + }); + + after(() => app.close()); + + it('should app request auto set tracer', function* () { + const httpclient = app.httpclient; + + let reqTracer; + let resTracer; + + httpclient.on('request', function(options) { + reqTracer = options.args.tracer; + }); + + httpclient.on('response', function(options) { + resTracer = options.req.args.tracer; + }); + + let res = yield httpclient.request('https://www.alipay.com', { + method: 'GET', + }); + + assert(res.status === 200); + assert(reqTracer === resTracer); + + assert(reqTracer.traceId); + assert(reqTracer.traceId === resTracer.traceId); + + reqTracer = null; + resTracer = null; + + res = yield httpclient.request('https://www.alipay.com'); + + assert(res.status === 200); + assert(reqTracer === resTracer); + + assert(reqTracer.traceId); + assert(reqTracer.traceId === resTracer.traceId); + }); + + it('should agent request auto set tracer', function* () { + const httpclient = app.agent.httpclient; + + let reqTracer; + let resTracer; + + httpclient.on('request', function(options) { + reqTracer = options.args.tracer; + }); + + httpclient.on('response', function(options) { + resTracer = options.req.args.tracer; + }); + + const res = yield httpclient.request('https://www.alipay.com', { + method: 'GET', + }); + + assert(res.status === 200); + assert(reqTracer === resTracer); + + assert(reqTracer.traceId); + assert(reqTracer.traceId === resTracer.traceId); + }); + + it('should app request with ctx and tracer', function* () { + const httpclient = app.httpclient; + + let reqTracer; + let resTracer; + + httpclient.on('request', function(options) { + reqTracer = options.args.tracer || options.ctx.tracer; + }); + + httpclient.on('response', function(options) { + resTracer = options.req.args.tracer || options.ctx.tracer; + }); + + let res = yield httpclient.request('https://www.alipay.com', { + method: 'GET', + }); + + assert(res.status === 200); + + assert(reqTracer.traceId); + assert(reqTracer.traceId === resTracer.traceId); + + reqTracer = null; + resTracer = null; + res = yield httpclient.request('https://www.alipay.com', { + method: 'GET', + ctx: {}, + tracer: { + id: '1234', + }, + }); + + assert(res.status === 200); + assert(reqTracer.id === resTracer.id); + assert(reqTracer.id === '1234'); + + reqTracer = null; + resTracer = null; + res = yield httpclient.request('https://www.alipay.com', { + method: 'GET', + ctx: { + tracer: { + id: '5678', + }, + }, + }); + + assert(res.status === 200); + assert(reqTracer.id === resTracer.id); + assert(reqTracer.id === '5678'); + }); + }); + + describe('before app ready multi httpclient request tracer', () => { + let app; + before(() => { + app = utils.app('apps/httpclient-tracer'); + }); + + after(() => app.close()); + + it('should app request before ready use same tracer', function* () { + const httpclient = app.httpclient; + + let reqTracers = []; + let resTracers = []; + + httpclient.on('request', function(options) { + reqTracers.push(options.args.tracer); + }); + + httpclient.on('response', function(options) { + resTracers.push(options.req.args.tracer); + }); + + let res = yield httpclient.request('https://www.alipay.com', { + method: 'GET', + }); + assert(res.status === 200); + + + res = yield httpclient.request('https://github.com', { + method: 'GET', + }); + + assert(res.status === 200); + + res = yield httpclient.request('https://www.npmjs.com', { + method: 'GET', + }); + assert(res.status === 200); + + assert(reqTracers.length === 3); + assert(resTracers.length === 3); + + assert(reqTracers[0] === reqTracers[1]); + assert(reqTracers[1] === reqTracers[2]); + + assert(resTracers[0] === reqTracers[2]); + assert(resTracers[1] === resTracers[0]); + assert(resTracers[2] === resTracers[1]); + + assert(reqTracers[0].traceId); + + reqTracers = []; + resTracers = []; + + yield app.ready(); + + res = yield httpclient.request('https://www.alipay.com', { + method: 'GET', + }); + assert(res.status === 200); + + + res = yield httpclient.request('https://github.com', { + method: 'GET', + }); + assert(res.status === 200); + + res = yield httpclient.request('https://www.npmjs.com', { + method: 'GET', + }); + assert(res.status === 200); + + assert(reqTracers.length === 3); + assert(resTracers.length === 3); + + assert(reqTracers[0] !== reqTracers[1]); + assert(reqTracers[1] !== reqTracers[2]); + + assert(resTracers[0] !== reqTracers[2]); + assert(resTracers[1] !== resTracers[0]); + assert(resTracers[2] !== resTracers[1]); + + assert(reqTracers[0].traceId); + }); + }); + });