UNPKG

@graphql-mesh/plugin-prometheus

Version:
183 lines (182 loc) • 7.58 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const graphql_yoga_1 = require("graphql-yoga"); const prom_client_1 = require("prom-client"); const utils_1 = require("@graphql-mesh/utils"); const plugin_prometheus_1 = require("@graphql-yoga/plugin-prometheus"); function useMeshPrometheus(pluginOptions) { let registry; if (pluginOptions.registry) { if (typeof pluginOptions.registry === 'string') { const registry$ = (0, utils_1.loadFromModuleExportExpression)(pluginOptions.registry, { cwd: pluginOptions.baseDir || globalThis.process?.cwd(), importFn: pluginOptions.importFn || utils_1.defaultImportFn, defaultExportName: 'default', }); const registryProxy = Proxy.revocable(prom_client_1.register, { get(target, prop, receiver) { if (typeof target[prop] === 'function') { return function (...args) { return registry$.then(registry => registry[prop](...args)); }; } return Reflect.get(target, prop, receiver); }, }); registry = registryProxy.proxy; registry$.then(() => registryProxy.revoke()).catch(e => pluginOptions.logger.error(e)); } else { registry = pluginOptions.registry; } } else { registry = prom_client_1.register; } let fetchHistogram; if (pluginOptions.fetchMetrics) { const name = typeof pluginOptions.fetchMetrics === 'string' ? pluginOptions.fetchMetrics : 'graphql_mesh_fetch_duration'; const labelNames = ['url', 'method', 'statusCode', 'statusText']; if (pluginOptions.fetchRequestHeaders) { labelNames.push('requestHeaders'); } if (pluginOptions.fetchResponseHeaders) { labelNames.push('responseHeaders'); } fetchHistogram = new prom_client_1.Histogram({ name, help: 'Time spent on outgoing HTTP calls', labelNames, registers: [registry], }); } let delegateHistogram; if (pluginOptions.delegation) { const name = typeof pluginOptions.delegation === 'string' ? pluginOptions.delegation : 'graphql_mesh_delegate_duration'; const delegationLabelNames = ['sourceName', 'typeName', 'fieldName']; if (pluginOptions.delegationArgs) { delegationLabelNames.push('args'); } if (pluginOptions.delegationKey) { delegationLabelNames.push('key'); } delegateHistogram = new prom_client_1.Histogram({ name, help: 'Time spent on delegate execution', labelNames: delegationLabelNames, registers: [registry], }); } let subgraphExecuteHistogram; let subgraphExecuteErrorCounter; if (pluginOptions.subgraphExecute !== false) { const name = typeof pluginOptions.subgraphExecute === 'string' ? pluginOptions.subgraphExecute : 'graphql_mesh_subgraph_execute_duration'; const subgraphExecuteLabelNames = ['subgraphName', 'operationType']; subgraphExecuteHistogram = new prom_client_1.Histogram({ name, help: 'Time spent on subgraph execution', labelNames: subgraphExecuteLabelNames, registers: [registry], }); subgraphExecuteErrorCounter = new prom_client_1.Counter({ name: `graphql_mesh_subgraph_execute_errors`, help: 'Number of errors on subgraph execution', labelNames: subgraphExecuteLabelNames, registers: [registry], }); } return { onPluginInit({ addPlugin }) { addPlugin((0, plugin_prometheus_1.usePrometheus)({ ...pluginOptions, registry, })); }, onDelegate({ sourceName, typeName, fieldName, args, key }) { if (delegateHistogram) { const start = Date.now(); return () => { const end = Date.now(); const duration = end - start; delegateHistogram.observe({ sourceName, typeName, fieldName, args: pluginOptions.delegationArgs ? JSON.stringify(args) : undefined, key: pluginOptions.delegationKey ? JSON.stringify(key) : undefined, }, duration); }; } return undefined; }, onSubgraphExecute({ subgraphName, executionRequest: { operationType = 'query' } }) { if (subgraphExecuteHistogram) { const start = Date.now(); return ({ result }) => { if ((0, graphql_yoga_1.isAsyncIterable)(result)) { return { onNext({ result }) { if (result.errors) { result.errors.forEach(() => { subgraphExecuteErrorCounter?.inc({ subgraphName, operationType }); }); } }, onEnd: () => { const end = Date.now(); const duration = end - start; subgraphExecuteHistogram.observe({ subgraphName, operationType, }, duration); }, }; } if (result.errors) { result.errors.forEach(() => { subgraphExecuteErrorCounter?.inc({ subgraphName, operationType }); }); } const end = Date.now(); const duration = end - start; subgraphExecuteHistogram.observe({ subgraphName, operationType, }, duration); return undefined; }; } return undefined; }, onFetch({ url, options }) { if (fetchHistogram) { const start = Date.now(); return ({ response }) => { const end = Date.now(); const duration = end - start; const labels = { url, method: options.method, statusCode: response.status, statusText: response.statusText, }; if (pluginOptions.fetchRequestHeaders) { labels.requestHeaders = JSON.stringify(options.headers); } if (pluginOptions.fetchResponseHeaders) { labels.responseHeaders = JSON.stringify((0, utils_1.getHeadersObj)(response.headers)); } fetchHistogram.observe(labels, duration); }; } return undefined; }, }; } exports.default = useMeshPrometheus;