-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
docs(dart): (NOT-TO-MERGE) add gRPC integration documentation #18576
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
lucas-zimerman
wants to merge
1
commit into
master
Choose a base branch
from
lz/doc/dart-grpc
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+196
−0
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| --- | ||
| title: gRPC Integration | ||
| description: "Learn more about the Sentry gRPC integration for the Dart SDK." | ||
| sidebar_order: 10 | ||
| redirect_from: | ||
| - /platforms/dart/guides/grpc/ | ||
| --- | ||
|
|
||
| <Include name="dart-integrations/grpc.mdx" /> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| --- | ||
| title: gRPC Integration | ||
| description: "Learn more about the Sentry gRPC integration for the Flutter SDK." | ||
| sidebar_order: 40 | ||
| redirect_from: | ||
| - /platforms/dart/guides/flutter/grpc/ | ||
| --- | ||
|
|
||
| <Include name="dart-integrations/grpc.mdx" /> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,178 @@ | ||
| --- | ||
| title: gRPC Integration | ||
| description: "Learn more about the Sentry gRPC integration for the Dart SDK." | ||
| platforms: | ||
| - dart | ||
| - flutter | ||
| sidebar_order: 4 | ||
| --- | ||
|
|
||
| The `sentry_grpc` package provides [gRPC](https://pub.dev/packages/grpc) support for Sentry. It instruments outgoing unary calls with spans, records breadcrumbs, injects distributed tracing headers into gRPC metadata, and can capture failed calls as Sentry errors. | ||
|
|
||
| ## Requirements | ||
|
|
||
| - `grpc` 4.0.4 or higher | ||
| - `sentry_grpc` X or higher | ||
|
|
||
| ## Install | ||
|
|
||
| Add `sentry_grpc` to your dependencies: | ||
|
|
||
| ```yml {filename:pubspec.yaml} | ||
| dependencies: | ||
| sentry: ^{{@inject packages.version('sentry.dart', '9.22.0') }} | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe we should add a short comment sentry: xyz # or sentry_fluttersomething like that, since if you use flutter you should use |
||
| sentry_grpc: ^{{@inject packages.version('sentry.dart.grpc', '9.22.0') }} | ||
| grpc: '>=4.0.4 <6.0.0' | ||
| ``` | ||
| ## Configure | ||
| Add `SentryGrpcInterceptor` to your gRPC client's interceptor list. This should happen once, when the client is created. | ||
|
|
||
| ```dart | ||
| import 'package:grpc/grpc.dart'; | ||
| import 'package:sentry/sentry.dart'; | ||
| import 'package:sentry_grpc/sentry_grpc.dart'; | ||
| Future<void> main() async { | ||
| await Sentry.init( | ||
| (options) { | ||
| options.dsn = '___PUBLIC_DSN___'; | ||
| options.tracesSampleRate = 1.0; | ||
| }, | ||
| appRunner: runApp, | ||
| ); | ||
| } | ||
| Future<void> runApp() async { | ||
| final channel = ClientChannel( | ||
| 'api.example.com', | ||
| options: const ChannelOptions(credentials: ChannelCredentials.secure()), | ||
| ); | ||
| final client = MyServiceClient( | ||
| channel, | ||
| interceptors: [SentryGrpcInterceptor()], | ||
| ); | ||
| // All calls through this client are now automatically instrumented. | ||
| } | ||
| ``` | ||
|
|
||
| ## Capturing Failed Requests as Errors | ||
|
|
||
| When a gRPC call fails, either because the server returns a non-OK status code or because a transport error occurs, the interceptor can capture it as a Sentry error. | ||
|
|
||
| This feature is controlled by `captureFailedRequests`. By default, the interceptor respects the global `SentryOptions.captureFailedRequests` setting. You can override this per-interceptor: | ||
|
|
||
| ```dart | ||
| // Capture failed gRPC calls regardless of the global setting | ||
| final interceptor = SentryGrpcInterceptor(captureFailedRequests: true); | ||
| // Disable for this client only | ||
| final interceptor = SentryGrpcInterceptor(captureFailedRequests: false); | ||
| ``` | ||
|
|
||
| When a failed call is captured, Sentry attaches the gRPC method path, status code, status name, and error message as context on the event. | ||
|
|
||
| ## Breadcrumbs | ||
|
|
||
| The interceptor automatically records a breadcrumb for every unary call. Successful calls are recorded at the `info` level; failed calls at the `error` level. Each breadcrumb includes the method path, gRPC status code and name, and call duration in milliseconds. | ||
|
|
||
| To disable breadcrumbs: | ||
|
|
||
| ```dart | ||
| final interceptor = SentryGrpcInterceptor(enableBreadcrumbs: false); | ||
| ``` | ||
|
|
||
| ## Tracing for gRPC Calls | ||
|
|
||
| ### Instrumentation Behaviour | ||
|
|
||
| For each unary call, the interceptor: | ||
|
|
||
| - Creates a child span under the active transaction with operation `grpc.client` and a description set to the full method path (for example, `/helloworld.Greeter/SayHello`). | ||
| - Sets span data following OpenTelemetry gRPC semantic conventions: | ||
| - `rpc.system` = `grpc` | ||
| - `rpc.service` = the service portion of the method path (for example, `helloworld.Greeter`) | ||
| - `rpc.method` = the method name (for example, `SayHello`) | ||
| - `rpc.response.status_code` = the gRPC status name (for example, `OK`, `NOT_FOUND`) | ||
| - Injects `sentry-trace` and `baggage` headers into the call's gRPC metadata for distributed tracing. | ||
| - Finishes the span and sets its status when the call completes. | ||
| - Associates any thrown exception with the span. | ||
|
|
||
| <Alert> | ||
| Spans are only created when there is an active transaction on the scope. If no transaction is active, the interceptor still injects trace headers and records breadcrumbs. | ||
| </Alert> | ||
|
|
||
| <Alert> | ||
| Server-streaming and client-streaming calls receive distributed tracing header injection only. Full span lifecycle tracking for streaming RPCs will be added in a future release. | ||
| </Alert> | ||
|
|
||
| ### Controlling Trace Header Propagation | ||
|
|
||
| By default, `sentry-trace` and `baggage` headers are injected for all gRPC method paths. Use `tracePropagationTargets` to restrict injection to specific services or methods. Targets are matched against the full method path (for example, `/helloworld.Greeter/SayHello`): | ||
|
|
||
| ```dart | ||
| await Sentry.init((options) { | ||
| options.dsn = '___PUBLIC_DSN___'; | ||
| options.tracePropagationTargets = [ | ||
| 'myservice.MyService', // Matches any method under this service | ||
| ]; | ||
| }); | ||
| ``` | ||
|
|
||
| ### Sending Request Metadata (PII) | ||
|
|
||
| When `sendDefaultPii` is enabled, the interceptor attaches the gRPC call's metadata headers to the span as `rpc.request.metadata.<key>` attributes. This is opt-in because metadata can contain sensitive values such as authorization tokens. | ||
|
|
||
| ```dart | ||
| await Sentry.init((options) { | ||
| options.dsn = '___PUBLIC_DSN___'; | ||
| options.sendDefaultPii = true; // Metadata headers will appear in span data | ||
| }); | ||
| ``` | ||
|
|
||
| ### Prerequisites | ||
|
|
||
| Before enabling tracing: | ||
|
|
||
| 1. Initialize the Sentry SDK. Learn more [here](/platforms/dart/guides/flutter/#configure). | ||
| 2. Set up tracing. Learn more [here](/platforms/dart/guides/flutter/tracing/). | ||
|
|
||
| ### Verify | ||
|
|
||
| ```dart | ||
| import 'package:grpc/grpc.dart'; | ||
| import 'package:sentry/sentry.dart'; | ||
| import 'package:sentry_grpc/sentry_grpc.dart'; | ||
| Future<void> makeGrpcRequest() async { | ||
| final channel = ClientChannel('api.example.com'); | ||
| final client = GreeterClient( | ||
| channel, | ||
| interceptors: [SentryGrpcInterceptor()], | ||
| ); | ||
| // Start a transaction so the interceptor has a parent span to attach to. | ||
| final transaction = Sentry.startTransaction( | ||
| 'grpc-example', | ||
| 'grpc.client', | ||
| bindToScope: true, | ||
| ); | ||
| try { | ||
| final response = await client.sayHello(HelloRequest(name: 'Sentry')); | ||
| transaction.status = const SpanStatus.ok(); | ||
| print(response.message); | ||
| } catch (exception, stackTrace) { | ||
| transaction.throwable = exception; | ||
| transaction.status = const SpanStatus.internalError(); | ||
| await Sentry.captureException(exception, stackTrace: stackTrace); | ||
| } finally { | ||
| await transaction.finish(); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| To view the recorded transaction, log into [sentry.io](https://sentry.io) and open your project. Clicking **Performance** will open a page with transactions, where you can select the transaction with the name `grpc-example` and see the `grpc.client` child span for the `/helloworld.Greeter/SayHello` call. | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: The documentation for the
sentry_grpcpackage uses a literal 'X' as a version placeholder instead of the correct version injection syntax.Severity: LOW
Suggested Fix
Replace the literal 'X' on line 15 with the correct version injection syntax, likely
{{@inject packages.version(sentry_grpc)}}, to ensure the correct package version is always displayed in the documentation.Prompt for AI Agent
Did we get this right? 👍 / 👎 to inform future reviews.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
correct, it was intentional, the correct version will be resolved once the first gRPC integration is released