Skip to content

Commit

Permalink
refactor(prometheus-plugin): rename metric options names (#3391)
Browse files Browse the repository at this point in the history
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
EmrysMyrddin and github-actions[bot] authored Aug 13, 2024
1 parent f5a2ae9 commit 0788d8a
Show file tree
Hide file tree
Showing 11 changed files with 920 additions and 494 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@graphql-yoga/plugin-prometheus': patch
---
dependencies updates:
- Updated dependency [`@envelop/[email protected]`
↗︎](https://www.npmjs.com/package/@envelop/prometheus/v/11.0.0) (from `^10.0.0`, in
`dependencies`)
53 changes: 53 additions & 0 deletions .changeset/chilly-ladybugs-smoke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
'@graphql-yoga/plugin-prometheus': major
---

**Breaking Change:** Rename all metrics options to their actual metric name to avoid confusion.

All metric options have been moved under a mandatory `metrics` key, and the name of each options
have been renamed to match the default metric name.

The plugin option argument is also now mandatory.

```diff
export const serveConfig = defineConfig({
plugins: pluginCtx => [
usePrometheus({
...pluginCtx,

// Enable all available metrics
- http: true
- requestSummary: true,
- parse: true,
- validate: true,
- contextBuilding: true,
- execute: true,
- subscribe: true,
- errors: true,
- deprecatedFields: true,
- requestTotalDuration: true,
- schemaChangeCount: true,

// Warning: enabling resolvers level metrics will introduce significant overhead
- resolvers: true,
+ metrics: {
+ graphql_yoga_http_duration: true,
+ 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,

// Warning: enabling resolvers level metrics will introduce significant overhead
+ graphql_envelop_execute_resolver: true,
+ }
})
]
})
```

7 changes: 7 additions & 0 deletions .changeset/clever-doors-listen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@graphql-yoga/plugin-prometheus': minor
---

Add missing labels `path` and `phase` of `graphql_envelop_error_result` metric to the configuration.

Add missing labels `method` and `statusCode` of `graphql_yoga_http_duration` metric to the configuration.
15 changes: 6 additions & 9 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,36 +10,33 @@ jobs:
permissions:
contents: read
id-token: write
uses: the-guild-org/shared-config/.github/workflows/release-snapshot.yml@main
uses: the-guild-org/shared-config/.github/workflows/release-snapshot.yml@v1
if: ${{ github.event.pull_request.title != 'Upcoming Release Changes' }}
with:
npmTag: alpha
buildScript: build
nodeVersion: 22
packageManager: pnpm
node-version-file: .node-version
secrets:
githubToken: ${{ secrets.GITHUB_TOKEN }}
npmToken: ${{ secrets.NODE_AUTH_TOKEN }}

release-candidate:
uses: the-guild-org/shared-config/.github/workflows/release-snapshot.yml@main
uses: the-guild-org/shared-config/.github/workflows/release-snapshot.yml@v1
if: ${{ github.event.pull_request.title == 'Upcoming Release Changes' }}
with:
npmTag: rc
restoreDeletedChangesets: false
buildScript: build
nodeVersion: 22
packageManager: pnpm
node-version-file: .node-version
secrets:
githubToken: ${{ secrets.GITHUB_TOKEN }}
npmToken: ${{ secrets.NODE_AUTH_TOKEN }}

dependencies:
uses: the-guild-org/shared-config/.github/workflows/changesets-dependencies.yaml@main
uses: the-guild-org/shared-config/.github/workflows/changesets-dependencies.yml@v1
if: ${{ github.event.pull_request.title != 'Upcoming Release Changes' }}
secrets:
githubToken: ${{ secrets.GUILD_BOT_TOKEN }}
with:
installDependencies: true
packageManager: pnpm
nodeVersion: 22
node-version-file: .node-version
5 changes: 2 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,11 @@ jobs:
permissions:
contents: read
id-token: write
uses: the-guild-org/shared-config/.github/workflows/release-stable.yml@main
uses: the-guild-org/shared-config/.github/workflows/release-stable.yml@v1
if: ${{ github.event.pull_request.title != 'Upcoming Release Changes' }}
with:
releaseScript: release
nodeVersion: 22
packageManager: pnpm
node-version-file: .node-version
secrets:
githubToken: ${{ secrets.GUILD_BOT_TOKEN }}
npmToken: ${{ secrets.NODE_AUTH_TOKEN }}
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,3 @@ out/

packages/graphql-yoga/src/landing-page-html.ts
packages/graphql-yoga/src/graphiql-html.ts
.tool-versions

.mise.toml
4 changes: 2 additions & 2 deletions packages/plugins/prometheus/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@
"prom-client": "^15.0.0"
},
"dependencies": {
"@envelop/prometheus": "^10.0.0"
"@envelop/prometheus": "11.0.0"
},
"devDependencies": {
"graphql-yoga": "workspace:*",
"prom-client": "15.0.0"
"prom-client": "15.1.3"
},
"publishConfig": {
"directory": "dist",
Expand Down
97 changes: 52 additions & 45 deletions packages/plugins/prometheus/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import {
createSummary,
PrometheusTracingPluginConfig as EnvelopPrometheusTracingPluginConfig,
FillLabelsFnParams,
getCounterFromConfig,
getHistogramFromConfig,
getSummaryFromConfig,
HistogramAndLabels,
SummaryAndLabels,
usePrometheus as useEnvelopPrometheus,
Expand All @@ -21,63 +24,67 @@ export {
FillLabelsFnParams,
HistogramAndLabels,
SummaryAndLabels,
getHistogramFromConfig,
getCounterFromConfig,
getSummaryFromConfig,
};

export interface PrometheusTracingPluginConfig extends EnvelopPrometheusTracingPluginConfig {
http?: boolean | string | ReturnType<typeof createHistogram>;
export type PrometheusTracingPluginConfig = EnvelopPrometheusTracingPluginConfig & {
metrics: {
/**
* Tracks the duration of HTTP requests. It reports the time spent to
* process each incoming request as an 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_yoga_http_duration?: boolean | string | number[] | ReturnType<typeof createHistogram>;
};

labels?: {
/**
* The HTTP method of the request
*/
method?: boolean;
/**
* The status code of the response
*/
statusCode?: boolean;
/**
* The url of the HTTP request
*/
url?: boolean;
};

/**
* The endpoint to serve metrics exposed by this plugin.
* Defaults to "/metrics".
*/
endpoint?: string | boolean;
}
};

export function usePrometheus(options: PrometheusTracingPluginConfig): Plugin {
const endpoint = options.endpoint || '/metrics';
const registry = options.registry || defaultRegistry;
let httpHistogram: ReturnType<typeof createHistogram> | undefined;

function labelExists(label: string) {
if ((options.labels as Record<string, boolean>)?.[label] == null) {
return true;
}
return (options.labels as Record<string, boolean>)[label];
}

if (options.http) {
const labelNames = ['method', 'statusCode'];
if (labelExists('operationName')) {
labelNames.push('operationName');
}
if (labelExists('operationType')) {
labelNames.push('operationType');
}
httpHistogram =
typeof options.http === 'object'
? options.http
: createHistogram({
registry,
histogram: {
name: typeof options.http === 'string' ? options.http : 'graphql_yoga_http_duration',
help: 'Time spent on HTTP connection',
labelNames,
},
fillLabelsFn(params, { request, response }) {
const labels: Record<string, string> = {
method: request.method,
statusCode: response.status,
};
if (labelExists('operationType') && params.operationType) {
labels.operationType = params.operationType;
}
if (labelExists('operationName')) {
labels.operationName = params.operationName || 'Anonymous';
}
return labels;
},
});
}
const httpHistogram = getHistogramFromConfig<PrometheusTracingPluginConfig['metrics']>(
options,
'graphql_yoga_http_duration',
{
help: 'Time spent on HTTP connection',
labelNames: ['operationName', 'operationType', 'method', 'statusCode', 'url'],
},
(params, { request, response }) => ({
method: request.method,
statusCode: response.status,
operationType: params.operationType || 'unknown',
operationName: params.operationName || 'Anonymous',
url: request.url,
}),
);

const startByRequest = new WeakMap<Request, number>();
const paramsByRequest = new WeakMap<Request, FillLabelsFnParams>();
Expand Down Expand Up @@ -114,7 +121,7 @@ export function usePrometheus(options: PrometheusTracingPluginConfig): Plugin {
onResponse({ request, response, serverContext }) {
const start = startByRequest.get(request);
if (start) {
const duration = Date.now() - start;
const duration = (Date.now() - start) / 1000;
const params = paramsByRequest.get(request);
httpHistogram?.histogram.observe(
httpHistogram.fillLabelsFn(params || {}, {
Expand Down
26 changes: 19 additions & 7 deletions packages/plugins/prometheus/tests/prometheus.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ describe('Prometheus', () => {
schema,
plugins: [
usePrometheus({
http: true,
metrics: {
graphql_yoga_http_duration: true,
},
registry,
}),
],
Expand Down Expand Up @@ -55,7 +57,9 @@ describe('Prometheus', () => {
schema,
plugins: [
usePrometheus({
http: true,
metrics: {
graphql_yoga_http_duration: true,
},
registry,
labels: {
operationName: false,
Expand Down Expand Up @@ -93,8 +97,10 @@ describe('Prometheus', () => {
plugins: [
usePrometheus({
endpoint: '/metrics',
http: true,
execute: true,
metrics: {
graphql_yoga_http_duration: true,
graphql_envelop_phase_execute: true,
},
registry,
}),
],
Expand Down Expand Up @@ -125,11 +131,15 @@ describe('Prometheus', () => {

it('should be able to register the same histogram for multiple different registries', async () => {
usePrometheus({
http: true,
metrics: {
graphql_yoga_http_duration: true,
},
registry,
});
usePrometheus({
http: true,
metrics: {
graphql_yoga_http_duration: true,
},
registry,
});
});
Expand All @@ -139,7 +149,9 @@ describe('Prometheus', () => {
schema,
plugins: [
usePrometheus({
http: true,
metrics: {
graphql_yoga_http_duration: true,
},
registry,
}),
],
Expand Down
698 changes: 301 additions & 397 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

Loading

0 comments on commit 0788d8a

Please sign in to comment.