diff --git a/src/server/index.js b/src/server/index.js index 0d96380..edfacc9 100644 --- a/src/server/index.js +++ b/src/server/index.js @@ -1,6 +1,6 @@ const util = require("util"); -const { addBeelineToSchema, beelinePlugin } = require("./lib/beeline-graphql"); +const { beelinePlugin } = require("./lib/beeline-graphql"); const { gql, makeExecutableSchema } = require("apollo-server"); const jwtVerify = util.promisify(require("jsonwebtoken").verify); const jwksClient = require("jwks-rsa"); @@ -49,7 +49,6 @@ const schema = makeExecutableSchema( const plugins = [svgLoggingPlugin]; if (process.env["NODE_ENV"] !== "test") { - addBeelineToSchema(schema); plugins.push(beelinePlugin); } diff --git a/src/server/lib/beeline-graphql.js b/src/server/lib/beeline-graphql.js index 7b8aea1..c5972ab 100644 --- a/src/server/lib/beeline-graphql.js +++ b/src/server/lib/beeline-graphql.js @@ -1,72 +1,4 @@ -// Integrates Honeycomb tracing with Apollo Server. -// Adapted from https://gist.github.com/numso/504faeca4e946c2c54e8b890c6469d81 const beeline = require("honeycomb-beeline"); -const gql = require("graphql"); - -function addBeelineToSchema(schema) { - if (!beeline) return; - forEachField(schema, (field) => { - if (!field.resolve) return; - const oldResolve = field.resolve; - field.resolve = (source, args, context, info) => { - context.spans = context.spans || {}; - let result; - const path = responsePathAsString(info.path); - beeline.startAsyncSpan(fieldsFor("resolve", path), async (span) => { - context.spans[path] = span.payload["trace.span_id"]; - try { - result = oldResolve(source, args, { ...context, span }, info); - if (result.then) await result; - } catch (error) { - span.addContext({ "error.message": error.message }); - span.addContext({ "error.stacktrace": error.stack }); - } - const parent = getParentId(context.spans, path); - if (parent) span.addContext({ "trace.parent_id": parent }); - beeline.finishSpan(span); - }); - return result; - }; - }); -} - -function forEachField(schema, fn) { - const typeMap = schema.getTypeMap(); - Object.keys(typeMap).forEach((typeName) => { - const type = typeMap[typeName]; - if ( - !gql.getNamedType(type).name.startsWith("__") && - type instanceof gql.GraphQLObjectType - ) { - const fields = type.getFields(); - Object.keys(fields).forEach((fieldName) => { - const field = fields[fieldName]; - fn(field, typeName, fieldName); - }); - } - }); -} - -const responsePathAsString = (path) => gql.responsePathAsArray(path).join("."); - -function getParentId(spanIds, currentPath) { - const path = currentPath.split(".").slice(0, -1).join("."); - if (!path) return null; - if (!(path in spanIds)) { - const span = beeline.startSpan(fieldsFor("field", path)); - spanIds[path] = span.payload["trace.span_id"]; - const parent = getParentId(spanIds, path); - if (parent) span.addContext({ "trace.parent_id": parent }); - beeline.finishSpan(span); - } - return spanIds[path]; -} - -const fieldsFor = (name, path) => ({ - name, - "graphql.path": path, - "graphql.key": path.split(".").pop(), -}); const beelinePlugin = { requestDidStart() { @@ -86,6 +18,5 @@ const beelinePlugin = { }; module.exports = { - addBeelineToSchema, beelinePlugin, };