Socket
Socket
Sign inDemoInstall

apollo-tracing

Package Overview
Dependencies
Maintainers
1
Versions
121
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

apollo-tracing - npm Package Compare versions

Comparing version 0.10.1-alpha.0 to 0.11.0-alpha.0

17

dist/index.d.ts

@@ -1,3 +0,2 @@

import { GraphQLResolveInfo } from 'graphql';
import { GraphQLExtension } from 'graphql-extensions';
import { ApolloServerPlugin } from "apollo-server-plugin-base";
export interface TracingFormat {

@@ -19,15 +18,3 @@ version: 1;

}
export declare class TracingExtension<TContext = any> implements GraphQLExtension<TContext> {
private startWallTime?;
private endWallTime?;
private startHrTime?;
private duration?;
private resolverCalls;
requestDidStart(): void;
executionDidStart(): () => void;
willResolveField(_source: any, _args: {
[argName: string]: any;
}, _context: TContext, info: GraphQLResolveInfo): () => void;
format(): [string, TracingFormat] | undefined;
}
export declare const plugin: (_futureOptions?: {}) => () => ApolloServerPlugin<Record<string, any>>;
//# sourceMappingURL=index.d.ts.map

122

dist/index.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const graphql_1 = require("graphql");
class TracingExtension {
constructor() {
this.resolverCalls = [];
}
const { PACKAGE_NAME } = require("../package.json").name;
exports.plugin = (_futureOptions = {}) => () => ({
requestDidStart() {
this.startWallTime = new Date();
this.startHrTime = process.hrtime();
}
executionDidStart() {
return () => {
this.duration = process.hrtime(this.startHrTime);
this.endWallTime = new Date();
};
}
willResolveField(_source, _args, _context, info) {
const resolverCall = {
path: info.path,
fieldName: info.fieldName,
parentType: info.parentType,
returnType: info.returnType,
startOffset: process.hrtime(this.startHrTime),
};
this.resolverCalls.push(resolverCall);
return () => {
resolverCall.endOffset = process.hrtime(this.startHrTime);
};
}
format() {
if (typeof this.startWallTime === 'undefined' ||
typeof this.endWallTime === 'undefined' ||
typeof this.duration === 'undefined') {
return;
}
return [
'tracing',
{
version: 1,
startTime: this.startWallTime.toISOString(),
endTime: this.endWallTime.toISOString(),
duration: durationHrTimeToNanos(this.duration),
execution: {
resolvers: this.resolverCalls.map(resolverCall => {
const startOffset = durationHrTimeToNanos(resolverCall.startOffset);
const duration = resolverCall.endOffset
? durationHrTimeToNanos(resolverCall.endOffset) - startOffset
: 0;
return {
path: [...graphql_1.responsePathAsArray(resolverCall.path)],
parentType: resolverCall.parentType.toString(),
fieldName: resolverCall.fieldName,
returnType: resolverCall.returnType.toString(),
startOffset,
duration,
};
}),
let startWallTime;
let endWallTime;
let startHrTime;
let duration;
const resolverCalls = [];
startWallTime = new Date();
startHrTime = process.hrtime();
return {
executionDidStart: () => ({
executionDidEnd: () => {
duration = process.hrtime(startHrTime);
endWallTime = new Date();
},
willResolveField({ info }) {
const resolverCall = {
path: info.path,
fieldName: info.fieldName,
parentType: info.parentType,
returnType: info.returnType,
startOffset: process.hrtime(startHrTime),
};
resolverCalls.push(resolverCall);
return () => {
resolverCall.endOffset = process.hrtime(startHrTime);
};
},
}),
willSendResponse({ response }) {
if (typeof startWallTime === 'undefined' ||
typeof endWallTime === 'undefined' ||
typeof duration === 'undefined') {
return;
}
const extensions = response.extensions || (response.extensions = Object.create(null));
if (typeof extensions.tracing !== 'undefined') {
throw new Error(PACKAGE_NAME + ": Could not add `tracing` to " +
"`extensions` since `tracing` was unexpectedly already present.");
}
extensions.tracing = {
version: 1,
startTime: startWallTime.toISOString(),
endTime: endWallTime.toISOString(),
duration: durationHrTimeToNanos(duration),
execution: {
resolvers: resolverCalls.map(resolverCall => {
const startOffset = durationHrTimeToNanos(resolverCall.startOffset);
const duration = resolverCall.endOffset
? durationHrTimeToNanos(resolverCall.endOffset) - startOffset
: 0;
return {
path: [...graphql_1.responsePathAsArray(resolverCall.path)],
parentType: resolverCall.parentType.toString(),
fieldName: resolverCall.fieldName,
returnType: resolverCall.returnType.toString(),
startOffset,
duration,
};
}),
},
};
},
];
}
}
exports.TracingExtension = TracingExtension;
};
},
});
function durationHrTimeToNanos(hrtime) {

@@ -66,0 +72,0 @@ return hrtime[0] * 1e9 + hrtime[1];

{
"name": "apollo-tracing",
"version": "0.10.1-alpha.0",
"version": "0.11.0-alpha.0",
"description": "Collect and expose trace data for GraphQL requests",

@@ -15,3 +15,3 @@ "main": "./dist/index.js",

"apollo-server-env": "^2.4.4-alpha.0",
"graphql-extensions": "^0.12.1-alpha.0"
"apollo-server-plugin-base": "^0.9.0-alpha.0"
},

@@ -21,3 +21,3 @@ "peerDependencies": {

},
"gitHead": "626c4b6505ed98d47855712a568fc4eba9d8ff18"
"gitHead": "bfef89b8cc44d4bd94f9d5fcd3df8941de526360"
}

@@ -15,12 +15,11 @@ # Apollo Tracing (for Node.js)

The only code change required is to add `tracing: true` to the options passed to the Apollo Server middleware function for your framework of choice. For example, for Express:
The only code change required is to add `tracing: true` to the options passed to the `ApolloServer` constructor options for your integration of choice. For example, for [`apollo-server-express`](https://npm.im/apollo-server-express):
```javascript
app.use('/graphql', bodyParser.json(), graphqlExpress({
const { ApolloServer } = require('apollo-server-express');
const server = new ApolloServer({
schema,
context: {},
tracing: true,
}));
});
```
> If you are using `express-graphql`, we recommend you switch to Apollo Server. Both `express-graphql` and Apollo Server are based on the [`graphql-js`](https://github.com/graphql/graphql-js) reference implementation, and switching should only require changing a few lines of code.
import {
ResponsePath,
responsePathAsArray,
GraphQLResolveInfo,
GraphQLType,
} from 'graphql';
import { ApolloServerPlugin } from "apollo-server-plugin-base";
import { GraphQLExtension } from 'graphql-extensions';
const { PACKAGE_NAME } = require("../package.json").name;

@@ -36,90 +36,100 @@ export interface TracingFormat {

export class TracingExtension<TContext = any>
implements GraphQLExtension<TContext> {
private startWallTime?: Date;
private endWallTime?: Date;
private startHrTime?: HighResolutionTime;
private duration?: HighResolutionTime;
export const plugin = (_futureOptions = {}) => (): ApolloServerPlugin => ({
requestDidStart() {
let startWallTime: Date | undefined;
let endWallTime: Date | undefined;
let startHrTime: HighResolutionTime | undefined;
let duration: HighResolutionTime | undefined;
const resolverCalls: ResolverCall[] = [];
private resolverCalls: ResolverCall[] = [];
startWallTime = new Date();
startHrTime = process.hrtime();
public requestDidStart() {
this.startWallTime = new Date();
this.startHrTime = process.hrtime();
}
return {
executionDidStart: () => ({
// It's a little odd that we record the end time after execution rather
// than at the end of the whole request, but because we need to include
// our formatted trace in the request itself, we have to record it
// before the request is over!
public executionDidStart() {
// It's a little odd that we record the end time after execution rather than
// at the end of the whole request, but because we need to include our
// formatted trace in the request itself, we have to record it before the
// request is over! It's also odd that we don't do traces for parse or
// validation errors, but runQuery doesn't currently support that, as
// format() is only invoked after execution.
return () => {
this.duration = process.hrtime(this.startHrTime);
this.endWallTime = new Date();
};
}
// Historically speaking: It's WAS odd that we don't do traces for parse
// or validation errors. Reason being: at the time that this was written
// (now a plugin but originally an extension)). That was the case
// because runQuery DIDN'T (again, at the time, when it was an
// extension) support that since format() was only invoked after
// execution.
executionDidEnd: () => {
duration = process.hrtime(startHrTime);
endWallTime = new Date();
},
public willResolveField(
_source: any,
_args: { [argName: string]: any },
_context: TContext,
info: GraphQLResolveInfo,
) {
const resolverCall: ResolverCall = {
path: info.path,
fieldName: info.fieldName,
parentType: info.parentType,
returnType: info.returnType,
startOffset: process.hrtime(this.startHrTime),
};
willResolveField({ info }) {
const resolverCall: ResolverCall = {
path: info.path,
fieldName: info.fieldName,
parentType: info.parentType,
returnType: info.returnType,
startOffset: process.hrtime(startHrTime),
};
this.resolverCalls.push(resolverCall);
resolverCalls.push(resolverCall);
return () => {
resolverCall.endOffset = process.hrtime(this.startHrTime);
};
}
return () => {
resolverCall.endOffset = process.hrtime(startHrTime);
};
},
}),
public format(): [string, TracingFormat] | undefined {
// In the event that we are called prior to the initialization of critical
// date metrics, we'll return undefined to signal that the extension did not
// format properly. Any undefined extension results are simply purged by
// the graphql-extensions module.
if (
typeof this.startWallTime === 'undefined' ||
typeof this.endWallTime === 'undefined' ||
typeof this.duration === 'undefined'
) {
return;
}
willSendResponse({ response }) {
// In the event that we are called prior to the initialization of
// critical date metrics, we'll return undefined to signal that the
// extension did not format properly. Any undefined extension
// results are simply purged by the graphql-extensions module.
if (
typeof startWallTime === 'undefined' ||
typeof endWallTime === 'undefined' ||
typeof duration === 'undefined'
) {
return;
}
return [
'tracing',
{
version: 1,
startTime: this.startWallTime.toISOString(),
endTime: this.endWallTime.toISOString(),
duration: durationHrTimeToNanos(this.duration),
execution: {
resolvers: this.resolverCalls.map(resolverCall => {
const startOffset = durationHrTimeToNanos(resolverCall.startOffset);
const duration = resolverCall.endOffset
? durationHrTimeToNanos(resolverCall.endOffset) - startOffset
: 0;
return {
path: [...responsePathAsArray(resolverCall.path)],
parentType: resolverCall.parentType.toString(),
fieldName: resolverCall.fieldName,
returnType: resolverCall.returnType.toString(),
startOffset,
duration,
};
}),
},
const extensions =
response.extensions || (response.extensions = Object.create(null));
// Be defensive and make sure nothing else (other plugin, etc.) has
// already used the `tracing` property on `extensions`.
if (typeof extensions.tracing !== 'undefined') {
throw new Error(PACKAGE_NAME + ": Could not add `tracing` to " +
"`extensions` since `tracing` was unexpectedly already present.");
}
// Set the extensions.
extensions.tracing = {
version: 1,
startTime: startWallTime.toISOString(),
endTime: endWallTime.toISOString(),
duration: durationHrTimeToNanos(duration),
execution: {
resolvers: resolverCalls.map(resolverCall => {
const startOffset = durationHrTimeToNanos(
resolverCall.startOffset,
);
const duration = resolverCall.endOffset
? durationHrTimeToNanos(resolverCall.endOffset) - startOffset
: 0;
return {
path: [...responsePathAsArray(resolverCall.path)],
parentType: resolverCall.parentType.toString(),
fieldName: resolverCall.fieldName,
returnType: resolverCall.returnType.toString(),
startOffset,
duration,
};
}),
},
};
},
];
}
}
};
},
})

@@ -126,0 +136,0 @@ type HighResolutionTime = [number, number];

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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