@@ -13,6 +13,7 @@ v2 includes several breaking changes and improvements over v1. The most signific
13
13
- [ Remove Mocking Plugin from built-ins] ( #remove-mocking-plugin-from-built-ins )
14
14
- [ Disabled Automatic Forking] ( #disabled-automatic-forking )
15
15
- [ New Hive Logger for next-level observability and debugging] ( #hive-logger )
16
+ - [ New OpenTelemetry integration for better traces and custom spans] ( #opentelemetry )
16
17
17
18
## Drop Support for Node v18
18
19
@@ -538,3 +539,281 @@ export const gatewayConfig = defineConfig({
538
539
+ })
539
540
})
540
541
```
542
+
543
+ ## Opentelemetry
544
+
545
+ OpenTelemetry integration have been re-worked to offer better traces, custom attributes and spans,
546
+ and overall compatiblity with standard OTEL API.
547
+
548
+ For this features to be possible, we had to break the configuration API.
549
+
550
+ You can read more about the new capabilities of the OpenTelemetry Tracing integration in the
551
+ [ Hive Monitoring / Tracing documentation] ( /docs/gateway/monitoring-tracing )
552
+
553
+ ### OpenTelemetry SDK Setup
554
+
555
+ The OpenTelemetry SDK setup used to be automatically done by the plugin it self, it is no longer the
556
+ case. You have the choice to either setup it yourself using official ` @opentelemetry/* ` pacakges
557
+ (like official Node SDK ` @opentelemetry/sdk-node ` ), or to use our cross-plateform setup helper
558
+ (recommended).
559
+
560
+ Extracting OTEL setup out of the plugin allows to you to decide on the version of ` opentelemetry-js `
561
+ SDK you want to use.
562
+
563
+ Most of OTEL related settings have been moved to ` opentelemetrySetup ` options. Please refere to
564
+ [ OpenTelemetry Setup documentation] ( /docs/gateway/monitoring-tracing#opentelemetry-setup ) for more
565
+ informations.
566
+
567
+ #### Example with HTTP OTLP Exporter
568
+
569
+ <Tabs items = { [<div >Hive Gateway <code >opentelemetrySetup()</code > (recommended)</div >, <div >OpenTelemetry <code >NodeSDK</code ></div >]} >
570
+
571
+ <Tabs.Tab >
572
+
573
+ 1 . Install OpenTelemetry SDK
574
+
575
+ ``` sh npm2yarn
576
+ npm i @opentelemetry/api @opentelemetry/context-async-hooks @opentelemetry/exporter-trace-otlp-http
577
+ ```
578
+
579
+ 2 . Create a new ` telemetry.ts ` file which will contain your open telemetry setup
580
+
581
+ ``` ts filename="telemetry.ts"
582
+ import { opentelemetrySetup } from ' @graphql-hive/plugin-opentelemetry/setup'
583
+ import { AsyncLocalStorageContextManager } from ' @opentelemetry/context-async-hooks'
584
+ import { OTLPTraceExporter } from ' @opentelemetry/exporter-trace-otlp-http'
585
+
586
+ opentelemetrySetup ({
587
+ resource: {
588
+ serviceName: ' gateway'
589
+ },
590
+ contextManager: new AsyncLocalStorageContextManager (),
591
+ traces: {
592
+ exporter: new OTLPTraceExporter ({ url: ' http://<otlp-endpoint>:4318' }),
593
+ batching: {
594
+ // ... batching options
595
+ }
596
+ }
597
+ })
598
+ ```
599
+
600
+ 3 . Update ` gateway.config.ts ` to import your ` telemetry.ts ` file (very first import), and adapt the
601
+ plugin configuration
602
+
603
+ <Tabs items = { [" CLI" , " Programatic Usage" ]} >
604
+
605
+ <Tabs.Tab >
606
+
607
+ ``` diff filname="config.gateway.ts"
608
+ + import './telemetry.ts'
609
+ - import { createOtlpHttpExporter, defineConfig } from '@graphql-hive/gateway'
610
+ + import { defineConfig } from '@graphql-hive/gateway'
611
+
612
+ export const gatewayConfig = defineConfig({
613
+ openTelemetry: {
614
+ - serviceName: 'gateway',
615
+ - exporters: [
616
+ - createOtlpHttpExporter({
617
+ - url: 'http://<otlp-endpoint>:4318'
618
+ - }, {
619
+ - //... batching options
620
+ - })
621
+ - ]
622
+ + traces: true,
623
+ }
624
+ })
625
+ ```
626
+
627
+ </Tabs.Tab >
628
+
629
+ <Tabs.Tab >
630
+
631
+ ``` diff filname="config.gateway.ts"
632
+ + import './telemetry.ts'
633
+ import { createGatewayRuntime } from '@graphql-hive/gateway-runtime'
634
+ - import { useOpenTelemetry, createOtlHttpExporter } from '@graphql-mesh/plugin-opentelemetry'
635
+ + import { useOpenTelemetry } from '@graphql-mesh/plugin-opentelemetry'
636
+
637
+ export const gateway = createGatewayRuntime({
638
+ plugins: ctx => [
639
+ useOpenTelemetry({
640
+ ...ctx,
641
+ - serviceName: 'gateway',
642
+ - exporters: [
643
+ - createOtlpHttpExporter({
644
+ - url: 'http://<otlp-endpoint>:4318'
645
+ - }, {
646
+ - //... batching options
647
+ - })
648
+ - ]
649
+ + traces: true,
650
+ })
651
+ ]
652
+ })
653
+ ```
654
+
655
+ </Tabs.Tab >
656
+
657
+ </Tabs >
658
+
659
+ </Tabs.Tab >
660
+
661
+ <Tabs.Tab >
662
+
663
+ 1 . Install OpenTelemetry SDK
664
+
665
+ ``` sh npm2yarn
666
+ npm i @opentelemetry/sdk-node @opentelemetry/exporter-trace-otlp-http
667
+ ```
668
+
669
+ 2 . Create a new ` telemetry.ts ` file which will contain your open telemetry setup
670
+
671
+ ``` ts filename="telemetry.ts"
672
+ import { OTLPTraceExporter } from ' @opentelemetry/exporter-trace-otlp-http'
673
+ import { NodeSDK , tracing } from ' @opentelemetry/sdk-node'
674
+
675
+ new NodeSDK ({
676
+ traceExporter: new OTLPTraceExporter ({ url: ' http://<otlp-endpoint>:4318' }),
677
+ // or with batching options
678
+ spanProcessors: [new tracing .BatchSpanProcessor (
679
+ new OTLPTraceExporter ({ url: ' http://<otlp-endpoint>:4318' }),
680
+ {
681
+ // ... batching options
682
+ }
683
+ )]
684
+ }).start ()
685
+ ```
686
+
687
+ 3 . Update ` gateway.config.ts ` to import your ` telemetry.ts ` file (very first import), and adapt the
688
+ plugin configuration
689
+
690
+ <Tabs items = { [" CLI" , " Programatic Usage" ]} >
691
+
692
+ <Tabs.Tab >
693
+
694
+ ``` diff filname="config.gateway.ts"
695
+ + import './telemetry.ts'
696
+ - import { createOtlpHttpExporter, defineConfig } from '@graphql-hive/gateway'
697
+ + import { defineConfig } from '@graphql-hive/gateway'
698
+
699
+ export const gatewayConfig = defineConfig({
700
+ openTelemetry: {
701
+ - serviceName: 'gateway',
702
+ - exporters: [
703
+ - createOtlpHttpExporter({
704
+ - url: 'http://<otlp-endpoint>:4318'
705
+ - }, {
706
+ - //... batching options
707
+ - })
708
+ - ]
709
+ + traces: true,
710
+ }
711
+ })
712
+ ```
713
+
714
+ </Tabs.Tab >
715
+
716
+ <Tabs.Tab >
717
+
718
+ ``` diff filname="config.gateway.ts"
719
+ + import './telemetry.ts'
720
+ import { createGatewayRuntime } from '@graphql-hive/gateway-runtime'
721
+ - import { useOpenTelemetry, createOtlHttpExporter } from '@graphql-mesh/plugin-opentelemetry'
722
+ + import { useOpenTelemetry } from '@graphql-mesh/plugin-opentelemetry'
723
+
724
+ export const gateway = createGatewayRuntime({
725
+ plugins: ctx => [
726
+ useOpenTelemetry({
727
+ ...ctx,
728
+ - serviceName: 'gateway',
729
+ - exporters: [
730
+ - createOtlpHttpExporter({
731
+ - url: 'http://<otlp-endpoint>:4318'
732
+ - }, {
733
+ - //... batching options
734
+ - })
735
+ - ]
736
+ + traces: true,
737
+ })
738
+ ]
739
+ })
740
+ ```
741
+
742
+ </Tabs.Tab >
743
+
744
+ </Tabs >
745
+
746
+ </Tabs.Tab >
747
+
748
+ </Tabs >
749
+
750
+ ### Tracing related configuration
751
+
752
+ All tracing related options has been moved to a ` traces ` option.
753
+
754
+ ``` diff filename="gateway.config"
755
+ import { denfineConfig } from '@grahpl-hive/gateway'
756
+
757
+ export const gatewayConfig = defineConfig({
758
+ openTelemetry: {
759
+ + traces: {
760
+ tracer: ...,
761
+ spans: {
762
+ ...
763
+ }
764
+ + }
765
+ }
766
+ })
767
+ ```
768
+
769
+ ### Spans filter functions payload
770
+
771
+ The payload given as a parameter of the span filtering functions have been restrained.
772
+
773
+ Due to internal changes, the informations available at span filtering time have been reduced to only
774
+ include (depending on the span) the GraphQL ` context ` , the HTTP ` request ` and the Upsream
775
+ ` executionRequest ` .
776
+
777
+ Please refere to [ Request Spans documentation] ( /docs/gateway/monitoring-tracing#request-spans ) for
778
+ details of what is availbe for each span filter.
779
+
780
+ ### Span parenting
781
+
782
+ Spans are now parented correctly. This can have impact on trace queries used in your dashboard.
783
+
784
+ Please review your queries to not filter against ` null ` parent span id.
785
+
786
+ ### New Graphql Operation Span
787
+
788
+ A new span encapsulating each GraphQL operation have been added.
789
+
790
+ It is a subspan of the HTTP request span, and encapsulate all the actual GraphQL processing.
791
+ There can be multiple GraphQL operation spans for one HTTP request span if you have enabled graphql operation batching over http.
792
+
793
+ ### OpenTelemetry Context
794
+
795
+ The OpenTelemetry Context is now modified by Hive Gateway. The Context is set with the current phase
796
+ span. This means that if you were creating custom spans in your plugin without explicitly providing
797
+ a parent context, your spans will be considered sub-spans of Hive Gateway's current span.
798
+
799
+ To maintain your span as a root span, add an explicit parent context a creation time:
800
+
801
+ ``` diff
802
+ import {
803
+ trace,
804
+ + ROOT_CONTEXT
805
+ } from '@opentelemetry/api'
806
+
807
+ export const myPlugin = () => ({
808
+ onExecute() {
809
+ trace.startActiveSpan(
810
+ 'my-custom-span',
811
+ { foo: 'bar' },
812
+ + ROOT_CONTEXT
813
+ () => {
814
+ // do something
815
+ }
816
+ )
817
+ }
818
+ })
819
+ ```
0 commit comments