diff --git a/package-lock.json b/package-lock.json index 459f9c65..bf7a51c8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1454,7 +1454,6 @@ "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", "dev": true, - "optional": true, "requires": { "kind-of": "^3.0.2", "longest": "^1.0.1", @@ -3223,7 +3222,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, "requires": { "object-keys": "^1.0.12" } @@ -3516,7 +3514,6 @@ "version": "1.12.0", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", - "dev": true, "requires": { "es-to-primitive": "^1.1.1", "function-bind": "^1.1.1", @@ -3529,7 +3526,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", - "dev": true, "requires": { "is-callable": "^1.1.1", "is-date-object": "^1.0.1", @@ -4236,8 +4232,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -4258,14 +4253,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -4280,20 +4273,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -4410,8 +4400,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -4423,7 +4412,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -4438,7 +4426,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -4446,14 +4433,12 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.2.4", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -4472,7 +4457,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -4553,8 +4537,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -4566,7 +4549,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -4652,8 +4634,7 @@ "safe-buffer": { "version": "5.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -4689,7 +4670,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -4709,7 +4689,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -4753,22 +4732,19 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "get-caller-file": { "version": "1.0.3", @@ -4947,7 +4923,21 @@ "graphql-extensions": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.2.0.tgz", - "integrity": "sha512-dW2PdomN+IXzUDQALzpBk++sEXm2LamCP16hCOZ2B/go50I967R7/K+rr8qOxoNb7lvtLW1BjQg8kRoPqByrug==" + "integrity": "sha512-dW2PdomN+IXzUDQALzpBk++sEXm2LamCP16hCOZ2B/go50I967R7/K+rr8qOxoNb7lvtLW1BjQg8kRoPqByrug==", + "requires": { + "apollo-server-env": "2.0.3" + }, + "dependencies": { + "apollo-server-env": { + "version": "2.0.3", + "resolved": "https://artifactory.ops.babylontech.co.uk/artifactory/api/npm/babylon-virtual-npm/apollo-server-env/-/apollo-server-env-2.0.3.tgz", + "integrity": "sha1-PBNVLNM/QAFgB2z44cmyS+TSfhM=", + "requires": { + "node-fetch": "^2.1.2", + "util.promisify": "^1.0.0" + } + } + } }, "graphql-subscriptions": { "version": "1.0.0", @@ -5059,7 +5049,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -5397,8 +5386,7 @@ "is-callable": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", - "dev": true + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==" }, "is-ci": { "version": "1.2.0", @@ -5421,8 +5409,7 @@ "is-date-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "dev": true + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" }, "is-descriptor": { "version": "0.1.6", @@ -5589,7 +5576,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "dev": true, "requires": { "has": "^1.0.1" } @@ -5615,8 +5601,7 @@ "is-symbol": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", - "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", - "dev": true + "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=" }, "is-text-path": { "version": "1.0.1", @@ -6546,8 +6531,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", - "dev": true, - "optional": true + "dev": true }, "loose-envify": { "version": "1.4.0", @@ -7045,8 +7029,7 @@ "node-fetch": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.2.0.tgz", - "integrity": "sha512-OayFWziIxiHY8bCUyLX6sTpDH8Jsbp4FfYd1j1f7vZyfgkcOnAyM4oQR16f8a0s7Gl/viMGRey8eScYk4V4EZA==", - "dev": true + "integrity": "sha512-OayFWziIxiHY8bCUyLX6sTpDH8Jsbp4FfYd1j1f7vZyfgkcOnAyM4oQR16f8a0s7Gl/viMGRey8eScYk4V4EZA==" }, "node-int64": { "version": "0.4.0", @@ -10266,8 +10249,7 @@ "object-keys": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", - "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", - "dev": true + "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==" }, "object-path": { "version": "0.11.4", @@ -10288,7 +10270,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", - "dev": true, "requires": { "define-properties": "^1.1.2", "es-abstract": "^1.5.1" @@ -12932,7 +12913,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", - "dev": true, "requires": { "define-properties": "^1.1.2", "object.getownpropertydescriptors": "^2.0.3" diff --git a/src/__tests__/__snapshots__/integration-test.ts.snap b/src/__tests__/__snapshots__/integration-test.ts.snap index 544ef11b..f43664b4 100644 --- a/src/__tests__/__snapshots__/integration-test.ts.snap +++ b/src/__tests__/__snapshots__/integration-test.ts.snap @@ -7,12 +7,8 @@ request:1 1. {"queryString":"\\n fragment F on A {\\n dos: two\\n }\\n\\n query {\\n a {\\n ...F\\n }\\n }"} +-- a:2 finished: true - logs: - 1. {"result":"{one:1,two:2,three:[{four:4},{four:IV}]}"} +-- dos:3 finished: true - logs: - 1. {"result":"2"} `; @@ -23,16 +19,10 @@ request:1 1. {"queryString":"query {\\n a {\\n uno: one\\n two\\n }\\n }"} +-- a:2 finished: true - logs: - 1. {"result":"{one:1,two:2,three:[{four:4},{four:IV}]}"} +-- uno:3 finished: true - logs: - 1. {"result":"1"} +-- two:4 finished: true - logs: - 1. {"result":"2"} `; @@ -43,16 +33,10 @@ request:1 1. {"queryString":"query {\\n a {\\n one\\n two\\n }\\n }"} +-- a:2 finished: true - logs: - 1. {"result":"{one:1,two:2,three:[{four:4},{four:IV}]}"} +-- one:3 finished: true - logs: - 1. {"result":"1"} +-- two:4 finished: true - logs: - 1. {"result":"2"} `; @@ -63,12 +47,8 @@ request:1 1. {"queryString":"query {\\n a {\\n one\\n two\\n }\\n b {\\n four\\n }\\n }"} +-- b:2 finished: true - logs: - 1. {"result":"{four:4}"} +-- four:3 finished: true - logs: - 1. {"result":"4"} `; @@ -79,31 +59,17 @@ request:1 1. {"queryString":"query {\\n as {\\n one\\n two\\n }\\n }"} +-- as:2 finished: true - logs: - 1. {"result":"[{one:1,two:2},{one:I,two:II},{one:eins,two:zwei}]"} +-- one:3 finished: true - logs: - 1. {"result":"1"} +-- two:4 finished: true - logs: - 1. {"result":"2"} +-- one:5 finished: true - logs: - 1. {"result":"I"} +-- two:6 finished: true - logs: - 1. {"result":"II"} +-- one:7 finished: true - logs: - 1. {"result":"eins"} +-- two:8 finished: true - logs: - 1. {"result":"zwei"} `; diff --git a/src/__tests__/index-test.ts b/src/__tests__/index-test.ts index d6d3f46d..c9160cf3 100644 --- a/src/__tests__/index-test.ts +++ b/src/__tests__/index-test.ts @@ -229,26 +229,39 @@ describe("Apollo Tracing", () => { expect(info.span).toBeDefined(); }); - it("logs an error", () => { - tracingMiddleware.requestSpan = { id: "23" }; - const err = new Error("my-error"); - - const cb = tracingMiddleware.willResolveField({}, {}, {}, {}); - cb(err); - - expect(local.span.log).toHaveBeenCalledWith({ - error: JSON.stringify(err) + it("calls onFieldResolve in willResolveField", () => { + const onFieldResolve = jest.fn(); + tracingMiddleware = new ApolloOpentracing({ + server, + local, + onFieldResolve }); + tracingMiddleware.requestSpan = { id: "23" }; + const info = {}; + const context = { headers: "abc" }; + tracingMiddleware.willResolveField({}, {}, context, info); + expect(onFieldResolve).toHaveBeenCalledWith({}, {}, context, info); }); - it("logs a result", () => { + it("doesn't logs a result and calls on field resolve finish", () => { + const onFieldResolveFinish = jest.fn(); + tracingMiddleware = new ApolloOpentracing({ + server, + local, + onFieldResolveFinish + }); tracingMiddleware.requestSpan = { id: "23" }; const result = { data: { id: "42" } }; const cb = tracingMiddleware.willResolveField({}, {}, {}, {}); cb(null, result); - expect(local.span.log).toHaveBeenCalledWith({ + expect(onFieldResolveFinish).toHaveBeenCalledWith( + null, + result, + local.span + ); + expect(local.span.log).not.toHaveBeenCalledWith({ result: JSON.stringify(result) }); }); diff --git a/src/index.ts b/src/index.ts index a291b962..eee38c04 100644 --- a/src/index.ts +++ b/src/index.ts @@ -10,6 +10,13 @@ const alwaysTrue = () => true; interface InitOptions { server?: Tracer; local?: Tracer; + onFieldResolveFinish?: (error: Error | null, result: any, span: Span) => void; + onFieldResolve?: ( + source: any, + args: { [argName: string]: any }, + context: SpanContext, + info: GraphQLResolveInfo + ) => void; shouldTraceRequest?: (info: RequestStart) => boolean; shouldTraceFieldResolver?: ( source: any, @@ -49,6 +56,17 @@ export default class OpentracingExtension private serverTracer: Tracer; private localTracer: Tracer; private requestSpan: Span | null; + private onFieldResolveFinish?: ( + error: Error | null, + result: any, + span: Span + ) => void; + private onFieldResolve?: ( + source: any, + args: { [argName: string]: any }, + context: SpanContext, + info: GraphQLResolveInfo + ) => void; private shouldTraceRequest: (info: RequestStart) => boolean; private shouldTraceFieldResolver: ( source: any, @@ -61,7 +79,9 @@ export default class OpentracingExtension server, local, shouldTraceRequest, - shouldTraceFieldResolver + shouldTraceFieldResolver, + onFieldResolveFinish, + onFieldResolve }: InitOptions = {}) { if (!server) { throw new Error( @@ -80,6 +100,8 @@ export default class OpentracingExtension this.requestSpan = null; this.shouldTraceRequest = shouldTraceRequest || alwaysTrue; this.shouldTraceFieldResolver = shouldTraceFieldResolver || alwaysTrue; + this.onFieldResolveFinish = onFieldResolveFinish; + this.onFieldResolve = onFieldResolve; } requestDidStart(infos: RequestStart) { @@ -140,16 +162,16 @@ export default class OpentracingExtension }); context.addSpan(span, info); - // expose to field info.span = span; + if (this.onFieldResolve) { + this.onFieldResolve(source, args, context, info); + } + return (error: Error | null, result: any) => { - if (error) { - span.log({ error: JSON.stringify(error) }); - } - if (result) { - span.log({ result: JSON.stringify(result) }); + if (this.onFieldResolveFinish) { + this.onFieldResolveFinish(error, result, span); } span.finish(); };