@@ -9,6 +9,7 @@ instructions to ensure a smooth transition.
9
9
v2 includes several breaking changes and improvements over v1. The most significant changes are:
10
10
11
11
- [ New Hive Logger for next-level observability and debugging] ( #hive-logger )
12
+ - [ New OpenTelemetry integration for better traces and custom spans] ( #opentelemetry )
12
13
13
14
## Hive Logger
14
15
@@ -428,3 +429,281 @@ export const gatewayConfig = defineConfig({
428
429
+ })
429
430
})
430
431
```
432
+
433
+ ## Opentelemetry
434
+
435
+ OpenTelemetry integration have been re-worked to offer better traces, custom attributes and spans,
436
+ and overall compatiblity with standard OTEL API.
437
+
438
+ For this features to be possible, we had to break the configuration API.
439
+
440
+ You can read more about the new capabilities of the OpenTelemetry Tracing integration in the
441
+ [ Hive Monitoring / Tracing documentation] ( /docs/gateway/monitoring-tracing )
442
+
443
+ ### OpenTelemetry SDK Setup
444
+
445
+ The OpenTelemetry SDK setup used to be automatically done by the plugin it self, it is no longer the
446
+ case. You have the choice to either setup it yourself using official ` @opentelemetry/* ` pacakges
447
+ (like official Node SDK ` @opentelemetry/sdk-node ` ), or to use our cross-plateform setup helper
448
+ (recommended).
449
+
450
+ Extracting OTEL setup out of the plugin allows to you to decide on the version of ` opentelemetry-js `
451
+ SDK you want to use.
452
+
453
+ Most of OTEL related settings have been moved to ` opentelemetrySetup ` options. Please refere to
454
+ [ OpenTelemetry Setup documentation] ( /docs/gateway/monitoring-tracing#opentelemetry-setup ) for more
455
+ informations.
456
+
457
+ #### Example with HTTP OTLP Exporter
458
+
459
+ <Tabs items = { [<div >Hive Gateway <code >opentelemetrySetup()</code > (recommended)</div >, <div >OpenTelemetry <code >NodeSDK</code ></div >]} >
460
+
461
+ <Tabs.Tab >
462
+
463
+ 1 . Install OpenTelemetry SDK
464
+
465
+ ``` sh npm2yarn
466
+ npm i @opentelemetry/api @opentelemetry/context-async-hooks @opentelemetry/exporter-trace-otlp-http
467
+ ```
468
+
469
+ 2 . Create a new ` telemetry.ts ` file which will contain your open telemetry setup
470
+
471
+ ``` ts filename="telemetry.ts"
472
+ import { opentelemetrySetup } from ' @graphql-hive/plugin-opentelemetry/setup'
473
+ import { AsyncLocalStorageContextManager } from ' @opentelemetry/context-async-hooks'
474
+ import { OTLPTraceExporter } from ' @opentelemetry/exporter-trace-otlp-http'
475
+
476
+ opentelemetrySetup ({
477
+ resource: {
478
+ serviceName: ' gateway'
479
+ },
480
+ contextManager: new AsyncLocalStorageContextManager (),
481
+ traces: {
482
+ exporter: new OTLPTraceExporter ({ url: ' http://<otlp-endpoint>:4318' }),
483
+ batching: {
484
+ // ... batching options
485
+ }
486
+ }
487
+ })
488
+ ```
489
+
490
+ 3 . Update ` gateway.config.ts ` to import your ` telemetry.ts ` file (very first import), and adapt the
491
+ plugin configuration
492
+
493
+ <Tabs items = { [" CLI" , " Programatic Usage" ]} >
494
+
495
+ <Tabs.Tab >
496
+
497
+ ``` diff filname="config.gateway.ts"
498
+ + import './telemetry.ts'
499
+ - import { createOtlpHttpExporter, defineConfig } from '@graphql-hive/gateway'
500
+ + import { defineConfig } from '@graphql-hive/gateway'
501
+
502
+ export const gatewayConfig = defineConfig({
503
+ openTelemetry: {
504
+ - serviceName: 'gateway',
505
+ - exporters: [
506
+ - createOtlpHttpExporter({
507
+ - url: 'http://<otlp-endpoint>:4318'
508
+ - }, {
509
+ - //... batching options
510
+ - })
511
+ - ]
512
+ + traces: true,
513
+ }
514
+ })
515
+ ```
516
+
517
+ </Tabs.Tab >
518
+
519
+ <Tabs.Tab >
520
+
521
+ ``` diff filname="config.gateway.ts"
522
+ + import './telemetry.ts'
523
+ import { createGatewayRuntime } from '@graphql-hive/gateway-runtime'
524
+ - import { useOpenTelemetry, createOtlHttpExporter } from '@graphql-mesh/plugin-opentelemetry'
525
+ + import { useOpenTelemetry } from '@graphql-mesh/plugin-opentelemetry'
526
+
527
+ export const gateway = createGatewayRuntime({
528
+ plugins: ctx => [
529
+ useOpenTelemetry({
530
+ ...ctx,
531
+ - serviceName: 'gateway',
532
+ - exporters: [
533
+ - createOtlpHttpExporter({
534
+ - url: 'http://<otlp-endpoint>:4318'
535
+ - }, {
536
+ - //... batching options
537
+ - })
538
+ - ]
539
+ + traces: true,
540
+ })
541
+ ]
542
+ })
543
+ ```
544
+
545
+ </Tabs.Tab >
546
+
547
+ </Tabs >
548
+
549
+ </Tabs.Tab >
550
+
551
+ <Tabs.Tab >
552
+
553
+ 1 . Install OpenTelemetry SDK
554
+
555
+ ``` sh npm2yarn
556
+ npm i @opentelemetry/sdk-node @opentelemetry/exporter-trace-otlp-http
557
+ ```
558
+
559
+ 2 . Create a new ` telemetry.ts ` file which will contain your open telemetry setup
560
+
561
+ ``` ts filename="telemetry.ts"
562
+ import { OTLPTraceExporter } from ' @opentelemetry/exporter-trace-otlp-http'
563
+ import { NodeSDK , tracing } from ' @opentelemetry/sdk-node'
564
+
565
+ new NodeSDK ({
566
+ traceExporter: new OTLPTraceExporter ({ url: ' http://<otlp-endpoint>:4318' }),
567
+ // or with batching options
568
+ spanProcessors: [new tracing .BatchSpanProcessor (
569
+ new OTLPTraceExporter ({ url: ' http://<otlp-endpoint>:4318' }),
570
+ {
571
+ // ... batching options
572
+ }
573
+ )]
574
+ }).start ()
575
+ ```
576
+
577
+ 3 . Update ` gateway.config.ts ` to import your ` telemetry.ts ` file (very first import), and adapt the
578
+ plugin configuration
579
+
580
+ <Tabs items = { [" CLI" , " Programatic Usage" ]} >
581
+
582
+ <Tabs.Tab >
583
+
584
+ ``` diff filname="config.gateway.ts"
585
+ + import './telemetry.ts'
586
+ - import { createOtlpHttpExporter, defineConfig } from '@graphql-hive/gateway'
587
+ + import { defineConfig } from '@graphql-hive/gateway'
588
+
589
+ export const gatewayConfig = defineConfig({
590
+ openTelemetry: {
591
+ - serviceName: 'gateway',
592
+ - exporters: [
593
+ - createOtlpHttpExporter({
594
+ - url: 'http://<otlp-endpoint>:4318'
595
+ - }, {
596
+ - //... batching options
597
+ - })
598
+ - ]
599
+ + traces: true,
600
+ }
601
+ })
602
+ ```
603
+
604
+ </Tabs.Tab >
605
+
606
+ <Tabs.Tab >
607
+
608
+ ``` diff filname="config.gateway.ts"
609
+ + import './telemetry.ts'
610
+ import { createGatewayRuntime } from '@graphql-hive/gateway-runtime'
611
+ - import { useOpenTelemetry, createOtlHttpExporter } from '@graphql-mesh/plugin-opentelemetry'
612
+ + import { useOpenTelemetry } from '@graphql-mesh/plugin-opentelemetry'
613
+
614
+ export const gateway = createGatewayRuntime({
615
+ plugins: ctx => [
616
+ useOpenTelemetry({
617
+ ...ctx,
618
+ - serviceName: 'gateway',
619
+ - exporters: [
620
+ - createOtlpHttpExporter({
621
+ - url: 'http://<otlp-endpoint>:4318'
622
+ - }, {
623
+ - //... batching options
624
+ - })
625
+ - ]
626
+ + traces: true,
627
+ })
628
+ ]
629
+ })
630
+ ```
631
+
632
+ </Tabs.Tab >
633
+
634
+ </Tabs >
635
+
636
+ </Tabs.Tab >
637
+
638
+ </Tabs >
639
+
640
+ ### Tracing related configuration
641
+
642
+ All tracing related options has been moved to a ` traces ` option.
643
+
644
+ ``` diff filename="gateway.config"
645
+ import { denfineConfig } from '@grahpl-hive/gateway'
646
+
647
+ export const gatewayConfig = defineConfig({
648
+ openTelemetry: {
649
+ + traces: {
650
+ tracer: ...,
651
+ spans: {
652
+ ...
653
+ }
654
+ + }
655
+ }
656
+ })
657
+ ```
658
+
659
+ ### Spans filter functions payload
660
+
661
+ The payload given as a parameter of the span filtering functions have been restrained.
662
+
663
+ Due to internal changes, the informations available at span filtering time have been reduced to only
664
+ include (depending on the span) the GraphQL ` context ` , the HTTP ` request ` and the Upsream
665
+ ` executionRequest ` .
666
+
667
+ Please refere to [ Request Spans documentation] ( /docs/gateway/monitoring-tracing#request-spans ) for
668
+ details of what is availbe for each span filter.
669
+
670
+ ### Span parenting
671
+
672
+ Spans are now parented correctly. This can have impact on trace queries used in your dashboard.
673
+
674
+ Please review your queries to not filter against ` null ` parent span id.
675
+
676
+ ### New Graphql Operation Span
677
+
678
+ A new span encapsulating each GraphQL operation have been added.
679
+
680
+ It is a subspan of the HTTP request span, and encapsulate all the actual GraphQL processing.
681
+ There can be multiple GraphQL operation spans for one HTTP request span if you have enabled graphql operation batching over http.
682
+
683
+ ### OpenTelemetry Context
684
+
685
+ The OpenTelemetry Context is now modified by Hive Gateway. The Context is set with the current phase
686
+ span. This means that if you were creating custom spans in your plugin without explicitly providing
687
+ a parent context, your spans will be considered sub-spans of Hive Gateway's current span.
688
+
689
+ To maintain your span as a root span, add an explicit parent context a creation time:
690
+
691
+ ``` diff
692
+ import {
693
+ trace,
694
+ + ROOT_CONTEXT
695
+ } from '@opentelemetry/api'
696
+
697
+ export const myPlugin = () => ({
698
+ onExecute() {
699
+ trace.startActiveSpan(
700
+ 'my-custom-span',
701
+ { foo: 'bar' },
702
+ + ROOT_CONTEXT
703
+ () => {
704
+ // do something
705
+ }
706
+ )
707
+ }
708
+ })
709
+ ```
0 commit comments