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
8 changes: 5 additions & 3 deletions docs/graphql/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ linkTitle: GraphQL

**Status**: [Development][DocumentStatus]

This document defines semantic conventions for GraphQL.
This document defines semantic conventions for GraphQL spans, metrics, and events.

Semantic conventions are defined for the following signals:
Semantic conventions for GraphQL are defined for the following signals:

* [Spans](graphql-spans.md)
* [GraphQL Spans](graphql-spans.md): Semantic Conventions for GraphQL client and server *spans*.
* [GraphQL Metrics](graphql-metrics.md): Semantic Conventions for GraphQL client and server *metrics*.
* [GraphQL Events](graphql-events.md): Semantic Conventions for GraphQL error *events*.

[DocumentStatus]: https://opentelemetry.io/docs/specs/otel/document-status
112 changes: 112 additions & 0 deletions docs/graphql/graphql-events.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<!--- Hugo front matter used to generate the website version of this page:
linkTitle: Events
--->

# Semantic conventions for GraphQL events

**Status**: [Development][DocumentStatus]

This document defines semantic conventions for GraphQL error events.

<!-- toc -->

- [GraphQL error event](#graphql-error-event)

<!-- tocstop -->

## GraphQL error event

<!-- semconv event.graphql.error -->
<!-- NOTE: THIS TEXT IS AUTOGENERATED. DO NOT EDIT BY HAND. -->
<!-- see templates/registry/markdown/snippet.md.j2 -->
<!-- prettier-ignore-start -->

**Status:** ![Development](https://img.shields.io/badge/-development-blue)

The event name MUST be `graphql.error`.

This event describes a GraphQL error that occurred during operation execution.

GraphQL errors can occur during various phases of request processing including parsing, validation, and execution. Errors SHOULD be recorded on the span that represents the work during which the error occurred:
- For queries and mutations, errors SHOULD be recorded on the root
`graphql.server` span.
- For subscriptions, errors that occur during the initial subscription
request and setup SHOULD be recorded on the root `graphql.server` span.
Errors that occur while processing an individual subscription event
SHOULD be recorded on the corresponding `graphql.subscription.event`
span, not on the root, so that each error is correlated with the event
it belongs to.

Multiple errors can be recorded as separate events on the same span.
Instrumentations SHOULD set the severity based on the impact of the error. When the response contains both `data` and `errors` (partial success), the severity SHOULD be WARN (severity number 13). When the response contains only `errors` and no `data` (complete failure), the severity SHOULD be ERROR (severity number 17). When severity cannot be determined, instrumentations SHOULD default to ERROR.
**GraphQL errors and exceptions:** When a GraphQL error is caused by an underlying exception, instrumentations SHOULD record both the GraphQL error details and the exception information on the same `graphql.error` event rather than emitting separate events. The exception attributes (`exception.type`, `exception.message`, `exception.stacktrace`) MAY be included alongside the GraphQL-specific error detail attributes on the same event. This avoids duplicate events for the same underlying issue and keeps the error context together.
When a GraphQL error is NOT caused by an exception (e.g., validation errors, authorization errors returned by the GraphQL layer), only the GraphQL-specific error detail attributes are needed.
Instrumentations SHOULD cap the number of error events per span to a configurable maximum (default: 10) to prevent excessive telemetry. If error events are capped, `graphql.error.count` on the parent span SHOULD reflect the total number of errors rather than the number of emitted events. `graphql.error.count` SHOULD be omitted when the count is 0.
**Relationship to span status and `error.type`:** GraphQL error events provide detailed per-error information from the response `errors` array. They are complementary to span-level error signals:
- `error.type` on the parent span provides a low-cardinality error classification
for the overall operation outcome. It SHOULD be set based on the `graphql.error.code`
of the first error or a general error category.
- Individual `graphql.error` events provide the structured details for each error
in the response.

Instrumentations SHOULD set both `error.type` on the span and emit error events for each error in the response. The error events provide the detail; `error.type` and span status provide the summary.

**Attributes:**

| Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values |
| --- | --- | --- | --- | --- | --- |
| [`graphql.error.message`](/docs/registry/attributes/graphql.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Required` | string | The error message intended for the developer as a guide to understand and correct the error. [1] | `Cannot query field 'nonExistentField' on type 'User'`; `Variable '$id' of required type 'ID!' was not provided.` |
| [`exception.message`](/docs/registry/attributes/exception.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If the error was caused by an exception. | string | The exception message. [2] | `Division by zero`; `Can't convert 'int' object to str implicitly` |
| [`exception.type`](/docs/registry/attributes/exception.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Conditionally Required` If the error was caused by an exception. | string | The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. [3] | `java.net.ConnectException`; `OSError` |
| [`graphql.document.locations`](/docs/registry/attributes/graphql.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` [4] | any | The locations in the GraphQL document associated with an error. [5] | `[{ "line": 3, "column": 7 }, { "line": 5, "column": 4 }]` |
| [`graphql.field.path`](/docs/registry/attributes/graphql.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` [6] | string | The path of the field that is being resolved. [7] | `person[0].address` |
| [`graphql.field.schema_coordinate`](/docs/registry/attributes/graphql.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` [8] | string | The schema coordinate of the field that is being resolved, in the form `{ParentType}.{fieldName}`. | `Person.address`; `Query.findBookById` |
| [`graphql.operation.name`](/docs/registry/attributes/graphql.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Conditionally Required` If available and not empty. | string | The name of the operation being executed. [9] | `FindBookById`; `GetUserProfile` |
| [`graphql.operation.type`](/docs/registry/attributes/graphql.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Recommended` | string | The type of the operation being executed. [10] | `query`; `mutation`; `subscription` |
| [`exception.stacktrace`](/docs/registry/attributes/exception.md) | ![Stable](https://img.shields.io/badge/-stable-lightgreen) | `Opt-In` | string | A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. [11] | `Exception in thread "main" java.lang.RuntimeException: Test exception\n at com.example.GenerateTrace.methodB(GenerateTrace.java:13)\n at com.example.GenerateTrace.methodA(GenerateTrace.java:9)\n at com.example.GenerateTrace.main(GenerateTrace.java:5)` |
| [`graphql.error.code`](/docs/registry/attributes/graphql.md) | ![Development](https://img.shields.io/badge/-development-blue) | `Opt-In` | string | An optional error code from the extensions field. [12] | `GRAPHQL_VALIDATION_FAILED`; `UNAUTHENTICATED`; `HC00116` |

**[1] `graphql.error.message`:** Every error must contain an entry with the key message with a string description of the error intended for the developer as a guide to understand and correct the error.
> **Warning** > This attribute has unbounded cardinality and MUST NOT be used as a metric > dimension. It is intended for span events and log records only.

**[2] `exception.message`:** The exception message. When both `graphql.error.message` and `exception.message` are available, both SHOULD be set as they may differ (the GraphQL error message is user-facing, while the exception message is the raw internal error).

**[3] `exception.type`:** The fully qualified class name or type of the exception that caused this GraphQL error, when applicable.

**[4] `graphql.document.locations`:** Should be included when the error can be associated with a specific location in the GraphQL document.

**[5] `graphql.document.locations`:** If an error can be associated to a particular point in the requested GraphQL document, it should contain an array of location objects. Each location is a JSON object with the keys `line` and `column`, both positive integers starting from 1, which describe the beginning of an associated syntax element.
The value MUST be an array of objects, where each object has the following properties: - `line` (integer, required): The line number in the GraphQL document. - `column` (integer, required): The column number in the GraphQL document.

**[6] `graphql.field.path`:** Must be included when the error can be associated with a particular field in the GraphQL result.

**[7] `graphql.field.path`:** The path of the response field which experienced the error. If an error can be associated to a particular field in the GraphQL result, it must contain an entry with the key path that details the path of the response field which experienced the error.
This allows clients to identify whether a null result is intentional or caused by a runtime error.
The path starts from the root of the response. Field names are separated by dots and list indices are represented using bracket notation. If the error happens in an aliased field, the path should use the aliased name, since it represents a path in the response, not in the request.

**[8] `graphql.field.schema_coordinate`:** Should be included when the error can be associated with a particular field in the GraphQL schema.

**[9] `graphql.operation.name`:** Including the operation name on error events enables correlation of errors to specific operations, especially useful when error events are processed independently of spans (e.g., in log-based pipelines).

**[10] `graphql.operation.type`:** Including the operation type on error events enables correlation and filtering of errors by operation type without requiring access to the parent span.

**[11] `exception.stacktrace`:** The exception stacktrace, when available and the error was caused by an exception. This attribute is opt-in due to its size and potential to contain sensitive information.

**[12] `graphql.error.code`:** This is an optional field that can be used to categorize errors. The error extension code is a recommended way to categorize errors for easier filtering and monitoring.

---

`graphql.operation.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.

| Value | Description | Stability |
| --- | --- | --- |
| `_OTHER` | A fallback for operation types not covered by specific values in this enum. | ![Development](https://img.shields.io/badge/-development-blue) |
| `mutation` | GraphQL mutation operation | ![Development](https://img.shields.io/badge/-development-blue) |
| `query` | GraphQL query operation | ![Development](https://img.shields.io/badge/-development-blue) |
| `subscription` | GraphQL subscription operation | ![Development](https://img.shields.io/badge/-development-blue) |

<!-- prettier-ignore-end -->
<!-- END AUTOGENERATED TEXT -->
<!-- endsemconv -->

[DocumentStatus]: https://opentelemetry.io/docs/specs/otel/document-status
Loading