Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions deployment/services/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,14 @@ export function deployGraphQL({
GRAPHQL_PUBLIC_ORIGIN: `https://${environment.appDns}`,
CDN_CF: '1',
HIVE_USAGE: '1',
HIVE_USAGE_TARGET: hiveConfig.require('target'),
HIVE_TARGET: hiveConfig.require('target'),
HIVE_USAGE_ENDPOINT: serviceLocalEndpoint(usage.service),
HIVE_TRACING: '1',
HIVE_TRACING_ENDPOINT: environment.isProduction
Copy link
Contributor

@n1ru4l n1ru4l Dec 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: using the public endpoints to avoid having to solve a circular pulumi dependency of graphql api and otel :D We can alter on fix it.

? 'https://api.graphql-hive.com/otel/v1/traces'
: environment.isStaging
? 'https://api.hiveready.dev/otel/v1/traces'
: 'https://api.buzzcheck.dev/otel/v1/traces',
HIVE_PERSISTED_DOCUMENTS: '1',
ZENDESK_SUPPORT: zendesk.enabled ? '1' : '0',
INTEGRATION_GITHUB: '1',
Expand Down Expand Up @@ -210,7 +216,7 @@ export function deployGraphQL({
.withSecret('AUTH_GOOGLE_CLIENT_ID', googleOAuthSecret, 'clientId')
.withSecret('AUTH_GOOGLE_CLIENT_SECRET', googleOAuthSecret, 'clientSecret')
// Hive Usage Reporting
.withSecret('HIVE_USAGE_ACCESS_TOKEN', hiveUsageSecret, 'usageAccessToken')
.withSecret('HIVE_ACCESS_TOKEN', hiveUsageSecret, 'usageAccessToken')
// Persisted Documents
.withSecret(
'HIVE_PERSISTED_DOCUMENTS_CDN_ACCESS_KEY_ID',
Expand Down
2 changes: 1 addition & 1 deletion deployment/services/otel-collector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Docker } from './docker';
import { Environment } from './environment';
import { GraphQL } from './graphql';

export type OTELCollector = ReturnType<typeof deployOTELCollector>;
export type OTELCollector = ReturnType<ServiceDeployment['deploy']>;

export function deployOTELCollector(args: {
image: string;
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@
"tar-fs": "2.1.4",
"ip": "npm:[email protected]",
"miniflare@3>undici": "5.29.0",
"tailwindcss": "3.4.17"
"tailwindcss": "3.4.17",
"@graphql-hive/plugin-opentelemetry": "1.3.0-alpha-23838ba35fd408a4b5d1eea6368ca1d4874b955b"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs to be updated

},
"patchedDependencies": {
"[email protected]": "patches/[email protected]",
Expand Down
3 changes: 1 addition & 2 deletions packages/services/commerce/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ async function main() {
});

tracing.instrumentNodeFetch();
tracing.build();
tracing.start();
tracing.setup();
}

if (env.sentry) {
Expand Down
3 changes: 1 addition & 2 deletions packages/services/emails/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ async function main() {
});

tracing.instrumentNodeFetch();
tracing.build();
tracing.start();
tracing.setup();
}

if (env.sentry) {
Expand Down
3 changes: 1 addition & 2 deletions packages/services/policy/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ async function main() {
});

tracing.instrumentNodeFetch();
tracing.build();
tracing.start();
tracing.setup();
}

if (env.sentry) {
Expand Down
3 changes: 1 addition & 2 deletions packages/services/schema/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ async function main() {
});

tracing.instrumentNodeFetch();
tracing.build();
tracing.start();
tracing.setup();
}

if (env.sentry) {
Expand Down
22 changes: 12 additions & 10 deletions packages/services/server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,15 @@ The GraphQL API for GraphQL Hive.
If you are self-hosting GraphQL Hive, you can ignore this section. It is only required for the Cloud
version.

| Name | Required | Description | Example Value |
| ------------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- |
| `COMMERCE_ENDPOINT` | **Yes** | The endpoint of the commerce service. | `http://127.0.0.1:4012` |
| `CDN_CF` | No | Whether the CDN is enabled. | `1` (enabled) or `0` (disabled) |
| `CDN_CF_BASE_URL` | No (**Yes** if `CDN` is `1`) | The base URL of the cdn. | `https://cdn.graphql-hive.com` |
| `CDN_CF_KV_BASE_URL` | No (**Optional** if `CDN` is `1`) | The base URL for the key-value store used for CDN access key validation caching when using the Cloudflare provider. | `https://key-cache.graphql-hive.com` |
| `HIVE_USAGE` | No | Whether usage reporting for the GraphQL API to Hive is enabled | `1` (enabled) or `0` (disabled) |
| `HIVE_USAGE_TARGET` | No (**Yes** if `HIVE` is set to `1`) | The target to which the usage data should be reported | `the-guild/graphql-hive/development` |
| `HIVE_USAGE_ACCESS_TOKEN` | No (**Yes** if `HIVE` is set to `1`) | The internal endpoint key. | `iliketurtles` |
| `HIVE_USAGE_ENDPOINT` | No | The endpoint used for usage reporting. | `http://app.graphql-hive.com/usage` (default value) |
| Name | Required | Description | Example Value |
| ----------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ |
| `COMMERCE_ENDPOINT` | **Yes** | The endpoint of the commerce service. | `http://127.0.0.1:4012` |
| `CDN_CF` | No | Whether the CDN is enabled. | `1` (enabled) or `0` (disabled) |
| `CDN_CF_BASE_URL` | No (**Yes** if `CDN` is `1`) | The base URL of the cdn. | `https://cdn.graphql-hive.com` |
| `CDN_CF_KV_BASE_URL` | No (**Optional** if `CDN` is `1`) | The base URL for the key-value store used for CDN access key validation caching when using the Cloudflare provider. | `https://key-cache.graphql-hive.com` |
| `HIVE_USAGE` | No | Whether usage reporting for the GraphQL API to Hive is enabled | `1` (enabled) or `0` (disabled) |
| `HIVE_TARGET` | No (**Yes** if `HIVE` is set to `1`) | The target to which the usage data and traces should be reported | `the-guild/graphql-hive/development` |
| `HIVE_ACCESS_TOKEN` | No (**Yes** if `HIVE` is set to `1`) | The internal endpoint key. | `iliketurtles` |
| `HIVE_USAGE_ENDPOINT` | No | The endpoint used for usage reporting. | `http://app.graphql-hive.com/usage` (default value) |
| `HIVE_TRACING` | No | Whether trace reporting for the GraphQL API to Hive is enabled | `1` (enabled) or `0` (disabled) |
| `HIVE_TRACING_ENDPOINT` | No | The endpoint used for trace reporting. | `http://api.graphql-hive.com/otel/v1/traces` (default value) |
1 change: 1 addition & 0 deletions packages/services/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"@escape.tech/graphql-armor-max-tokens": "2.5.1",
"@fastify/cors": "9.0.1",
"@fastify/formbody": "7.4.0",
"@graphql-hive/plugin-opentelemetry": "^1.2.5",
"@graphql-hive/yoga": "workspace:*",
"@graphql-tools/merge": "9.1.1",
"@graphql-yoga/plugin-response-cache": "3.15.4",
Expand Down
46 changes: 34 additions & 12 deletions packages/services/server/src/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,15 +137,29 @@ const CdnApiModel = zod.union([
}),
]);

