@envelop/prometheus
Advanced tools
Comparing version 11.0.0-alpha-20240729092544-f8b6dbe5 to 11.0.0-alpha-20240802132552-808b9dc3
@@ -108,2 +108,3 @@ "use strict"; | ||
...histogram, | ||
buckets: Array.isArray(metric) ? metric : histogram.buckets, | ||
labelNames: (histogram.labelNames ?? ['operationType', 'operationName']).filter(label => labelExists(config, label)), | ||
@@ -110,0 +111,0 @@ }, |
@@ -97,2 +97,3 @@ import { visit, visitWithTypeInfo, } from 'graphql'; | ||
...histogram, | ||
buckets: Array.isArray(metric) ? metric : histogram.buckets, | ||
labelNames: (histogram.labelNames ?? ['operationType', 'operationName']).filter(label => labelExists(config, label)), | ||
@@ -99,0 +100,0 @@ }, |
{ | ||
"name": "@envelop/prometheus", | ||
"version": "11.0.0-alpha-20240729092544-f8b6dbe5", | ||
"version": "11.0.0-alpha-20240802132552-808b9dc3", | ||
"sideEffects": false, | ||
@@ -5,0 +5,0 @@ "peerDependencies": { |
467
README.md
@@ -39,14 +39,21 @@ ## `@envelop/prometheus` | ||
usePrometheus({ | ||
// all optional, and by default, all set to false, please opt-in to the metrics you wish to get | ||
requestCount: true, // requires `execute` to be true as well | ||
requestSummary: true, // requires `execute` to be true as well | ||
parse: true, | ||
validate: true, | ||
contextBuilding: true, | ||
execute: true, | ||
errors: true, | ||
resolvers: true, // requires "execute" to be `true` as well | ||
resolversWhitelist: ['Mutation.*', 'Query.user'], // reports metrics als for these resolvers, leave `undefined` to report all fields | ||
deprecatedFields: true, | ||
registry: myRegistry // If you are using a custom prom-client registry, please set it here | ||
// all metrics are disabled by default, please opt-in to the metrics you wish to get | ||
metrics: { | ||
graphql_envelop_request_time_summary: true, | ||
graphql_envelop_phase_parse: true, | ||
graphql_envelop_phase_validate: true, | ||
graphql_envelop_phase_context: true, | ||
graphql_envelop_phase_execute: true, | ||
graphql_envelop_phase_subscribe: true, | ||
graphql_envelop_error_result: true, | ||
graphql_envelop_deprecated_field: true, | ||
graphql_envelop_request_duration: true, | ||
graphql_envelop_schema_change: true, | ||
graphql_envelop_request: true, | ||
// Warning: enabling resolvers level metrics will introduce significant overhead | ||
graphql_envelop_execute_resolver: true | ||
}, | ||
resolversWhitelist: ['Mutation.*', 'Query.user'] // reports metrics for these resolvers, leave `undefined` to report all fields | ||
}) | ||
@@ -57,5 +64,405 @@ ] | ||
> 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. | ||
## Available Metrics | ||
All metrics are disabled by default. You can enable the one you are interested in by setting the | ||
corresponding key in the `metric` option object to `true`. Histogram metrics can be passed an array | ||
of numbers to configure buckets. You can also provide a string to customize the metric name, or an | ||
object to provide more options by using `createHistogram`, `createCounter` and `createSummary` (see | ||
[`siimon/prom-client` documentation](https://github.com/siimon/prom-client#custom-metrics)). | ||
Each metric also expose a set of labels. All labels are exposed by default but can be separately | ||
disabled by setting the corresponding key in `labels` option object to `false`. | ||
### `graphql_envelop_phase_parse` | ||
This metric tracks the duration of the `parse` phase of the GraphQL execution. It reports the time | ||
spent parsing the incoming GraphQL operation. | ||
It is reported as a [histogram](https://prometheus.io/docs/concepts/metric_types/#histogram). | ||
Since you don't have control over the parsing phase, this metric is mostly useful to track potential | ||
attacks. A spike in this metric could indicate someone is trying to send malicious operations to | ||
your gateway. | ||
#### Labels | ||
| Label | Description | | ||
| --------------- | ------------------------------------------------------------------------------------------------------- | | ||
| `operationType` | The type of the GraphQL operation requested. This can be one of `query`, `mutation`, or `subscription`. | | ||
| `operationName` | The name of the GraphQL operation requested. It will be `Anonymous` if no `operationName` is found. | | ||
#### Sample Output | ||
```text | ||
# HELP graphql_envelop_phase_parse Time spent on running GraphQL "parse" function | ||
# TYPE graphql_envelop_phase_parse histogram | ||
graphql_envelop_phase_parse_bucket{le="0.005",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_parse_bucket{le="0.01",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_parse_bucket{le="0.025",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_parse_bucket{le="0.05",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_parse_bucket{le="0.1",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_parse_bucket{le="0.25",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_parse_bucket{le="0.5",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_parse_bucket{le="1",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_parse_bucket{le="2.5",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_parse_bucket{le="5",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_parse_bucket{le="10",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_parse_bucket{le="+Inf",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_parse_sum{operationName="Anonymous",operationType="query"} 0.001 | ||
graphql_envelop_phase_parse_count{operationName="Anonymous",operationType="query"} 1 | ||
``` | ||
### `graphql_envelop_phase_validate` | ||
This metric tracks the duration of the `validate` phase of the GraphQL execution. It reports the | ||
time spent validating the incoming GraphQL operation. | ||
It is reported as a [histogram](https://prometheus.io/docs/concepts/metric_types/#histogram). | ||
#### Labels | ||
| Label | Description | | ||
| --------------- | ------------------------------------------------------------------------------------------------------- | | ||
| `operationType` | The type of the GraphQL operation requested. This can be one of `query`, `mutation`, or `subscription`. | | ||
| `operationName` | The name of the GraphQL operation requested. It will be `Anonymous` if no `operationName` is found. | | ||
#### Sample Output | ||
```text | ||
# HELP graphql_envelop_phase_validate Time spent on running GraphQL "validate" function | ||
# TYPE graphql_envelop_phase_validate histogram | ||
graphql_envelop_phase_validate_bucket{le="0.005",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_validate_bucket{le="0.01",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_validate_bucket{le="0.025",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_validate_bucket{le="0.05",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_validate_bucket{le="0.1",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_validate_bucket{le="0.25",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_validate_bucket{le="0.5",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_validate_bucket{le="1",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_validate_bucket{le="2.5",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_validate_bucket{le="5",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_validate_bucket{le="10",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_validate_bucket{le="+Inf",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_validate_sum{operationName="Anonymous",operationType="query"} 0.004 | ||
graphql_envelop_phase_validate_count{operationName="Anonymous",operationType="query"} 1 | ||
``` | ||
### `graphql_envelop_phase_context` | ||
This metric tracks the duration of the `context` phase of the GraphQL execution. It reports the time | ||
spent building the context object that will be passed to the executors. | ||
It is reported as a [histogram](https://prometheus.io/docs/concepts/metric_types/#histogram). | ||
#### Labels | ||
| Label | Description | | ||
| --------------- | ------------------------------------------------------------------------------------------------------- | | ||
| `operationType` | The type of the GraphQL operation requested. This can be one of `query`, `mutation`, or `subscription`. | | ||
| `operationName` | The name of the GraphQL operation requested. It will be `Anonymous` if no `operationName` is found. | | ||
#### Sample Output | ||
```text | ||
# HELP graphql_envelop_phase_context Time spent on building the GraphQL context | ||
# TYPE graphql_envelop_phase_context histogram | ||
graphql_envelop_phase_context_bucket{le="0.005",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_context_bucket{le="0.01",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_context_bucket{le="0.025",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_context_bucket{le="0.05",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_context_bucket{le="0.1",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_context_bucket{le="0.25",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_context_bucket{le="0.5",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_context_bucket{le="1",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_context_bucket{le="2.5",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_context_bucket{le="5",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_context_bucket{le="10",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_context_bucket{le="+Inf",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_context_sum{operationName="Anonymous",operationType="query"} 0 | ||
graphql_envelop_phase_context_count{operationName="Anonymous",operationType="query"} 1 | ||
``` | ||
### `graphql_envelop_phase_execute` | ||
This metric tracks the duration of the `execute` phase of the GraphQL execution. It reports the time | ||
spent actually resolving the response of the incoming operation. This includes the gathering of all | ||
the data from all sources required to construct the final response. It is reported as a | ||
[histogram](https://prometheus.io/docs/concepts/metric_types/#histogram). | ||
It is the metric that will give you the most insights into the performance of your own code, since | ||
this is where most of the work from your code (resolvers) is done. | ||
#### Labels | ||
| Label | Description | | ||
| --------------- | ------------------------------------------------------------------------------------------------------- | | ||
| `operationType` | The type of the GraphQL operation requested. This can be one of `query`, `mutation`, or `subscription`. | | ||
| `operationName` | The name of the GraphQL operation requested. It will be `Anonymous` if no `operationName` is found. | | ||
#### Sample Output | ||
```text | ||
# HELP graphql_envelop_phase_execute Time spent on running the GraphQL "execute" function | ||
# TYPE graphql_envelop_phase_execute histogram | ||
graphql_envelop_phase_execute_bucket{le="0.005",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_execute_bucket{le="0.01",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_execute_bucket{le="0.025",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_execute_bucket{le="0.05",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_execute_bucket{le="0.1",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_execute_bucket{le="0.25",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_execute_bucket{le="0.5",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_execute_bucket{le="1",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_execute_bucket{le="2.5",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_execute_bucket{le="5",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_execute_bucket{le="10",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_execute_bucket{le="+Inf",operationName="Anonymous",operationType="query"} 1 | ||
graphql_envelop_phase_execute_sum{operationName="Anonymous",operationType="query"} 0.002 | ||
graphql_envelop_phase_execute_count{operationName="Anonymous",operationType="query"} 1 | ||
``` | ||
### `graphql_envelop_phase_subscribe` | ||
This metric tracks the duration of the `subscribe` phase of the GraphQL execution. It reports the | ||
time spent initiating a subscription (which doesn't include actually sending the first response). | ||
It is reported as a [histogram](https://prometheus.io/docs/concepts/metric_types/#histogram). | ||
#### Labels | ||
| Label | Description | | ||
| --------------- | ------------------------------------------------------------------------------------------------------- | | ||
| `operationType` | The type of the GraphQL operation requested. This can be one of `query`, `mutation`, or `subscription`. | | ||
| `operationName` | The name of the GraphQL operation requested. It will be `Anonymous` if no `operationName` is found. | | ||
#### Sample Output | ||
```text | ||
# HELP graphql_envelop_phase_subscribe Time spent on running the GraphQL "subscribe" function | ||
# TYPE graphql_envelop_phase_subscribe histogram | ||
graphql_envelop_phase_subscribe_bucket{le="0.005",operationName="Anonymous",operationType="subscription"} 0 | ||
graphql_envelop_phase_subscribe_bucket{le="0.01",operationName="Anonymous",operationType="subscription"} 0 | ||
graphql_envelop_phase_subscribe_bucket{le="0.025",operationName="Anonymous",operationType="subscription"} 1 | ||
graphql_envelop_phase_subscribe_bucket{le="0.05",operationName="Anonymous",operationType="subscription"} 1 | ||
graphql_envelop_phase_subscribe_bucket{le="0.1",operationName="Anonymous",operationType="subscription"} 1 | ||
graphql_envelop_phase_subscribe_bucket{le="0.25",operationName="Anonymous",operationType="subscription"} 1 | ||
graphql_envelop_phase_subscribe_bucket{le="0.5",operationName="Anonymous",operationType="subscription"} 1 | ||
graphql_envelop_phase_subscribe_bucket{le="1",operationName="Anonymous",operationType="subscription"} 1 | ||
graphql_envelop_phase_subscribe_bucket{le="2.5",operationName="Anonymous",operationType="subscription"} 1 | ||
graphql_envelop_phase_subscribe_bucket{le="5",operationName="Anonymous",operationType="subscription"} 1 | ||
graphql_envelop_phase_subscribe_bucket{le="10",operationName="Anonymous",operationType="subscription"} 1 | ||
graphql_envelop_phase_subscribe_bucket{le="+Inf",operationName="Anonymous",operationType="subscription"} 1 | ||
graphql_envelop_phase_subscribe_sum{operationName="Anonymous",operationType="subscription"} 0.011 | ||
graphql_envelop_phase_subscribe_count{operationName="Anonymous",operationType="subscription"} 1 | ||
``` | ||
### `graphql_envelop_request_duration` | ||
This metric tracks the duration of the complete GraphQL operation execution. | ||
It is reported as a [histogram](https://prometheus.io/docs/concepts/metric_types/#histogram). | ||
#### Labels | ||
| Label | Description | | ||
| --------------- | ------------------------------------------------------------------------------------------------------- | | ||
| `operationType` | The type of the GraphQL operation requested. This can be one of `query`, `mutation`, or `subscription`. | | ||
| `operationName` | The name of the GraphQL operation requested. It will be `Anonymous` if no `operationName` is found. | | ||
#### Sample Output | ||
```text | ||
# HELP graphql_envelop_request_duration Time spent on running the GraphQL operation from parse to execute | ||
# TYPE graphql_envelop_request_duration histogram | ||
graphql_envelop_request_duration_bucket{le="0.005",operationName="Anonymous",operationType="subscription"} 0 | ||
graphql_envelop_request_duration_bucket{le="0.01",operationName="Anonymous",operationType="subscription"} 0 | ||
graphql_envelop_request_duration_bucket{le="0.025",operationName="Anonymous",operationType="subscription"} 1 | ||
graphql_envelop_request_duration_bucket{le="0.05",operationName="Anonymous",operationType="subscription"} 1 | ||
graphql_envelop_request_duration_bucket{le="0.1",operationName="Anonymous",operationType="subscription"} 1 | ||
graphql_envelop_request_duration_bucket{le="0.25",operationName="Anonymous",operationType="subscription"} 1 | ||
graphql_envelop_request_duration_bucket{le="0.5",operationName="Anonymous",operationType="subscription"} 1 | ||
graphql_envelop_request_duration_bucket{le="1",operationName="Anonymous",operationType="subscription"} 1 | ||
graphql_envelop_request_duration_bucket{le="2.5",operationName="Anonymous",operationType="subscription"} 1 | ||
graphql_envelop_request_duration_bucket{le="5",operationName="Anonymous",operationType="subscription"} 1 | ||
graphql_envelop_request_duration_bucket{le="10",operationName="Anonymous",operationType="subscription"} 1 | ||
graphql_envelop_request_duration_bucket{le="+Inf",operationName="Anonymous",operationType="subscription"} 1 | ||
graphql_envelop_request_duration_sum{operationName="Anonymous",operationType="subscription"} 0.011 | ||
graphql_envelop_request_duration_count{operationName="Anonymous",operationType="subscription"} 1 | ||
``` | ||
### `graphql_envelop_request_time_summary` | ||
This metric provides a summary of the time spent on the GraphQL operation execution. | ||
It reports the same timing than | ||
[`graphql_envelop_request_duration`](#graphql_envelop_request_duration) but as a | ||
[summary](https://prometheus.io/docs/concepts/metric_types/#summary). | ||
#### Labels | ||
| Label | Description | | ||
| --------------- | ------------------------------------------------------------------------------------------------------- | | ||
| `operationType` | The type of the GraphQL operation requested. This can be one of `query`, `mutation`, or `subscription`. | | ||
| `operationName` | The name of the GraphQL operation requested. It will be `Anonymous` if no `operationName` is found. | | ||
#### Sample output | ||
```text | ||
# HELP graphql_envelop_request_time_summary Summary to measure the time to complete GraphQL operations | ||
# TYPE graphql_envelop_request_time_summary summary | ||
graphql_envelop_request_time_summary{quantile="0.01",operationName="Anonymous",operationType="subscription"} 0.022 | ||
graphql_envelop_request_time_summary{quantile="0.05",operationName="Anonymous",operationType="subscription"} 0.022 | ||
graphql_envelop_request_time_summary{quantile="0.5",operationName="Anonymous",operationType="subscription"} 0.022 | ||
graphql_envelop_request_time_summary{quantile="0.9",operationName="Anonymous",operationType="subscription"} 0.022 | ||
graphql_envelop_request_time_summary{quantile="0.95",operationName="Anonymous",operationType="subscription"} 0.022 | ||
graphql_envelop_request_time_summary{quantile="0.99",operationName="Anonymous",operationType="subscription"} 0.022 | ||
graphql_envelop_request_time_summary{quantile="0.999",operationName="Anonymous",operationType="subscription"} 0.022 | ||
graphql_envelop_request_time_summary_sum{operationName="Anonymous",operationType="subscription"} 0.022 | ||
graphql_envelop_request_time_summary_count{operationName="Anonymous",operationType="subscription"} 1 | ||
``` | ||
### `graphql_envelop_error_result` | ||
This metric tracks the number of errors that occurred returned by the GraphQL execution. It counts | ||
all errors found in the final response, but it also includes errors from other GraphQL processing | ||
phases (parsing, validation and context building). | ||
It is exposed as a [counter](https://prometheus.io/docs/concepts/metric_types/#counter). | ||
#### Labels | ||
Depending on the phase when the error occurred, some labels may be missing. For example, if the | ||
error occurred during the context phase, only the `phase` label will be present. | ||
| Label | Description | | ||
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| `path` | The path of the field that caused the error. It can be `undefined` if the error is not related to a given field. | | ||
| `phase` | The phase of the GraphQL execution where the error occurred. It can be `parse`, `validate`, `context`, `execute` (for every operation types including subscriptions). | | ||
| `operationType` | The type of the GraphQL operation requested. This can be one of `query`, `mutation`, or `subscription`. | | ||
| `operationName` | The name of the GraphQL operation requested. It will be `Anonymous` if no `operationName` is found. | | ||
#### Sample Output | ||
```text | ||
# HELP graphql_envelop_error_result Counts the amount of errors reported from all phases | ||
# TYPE graphql_envelop_error_result counter | ||
graphql_envelop_error_result{operationName="Anonymous",operationType="query",path="undefined",phase="execute"} 1 | ||
``` | ||
### `graphql_envelop_request` | ||
This metric tracks the number of GraphQL operations executed. It counts all operations, either | ||
failed or successful, including subscriptions. | ||
It is exposed as a [counter](https://prometheus.io/docs/concepts/metric_types/#counter). | ||
#### Labels | ||
| Label | Description | | ||
| --------------- | ------------------------------------------------------------------------------------------------------- | | ||
| `operationType` | The type of the GraphQL operation requested. This can be one of `query`, `mutation`, or `subscription`. | | ||
| `operationName` | The name of the GraphQL operation requested. It will be `Anonymous` if no `operationName` is found. | | ||
#### Sample output | ||
```text | ||
# HELP graphql_envelop_request Counts the amount of GraphQL requests executed through Envelop | ||
# TYPE graphql_envelop_request counter | ||
graphql_envelop_request{operationName="Anonymous",operationType="query"} 1 | ||
``` | ||
### `graphql_envelop_deprecated_field` | ||
This metric tracks the number of deprecated fields used in the GraphQL operation. | ||
#### Labels | ||
| Label | Description | | ||
| --------------- | ------------------------------------------------------------------------------------------------------- | | ||
| `fieldName` | The name of the deprecated field that has been used. | | ||
| `typeName` | The name of the parent type of the deprecated field that has been used. | | ||
| `operationType` | The type of the GraphQL operation requested. This can be one of `query`, `mutation`, or `subscription`. | | ||
| `operationName` | The name of the GraphQL operation requested. It will be `Anonymous` if no `operationName` is found. | | ||
#### Sample Output | ||
```text | ||
# HELP graphql_envelop_deprecated_field Counts the amount of deprecated fields used in selection sets | ||
# TYPE graphql_envelop_deprecated_field counter | ||
graphql_envelop_deprecated_field{operationName="Anonymous",operationType="query",fieldName="hello",typeName="Query"} 1 | ||
``` | ||
### `graphql_envelop_schema_change` | ||
This metric tracks the number of schema changes that have occurred since the gateway started. | ||
If you are using a plugin that modifies the schema on the fly, be aware that this metric will also | ||
include updates made by those plugins. Which means that one schema update can actually trigger | ||
multiple schema changes. | ||
#### Labels | ||
This metric does not include any labels. | ||
#### Sample output | ||
```text | ||
# HELP graphql_envelop_schema_change Counts the amount of schema changes | ||
# TYPE graphql_envelop_schema_change counter | ||
graphql_envelop_schema_change 1 | ||
``` | ||
### `graphql_envelop_execute_resolver` | ||
> **Caution**: Enabling resolvers level metrics will introduce significant overhead. | ||
> | ||
> We highly recommend to enable this for debugging purpose only. | ||
This metric tracks the duration of each resolver execution. It reports the time spent only on | ||
additional resolvers, not on fields that are resolved by a subgraph. It is up to the subgraph server | ||
to implement resolver level metrics, the gateway can't remotely track their execution time. | ||
#### Filter resolvers to instrument | ||
To mitigate the cost of instrumenting all resolvers, you can explicitly list the fields that should | ||
be instrumented by providing a list of field names to the `instrumentResolvers` option. | ||
It is a list of strings in the form of `TypeName.fieldName`. For example, to instrument the `hello` | ||
root query, you would use `Query.hello`. | ||
You can also use wildcards to instrument all the fields for a type. For example, to instrument all | ||
root queries, you would use `Query.*`. | ||
#### Labels | ||
| Label | Description | | ||
| --------------- | ------------------------------------------------------------------------------------------------------- | | ||
| `operationType` | The type of the GraphQL operation requested. This can be one of `query`, `mutation`, or `subscription`. | | ||
| `operationName` | The name of the GraphQL operation requested. It will be `Anonymous` if no `operationName` is found. | | ||
| `fieldName` | The name of the field being resolved. | | ||
| `typeName` | The name of the parent type of the field being resolved. | | ||
| `returnType` | The name of the return type of the field being resolved. | | ||
#### Sample output | ||
```text | ||
# HELP graphql_envelop_execute_resolver Time spent on running the GraphQL resolvers | ||
# TYPE graphql_envelop_execute_resolver histogram | ||
graphql_envelop_execute_resolver_bucket{le="0.005",operationName="Anonymous",operationType="query",fieldName="hello",typeName="Query",returnType="String!"} 1 | ||
graphql_envelop_execute_resolver_bucket{le="0.01",operationName="Anonymous",operationType="query",fieldName="hello",typeName="Query",returnType="String!"} 1 | ||
graphql_envelop_execute_resolver_bucket{le="0.025",operationName="Anonymous",operationType="query",fieldName="hello",typeName="Query",returnType="String!"} 1 | ||
graphql_envelop_execute_resolver_bucket{le="0.05",operationName="Anonymous",operationType="query",fieldName="hello",typeName="Query",returnType="String!"} 1 | ||
graphql_envelop_execute_resolver_bucket{le="0.1",operationName="Anonymous",operationType="query",fieldName="hello",typeName="Query",returnType="String!"} 1 | ||
graphql_envelop_execute_resolver_bucket{le="0.25",operationName="Anonymous",operationType="query",fieldName="hello",typeName="Query",returnType="String!"} 1 | ||
graphql_envelop_execute_resolver_bucket{le="0.5",operationName="Anonymous",operationType="query",fieldName="hello",typeName="Query",returnType="String!"} 1 | ||
graphql_envelop_execute_resolver_bucket{le="1",operationName="Anonymous",operationType="query",fieldName="hello",typeName="Query",returnType="String!"} 1 | ||
graphql_envelop_execute_resolver_bucket{le="2.5",operationName="Anonymous",operationType="query",fieldName="hello",typeName="Query",returnType="String!"} 1 | ||
graphql_envelop_execute_resolver_bucket{le="5",operationName="Anonymous",operationType="query",fieldName="hello",typeName="Query",returnType="String!"} 1 | ||
graphql_envelop_execute_resolver_bucket{le="10",operationName="Anonymous",operationType="query",fieldName="hello",typeName="Query",returnType="String!"} 1 | ||
graphql_envelop_execute_resolver_bucket{le="+Inf",operationName="Anonymous",operationType="query",fieldName="hello",typeName="Query",returnType="String!"} 1 | ||
graphql_envelop_execute_resolver_sum{operationName="Anonymous",operationType="query",fieldName="hello",typeName="Query",returnType="String!"} 0 | ||
graphql_envelop_execute_resolver_count{operationName="Anonymous",operationType="query",fieldName="hello",typeName="Query",returnType="String!"} 1 | ||
``` | ||
## Configuration | ||
### Custom registry | ||
@@ -90,3 +497,3 @@ | ||
If you wish to disable introspection logging, you can use `skipIntrospection: true` in your config | ||
You can exclude introspection from monitoring by setting `skipIntrospection: true` in your config | ||
object. | ||
@@ -108,19 +515,19 @@ | ||
useEngine({ parse, validate, specifiedRules, execute, subscribe }), | ||
// ... other plugins ... | ||
usePrometheus({ | ||
// all optional, and by default, all set to false, please opt-in to the metrics you wish to get | ||
parse: createHistogram({ | ||
registry: registry // make sure to add your custom registry, if you are not using the default one | ||
histogram: new Histogram({ | ||
name: 'my_custom_name', | ||
help: 'HELP ME', | ||
labelNames: ['opText'] as const, | ||
metrics: { | ||
graphql_envelop_phase_parse: createHistogram({ | ||
registry: registry // if you are not using the default one, make sure to add your custom registry, | ||
histogram: new Histogram({ | ||
name: 'my_custom_name', | ||
help: 'HELP ME', | ||
labelNames: ['opText'] as const, | ||
}), | ||
fillLabelsFn: params => { | ||
// if you wish to fill your `labels` 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) | ||
return { | ||
opText: print(params.document) | ||
} | ||
} | ||
}), | ||
fillLabelsFn: params => { | ||
// if you wish to fill your `labels` 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) | ||
return { | ||
opText: print(params.document) | ||
} | ||
} | ||
}) | ||
} | ||
}) | ||
@@ -127,0 +534,0 @@ ] |
import { Registry } from 'prom-client'; | ||
import { createCounter, createHistogram, createSummary } from './utils.js'; | ||
export type PrometheusTracingPluginConfig = { | ||
/** | ||
* The `prom-client` registry to use. If not provided, the default global registry will be used. | ||
*/ | ||
registry?: Registry; | ||
/** | ||
* Ignore introspection queries when collecting metrics. | ||
* | ||
* @default false | ||
*/ | ||
skipIntrospection?: boolean; | ||
/** | ||
* Only applicable when `metrics.graphql_envelop_execute_resolver` is enabled. | ||
* | ||
* Allows to whitelist resolvers to collect metrics for. It is highly recommended to provide this | ||
* option to avoid metrics explosion and performance degradation. | ||
*/ | ||
resolversWhitelist?: string[]; | ||
/** | ||
* Metrics configuration. | ||
* | ||
* By default, all metrics are disabled. You can enable them by setting the corresponding field to `true`. | ||
* | ||
* An object can also be passed to configure the metric. | ||
* Please use the factories `createCounter`, `createHistogram` and `createSummary` | ||
* to create those metric configuration objects. | ||
*/ | ||
metrics: MetricsConfig; | ||
/** | ||
* All labels attached to metrics can be disabled. This can help you reduce the size of the exported metrics | ||
* | ||
* By default, all labels are enabled, but all labels are not available for all metrics. | ||
* See the documentation for each metric to see which labels are available. | ||
*/ | ||
labels?: LabelsConfig; | ||
}; | ||
export type MetricsConfig = { | ||
/** | ||
* Tracks the number of GraphQL operations executed. | ||
* It counts all operations, either failed or successful, including subscriptions. | ||
* It is exposed as a counter. | ||
*/ | ||
graphql_envelop_request?: boolean | string | ReturnType<typeof createCounter>; | ||
graphql_envelop_request_duration?: boolean | string | ReturnType<typeof createHistogram>; | ||
/** | ||
* Tracks the duration of the complete GraphQL operation execution. | ||
* It is reported as a histogram. | ||
* | ||
* You can pass multiple type of values: | ||
* - boolean: Disable or Enable the metric with default configuration | ||
* - string: Enable the metric with custom name | ||
* - number[]: Enable the metric with custom buckets | ||
* - ReturnType<typeof createHistogram>: Enable the metric with custom configuration | ||
*/ | ||
graphql_envelop_request_duration?: boolean | string | number[] | ReturnType<typeof createHistogram>; | ||
/** | ||
* Provides a summary of the time spent on the GraphQL operation execution. | ||
* It reports the same timing than graphql_envelop_request_duration but as a summary. | ||
*/ | ||
graphql_envelop_request_time_summary?: boolean | string | ReturnType<typeof createSummary>; | ||
graphql_envelop_phase_parse?: boolean | string | ReturnType<typeof createHistogram>; | ||
graphql_envelop_phase_validate?: boolean | string | ReturnType<typeof createHistogram>; | ||
graphql_envelop_phase_context?: boolean | string | ReturnType<typeof createHistogram>; | ||
graphql_envelop_phase_execute?: boolean | string | ReturnType<typeof createHistogram>; | ||
graphql_envelop_phase_subscribe?: boolean | string | ReturnType<typeof createHistogram>; | ||
/** | ||
* Tracks the duration of the parse phase of the GraphQL execution. | ||
* It reports the time spent parsing the incoming GraphQL operation. | ||
* It is reported as a histogram. | ||
* | ||
* You can pass multiple type of values: | ||
* - boolean: Disable or Enable the metric with default configuration | ||
* - string: Enable the metric with custom name | ||
* - number[]: Enable the metric with custom buckets | ||
* - ReturnType<typeof createHistogram>: Enable the metric with custom configuration | ||
*/ | ||
graphql_envelop_phase_parse?: boolean | string | number[] | ReturnType<typeof createHistogram>; | ||
/** | ||
* Tracks the duration of the validate phase of the GraphQL execution. | ||
* It reports the time spent validating the incoming GraphQL operation. | ||
* It is reported as a histogram. | ||
* | ||
* You can pass multiple type of values: | ||
* - boolean: Disable or Enable the metric with default configuration | ||
* - string: Enable the metric with custom name | ||
* - number[]: Enable the metric with custom buckets | ||
* - ReturnType<typeof createHistogram>: Enable the metric with custom configuration | ||
*/ | ||
graphql_envelop_phase_validate?: boolean | string | number[] | ReturnType<typeof createHistogram>; | ||
/** | ||
* Tracks the duration of the context phase of the GraphQL execution. | ||
* It reports the time spent building the context object that will be passed to the executors. | ||
* It is reported as a histogram. | ||
* | ||
* You can pass multiple type of values: | ||
* - boolean: Disable or Enable the metric with default configuration | ||
* - string: Enable the metric with custom name | ||
* - number[]: Enable the metric with custom buckets | ||
* - ReturnType<typeof createHistogram>: Enable the metric with custom configuration | ||
*/ | ||
graphql_envelop_phase_context?: boolean | string | number[] | ReturnType<typeof createHistogram>; | ||
/** | ||
* Tracks the duration of the execute phase of the GraphQL execution. | ||
* It reports the time spent actually resolving the response of the incoming operation. | ||
* This includes the gathering of all the data from all sources required to construct the final response. | ||
* It is reported as a histogram. | ||
* | ||
* You can pass multiple type of values: | ||
* - boolean: Disable or Enable the metric with default configuration | ||
* - string: Enable the metric with custom name | ||
* - number[]: Enable the metric with custom buckets | ||
* - ReturnType<typeof createHistogram>: Enable the metric with custom configuration | ||
*/ | ||
graphql_envelop_phase_execute?: boolean | string | number[] | ReturnType<typeof createHistogram>; | ||
/** | ||
* This metric tracks the duration of the subscribe phase of the GraphQL execution. | ||
* It reports the time spent initiating a subscription (which doesn’t include actually sending the first response). | ||
* It is reported as a histogram. | ||
* | ||
* You can pass multiple type of values: | ||
* - boolean: Disable or Enable the metric with default configuration | ||
* - string: Enable the metric with custom name | ||
* - number[]: Enable the metric with custom buckets | ||
* - ReturnType<typeof createHistogram>: Enable the metric with custom configuration | ||
*/ | ||
graphql_envelop_phase_subscribe?: boolean | string | number[] | ReturnType<typeof createHistogram>; | ||
/** | ||
* This metric tracks the number of errors that returned by the GraphQL execution. | ||
* It counts all errors found in response, but it also includes errors from other GraphQL | ||
* processing phases (parsing, validation and context building). | ||
* It is exposed as a counter. | ||
*/ | ||
graphql_envelop_error_result?: boolean | string | ReturnType<typeof createCounter>; | ||
/** | ||
* This metric tracks the number of deprecated fields used in the GraphQL operation. | ||
* It is exposed as a counter. | ||
*/ | ||
graphql_envelop_deprecated_field?: boolean | string | ReturnType<typeof createCounter>; | ||
/** | ||
* This metric tracks the number of schema changes that have occurred since the gateway started. | ||
* If you are using a plugin that modifies the schema on the fly, | ||
* be aware that this metric will also include updates made by those plugins. | ||
* Which means that one schema update can actually trigger multiple schema changes. | ||
* It is exposed as a counter. | ||
*/ | ||
graphql_envelop_schema_change?: boolean | string | ReturnType<typeof createCounter>; | ||
graphql_envelop_execute_resolver?: boolean | string | ReturnType<typeof createHistogram>; | ||
/** | ||
* This metric tracks the duration of each resolver execution. | ||
* | ||
* It is highly recommended to enable this metric for debugging purposes only, | ||
* since it can have a significant performance impact. | ||
* You can use the `resolversWhitelist` option to limit metrics explosion and performance degradation. | ||
* | ||
* You can pass multiple type of values: | ||
* - boolean: Disable or Enable the metric with default configuration | ||
* - string: Enable the metric with custom name | ||
* - number[]: Enable the metric with custom buckets | ||
* - ReturnType<typeof createHistogram>: Enable the metric with custom configuration | ||
*/ | ||
graphql_envelop_execute_resolver?: boolean | string | number[] | ReturnType<typeof createHistogram>; | ||
}; | ||
export type LabelsConfig = { | ||
/** | ||
* The currently executing operation name. | ||
* | ||
* If no operation name is provided, this will be set to 'Anonymous' | ||
* | ||
* @default true | ||
*/ | ||
operationName?: boolean; | ||
/** | ||
* The currently executing operation type. | ||
* | ||
* @default true | ||
*/ | ||
operationType?: boolean; | ||
/** | ||
* The resolved field name. | ||
* | ||
* @default true | ||
*/ | ||
fieldName?: boolean; | ||
/** | ||
* The resolved field parent type name. | ||
* | ||
* @default true | ||
*/ | ||
typeName?: boolean; | ||
/** | ||
* The resolved field type name. This is only available for the `graphql_envelop_execute_resolver` metric. | ||
* | ||
* @default true | ||
*/ | ||
returnType?: boolean; | ||
/** | ||
* The path of the field from which originated the error. Only available for the `graphql_envelop_error_result` metric. | ||
*/ | ||
path?: boolean; | ||
/** | ||
* The execution phase where the error occurred. Only available for the `graphql_envelop_error_result` metric. | ||
*/ | ||
phase?: boolean; | ||
}; |
Sorry, the diff of this file is not supported yet
108811
1290
559