@envelop/prometheus 6.4.0-alpha-c0cc559.0 → 6.4.0-alpha-e9434aa.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/config.js +2 -0
- package/{index.mjs → cjs/index.js} +39 -106
- package/cjs/package.json +1 -0
- package/cjs/utils.js +81 -0
- package/esm/config.js +2 -0
- package/{index.js → esm/index.js} +38 -112
- package/esm/utils.js +81 -0
- package/package.json +35 -14
- package/{config.d.ts → typings/config.d.ts} +1 -1
- package/{index.d.ts → typings/index.d.ts} +2 -2
- package/{utils.d.ts → typings/utils.d.ts} +1 -1
- package/README.md +0 -112
package/cjs/config.js
ADDED
|
@@ -1,97 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
function shouldTraceFieldResolver(info, whitelist) {
|
|
6
|
-
if (!whitelist) {
|
|
7
|
-
return true;
|
|
8
|
-
}
|
|
9
|
-
const parentType = info.parentType.name;
|
|
10
|
-
const fieldName = info.fieldName;
|
|
11
|
-
const coordinate = `${parentType}.${fieldName}`;
|
|
12
|
-
return whitelist.includes(coordinate) || whitelist.includes(`${parentType}.*`);
|
|
13
|
-
}
|
|
14
|
-
function getOperation(document) {
|
|
15
|
-
return document.definitions[0];
|
|
16
|
-
}
|
|
17
|
-
function createInternalContext(parseResult) {
|
|
18
|
-
var _a;
|
|
19
|
-
if (parseResult === null) {
|
|
20
|
-
return null;
|
|
21
|
-
}
|
|
22
|
-
else if (parseResult instanceof Error) {
|
|
23
|
-
return null;
|
|
24
|
-
}
|
|
25
|
-
else {
|
|
26
|
-
const operation = getOperation(parseResult);
|
|
27
|
-
return {
|
|
28
|
-
document: parseResult,
|
|
29
|
-
operationName: ((_a = operation.name) === null || _a === void 0 ? void 0 : _a.value) || 'Anonymous',
|
|
30
|
-
operationType: operation.operation,
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
function createHistogram(options) {
|
|
35
|
-
return options;
|
|
36
|
-
}
|
|
37
|
-
function createSummary(options) {
|
|
38
|
-
return options;
|
|
39
|
-
}
|
|
40
|
-
function createCounter(options) {
|
|
41
|
-
return options;
|
|
42
|
-
}
|
|
43
|
-
function getHistogramFromConfig(config, phase, name, help) {
|
|
44
|
-
return typeof config[phase] === 'object'
|
|
45
|
-
? config[phase]
|
|
46
|
-
: config[phase] === true
|
|
47
|
-
? createHistogram({
|
|
48
|
-
histogram: new Histogram({
|
|
49
|
-
name,
|
|
50
|
-
help,
|
|
51
|
-
labelNames: ['operationType', 'operationName'],
|
|
52
|
-
registers: [config.registry || register],
|
|
53
|
-
}),
|
|
54
|
-
fillLabelsFn: params => ({
|
|
55
|
-
operationName: params.operationName,
|
|
56
|
-
operationType: params.operationType,
|
|
57
|
-
}),
|
|
58
|
-
})
|
|
59
|
-
: undefined;
|
|
60
|
-
}
|
|
61
|
-
function extractDeprecatedFields(node, typeInfo) {
|
|
62
|
-
const found = [];
|
|
63
|
-
visit(node, visitWithTypeInfo(typeInfo, {
|
|
64
|
-
Field: () => {
|
|
65
|
-
const field = typeInfo.getFieldDef();
|
|
66
|
-
if (field && (field.deprecationReason != null || field.isDeprecated)) {
|
|
67
|
-
found.push({
|
|
68
|
-
fieldName: field.name,
|
|
69
|
-
typeName: typeInfo.getParentType().name || '',
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
},
|
|
73
|
-
}));
|
|
74
|
-
return found;
|
|
75
|
-
}
|
|
76
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.usePrometheus = exports.createSummary = exports.createHistogram = exports.createCounter = void 0;
|
|
77
4
|
/* eslint-disable @typescript-eslint/no-non-null-asserted-optional-chain */
|
|
5
|
+
const core_1 = require("@envelop/core");
|
|
6
|
+
const graphql_1 = require("graphql");
|
|
7
|
+
const prom_client_1 = require("prom-client");
|
|
8
|
+
const utils_js_1 = require("./utils.js");
|
|
9
|
+
Object.defineProperty(exports, "createHistogram", { enumerable: true, get: function () { return utils_js_1.createHistogram; } });
|
|
10
|
+
Object.defineProperty(exports, "createCounter", { enumerable: true, get: function () { return utils_js_1.createCounter; } });
|
|
11
|
+
Object.defineProperty(exports, "createSummary", { enumerable: true, get: function () { return utils_js_1.createSummary; } });
|
|
78
12
|
const promPluginContext = Symbol('promPluginContext');
|
|
79
13
|
const promPluginExecutionStartTimeSymbol = Symbol('promPluginExecutionStartTimeSymbol');
|
|
80
14
|
const usePrometheus = (config = {}) => {
|
|
81
15
|
let typeInfo = null;
|
|
82
|
-
const parseHistogram = getHistogramFromConfig(config, 'parse', 'graphql_envelop_phase_parse', 'Time spent on running GraphQL "parse" function');
|
|
83
|
-
const validateHistogram = getHistogramFromConfig(config, 'validate', 'graphql_envelop_phase_validate', 'Time spent on running GraphQL "validate" function');
|
|
84
|
-
const contextBuildingHistogram = getHistogramFromConfig(config, 'contextBuilding', 'graphql_envelop_phase_context', 'Time spent on building the GraphQL context');
|
|
85
|
-
const executeHistogram = getHistogramFromConfig(config, 'execute', 'graphql_envelop_phase_execute', 'Time spent on running the GraphQL "execute" function');
|
|
16
|
+
const parseHistogram = (0, utils_js_1.getHistogramFromConfig)(config, 'parse', 'graphql_envelop_phase_parse', 'Time spent on running GraphQL "parse" function');
|
|
17
|
+
const validateHistogram = (0, utils_js_1.getHistogramFromConfig)(config, 'validate', 'graphql_envelop_phase_validate', 'Time spent on running GraphQL "validate" function');
|
|
18
|
+
const contextBuildingHistogram = (0, utils_js_1.getHistogramFromConfig)(config, 'contextBuilding', 'graphql_envelop_phase_context', 'Time spent on building the GraphQL context');
|
|
19
|
+
const executeHistogram = (0, utils_js_1.getHistogramFromConfig)(config, 'execute', 'graphql_envelop_phase_execute', 'Time spent on running the GraphQL "execute" function');
|
|
86
20
|
const resolversHistogram = typeof config.resolvers === 'object'
|
|
87
21
|
? config.resolvers
|
|
88
22
|
: config.resolvers === true
|
|
89
|
-
? createHistogram({
|
|
90
|
-
histogram: new Histogram({
|
|
23
|
+
? (0, utils_js_1.createHistogram)({
|
|
24
|
+
histogram: new prom_client_1.Histogram({
|
|
91
25
|
name: 'graphql_envelop_execute_resolver',
|
|
92
26
|
help: 'Time spent on running the GraphQL resolvers',
|
|
93
27
|
labelNames: ['operationType', 'operationName', 'fieldName', 'typeName', 'returnType'],
|
|
94
|
-
registers: [config.registry || register],
|
|
28
|
+
registers: [config.registry || prom_client_1.register],
|
|
95
29
|
}),
|
|
96
30
|
fillLabelsFn: params => {
|
|
97
31
|
var _a, _b, _c;
|
|
@@ -108,12 +42,12 @@ const usePrometheus = (config = {}) => {
|
|
|
108
42
|
const requestTotalHistogram = typeof config.requestTotalDuration === 'object'
|
|
109
43
|
? config.requestTotalDuration
|
|
110
44
|
: config.requestTotalDuration === true
|
|
111
|
-
? createHistogram({
|
|
112
|
-
histogram: new Histogram({
|
|
45
|
+
? (0, utils_js_1.createHistogram)({
|
|
46
|
+
histogram: new prom_client_1.Histogram({
|
|
113
47
|
name: 'graphql_envelop_request_duration',
|
|
114
48
|
help: 'Time spent on running the GraphQL operation from parse to execute',
|
|
115
49
|
labelNames: ['operationType', 'operationName'],
|
|
116
|
-
registers: [config.registry || register],
|
|
50
|
+
registers: [config.registry || prom_client_1.register],
|
|
117
51
|
}),
|
|
118
52
|
fillLabelsFn: params => ({
|
|
119
53
|
operationName: params.operationName,
|
|
@@ -124,12 +58,12 @@ const usePrometheus = (config = {}) => {
|
|
|
124
58
|
const requestSummary = typeof config.requestSummary === 'object'
|
|
125
59
|
? config.requestSummary
|
|
126
60
|
: config.requestSummary === true
|
|
127
|
-
? createSummary({
|
|
128
|
-
summary: new Summary({
|
|
61
|
+
? (0, utils_js_1.createSummary)({
|
|
62
|
+
summary: new prom_client_1.Summary({
|
|
129
63
|
name: 'graphql_envelop_request_time_summary',
|
|
130
64
|
help: 'Summary to measure the time to complete GraphQL operations',
|
|
131
65
|
labelNames: ['operationType', 'operationName'],
|
|
132
|
-
registers: [config.registry || register],
|
|
66
|
+
registers: [config.registry || prom_client_1.register],
|
|
133
67
|
}),
|
|
134
68
|
fillLabelsFn: params => ({
|
|
135
69
|
operationName: params.operationName,
|
|
@@ -140,12 +74,12 @@ const usePrometheus = (config = {}) => {
|
|
|
140
74
|
const errorsCounter = typeof config.errors === 'object'
|
|
141
75
|
? config.errors
|
|
142
76
|
: config.errors === true
|
|
143
|
-
? createCounter({
|
|
144
|
-
counter: new Counter({
|
|
77
|
+
? (0, utils_js_1.createCounter)({
|
|
78
|
+
counter: new prom_client_1.Counter({
|
|
145
79
|
name: 'graphql_envelop_error_result',
|
|
146
80
|
help: 'Counts the amount of errors reported from all phases',
|
|
147
81
|
labelNames: ['operationType', 'operationName', 'path', 'phase'],
|
|
148
|
-
registers: [config.registry || register],
|
|
82
|
+
registers: [config.registry || prom_client_1.register],
|
|
149
83
|
}),
|
|
150
84
|
fillLabelsFn: params => {
|
|
151
85
|
var _a, _b;
|
|
@@ -161,12 +95,12 @@ const usePrometheus = (config = {}) => {
|
|
|
161
95
|
const reqCounter = typeof config.requestCount === 'object'
|
|
162
96
|
? config.requestCount
|
|
163
97
|
: config.requestCount === true
|
|
164
|
-
? createCounter({
|
|
165
|
-
counter: new Counter({
|
|
98
|
+
? (0, utils_js_1.createCounter)({
|
|
99
|
+
counter: new prom_client_1.Counter({
|
|
166
100
|
name: 'graphql_envelop_request',
|
|
167
101
|
help: 'Counts the amount of GraphQL requests executed through Envelop',
|
|
168
102
|
labelNames: ['operationType', 'operationName'],
|
|
169
|
-
registers: [config.registry || register],
|
|
103
|
+
registers: [config.registry || prom_client_1.register],
|
|
170
104
|
}),
|
|
171
105
|
fillLabelsFn: params => ({
|
|
172
106
|
operationName: params.operationName,
|
|
@@ -177,12 +111,12 @@ const usePrometheus = (config = {}) => {
|
|
|
177
111
|
const deprecationCounter = typeof config.deprecatedFields === 'object'
|
|
178
112
|
? config.deprecatedFields
|
|
179
113
|
: config.deprecatedFields === true
|
|
180
|
-
? createCounter({
|
|
181
|
-
counter: new Counter({
|
|
114
|
+
? (0, utils_js_1.createCounter)({
|
|
115
|
+
counter: new prom_client_1.Counter({
|
|
182
116
|
name: 'graphql_envelop_deprecated_field',
|
|
183
117
|
help: 'Counts the amount of deprecated fields used in selection sets',
|
|
184
118
|
labelNames: ['operationType', 'operationName', 'fieldName', 'typeName'],
|
|
185
|
-
registers: [config.registry || register],
|
|
119
|
+
registers: [config.registry || prom_client_1.register],
|
|
186
120
|
}),
|
|
187
121
|
fillLabelsFn: params => {
|
|
188
122
|
var _a, _b;
|
|
@@ -196,20 +130,20 @@ const usePrometheus = (config = {}) => {
|
|
|
196
130
|
})
|
|
197
131
|
: undefined;
|
|
198
132
|
const onParse = ({ context, extendContext, params }) => {
|
|
199
|
-
if (config.skipIntrospection && isIntrospectionOperationString(params.source)) {
|
|
133
|
+
if (config.skipIntrospection && (0, core_1.isIntrospectionOperationString)(params.source)) {
|
|
200
134
|
return;
|
|
201
135
|
}
|
|
202
136
|
const startTime = Date.now();
|
|
203
137
|
return params => {
|
|
204
138
|
const totalTime = (Date.now() - startTime) / 1000;
|
|
205
|
-
const internalContext = createInternalContext(params.result);
|
|
139
|
+
const internalContext = (0, utils_js_1.createInternalContext)(params.result);
|
|
206
140
|
if (internalContext) {
|
|
207
141
|
extendContext({
|
|
208
142
|
[promPluginContext]: internalContext,
|
|
209
143
|
});
|
|
210
144
|
parseHistogram === null || parseHistogram === void 0 ? void 0 : parseHistogram.histogram.observe(parseHistogram.fillLabelsFn(internalContext, context), totalTime);
|
|
211
145
|
if (deprecationCounter && typeInfo) {
|
|
212
|
-
const deprecatedFields = extractDeprecatedFields(internalContext.document, typeInfo);
|
|
146
|
+
const deprecatedFields = (0, utils_js_1.extractDeprecatedFields)(internalContext.document, typeInfo);
|
|
213
147
|
if (deprecatedFields.length > 0) {
|
|
214
148
|
for (const depField of deprecatedFields) {
|
|
215
149
|
deprecationCounter.counter
|
|
@@ -277,7 +211,7 @@ const usePrometheus = (config = {}) => {
|
|
|
277
211
|
const summaryTime = (Date.now() - args.contextValue[promPluginExecutionStartTimeSymbol]) / 1000;
|
|
278
212
|
requestSummary.summary.observe(requestSummary.fillLabelsFn(args.contextValue[promPluginContext], args.contextValue), summaryTime);
|
|
279
213
|
}
|
|
280
|
-
if (errorsCounter && !isAsyncIterable(result) && result.errors && result.errors.length > 0) {
|
|
214
|
+
if (errorsCounter && !(0, core_1.isAsyncIterable)(result) && result.errors && result.errors.length > 0) {
|
|
281
215
|
for (const error of result.errors) {
|
|
282
216
|
errorsCounter.counter
|
|
283
217
|
.labels(errorsCounter.fillLabelsFn({
|
|
@@ -296,7 +230,7 @@ const usePrometheus = (config = {}) => {
|
|
|
296
230
|
return {
|
|
297
231
|
onResolverCalled: resolversHistogram
|
|
298
232
|
? ({ info, context }) => {
|
|
299
|
-
const shouldTrace = shouldTraceFieldResolver(info, config.resolversWhitelist);
|
|
233
|
+
const shouldTrace = (0, utils_js_1.shouldTraceFieldResolver)(info, config.resolversWhitelist);
|
|
300
234
|
if (!shouldTrace) {
|
|
301
235
|
return undefined;
|
|
302
236
|
}
|
|
@@ -317,7 +251,7 @@ const usePrometheus = (config = {}) => {
|
|
|
317
251
|
});
|
|
318
252
|
},
|
|
319
253
|
onSchemaChange({ schema }) {
|
|
320
|
-
typeInfo = new TypeInfo(schema);
|
|
254
|
+
typeInfo = new graphql_1.TypeInfo(schema);
|
|
321
255
|
},
|
|
322
256
|
onParse,
|
|
323
257
|
onValidate,
|
|
@@ -325,5 +259,4 @@ const usePrometheus = (config = {}) => {
|
|
|
325
259
|
onExecute,
|
|
326
260
|
};
|
|
327
261
|
};
|
|
328
|
-
|
|
329
|
-
export { createCounter, createHistogram, createSummary, usePrometheus };
|
|
262
|
+
exports.usePrometheus = usePrometheus;
|
package/cjs/package.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"commonjs"}
|
package/cjs/utils.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractDeprecatedFields = exports.getHistogramFromConfig = exports.createCounter = exports.createSummary = exports.createHistogram = exports.createInternalContext = exports.shouldTraceFieldResolver = void 0;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
const prom_client_1 = require("prom-client");
|
|
6
|
+
function shouldTraceFieldResolver(info, whitelist) {
|
|
7
|
+
if (!whitelist) {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
const parentType = info.parentType.name;
|
|
11
|
+
const fieldName = info.fieldName;
|
|
12
|
+
const coordinate = `${parentType}.${fieldName}`;
|
|
13
|
+
return whitelist.includes(coordinate) || whitelist.includes(`${parentType}.*`);
|
|
14
|
+
}
|
|
15
|
+
exports.shouldTraceFieldResolver = shouldTraceFieldResolver;
|
|
16
|
+
function getOperation(document) {
|
|
17
|
+
return document.definitions[0];
|
|
18
|
+
}
|
|
19
|
+
function createInternalContext(parseResult) {
|
|
20
|
+
var _a;
|
|
21
|
+
if (parseResult === null) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
if (parseResult instanceof Error) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
const operation = getOperation(parseResult);
|
|
28
|
+
return {
|
|
29
|
+
document: parseResult,
|
|
30
|
+
operationName: ((_a = operation.name) === null || _a === void 0 ? void 0 : _a.value) || 'Anonymous',
|
|
31
|
+
operationType: operation.operation,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
exports.createInternalContext = createInternalContext;
|
|
35
|
+
function createHistogram(options) {
|
|
36
|
+
return options;
|
|
37
|
+
}
|
|
38
|
+
exports.createHistogram = createHistogram;
|
|
39
|
+
function createSummary(options) {
|
|
40
|
+
return options;
|
|
41
|
+
}
|
|
42
|
+
exports.createSummary = createSummary;
|
|
43
|
+
function createCounter(options) {
|
|
44
|
+
return options;
|
|
45
|
+
}
|
|
46
|
+
exports.createCounter = createCounter;
|
|
47
|
+
function getHistogramFromConfig(config, phase, name, help) {
|
|
48
|
+
return typeof config[phase] === 'object'
|
|
49
|
+
? config[phase]
|
|
50
|
+
: config[phase] === true
|
|
51
|
+
? createHistogram({
|
|
52
|
+
histogram: new prom_client_1.Histogram({
|
|
53
|
+
name,
|
|
54
|
+
help,
|
|
55
|
+
labelNames: ['operationType', 'operationName'],
|
|
56
|
+
registers: [config.registry || prom_client_1.register],
|
|
57
|
+
}),
|
|
58
|
+
fillLabelsFn: params => ({
|
|
59
|
+
operationName: params.operationName,
|
|
60
|
+
operationType: params.operationType,
|
|
61
|
+
}),
|
|
62
|
+
})
|
|
63
|
+
: undefined;
|
|
64
|
+
}
|
|
65
|
+
exports.getHistogramFromConfig = getHistogramFromConfig;
|
|
66
|
+
function extractDeprecatedFields(node, typeInfo) {
|
|
67
|
+
const found = [];
|
|
68
|
+
(0, graphql_1.visit)(node, (0, graphql_1.visitWithTypeInfo)(typeInfo, {
|
|
69
|
+
Field: () => {
|
|
70
|
+
const field = typeInfo.getFieldDef();
|
|
71
|
+
if (field && (field.deprecationReason != null || field.isDeprecated)) {
|
|
72
|
+
found.push({
|
|
73
|
+
fieldName: field.name,
|
|
74
|
+
typeName: typeInfo.getParentType().name || '',
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
}));
|
|
79
|
+
return found;
|
|
80
|
+
}
|
|
81
|
+
exports.extractDeprecatedFields = extractDeprecatedFields;
|
package/esm/config.js
ADDED
|
@@ -1,101 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const core = require('@envelop/core');
|
|
6
|
-
const graphql = require('graphql');
|
|
7
|
-
const promClient = require('prom-client');
|
|
8
|
-
|
|
9
|
-
function shouldTraceFieldResolver(info, whitelist) {
|
|
10
|
-
if (!whitelist) {
|
|
11
|
-
return true;
|
|
12
|
-
}
|
|
13
|
-
const parentType = info.parentType.name;
|
|
14
|
-
const fieldName = info.fieldName;
|
|
15
|
-
const coordinate = `${parentType}.${fieldName}`;
|
|
16
|
-
return whitelist.includes(coordinate) || whitelist.includes(`${parentType}.*`);
|
|
17
|
-
}
|
|
18
|
-
function getOperation(document) {
|
|
19
|
-
return document.definitions[0];
|
|
20
|
-
}
|
|
21
|
-
function createInternalContext(parseResult) {
|
|
22
|
-
var _a;
|
|
23
|
-
if (parseResult === null) {
|
|
24
|
-
return null;
|
|
25
|
-
}
|
|
26
|
-
else if (parseResult instanceof Error) {
|
|
27
|
-
return null;
|
|
28
|
-
}
|
|
29
|
-
else {
|
|
30
|
-
const operation = getOperation(parseResult);
|
|
31
|
-
return {
|
|
32
|
-
document: parseResult,
|
|
33
|
-
operationName: ((_a = operation.name) === null || _a === void 0 ? void 0 : _a.value) || 'Anonymous',
|
|
34
|
-
operationType: operation.operation,
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
function createHistogram(options) {
|
|
39
|
-
return options;
|
|
40
|
-
}
|
|
41
|
-
function createSummary(options) {
|
|
42
|
-
return options;
|
|
43
|
-
}
|
|
44
|
-
function createCounter(options) {
|
|
45
|
-
return options;
|
|
46
|
-
}
|
|
47
|
-
function getHistogramFromConfig(config, phase, name, help) {
|
|
48
|
-
return typeof config[phase] === 'object'
|
|
49
|
-
? config[phase]
|
|
50
|
-
: config[phase] === true
|
|
51
|
-
? createHistogram({
|
|
52
|
-
histogram: new promClient.Histogram({
|
|
53
|
-
name,
|
|
54
|
-
help,
|
|
55
|
-
labelNames: ['operationType', 'operationName'],
|
|
56
|
-
registers: [config.registry || promClient.register],
|
|
57
|
-
}),
|
|
58
|
-
fillLabelsFn: params => ({
|
|
59
|
-
operationName: params.operationName,
|
|
60
|
-
operationType: params.operationType,
|
|
61
|
-
}),
|
|
62
|
-
})
|
|
63
|
-
: undefined;
|
|
64
|
-
}
|
|
65
|
-
function extractDeprecatedFields(node, typeInfo) {
|
|
66
|
-
const found = [];
|
|
67
|
-
graphql.visit(node, graphql.visitWithTypeInfo(typeInfo, {
|
|
68
|
-
Field: () => {
|
|
69
|
-
const field = typeInfo.getFieldDef();
|
|
70
|
-
if (field && (field.deprecationReason != null || field.isDeprecated)) {
|
|
71
|
-
found.push({
|
|
72
|
-
fieldName: field.name,
|
|
73
|
-
typeName: typeInfo.getParentType().name || '',
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
},
|
|
77
|
-
}));
|
|
78
|
-
return found;
|
|
79
|
-
}
|
|
80
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.usePrometheus = exports.createSummary = exports.createHistogram = exports.createCounter = void 0;
|
|
81
4
|
/* eslint-disable @typescript-eslint/no-non-null-asserted-optional-chain */
|
|
5
|
+
const core_1 = require("@envelop/core");
|
|
6
|
+
const graphql_1 = require("graphql");
|
|
7
|
+
const prom_client_1 = require("prom-client");
|
|
8
|
+
const utils_js_1 = require("./utils.js");
|
|
9
|
+
Object.defineProperty(exports, "createHistogram", { enumerable: true, get: function () { return utils_js_1.createHistogram; } });
|
|
10
|
+
Object.defineProperty(exports, "createCounter", { enumerable: true, get: function () { return utils_js_1.createCounter; } });
|
|
11
|
+
Object.defineProperty(exports, "createSummary", { enumerable: true, get: function () { return utils_js_1.createSummary; } });
|
|
82
12
|
const promPluginContext = Symbol('promPluginContext');
|
|
83
13
|
const promPluginExecutionStartTimeSymbol = Symbol('promPluginExecutionStartTimeSymbol');
|
|
84
14
|
const usePrometheus = (config = {}) => {
|
|
85
15
|
let typeInfo = null;
|
|
86
|
-
const parseHistogram = getHistogramFromConfig(config, 'parse', 'graphql_envelop_phase_parse', 'Time spent on running GraphQL "parse" function');
|
|
87
|
-
const validateHistogram = getHistogramFromConfig(config, 'validate', 'graphql_envelop_phase_validate', 'Time spent on running GraphQL "validate" function');
|
|
88
|
-
const contextBuildingHistogram = getHistogramFromConfig(config, 'contextBuilding', 'graphql_envelop_phase_context', 'Time spent on building the GraphQL context');
|
|
89
|
-
const executeHistogram = getHistogramFromConfig(config, 'execute', 'graphql_envelop_phase_execute', 'Time spent on running the GraphQL "execute" function');
|
|
16
|
+
const parseHistogram = (0, utils_js_1.getHistogramFromConfig)(config, 'parse', 'graphql_envelop_phase_parse', 'Time spent on running GraphQL "parse" function');
|
|
17
|
+
const validateHistogram = (0, utils_js_1.getHistogramFromConfig)(config, 'validate', 'graphql_envelop_phase_validate', 'Time spent on running GraphQL "validate" function');
|
|
18
|
+
const contextBuildingHistogram = (0, utils_js_1.getHistogramFromConfig)(config, 'contextBuilding', 'graphql_envelop_phase_context', 'Time spent on building the GraphQL context');
|
|
19
|
+
const executeHistogram = (0, utils_js_1.getHistogramFromConfig)(config, 'execute', 'graphql_envelop_phase_execute', 'Time spent on running the GraphQL "execute" function');
|
|
90
20
|
const resolversHistogram = typeof config.resolvers === 'object'
|
|
91
21
|
? config.resolvers
|
|
92
22
|
: config.resolvers === true
|
|
93
|
-
? createHistogram({
|
|
94
|
-
histogram: new
|
|
23
|
+
? (0, utils_js_1.createHistogram)({
|
|
24
|
+
histogram: new prom_client_1.Histogram({
|
|
95
25
|
name: 'graphql_envelop_execute_resolver',
|
|
96
26
|
help: 'Time spent on running the GraphQL resolvers',
|
|
97
27
|
labelNames: ['operationType', 'operationName', 'fieldName', 'typeName', 'returnType'],
|
|
98
|
-
registers: [config.registry ||
|
|
28
|
+
registers: [config.registry || prom_client_1.register],
|
|
99
29
|
}),
|
|
100
30
|
fillLabelsFn: params => {
|
|
101
31
|
var _a, _b, _c;
|
|
@@ -112,12 +42,12 @@ const usePrometheus = (config = {}) => {
|
|
|
112
42
|
const requestTotalHistogram = typeof config.requestTotalDuration === 'object'
|
|
113
43
|
? config.requestTotalDuration
|
|
114
44
|
: config.requestTotalDuration === true
|
|
115
|
-
? createHistogram({
|
|
116
|
-
histogram: new
|
|
45
|
+
? (0, utils_js_1.createHistogram)({
|
|
46
|
+
histogram: new prom_client_1.Histogram({
|
|
117
47
|
name: 'graphql_envelop_request_duration',
|
|
118
48
|
help: 'Time spent on running the GraphQL operation from parse to execute',
|
|
119
49
|
labelNames: ['operationType', 'operationName'],
|
|
120
|
-
registers: [config.registry ||
|
|
50
|
+
registers: [config.registry || prom_client_1.register],
|
|
121
51
|
}),
|
|
122
52
|
fillLabelsFn: params => ({
|
|
123
53
|
operationName: params.operationName,
|
|
@@ -128,12 +58,12 @@ const usePrometheus = (config = {}) => {
|
|
|
128
58
|
const requestSummary = typeof config.requestSummary === 'object'
|
|
129
59
|
? config.requestSummary
|
|
130
60
|
: config.requestSummary === true
|
|
131
|
-
? createSummary({
|
|
132
|
-
summary: new
|
|
61
|
+
? (0, utils_js_1.createSummary)({
|
|
62
|
+
summary: new prom_client_1.Summary({
|
|
133
63
|
name: 'graphql_envelop_request_time_summary',
|
|
134
64
|
help: 'Summary to measure the time to complete GraphQL operations',
|
|
135
65
|
labelNames: ['operationType', 'operationName'],
|
|
136
|
-
registers: [config.registry ||
|
|
66
|
+
registers: [config.registry || prom_client_1.register],
|
|
137
67
|
}),
|
|
138
68
|
fillLabelsFn: params => ({
|
|
139
69
|
operationName: params.operationName,
|
|
@@ -144,12 +74,12 @@ const usePrometheus = (config = {}) => {
|
|
|
144
74
|
const errorsCounter = typeof config.errors === 'object'
|
|
145
75
|
? config.errors
|
|
146
76
|
: config.errors === true
|
|
147
|
-
? createCounter({
|
|
148
|
-
counter: new
|
|
77
|
+
? (0, utils_js_1.createCounter)({
|
|
78
|
+
counter: new prom_client_1.Counter({
|
|
149
79
|
name: 'graphql_envelop_error_result',
|
|
150
80
|
help: 'Counts the amount of errors reported from all phases',
|
|
151
81
|
labelNames: ['operationType', 'operationName', 'path', 'phase'],
|
|
152
|
-
registers: [config.registry ||
|
|
82
|
+
registers: [config.registry || prom_client_1.register],
|
|
153
83
|
}),
|
|
154
84
|
fillLabelsFn: params => {
|
|
155
85
|
var _a, _b;
|
|
@@ -165,12 +95,12 @@ const usePrometheus = (config = {}) => {
|
|
|
165
95
|
const reqCounter = typeof config.requestCount === 'object'
|
|
166
96
|
? config.requestCount
|
|
167
97
|
: config.requestCount === true
|
|
168
|
-
? createCounter({
|
|
169
|
-
counter: new
|
|
98
|
+
? (0, utils_js_1.createCounter)({
|
|
99
|
+
counter: new prom_client_1.Counter({
|
|
170
100
|
name: 'graphql_envelop_request',
|
|
171
101
|
help: 'Counts the amount of GraphQL requests executed through Envelop',
|
|
172
102
|
labelNames: ['operationType', 'operationName'],
|
|
173
|
-
registers: [config.registry ||
|
|
103
|
+
registers: [config.registry || prom_client_1.register],
|
|
174
104
|
}),
|
|
175
105
|
fillLabelsFn: params => ({
|
|
176
106
|
operationName: params.operationName,
|
|
@@ -181,12 +111,12 @@ const usePrometheus = (config = {}) => {
|
|
|
181
111
|
const deprecationCounter = typeof config.deprecatedFields === 'object'
|
|
182
112
|
? config.deprecatedFields
|
|
183
113
|
: config.deprecatedFields === true
|
|
184
|
-
? createCounter({
|
|
185
|
-
counter: new
|
|
114
|
+
? (0, utils_js_1.createCounter)({
|
|
115
|
+
counter: new prom_client_1.Counter({
|
|
186
116
|
name: 'graphql_envelop_deprecated_field',
|
|
187
117
|
help: 'Counts the amount of deprecated fields used in selection sets',
|
|
188
118
|
labelNames: ['operationType', 'operationName', 'fieldName', 'typeName'],
|
|
189
|
-
registers: [config.registry ||
|
|
119
|
+
registers: [config.registry || prom_client_1.register],
|
|
190
120
|
}),
|
|
191
121
|
fillLabelsFn: params => {
|
|
192
122
|
var _a, _b;
|
|
@@ -200,20 +130,20 @@ const usePrometheus = (config = {}) => {
|
|
|
200
130
|
})
|
|
201
131
|
: undefined;
|
|
202
132
|
const onParse = ({ context, extendContext, params }) => {
|
|
203
|
-
if (config.skipIntrospection &&
|
|
133
|
+
if (config.skipIntrospection && (0, core_1.isIntrospectionOperationString)(params.source)) {
|
|
204
134
|
return;
|
|
205
135
|
}
|
|
206
136
|
const startTime = Date.now();
|
|
207
137
|
return params => {
|
|
208
138
|
const totalTime = (Date.now() - startTime) / 1000;
|
|
209
|
-
const internalContext = createInternalContext(params.result);
|
|
139
|
+
const internalContext = (0, utils_js_1.createInternalContext)(params.result);
|
|
210
140
|
if (internalContext) {
|
|
211
141
|
extendContext({
|
|
212
142
|
[promPluginContext]: internalContext,
|
|
213
143
|
});
|
|
214
144
|
parseHistogram === null || parseHistogram === void 0 ? void 0 : parseHistogram.histogram.observe(parseHistogram.fillLabelsFn(internalContext, context), totalTime);
|
|
215
145
|
if (deprecationCounter && typeInfo) {
|
|
216
|
-
const deprecatedFields = extractDeprecatedFields(internalContext.document, typeInfo);
|
|
146
|
+
const deprecatedFields = (0, utils_js_1.extractDeprecatedFields)(internalContext.document, typeInfo);
|
|
217
147
|
if (deprecatedFields.length > 0) {
|
|
218
148
|
for (const depField of deprecatedFields) {
|
|
219
149
|
deprecationCounter.counter
|
|
@@ -281,7 +211,7 @@ const usePrometheus = (config = {}) => {
|
|
|
281
211
|
const summaryTime = (Date.now() - args.contextValue[promPluginExecutionStartTimeSymbol]) / 1000;
|
|
282
212
|
requestSummary.summary.observe(requestSummary.fillLabelsFn(args.contextValue[promPluginContext], args.contextValue), summaryTime);
|
|
283
213
|
}
|
|
284
|
-
if (errorsCounter && !
|
|
214
|
+
if (errorsCounter && !(0, core_1.isAsyncIterable)(result) && result.errors && result.errors.length > 0) {
|
|
285
215
|
for (const error of result.errors) {
|
|
286
216
|
errorsCounter.counter
|
|
287
217
|
.labels(errorsCounter.fillLabelsFn({
|
|
@@ -300,7 +230,7 @@ const usePrometheus = (config = {}) => {
|
|
|
300
230
|
return {
|
|
301
231
|
onResolverCalled: resolversHistogram
|
|
302
232
|
? ({ info, context }) => {
|
|
303
|
-
const shouldTrace = shouldTraceFieldResolver(info, config.resolversWhitelist);
|
|
233
|
+
const shouldTrace = (0, utils_js_1.shouldTraceFieldResolver)(info, config.resolversWhitelist);
|
|
304
234
|
if (!shouldTrace) {
|
|
305
235
|
return undefined;
|
|
306
236
|
}
|
|
@@ -321,7 +251,7 @@ const usePrometheus = (config = {}) => {
|
|
|
321
251
|
});
|
|
322
252
|
},
|
|
323
253
|
onSchemaChange({ schema }) {
|
|
324
|
-
typeInfo = new
|
|
254
|
+
typeInfo = new graphql_1.TypeInfo(schema);
|
|
325
255
|
},
|
|
326
256
|
onParse,
|
|
327
257
|
onValidate,
|
|
@@ -329,8 +259,4 @@ const usePrometheus = (config = {}) => {
|
|
|
329
259
|
onExecute,
|
|
330
260
|
};
|
|
331
261
|
};
|
|
332
|
-
|
|
333
|
-
exports.createCounter = createCounter;
|
|
334
|
-
exports.createHistogram = createHistogram;
|
|
335
|
-
exports.createSummary = createSummary;
|
|
336
262
|
exports.usePrometheus = usePrometheus;
|
package/esm/utils.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractDeprecatedFields = exports.getHistogramFromConfig = exports.createCounter = exports.createSummary = exports.createHistogram = exports.createInternalContext = exports.shouldTraceFieldResolver = void 0;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
const prom_client_1 = require("prom-client");
|
|
6
|
+
function shouldTraceFieldResolver(info, whitelist) {
|
|
7
|
+
if (!whitelist) {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
const parentType = info.parentType.name;
|
|
11
|
+
const fieldName = info.fieldName;
|
|
12
|
+
const coordinate = `${parentType}.${fieldName}`;
|
|
13
|
+
return whitelist.includes(coordinate) || whitelist.includes(`${parentType}.*`);
|
|
14
|
+
}
|
|
15
|
+
exports.shouldTraceFieldResolver = shouldTraceFieldResolver;
|
|
16
|
+
function getOperation(document) {
|
|
17
|
+
return document.definitions[0];
|
|
18
|
+
}
|
|
19
|
+
function createInternalContext(parseResult) {
|
|
20
|
+
var _a;
|
|
21
|
+
if (parseResult === null) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
if (parseResult instanceof Error) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
const operation = getOperation(parseResult);
|
|
28
|
+
return {
|
|
29
|
+
document: parseResult,
|
|
30
|
+
operationName: ((_a = operation.name) === null || _a === void 0 ? void 0 : _a.value) || 'Anonymous',
|
|
31
|
+
operationType: operation.operation,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
exports.createInternalContext = createInternalContext;
|
|
35
|
+
function createHistogram(options) {
|
|
36
|
+
return options;
|
|
37
|
+
}
|
|
38
|
+
exports.createHistogram = createHistogram;
|
|
39
|
+
function createSummary(options) {
|
|
40
|
+
return options;
|
|
41
|
+
}
|
|
42
|
+
exports.createSummary = createSummary;
|
|
43
|
+
function createCounter(options) {
|
|
44
|
+
return options;
|
|
45
|
+
}
|
|
46
|
+
exports.createCounter = createCounter;
|
|
47
|
+
function getHistogramFromConfig(config, phase, name, help) {
|
|
48
|
+
return typeof config[phase] === 'object'
|
|
49
|
+
? config[phase]
|
|
50
|
+
: config[phase] === true
|
|
51
|
+
? createHistogram({
|
|
52
|
+
histogram: new prom_client_1.Histogram({
|
|
53
|
+
name,
|
|
54
|
+
help,
|
|
55
|
+
labelNames: ['operationType', 'operationName'],
|
|
56
|
+
registers: [config.registry || prom_client_1.register],
|
|
57
|
+
}),
|
|
58
|
+
fillLabelsFn: params => ({
|
|
59
|
+
operationName: params.operationName,
|
|
60
|
+
operationType: params.operationType,
|
|
61
|
+
}),
|
|
62
|
+
})
|
|
63
|
+
: undefined;
|
|
64
|
+
}
|
|
65
|
+
exports.getHistogramFromConfig = getHistogramFromConfig;
|
|
66
|
+
function extractDeprecatedFields(node, typeInfo) {
|
|
67
|
+
const found = [];
|
|
68
|
+
(0, graphql_1.visit)(node, (0, graphql_1.visitWithTypeInfo)(typeInfo, {
|
|
69
|
+
Field: () => {
|
|
70
|
+
const field = typeInfo.getFieldDef();
|
|
71
|
+
if (field && (field.deprecationReason != null || field.isDeprecated)) {
|
|
72
|
+
found.push({
|
|
73
|
+
fieldName: field.name,
|
|
74
|
+
typeName: typeInfo.getParentType().name || '',
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
}));
|
|
79
|
+
return found;
|
|
80
|
+
}
|
|
81
|
+
exports.extractDeprecatedFields = extractDeprecatedFields;
|
package/package.json
CHANGED
|
@@ -1,34 +1,55 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@envelop/prometheus",
|
|
3
|
-
"version": "6.4.0-alpha-
|
|
3
|
+
"version": "6.4.0-alpha-e9434aa.0",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"peerDependencies": {
|
|
6
|
-
"@envelop/core": "2.4.0-alpha-
|
|
7
|
-
"
|
|
8
|
-
"
|
|
6
|
+
"@envelop/core": "2.4.0-alpha-e9434aa.0",
|
|
7
|
+
"prom-client": "^13 || ^14.0.0",
|
|
8
|
+
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
|
|
9
9
|
},
|
|
10
10
|
"repository": {
|
|
11
11
|
"type": "git",
|
|
12
|
-
"url": "https://github.com/
|
|
12
|
+
"url": "https://github.com/n1ru4l/envelop.git",
|
|
13
13
|
"directory": "packages/plugins/prometheus"
|
|
14
14
|
},
|
|
15
15
|
"author": "Dotan Simha <dotansimha@gmail.com>",
|
|
16
16
|
"license": "MIT",
|
|
17
|
-
"main": "index.js",
|
|
18
|
-
"module": "index.
|
|
19
|
-
"typings": "index.d.ts",
|
|
17
|
+
"main": "cjs/index.js",
|
|
18
|
+
"module": "esm/index.js",
|
|
19
|
+
"typings": "typings/index.d.ts",
|
|
20
20
|
"typescript": {
|
|
21
|
-
"definition": "index.d.ts"
|
|
21
|
+
"definition": "typings/index.d.ts"
|
|
22
22
|
},
|
|
23
|
+
"type": "module",
|
|
23
24
|
"exports": {
|
|
24
25
|
".": {
|
|
25
|
-
"require":
|
|
26
|
-
|
|
26
|
+
"require": {
|
|
27
|
+
"types": "./typings/index.d.ts",
|
|
28
|
+
"default": "./cjs/index.js"
|
|
29
|
+
},
|
|
30
|
+
"import": {
|
|
31
|
+
"types": "./typings/index.d.ts",
|
|
32
|
+
"default": "./esm/index.js"
|
|
33
|
+
},
|
|
34
|
+
"default": {
|
|
35
|
+
"types": "./typings/index.d.ts",
|
|
36
|
+
"default": "./esm/index.js"
|
|
37
|
+
}
|
|
27
38
|
},
|
|
28
39
|
"./*": {
|
|
29
|
-
"require":
|
|
30
|
-
|
|
40
|
+
"require": {
|
|
41
|
+
"types": "./typings/*.d.ts",
|
|
42
|
+
"default": "./cjs/*.js"
|
|
43
|
+
},
|
|
44
|
+
"import": {
|
|
45
|
+
"types": "./typings/*.d.ts",
|
|
46
|
+
"default": "./esm/*.js"
|
|
47
|
+
},
|
|
48
|
+
"default": {
|
|
49
|
+
"types": "./typings/*.d.ts",
|
|
50
|
+
"default": "./esm/*.js"
|
|
51
|
+
}
|
|
31
52
|
},
|
|
32
53
|
"./package.json": "./package.json"
|
|
33
54
|
}
|
|
34
|
-
}
|
|
55
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createCounter, createHistogram, createSummary } from './utils';
|
|
1
|
+
import { createCounter, createHistogram, createSummary } from './utils.js';
|
|
2
2
|
import { Registry } from 'prom-client';
|
|
3
3
|
export declare type PrometheusTracingPluginConfig = {
|
|
4
4
|
requestCount?: boolean | ReturnType<typeof createCounter>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Plugin } from '@envelop/core';
|
|
2
|
-
import { createHistogram, createCounter, FillLabelsFnParams, createSummary } from './utils';
|
|
3
|
-
import { PrometheusTracingPluginConfig } from './config';
|
|
2
|
+
import { createHistogram, createCounter, FillLabelsFnParams, createSummary } from './utils.js';
|
|
3
|
+
import { PrometheusTracingPluginConfig } from './config.js';
|
|
4
4
|
export { PrometheusTracingPluginConfig, createCounter, createHistogram, createSummary, FillLabelsFnParams };
|
|
5
5
|
declare const promPluginContext: unique symbol;
|
|
6
6
|
declare const promPluginExecutionStartTimeSymbol: unique symbol;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { GraphQLError, DocumentNode, OperationDefinitionNode, GraphQLResolveInfo, TypeInfo, ASTNode } from 'graphql';
|
|
2
2
|
import { AfterParseEventPayload } from '@envelop/core';
|
|
3
|
-
import { PrometheusTracingPluginConfig } from './config';
|
|
3
|
+
import { PrometheusTracingPluginConfig } from './config.js';
|
|
4
4
|
import { Counter, Histogram, Summary } from 'prom-client';
|
|
5
5
|
export declare type DeprecatedFieldInfo = {
|
|
6
6
|
fieldName: string;
|
package/README.md
DELETED
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
## `@envelop/prometheus`
|
|
2
|
-
|
|
3
|
-
This plugin tracks the complete execution flow, and reports metrics using Prometheus tracing (based on `prom-client`).
|
|
4
|
-
|
|
5
|
-
You can opt-in to collect tracing from the following phases:
|
|
6
|
-
|
|
7
|
-
- Sucessfull requests (`requestCount`)
|
|
8
|
-
- Request summary (`requestSummary`)
|
|
9
|
-
- errors (categorized by `phase`)
|
|
10
|
-
- resolvers tracing and runtime
|
|
11
|
-
- deprecated fields usage
|
|
12
|
-
- count of graphql operations
|
|
13
|
-
- `parse` execution time
|
|
14
|
-
- `validate` execution time
|
|
15
|
-
- `contextBuilding` execution time
|
|
16
|
-
- `execute` execution time
|
|
17
|
-
|
|
18
|
-
> You can also customize each phase reporter, and add custom metadata and labels to the metrics.
|
|
19
|
-
|
|
20
|
-
## Getting Started
|
|
21
|
-
|
|
22
|
-
```
|
|
23
|
-
yarn add prom-client @envelop/prometheus
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## Usage Example
|
|
27
|
-
|
|
28
|
-
```ts
|
|
29
|
-
import { envelop } from '@envelop/core';
|
|
30
|
-
import { usePrometheus } from '@envelop/prometheus';
|
|
31
|
-
|
|
32
|
-
const getEnveloped = envelop({
|
|
33
|
-
plugins: [
|
|
34
|
-
// ... other plugins ...
|
|
35
|
-
usePrometheus({
|
|
36
|
-
// all optional, and by default, all set to false, please opt-in to the metrics you wish to get
|
|
37
|
-
requestCount: true, // requries `execute` to be true as well
|
|
38
|
-
requestSummary: true, // requries `execute` to be true as well
|
|
39
|
-
parse: true,
|
|
40
|
-
validate: true,
|
|
41
|
-
contextBuilding: true,
|
|
42
|
-
execute: true,
|
|
43
|
-
errors: true,
|
|
44
|
-
resolvers: true, // requires "execute" to be `true` as well
|
|
45
|
-
resolversWhitelist: ['Mutation.*', 'Query.user'], // reports metrics als for these resolvers, leave `undefined` to report all fields
|
|
46
|
-
deprecatedFields: true,
|
|
47
|
-
registry: myRegistry, // If you are using a custom prom-client registry, please set it here
|
|
48
|
-
}),
|
|
49
|
-
],
|
|
50
|
-
});
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
> Note: Tracing resolvers using `resovlers: true` might have a performance impact on your GraphQL runtime. Please consider to test it locally first and then decide if it's needed.
|
|
54
|
-
|
|
55
|
-
### Custom registry
|
|
56
|
-
|
|
57
|
-
You can customize the `prom-client` `Registry` object if you are using a custom one, by passing it along with the configuration object:
|
|
58
|
-
|
|
59
|
-
```ts
|
|
60
|
-
import { Registry } from 'prom-client';
|
|
61
|
-
|
|
62
|
-
const myRegistry = new Registry();
|
|
63
|
-
|
|
64
|
-
const getEnveloped = envelop({
|
|
65
|
-
plugins: [
|
|
66
|
-
// ... other plugins ...
|
|
67
|
-
usePrometheus({
|
|
68
|
-
// ... config ...
|
|
69
|
-
registry: myRegistry,
|
|
70
|
-
}),
|
|
71
|
-
],
|
|
72
|
-
});
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
> Note: if you are using custom `prom-client` instances, you need to make sure to pass your registry there as well.
|
|
76
|
-
|
|
77
|
-
### Introspection
|
|
78
|
-
|
|
79
|
-
If you wish to disable introspection logging, you can use `skipIntrospection: true` in your config object.
|
|
80
|
-
|
|
81
|
-
### Custom `prom-client` instances
|
|
82
|
-
|
|
83
|
-
Each tracing field supports custom `prom-client` objects, and custom `labels` a metadata, you can create a custom extraction function for every `Histogram` / `Summary` / `Counter`:
|
|
84
|
-
|
|
85
|
-
```ts
|
|
86
|
-
import { Histogram } from 'prom-client';
|
|
87
|
-
import { envelop } from '@envelop/core';
|
|
88
|
-
import { createHistogram, usePrometheus } from '@envelop/prometheus';
|
|
89
|
-
|
|
90
|
-
const getEnveloped = envelop({
|
|
91
|
-
plugins: [
|
|
92
|
-
// ... other plugins ...
|
|
93
|
-
usePrometheus({
|
|
94
|
-
// all optional, and by default, all set to false, please opt-in to the metrics you wish to get
|
|
95
|
-
parse: createHistogram({
|
|
96
|
-
histogram: new Histogram({
|
|
97
|
-
name: 'my_custom_name',
|
|
98
|
-
help: 'HELP ME',
|
|
99
|
-
labelNames: ['opText'] as const,
|
|
100
|
-
registers: [registry], // make sure to add your custom registry, if you are not using the default one
|
|
101
|
-
}),
|
|
102
|
-
fillLabelsFn: params => {
|
|
103
|
-
// if you wish to fill your `lables` with metadata, you can use the params in order to get access to things like DocumentNode, operationName, operationType, `error` (for error metrics) and `info` (for resolvers metrics)
|
|
104
|
-
return {
|
|
105
|
-
opText: print(params.document),
|
|
106
|
-
};
|
|
107
|
-
},
|
|
108
|
-
}),
|
|
109
|
-
}),
|
|
110
|
-
],
|
|
111
|
-
});
|
|
112
|
-
```
|