@envelop/prometheus
This plugin tracks the complete execution flow, and reports metrics using Prometheus tracing (based
on prom-client
).
You can opt-in to collect tracing from the following phases:
- Successful requests (
requestCount
) - Request summary (
requestSummary
) - errors (categorized by
phase
) - resolvers tracing and runtime
- deprecated fields usage
- count of graphql operations
parse
execution timevalidate
execution timecontextBuilding
execution timeexecute
execution time
You can also customize each phase reporter, and add custom metadata and labels to the metrics.
Getting Started
yarn add prom-client @envelop/prometheus
Usage Example
import { execute, parse, specifiedRules, subscribe, validate } from 'graphql'
import { envelop, useEngine } from '@envelop/core'
import { usePrometheus } from '@envelop/prometheus'
const getEnveloped = envelop({
plugins: [
useEngine({ parse, validate, specifiedRules, execute, subscribe }),
usePrometheus({
requestCount: true,
requestSummary: true,
parse: true,
validate: true,
contextBuilding: true,
execute: true,
errors: true,
resolvers: true,
resolversWhitelist: ['Mutation.*', 'Query.user'],
deprecatedFields: true,
registry: myRegistry
})
]
})
Note: Tracing resolvers using resolvers: true
might have a performance impact on your GraphQL
runtime. Please consider to test it locally first and then decide if it's needed.
Custom registry
You can customize the prom-client
Registry
object if you are using a custom one, by passing it
along with the configuration object:
import { execute, parse, specifiedRules, subscribe, validate } from 'graphql'
import { Registry } from 'prom-client'
import { envelop, useEngine } from '@envelop/core'
const myRegistry = new Registry()
const getEnveloped = envelop({
plugins: [
useEngine({ parse, validate, specifiedRules, execute, subscribe }),
usePrometheus({
registry: myRegistry
})
]
})
Note: if you are using custom prom-client
instances, you need to make sure to pass your registry
there as well.
Introspection
If you wish to disable introspection logging, you can use skipIntrospection: true
in your config
object.
Custom prom-client
instances
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
:
import { execute, parse, specifiedRules, subscribe, validate } from 'graphql'
import { Histogram, register as registry } from 'prom-client'
import { envelop, useEngine } from '@envelop/core'
import { createHistogram, usePrometheus } from '@envelop/prometheus'
const getEnveloped = envelop({
plugins: [
useEngine({ parse, validate, specifiedRules, execute, subscribe }),
usePrometheus({
parse: createHistogram({
registry: registry
histogram: new Histogram({
name: 'my_custom_name',
help: 'HELP ME',
labelNames: ['opText'] as const,
}),
fillLabelsFn: params => {
return {
opText: print(params.document)
}
}
})
})
]
})
Caveats
Due to Prometheus client API limitations, if this plugin is initialized multiple times, only the
metrics configuration of the first initialization will be applied.
If necessary, use a different registry instance for each plugin instance, or clear the registry
before plugin initialization.
function usePrometheusWithRegistry() {
const registry = new Registry()
registry.clear()
return usePrometheus({
registry,
...
})
}
Keep in mind that this implies potential data loss in pull mode if some data is produced between
last pull and the re-initialization of the plugin.