index.js 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import { Trace } from '@apollo/usage-reporting-protobuf';
  2. import { TraceTreeBuilder } from '../traceTreeBuilder.js';
  3. import { internalPlugin } from '../../internalPlugin.js';
  4. import { schemaIsSubgraph } from '../schemaIsSubgraph.js';
  5. export function ApolloServerPluginInlineTrace(options = Object.create(null)) {
  6. let enabled = options.__onlyIfSchemaIsSubgraph ? null : true;
  7. return internalPlugin({
  8. __internal_plugin_id__: 'InlineTrace',
  9. __is_disabled_plugin__: false,
  10. async serverWillStart({ schema, logger }) {
  11. if (enabled === null) {
  12. enabled = schemaIsSubgraph(schema);
  13. if (enabled) {
  14. logger.info('Enabling inline tracing for this subgraph. To disable, use ' +
  15. 'ApolloServerPluginInlineTraceDisabled.');
  16. }
  17. }
  18. },
  19. async requestDidStart({ request: { http }, metrics }) {
  20. if (!enabled) {
  21. return;
  22. }
  23. const treeBuilder = new TraceTreeBuilder({
  24. maskedBy: 'ApolloServerPluginInlineTrace',
  25. sendErrors: options.includeErrors,
  26. });
  27. if (http?.headers.get('apollo-federation-include-trace') !== 'ftv1') {
  28. return;
  29. }
  30. if (metrics.captureTraces === false) {
  31. return;
  32. }
  33. metrics.captureTraces = true;
  34. treeBuilder.startTiming();
  35. return {
  36. async executionDidStart() {
  37. return {
  38. willResolveField({ info }) {
  39. return treeBuilder.willResolveField(info);
  40. },
  41. };
  42. },
  43. async didEncounterErrors({ errors }) {
  44. treeBuilder.didEncounterErrors(errors);
  45. },
  46. async willSendResponse({ response }) {
  47. treeBuilder.stopTiming();
  48. if (response.body.kind === 'incremental') {
  49. return;
  50. }
  51. if (metrics.queryPlanTrace) {
  52. treeBuilder.trace.queryPlan = metrics.queryPlanTrace;
  53. }
  54. const encodedUint8Array = Trace.encode(treeBuilder.trace).finish();
  55. const encodedBuffer = Buffer.from(encodedUint8Array, encodedUint8Array.byteOffset, encodedUint8Array.byteLength);
  56. const extensions = response.body.singleResult.extensions ||
  57. (response.body.singleResult.extensions = Object.create(null));
  58. if (typeof extensions.ftv1 !== 'undefined') {
  59. throw new Error('The `ftv1` extension was already present.');
  60. }
  61. extensions.ftv1 = encodedBuffer.toString('base64');
  62. },
  63. };
  64. },
  65. });
  66. }
  67. //# sourceMappingURL=index.js.map