const HiveModel = zod.union([
zod.object({ HIVE_USAGE: emptyString(zod.literal('0').optional()) }),
zod.object({
HIVE_USAGE: zod.literal('1'),
HIVE_USAGE_ENDPOINT: zod.string().url().optional(),
HIVE_USAGE_TARGET: zod.string(),
HIVE_USAGE_ACCESS_TOKEN: zod.string(),
}),
]);
const HiveModel = zod.intersection(
zod.union([
zod.object({ HIVE_USAGE: emptyString(zod.literal('0').optional()) }),
zod.object({
HIVE_USAGE: zod.literal('1'),
HIVE_USAGE_ENDPOINT: zod.string().url().optional(),
HIVE_TARGET: zod.string(),
HIVE_ACCESS_TOKEN: zod.string(),
}),
]),
zod.union([
zod.object({ HIVE_TRACING: emptyString(zod.literal('0').optional()) }),
zod.object({
HIVE_TRACING: zod.literal('1'),
HIVE_TRACING_ENDPOINT: zod
.string()
.url()
.default('https://api.graphql-hive.com/otel/v1/traces'),
HIVE_TARGET: zod.string(),
HIVE_ACCESS_TOKEN: zod.string(),
}),
]),
);

const PrometheusModel = zod.object({
PROMETHEUS_METRICS: emptyString(zod.union([zod.literal('0'), zod.literal('1')]).optional()),
Expand Down Expand Up @@ -336,8 +350,8 @@ const hivePersistedDocuments = extractConfig(configs.hivePersistedDocuments);
const hiveUsageConfig =
hive.HIVE_USAGE === '1'
? {
target: hive.HIVE_USAGE_TARGET,
token: hive.HIVE_USAGE_ACCESS_TOKEN,
target: hive.HIVE_TARGET,
token: hive.HIVE_ACCESS_TOKEN,
endpoint: hive.HIVE_USAGE_ENDPOINT ?? null,
}
: null;
Expand All @@ -358,9 +372,17 @@ export const env = {
release: base.RELEASE ?? 'local',
encryptionSecret: base.ENCRYPTION_SECRET,
tracing: {
enabled: !!tracing.OPENTELEMETRY_COLLECTOR_ENDPOINT,
enabled: !!tracing.OPENTELEMETRY_COLLECTOR_ENDPOINT || hive.HIVE_TRACING === '1',
collectorEndpoint: tracing.OPENTELEMETRY_COLLECTOR_ENDPOINT,
enableConsoleExporter: tracing.OPENTELEMETRY_CONSOLE_EXPORTER === '1',
hive:
hive.HIVE_TRACING === '1'
? {
endpoint: hive.HIVE_TRACING_ENDPOINT,
target: hive.HIVE_TARGET,
accessToken: hive.HIVE_ACCESS_TOKEN,
}
: undefined,
},
hiveServices: {
webApp: {
Expand Down
40 changes: 23 additions & 17 deletions packages/services/server/src/graphql-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ import hyperid from 'hyperid';
import { isGraphQLError } from '@envelop/core';
import { useGraphQlJit } from '@envelop/graphql-jit';
import { useGraphQLModules } from '@envelop/graphql-modules';
import { useOpenTelemetry } from '@envelop/opentelemetry';
import { useSentry } from '@envelop/sentry';
import { useOpenTelemetry } from '@graphql-hive/plugin-opentelemetry';
import { hive, trace } from '@graphql-hive/plugin-opentelemetry/api';
import { useHive } from '@graphql-hive/yoga';
import { useResponseCache } from '@graphql-yoga/plugin-response-cache';
import { Registry, RegistryContext } from '@hive/api';
Expand Down Expand Up @@ -162,23 +163,28 @@ export function useHiveSentry() {
});
}

export function useHiveTracing(tracingProvider?: Parameters<typeof useOpenTelemetry>[1]) {
return useOpenTelemetry(
{
document: true,
resolvers: false,
result: false,
variables: variables => {
if (variables && typeof variables === 'object' && 'selector' in variables) {
return JSON.stringify(variables.selector);
}
export function useHiveTracing(): Plugin {
return {
onPluginInit({ addPlugin }) {
addPlugin(
useOpenTelemetry({
traces: {
spans: {
http: ({ request }) => request.headers.get('x-hive-tracing') !== 'ignore',
},
},
}) as Plugin,
);
},
onParams({ params: { variables }, context }) {
const otelCtx = hive.getOperationContext(context);
const operationSpan = otelCtx && trace.getSpan(otelCtx);

return '';
},
excludedOperationNames: ['readiness'],
if (operationSpan && variables && typeof variables === 'object' && 'selector' in variables) {
operationSpan?.setAttribute('hive.variables.selector', JSON.stringify(variables.selector));
}
},
tracingProvider,
);
};
}

export const graphqlHandler = (options: GraphQLHandlerOptions): RouteHandlerMethod => {
Expand Down Expand Up @@ -266,7 +272,7 @@ export const graphqlHandler = (options: GraphQLHandlerOptions): RouteHandlerMeth
},
},
),
options.tracing ? useHiveTracing(options.tracing.traceProvider()) : {},
options.tracing ? useHiveTracing() : {},
useExecutionCancellation(),
],
graphiql: !options.isProduction,
Expand Down
7 changes: 4 additions & 3 deletions packages/services/server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,16 @@ class CorsError extends Error {
export async function main() {
let tracing: TracingInstance | undefined;

if (env.tracing.enabled && env.tracing.collectorEndpoint) {
if (env.tracing.enabled) {
tracing = configureTracing({
collectorEndpoint: env.tracing.collectorEndpoint,
serviceName: 'graphql-api',
enableConsoleExporter: env.tracing.enableConsoleExporter,
hiveTracing: env.tracing.hive,
});

tracing.instrumentNodeFetch();
tracing.build();
tracing.start();
tracing.setup();
}

init({
Expand Down Expand Up @@ -560,6 +560,7 @@ export async function main() {
'Content-Type': 'application/json',
Accept: 'application/json',
'x-signature': signature,
'x-hive-tracing': 'ignore',
},
}),
storage.isReady(),
Expand Down
2 changes: 1 addition & 1 deletion packages/services/server/src/public-graphql-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export const createPublicGraphQLHandler = (
}
: false,
}),
args.tracing ? useHiveTracing(args.tracing.traceProvider()) : {},
args.tracing ? useHiveTracing() : {},
useExecutionCancellation(),
],
graphqlEndpoint: '/graphql-public',
Expand Down
19 changes: 10 additions & 9 deletions packages/services/service-common/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,17 @@
},
"devDependencies": {
"@fastify/cors": "9.0.1",
"@graphql-hive/plugin-opentelemetry": "^1.2.5",
"@opentelemetry/api": "1.9.0",
"@opentelemetry/auto-instrumentations-node": "0.64.1",
"@opentelemetry/context-async-hooks": "1.30.0",
"@opentelemetry/exporter-trace-otlp-http": "0.57.0",
"@opentelemetry/instrumentation": "0.57.0",
"@opentelemetry/resources": "1.30.0",
"@opentelemetry/sdk-node": "0.57.0",
"@opentelemetry/sdk-trace-base": "1.30.0",
"@opentelemetry/sdk-trace-node": "1.30.0",
"@opentelemetry/semantic-conventions": "1.28.0",
"@opentelemetry/auto-instrumentations-node": "0.67.2",
"@opentelemetry/context-async-hooks": "2.2.0",
"@opentelemetry/exporter-trace-otlp-http": "0.208.0",
"@opentelemetry/instrumentation": "0.208.0",
"@opentelemetry/resources": "2.2.0",
"@opentelemetry/sdk-node": "0.208.0",
"@opentelemetry/sdk-trace-base": "2.2.0",
"@opentelemetry/sdk-trace-node": "2.2.0",
"@opentelemetry/semantic-conventions": "1.38.0",
"@sentry/node": "7.120.2",
"@sentry/types": "7.120.2",
"@sentry/utils": "7.120.2",
Expand Down
Loading
Loading