@envelop/prometheus
Version:
This plugin tracks the complete execution flow, and reports metrics using Prometheus tracing (based on `prom-client`).
83 lines (82 loc) • 2.92 kB
JavaScript
import { visit, visitWithTypeInfo, } from 'graphql';
import { Histogram, register as defaultRegistry } from 'prom-client';
export function shouldTraceFieldResolver(info, whitelist) {
if (!whitelist) {
return true;
}
const parentType = info.parentType.name;
const fieldName = info.fieldName;
const coordinate = `${parentType}.${fieldName}`;
return whitelist.includes(coordinate) || whitelist.includes(`${parentType}.*`);
}
function getOperation(document) {
return document.definitions[0];
}
export function createInternalContext(parseResult) {
if (parseResult === null) {
return null;
}
if (parseResult instanceof Error) {
return null;
}
const operation = getOperation(parseResult);
return {
document: parseResult,
operationName: operation.name?.value || 'Anonymous',
operationType: operation.operation,
};
}
export function createHistogram(options) {
return options;
}
export function createSummary(options) {
return options;
}
export function createCounter(options) {
return options;
}
export function getHistogramFromConfig(config, phase, name, help) {
return typeof config[phase] === 'object'
? config[phase]
: config[phase] === true
? createHistogram({
histogram: new Histogram({
name,
help,
labelNames: ['operationType', 'operationName'],
registers: [config.registry || defaultRegistry],
}),
fillLabelsFn: params => ({
operationName: params.operationName,
operationType: params.operationType,
}),
})
: undefined;
}
export function extractDeprecatedFields(node, typeInfo) {
const found = [];
visit(node, visitWithTypeInfo(typeInfo, {
Argument: () => {
const argument = typeInfo.getArgument();
const field = typeInfo.getFieldDef();
if (field && argument && (argument.deprecationReason != null || argument.isDeprecated)) {
found.push({
fieldName: argument.name,
// the GraphQLArgument type doesn't contain context regarding the mutation the argument was passed to
// however, when visiting an argument, typeInfo.getFieldDef returns the mutation
typeName: field.name, // this is the mutation name
});
}
},
Field: () => {
const field = typeInfo.getFieldDef();
if (field && (field.deprecationReason != null || field.isDeprecated)) {
found.push({
fieldName: field.name,
typeName: typeInfo.getParentType().name || '',
});
}
},
}));
return found;
}