Skip to content
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

Update GraphQL docs for Java SDK #7647

Merged
merged 30 commits into from
Aug 18, 2023
Merged
Changes from 5 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
cf64bc6
Document SAGP auto install for backend
adinauer Aug 9, 2023
74e7a41
Update GraphQL docs for Java SDK
adinauer Aug 16, 2023
2b175c7
more details on why to upgrade
adinauer Aug 16, 2023
36c155e
Merge branch 'master' into feat/java-graphql
adinauer Aug 16, 2023
eba40ab
mention filtering
adinauer Aug 16, 2023
ae8e42b
Apply suggestions from code review
adinauer Aug 18, 2023
e6b2eff
Apply suggestions from code review
adinauer Aug 18, 2023
3d27d77
style(lint): Auto commit lint changes
getsantry[bot] Aug 18, 2023
80d2b74
style(lint): Auto commit lint changes
getsantry[bot] Aug 18, 2023
1959e98
Add source maps upload instructions for CRA (#7628)
lforst Aug 16, 2023
5352f77
feat(sdk): Upgrade `@sentry/gatsby` to v7.64.0-alpha.0 (#7644)
billyvg Aug 16, 2023
e6ecbe3
Add Banner for Upcoming Crons Webinar (#7632)
elijames-codecov Aug 16, 2023
d5ada5e
adding responses section explaining timeout (#7653)
chloeho7 Aug 16, 2023
ac30cb0
Update flame-charts-graphs.mdx (#7656)
ishkebab Aug 16, 2023
0ec40d3
Update profile-details.mdx (#7658)
ishkebab Aug 16, 2023
5f5954e
Update index.mdx (#7659)
ishkebab Aug 16, 2023
44148d5
Add resolve by PR on Associate Commits page
isabellaenriquez Aug 16, 2023
046f63e
fix(releases): Add note about repo name when associating commits (#7646)
lobsterkatie Aug 16, 2023
0b14140
add stale label (#7661)
hubertdeng123 Aug 17, 2023
640de8c
Sync with product-owners.yml in security-as-code@6137c6e6 (#7655)
getsantry[bot] Aug 17, 2023
59e3062
Add sourcemaps wizard to angular source map guide (#7663)
lforst Aug 17, 2023
a1f5912
feat(inbound-filters): Add health check explanation (#7649)
priscilawebdev Aug 17, 2023
6948361
Add Discord integration docs (#7645)
spalmurray Aug 17, 2023
a8ad69c
Document new issue details event dropdown and the recommended event (…
malwilley Aug 17, 2023
c2a3c54
Add browser profiling to profiling getting started (#7665)
AbhiPrasad Aug 17, 2023
4acd04f
reword set up
adinauer Aug 18, 2023
95b2f9b
style(lint): Auto commit lint changes
getsantry[bot] Aug 18, 2023
5c63084
dummy commit to get github ui to refresh
adinauer Aug 18, 2023
41df7ee
revert
adinauer Aug 18, 2023
0db0edb
Merge branch 'master' into feat/java-graphql
adinauer Aug 18, 2023
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
107 changes: 55 additions & 52 deletions src/platforms/java/common/configuration/integrations/graphql.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,109 +10,111 @@ notSupported:

Sentry GraphQL integration provides an integration with [GraphQL Java](https://github.com/graphql-java/graphql-java/) through:
adinauer marked this conversation as resolved.
Show resolved Hide resolved

- `SentryDataFetcherExceptionHandler` which captures exceptions thrown during data fetcher executions.
- `SentryInstrumentation` which creates spans around each data fetcher execution.
- `SentryGenericDataFetcherExceptionHandler` which checks for exceptions thrown during data fetcher executions and passes them to `SentryInstrumentation`.
- `SentryInstrumentation` which creates spans around each data fetcher execution, captures exceptions and adds breadcrumbs.

If you're using `spring-graphql`, we offer automatic configuration of our GraphQL integration when using our `sentry-spring-boot-starter` or `sentry-spring-boot-jakarta-starter` integrations.
adinauer marked this conversation as resolved.
Show resolved Hide resolved

## Install

```groovy {tabTitle:Gradle Plugin}
adinauer marked this conversation as resolved.
Show resolved Hide resolved
plugins {
id "io.sentry.jvm.gradle" version "{{@inject packages.version('sentry.java.android.gradle-plugin', '3.12.0') }}"
}
```

```groovy {tabTitle:Gradle}
implementation 'io.sentry:sentry-graphql:{{@inject packages.version('sentry.java.graphql', '6.28.0') }}'
```

```xml {tabTitle:Maven}
<dependency>
<groupId>io.sentry</groupId>
<artifactId>sentry-graphql</artifactId>
<version>{{@inject packages.version('sentry.java.graphql', '5.4.0') }}</version>
<version>{{@inject packages.version('sentry.java.graphql', '6.28.0') }}</version>
</dependency>
```

```groovy {tabTitle:Gradle}
implementation 'io.sentry:sentry-graphql:{{@inject packages.version('sentry.java.graphql', '5.4.0') }}'
```

```scala {tabTitle: SBT}
libraryDependencies += "io.sentry" % "sentry-graphql" % "{{@inject packages.version('sentry.java.graphql', '5.4.0') }}"
libraryDependencies += "io.sentry" % "sentry-graphql" % "{{@inject packages.version('sentry.java.graphql', '6.28.0') }}"
```

For other dependency managers, check out the [central Maven repository](https://search.maven.org/artifact/io.sentry/sentry-graphql).

## Capture Exceptions

`SentryDataFetcherExceptionHandler` captures the exception, sends it to Sentry, and calls the delegate responsible for handling the exception.
## Setup
adinauer marked this conversation as resolved.
Show resolved Hide resolved

Create a new instance of `SentryDataFetcherExceptionHandler`, pass the delegate that handles the exception, and configure `defaultDataFetcherExceptionHandler` when building a `GraphQL` instance:
Create a new instance of `SentryGenericDataFetcherExceptionHandler`, pass the delegate that handles the exception, and configure `defaultDataFetcherExceptionHandler` when building a `GraphQL` instance.
Create a new instance of `SentryInstrumentation` and configure `instrumentation` when building a `GraphQL` instance.
You may want to filter some of the errors by using `beforeSend` or an `EventProcessor` (see <PlatformLink to="/configuration/filtering/">Filters</PlatformLink>).
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
Create a new instance of `SentryGenericDataFetcherExceptionHandler`, pass the delegate that handles the exception, and configure `defaultDataFetcherExceptionHandler` when building a `GraphQL` instance.
Create a new instance of `SentryInstrumentation` and configure `instrumentation` when building a `GraphQL` instance.
You may want to filter some of the errors by using `beforeSend` or an `EventProcessor` (see <PlatformLink to="/configuration/filtering/">Filters</PlatformLink>).
- To integrate `GraphQL` through `SentryGenericDataFetcherExceptionHandler`, create a new instance, pass the delegate that handles the exception, then configure `defaultDataFetcherExceptionHandler`.
- To integrate `GraphQL` through `SentryInstrumentation`, create a new instance and configure `instrumentation`.
You may want to filter some of the errors by using `beforeSend` or an `EventProcessor` (read more about <PlatformLink to="/configuration/filtering/">Filters</PlatformLink>).

In case you're wondering about setup vs set up - Set up is the verb, so when you're telling someone to "Set up a new instance..." vs. setup, which is a noun, so "your setup process..." :)

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks :-)

Hmm this one I'm not sure about. You need to provide both SentryGenericDataFetcherExceptionHandler and SentryInstrumentation after the latest changes.


```java
import graphql.GraphQL;
import graphql.execution.SimpleDataFetcherExceptionHandler;
import io.sentry.graphql.SentryDataFetcherExceptionHandler;
import io.sentry.graphql.SentryGenericDataFetcherExceptionHandler;
import io.sentry.graphql.SentryInstrumentation;

SimpleDataFetcherExceptionHandler defaultExceptionHandler = new SimpleDataFetcherExceptionHandler();
SentryDataFetcherExceptionHandler sentryExceptionHandler = new SentryDataFetcherExceptionHandler(defaultExceptionHandler);
SentryGenericDataFetcherExceptionHandler sentryExceptionHandler = new SentryGenericDataFetcherExceptionHandler(defaultExceptionHandler);

GraphQL graphQL = GraphQL.newGraphQL(...)
// ...
.defaultDataFetcherExceptionHandler(sentryExceptionHandler)
.instrumentation(new SentryInstrumentation(
// If you're not using our Spring integration, please provide NoOpSubscriptionHandler.getInstance() instead.
new SentrySpringSubscriptionHandler(),
// Set this to false when using Spring WebMVC
true
))
.build();
```

```kotlin
import graphql.GraphQL
import graphql.execution.SimpleDataFetcherExceptionHandler
import io.sentry.graphql.SentryDataFetcherExceptionHandler
import io.sentry.graphql.SentryGenericDataFetcherExceptionHandler
import io.sentry.graphql.SentryInstrumentation

val defaultExceptionHandler = SimpleDataFetcherExceptionHandler()
val sentryExceptionHandler = SentryDataFetcherExceptionHandler(defaultExceptionHandler)
val sentryExceptionHandler = SentryGenericDataFetcherExceptionHandler(defaultExceptionHandler)

val graphql = GraphQL.newGraphQL()
.defaultDataFetcherExceptionHandler(sentryExceptionHandler)
.instrumentation(SentryInstrumentation(
// If you're not using our Spring integration, please provide NoOpSubscriptionHandler.getInstance() instead.
SentrySpringSubscriptionHandler(),
// Set this to false when using Spring WebMVC
true
))
.build()
```

## Capture Performance

<Note>

Capturing transactions requires that you first <PlatformLink to="/performance/">set up performance monitoring</PlatformLink> if you haven't already.
If you've been using the now deprecated `SentryDataFetcherExceptionHandler`, please upgrade to `SentryGenericDataFetcherExceptionHandler` and also make sure `SentryInstrumentation` is configured to have more exceptions captured, more detailed exceptions, breacrumbs and better hub propagation. You may want to filter some of the errors by using `beforeSend` or an `EventProcessor` (see <PlatformLink to="/configuration/filtering/">Filters</PlatformLink>).
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
If you've been using the now deprecated `SentryDataFetcherExceptionHandler`, please upgrade to `SentryGenericDataFetcherExceptionHandler` and also make sure `SentryInstrumentation` is configured to have more exceptions captured, more detailed exceptions, breacrumbs and better hub propagation. You may want to filter some of the errors by using `beforeSend` or an `EventProcessor` (see <PlatformLink to="/configuration/filtering/">Filters</PlatformLink>).
The `SentryDataFetcherExceptionHandler` has been deprecated. Please upgrade to `SentryGenericDataFetcherExceptionHandler` and make sure `SentryInstrumentation` is configured to have more exceptions captured, more detailed exceptions, breadcrumbs, and better hub propagation. You may want to filter the errors by using `beforeSend` or an `EventProcessor` (read more about <PlatformLink to="/configuration/filtering/">Filters</PlatformLink>).

This seems like a daunting list of thing to "make sure of..." do you think it's clear to users why they need to do this and how to do it? If not, maybe we can write a separate section about it?

Copy link
Member Author

Choose a reason for hiding this comment

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

It's just meant as a side note for people who already used our GraphQL integration before the latest changes. This should put them on the right track to upgrade plus some reasons why in case they missed the changelog entry.


</Note>

### Configure

Create a new instance of `SentryInstrumentation` and configure `instrumentation` when building a `GraphQL` instance:

```java
import graphql.GraphQL;
import io.sentry.graphql.SentryInstrumentation;

GraphQL graphQL = GraphQL.newGraphQL(...)
// ...
.instrumentation(new SentryInstrumentation())
.build();
```

```kotlin
import graphql.GraphQL
import io.sentry.graphql.SentryInstrumentation
## Capture Performance

val graphql = GraphQL.newGraphQL()
.instrumentation(SentryInstrumentation())
.build()
```
Capturing transactions requires that you first <PlatformLink to="/performance/">set up performance monitoring</PlatformLink> if you haven't already.
adinauer marked this conversation as resolved.
Show resolved Hide resolved

### Modify or Drop Spans

Spans created around requests can be modified or dropped using `SentryInstrumentation.BeforeSpanCallback` passed to `SentryInstrumentation`:
Spans created around requests can be modified (by returning a modified Span) or dropped (by returning `null`) using `SentryInstrumentation.BeforeSpanCallback` passed to `SentryInstrumentation`:
adinauer marked this conversation as resolved.
Show resolved Hide resolved

```java
import io.sentry.graphql.SentryInstrumentation;

import graphql.GraphQL;

GraphQL graphQL = GraphQL.newGraphQL()
// ...
.instrumentation(new SentryInstrumentation((span, environment, result) -> {
if ("/shows".equals(environment.getExecutionStepInfo().getPath().segmentToString())) {
span.setTag("tag-name", "tag-value");
}
return span;
}))
}, new SentrySpringSubscriptionHandler(), true))
.build();
```

Expand All @@ -122,22 +124,23 @@ import io.sentry.graphql.SentryInstrumentation
import graphql.GraphQL

val graphql = GraphQL.newGraphQL()
.instrumentation(SentryInstrumentation() { span: ISpan, env: DataFetchingEnvironment, result: Any? ->
// ...
.instrumentation(SentryInstrumentation({ span: ISpan, env: DataFetchingEnvironment, result: Any? ->
if ("/shows" == env.executionStepInfo.path.segmentToString()) {
span.setTag("tag-name", "tag-value")
}
span
})
}, SentrySpringSubscriptionHandler(), true))
.build()
```

## Using with Netflix DGS
adinauer marked this conversation as resolved.
Show resolved Hide resolved

[Netflix DGS](https://netflix.github.io/dgs) automatically detects and configures `Instrumentation` and `DataFetcherExceptionHandler` beans. To use Sentry GraphQL integration, create `SentryDataFetcherExceptionHandler` and `SentryInstrumentation` beans:
[Netflix DGS](https://netflix.github.io/dgs) automatically detects and configures `Instrumentation` and `DataFetcherExceptionHandler` beans. To use Sentry GraphQL integration, create `SentryGenericDataFetcherExceptionHandler` and `SentryInstrumentation` beans:
adinauer marked this conversation as resolved.
Show resolved Hide resolved

```java
import com.netflix.graphql.dgs.exceptions.DefaultDataFetcherExceptionHandler;
import io.sentry.graphql.SentryDataFetcherExceptionHandler;
import io.sentry.graphql.SentryGenericDataFetcherExceptionHandler;
import io.sentry.graphql.SentryInstrumentation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
Expand All @@ -147,20 +150,20 @@ class SentryConfiguration {

@Bean
SentryInstrumentation sentryInstrumentation() {
return new SentryInstrumentation();
return new SentryInstrumentation(new SentryDgsSubscriptionHandler(), true);
}

@Bean
SentryDataFetcherExceptionHandler sentryDataFetcherExceptionHandler() {
SentryGenericDataFetcherExceptionHandler sentryDataFetcherExceptionHandler() {
// delegate to default Netflix DGS exception handler
return new SentryDataFetcherExceptionHandler(new DefaultDataFetcherExceptionHandler());
return new SentryGenericDataFetcherExceptionHandler(new DefaultDataFetcherExceptionHandler());
}
}
```

```kotlin
import com.netflix.graphql.dgs.exceptions.DefaultDataFetcherExceptionHandler
import io.sentry.graphql.SentryDataFetcherExceptionHandler
import io.sentry.graphql.SentryGenericDataFetcherExceptionHandler
import io.sentry.graphql.SentryInstrumentation
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
Expand All @@ -169,9 +172,9 @@ import org.springframework.context.annotation.Configuration
class SentryConfiguration {

@Bean
fun sentryInstrumentation() = SentryInstrumentation()
fun sentryInstrumentation() = SentryInstrumentation(SentryDgsSubscriptionHandler(), true)

@Bean
fun sentryDataFetcherExceptionHandler() = SentryDataFetcherExceptionHandler(DefaultDataFetcherExceptionHandler())
fun sentryDataFetcherExceptionHandler() = SentryGenericDataFetcherExceptionHandler(DefaultDataFetcherExceptionHandler())
}
```
Loading