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

Exception reporting specification #697

Merged
merged 14 commits into from
Jul 17, 2020
14 changes: 14 additions & 0 deletions specification/trace/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Table of Contents
* [Set Status](#set-status)
* [UpdateName](#updatename)
* [End](#end)
* [Record Exception](#record-exception)
* [Span lifetime](#span-lifetime)
* [Status](#status)
* [StatusCanonicalCode](#statuscanonicalcode)
Expand Down Expand Up @@ -515,6 +516,19 @@ Parameters:

This API MUST be non-blocking.

#### Record Exception

To facilitate recording an exception languages SHOULD provide a
`RecordException` convenience method. The signature of the method is to be
determined by each language and can be overloaded as appropriate. The method
MUST record an exception as an `Event` with the conventions outlined in the
[exception semantic conventions](semantic_conventions/exceptions.md) document.

Examples:

- `RecordException(exception: Exception)`
- `RecordException(type: String, message: String, stacktrace: String)`

### Span lifetime

Span lifetime represents the process of recording the start and the end
Expand Down
58 changes: 58 additions & 0 deletions specification/trace/semantic_conventions/exceptions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Semantic Conventions for Exceptions

This document defines semantic conventions for recording application
exceptions.

<!-- toc -->

- [Recording an Exception](#recording-an-exception)
- [Attributes](#attributes)
- [Stacktrace Representation](#stacktrace-representation)

<!-- tocstop -->

## Recording an Exception

An exception SHOULD be recorded as an `Event` on the span during which it occurred.
The name of the event MUST be `"exception"`.

## Attributes

The table below indicates which attributes should be added to the `Event` and
their types.

| Attribute name | Type | Notes and examples | Required? |
| :------------------- | :----- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------- |
| exception.type | 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. E.g. "java.net.ConnectException", "OSError" | One of `exception.type` or `exception.message` is required |
| exception.message | String | The exception message. E.g. `"Division by zero"`, `"Can't convert 'int' object to str implicitly"` | One of `exception.type` or `exception.message` is required |
| exception.stacktrace | 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. E.g. `"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)"`. | No |

### Stacktrace Representation

The table below, adapted from [Google Cloud][gcp-error-reporting], includes
possible representations of stacktraces in various languages. The table is not
meant to be a recommendation for any particular language, although SIGs are free
to adopt them if they see fit.

| Language | Format |
| ---------- | ------------------------------------------------------------------- |
| C# | the return value of [Exception.ToString()][csharp-stacktrace] |
| Go | the return value of [runtime.Stack][go-stacktrace] |
| Java | the contents of [Throwable.printStackTrace()][java-stacktrace] |
| Javascript | the return value of [error.stack][js-stacktrace] as returned by V8 |
| Python | the return value of [traceback.format_exc()][python-stacktrace] |
| Ruby | the result of [Exception.backtrace][ruby-stacktrace] joined by "\n" |

Backends can use the language specified methodology for generating a stacktrace
combined with platform information from the
[telemetry sdk resource][telemetry-sdk-resource] in order to extract more fine
grained information from a stacktrace, if necessary.

[gcp-error-reporting]: https://cloud.google.com/error-reporting/reference/rest/v1beta1/projects.events/report
[java-stacktrace]: https://docs.oracle.com/javase/7/docs/api/java/lang/Throwable.html#printStackTrace%28%29
[python-stacktrace]: https://docs.python.org/3/library/traceback.html#traceback.format_exc
[js-stacktrace]: https://v8.dev/docs/stack-trace-api
[ruby-stacktrace]: https://ruby-doc.org/core-2.7.1/Exception.html#method-i-backtrace
[csharp-stacktrace]: https://docs.microsoft.com/en-us/dotnet/api/system.exception.tostring
[go-stacktrace]: https://golang.org/pkg/runtime/debug/#Stack
[telemetry-sdk-resource]: https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/resource/semantic_conventions#telemetry-sdk