From 7da8f56fb00fdb836f0e81758f1c8dd5cbe52b2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Fri, 7 Aug 2020 16:27:33 +0200 Subject: [PATCH 01/12] When to record an error and when not to. Original recommendation withouth the MUST NOT part: Co-authored-by: Amanda Murphy --- specification/trace/api.md | 3 +++ specification/trace/semantic_conventions/exceptions.md | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/specification/trace/api.md b/specification/trace/api.md index 2bbc6ec66e2..a9558e46f77 100644 --- a/specification/trace/api.md +++ b/specification/trace/api.md @@ -513,6 +513,9 @@ Examples: - `RecordException(exception: Exception)` - `RecordException(type: String, message: String, stacktrace: String)` +Note that as per the semantic conventions, only exceptions leaving the scope of +a span unhandled must be recorded. + ### Span lifetime Span lifetime represents the process of recording the start and the end diff --git a/specification/trace/semantic_conventions/exceptions.md b/specification/trace/semantic_conventions/exceptions.md index daa204690a8..b7d09980cb1 100644 --- a/specification/trace/semantic_conventions/exceptions.md +++ b/specification/trace/semantic_conventions/exceptions.md @@ -13,7 +13,12 @@ exceptions. ## Recording an Exception -An exception SHOULD be recorded as an `Event` on the span during which it occurred. +An unhandled exception that leaves the scope of a span +SHOULD be recorded as an `Event` on that span. +Other (handled, not leaving a span's scope) exceptions MUST NOT be recorded. +An exception is considered to leave the scope of a span if the span is ended +because of stack unwinding caused by the exception. + The name of the event MUST be `"exception"`. ## Attributes From 1f32e2ce92ad9c76e44b9394191753e8266b8cc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Thu, 6 Aug 2020 09:05:26 +0200 Subject: [PATCH 02/12] Add CHANGELOG entry. --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9335557c1ea..657177dfa11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,9 @@ the release. New: - Add resource semantic conventions for operating systems ([#693](https://github.com/open-telemetry/opentelemetry-specification/pull/693)) +- Add Span API and semantic conventions for unhandled exceptions + ([#697](https://github.com/open-telemetry/opentelemetry-specification/pull/697), + [#???](https://github.com/open-telemetry/opentelemetry-specification/pull/???)) Updates: From 1354f86f70f417d30b6ef54eae8784ca78174f3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Thu, 6 Aug 2020 09:23:02 +0200 Subject: [PATCH 03/12] Fill out PR# in CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 657177dfa11..ac2b49880f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ New: - Add resource semantic conventions for operating systems ([#693](https://github.com/open-telemetry/opentelemetry-specification/pull/693)) - Add Span API and semantic conventions for unhandled exceptions ([#697](https://github.com/open-telemetry/opentelemetry-specification/pull/697), - [#???](https://github.com/open-telemetry/opentelemetry-specification/pull/???)) + [#761](https://github.com/open-telemetry/opentelemetry-specification/pull/761)) Updates: From a20bea9ec7884b853e6a5b5b32b366d31245f2d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Thu, 6 Aug 2020 12:17:36 +0200 Subject: [PATCH 04/12] Add considerations for Go. --- specification/trace/semantic_conventions/exceptions.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/specification/trace/semantic_conventions/exceptions.md b/specification/trace/semantic_conventions/exceptions.md index b7d09980cb1..385740c46fb 100644 --- a/specification/trace/semantic_conventions/exceptions.md +++ b/specification/trace/semantic_conventions/exceptions.md @@ -17,7 +17,8 @@ An unhandled exception that leaves the scope of a span SHOULD be recorded as an `Event` on that span. Other (handled, not leaving a span's scope) exceptions MUST NOT be recorded. An exception is considered to leave the scope of a span if the span is ended -because of stack unwinding caused by the exception. +while the exception is still "in flight" +(special considerations may apply for Go, where exception semantic conventions are used for non-exceptions). The name of the event MUST be `"exception"`. From 11f0543341339ad04af04795ab60fdfa585c35b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Fri, 7 Aug 2020 16:18:31 +0200 Subject: [PATCH 05/12] Introdue exception.left_scope, go back to allowing all kinds. --- specification/trace/api.md | 7 ++----- specification/trace/semantic_conventions/exceptions.md | 7 ++++++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/specification/trace/api.md b/specification/trace/api.md index a9558e46f77..ba433f34c28 100644 --- a/specification/trace/api.md +++ b/specification/trace/api.md @@ -510,11 +510,8 @@ MUST record an exception as an `Event` with the conventions outlined in the Examples: -- `RecordException(exception: Exception)` -- `RecordException(type: String, message: String, stacktrace: String)` - -Note that as per the semantic conventions, only exceptions leaving the scope of -a span unhandled must be recorded. +- `RecordException(exception: Exception, leftScope: boolean? = null)` +- `RecordException(type: String, message: String, stacktrace: String, leftScope: boolean?)` ### Span lifetime diff --git a/specification/trace/semantic_conventions/exceptions.md b/specification/trace/semantic_conventions/exceptions.md index 385740c46fb..7006a982534 100644 --- a/specification/trace/semantic_conventions/exceptions.md +++ b/specification/trace/semantic_conventions/exceptions.md @@ -15,13 +15,17 @@ exceptions. An unhandled exception that leaves the scope of a span SHOULD be recorded as an `Event` on that span. -Other (handled, not leaving a span's scope) exceptions MUST NOT be recorded. An exception is considered to leave the scope of a span if the span is ended while the exception is still "in flight" (special considerations may apply for Go, where exception semantic conventions are used for non-exceptions). The name of the event MUST be `"exception"`. +Note that multiple events (on the same or different Spans) +might be logged for the same exception object instance. +E.g. one event might be logged in an instrumented exception constructor +and another event might be logged when an exception leaves the scope of a span. + ## Attributes The table below indicates which attributes should be added to the `Event` and @@ -32,6 +36,7 @@ their types. | 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 | +| exception.left_scope | Bool | SHOULD be set to true if the exception event is recoded while observing the exception leaving the scope of the span. Note that an exception may still leave the scope of the span even if this was not set or set to false, if the event was recorded at an earlier time. | No | ### Stacktrace Representation From 5a16f7fe0391929f08c90163889bba86667e701b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Fri, 7 Aug 2020 17:24:32 +0200 Subject: [PATCH 06/12] Update CHANGELOG.md Co-authored-by: Armin Ruech --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac2b49880f9..6de6b26d433 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ the release. New: - Add resource semantic conventions for operating systems ([#693](https://github.com/open-telemetry/opentelemetry-specification/pull/693)) -- Add Span API and semantic conventions for unhandled exceptions +- Add Span API and semantic conventions for recording exceptions ([#697](https://github.com/open-telemetry/opentelemetry-specification/pull/697), [#761](https://github.com/open-telemetry/opentelemetry-specification/pull/761)) From c4a40669010588a819036e2927ad78cf7bdb5c14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Mon, 10 Aug 2020 19:27:04 +0200 Subject: [PATCH 07/12] Add clarifying example. --- .../trace/semantic_conventions/exceptions.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/specification/trace/semantic_conventions/exceptions.md b/specification/trace/semantic_conventions/exceptions.md index 7006a982534..569c3b12b63 100644 --- a/specification/trace/semantic_conventions/exceptions.md +++ b/specification/trace/semantic_conventions/exceptions.md @@ -13,7 +13,7 @@ exceptions. ## Recording an Exception -An unhandled exception that leaves the scope of a span +An exception that leaves the scope of a span SHOULD be recorded as an `Event` on that span. An exception is considered to leave the scope of a span if the span is ended while the exception is still "in flight" @@ -26,6 +26,20 @@ might be logged for the same exception object instance. E.g. one event might be logged in an instrumented exception constructor and another event might be logged when an exception leaves the scope of a span. +A typical template for an auto-instrumentation implementing this semantic convention +could look like this: + +```java +Span span = myTracer.startSpan(/*...*/); +try { + // original code +} catch (Throwable e) { + span.recordException(e, /*leftScope=*/true); +} finally { + span.end(); +} +``` + ## Attributes The table below indicates which attributes should be added to the `Event` and From a55043d553090218b8838bbe4a343f20becaa43b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Tue, 11 Aug 2020 12:13:29 +0200 Subject: [PATCH 08/12] Rename left -> escaped, add clarifying note. --- .../trace/semantic_conventions/exceptions.md | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/specification/trace/semantic_conventions/exceptions.md b/specification/trace/semantic_conventions/exceptions.md index 569c3b12b63..7d8d90a370d 100644 --- a/specification/trace/semantic_conventions/exceptions.md +++ b/specification/trace/semantic_conventions/exceptions.md @@ -13,11 +13,18 @@ exceptions. ## Recording an Exception -An exception that leaves the scope of a span +An exception that escapes the scope of a span SHOULD be recorded as an `Event` on that span. -An exception is considered to leave the scope of a span if the span is ended -while the exception is still "in flight" -(special considerations may apply for Go, where exception semantic conventions are used for non-exceptions). +An exception is considered to have escaped the scope if the span is ended +while the exception is still "in flight". Note: + +* While it is usually not possible to determine whether some exception thrown + now *will* escape the scope of a span, it is trivial to know that an exception + will escape, if one checks for an active exception just before ending the span. + See the [example below](#exception-end-example). +* Special considerations may apply for Go, where exception semantic conventions + might be used for non-exceptions. + See [issue #764](https://github.com/open-telemetry/opentelemetry-specification/issues/764). The name of the event MUST be `"exception"`. @@ -26,6 +33,8 @@ might be logged for the same exception object instance. E.g. one event might be logged in an instrumented exception constructor and another event might be logged when an exception leaves the scope of a span. + + A typical template for an auto-instrumentation implementing this semantic convention could look like this: @@ -34,7 +43,7 @@ Span span = myTracer.startSpan(/*...*/); try { // original code } catch (Throwable e) { - span.recordException(e, /*leftScope=*/true); + span.recordException(e, /*escaped=*/true); } finally { span.end(); } @@ -50,7 +59,7 @@ their types. | 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 | -| exception.left_scope | Bool | SHOULD be set to true if the exception event is recoded while observing the exception leaving the scope of the span. Note that an exception may still leave the scope of the span even if this was not set or set to false, if the event was recorded at an earlier time. | No | +| exception.escaped | Bool | SHOULD be set to true if the exception event is recoded at a point where it is known that the exception is escaping the scope of the span (e.g. if there is an exception active just before ending the Span). Note that an exception may still leave the scope of the span even if this was not set or set to false, if the event was recorded at an earlier time. | No | ### Stacktrace Representation From 6aaa8adfe7aea8766683ff8df24de22699fc218d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Tue, 11 Aug 2020 13:57:06 +0200 Subject: [PATCH 09/12] Also rename parameter name in API example --- specification/trace/api.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specification/trace/api.md b/specification/trace/api.md index ba433f34c28..7ea76ad8ba2 100644 --- a/specification/trace/api.md +++ b/specification/trace/api.md @@ -510,8 +510,8 @@ MUST record an exception as an `Event` with the conventions outlined in the Examples: -- `RecordException(exception: Exception, leftScope: boolean? = null)` -- `RecordException(type: String, message: String, stacktrace: String, leftScope: boolean?)` +- `RecordException(exception: Exception, escaped: boolean? = null)` +- `RecordException(type: String, message: String, stacktrace: String, escaped: boolean?)` ### Span lifetime From 67e2c9896fc873ae5332fb81a981b674fcc5eb15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Tue, 11 Aug 2020 18:36:52 +0200 Subject: [PATCH 10/12] Fix missing rethrow in example. --- specification/trace/semantic_conventions/exceptions.md | 1 + 1 file changed, 1 insertion(+) diff --git a/specification/trace/semantic_conventions/exceptions.md b/specification/trace/semantic_conventions/exceptions.md index 7d8d90a370d..a84e7fe4274 100644 --- a/specification/trace/semantic_conventions/exceptions.md +++ b/specification/trace/semantic_conventions/exceptions.md @@ -44,6 +44,7 @@ try { // original code } catch (Throwable e) { span.recordException(e, /*escaped=*/true); + throw e; } finally { span.end(); } From 80ea27df4dd858b686d91ef37dad89aa8cd89439 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Tue, 11 Aug 2020 18:37:37 +0200 Subject: [PATCH 11/12] Remove exception.escaped attribute (as per SIG mtg). --- specification/trace/api.md | 4 ++-- specification/trace/semantic_conventions/exceptions.md | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/specification/trace/api.md b/specification/trace/api.md index 2991233ae7a..c3c1058417f 100644 --- a/specification/trace/api.md +++ b/specification/trace/api.md @@ -516,8 +516,8 @@ MUST record an exception as an `Event` with the conventions outlined in the Examples: -- `RecordException(exception: Exception, escaped: boolean? = null)` -- `RecordException(type: String, message: String, stacktrace: String, escaped: boolean?)` +- `RecordException(exception: Exception)` +- `RecordException(type: String, message: String, stacktrace: String)` ### Span lifetime diff --git a/specification/trace/semantic_conventions/exceptions.md b/specification/trace/semantic_conventions/exceptions.md index a84e7fe4274..b90d753a2f0 100644 --- a/specification/trace/semantic_conventions/exceptions.md +++ b/specification/trace/semantic_conventions/exceptions.md @@ -43,7 +43,7 @@ Span span = myTracer.startSpan(/*...*/); try { // original code } catch (Throwable e) { - span.recordException(e, /*escaped=*/true); + span.recordException(e); // We know that the exception is escaping here. throw e; } finally { span.end(); @@ -60,7 +60,6 @@ their types. | 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 | -| exception.escaped | Bool | SHOULD be set to true if the exception event is recoded at a point where it is known that the exception is escaping the scope of the span (e.g. if there is an exception active just before ending the Span). Note that an exception may still leave the scope of the span even if this was not set or set to false, if the event was recorded at an earlier time. | No | ### Stacktrace Representation From bd20a1a576f8b748d8fcd9b54554906cb6be9ee3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Fri, 14 Aug 2020 12:55:59 +0200 Subject: [PATCH 12/12] Improve wording. --- .../trace/semantic_conventions/exceptions.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/specification/trace/semantic_conventions/exceptions.md b/specification/trace/semantic_conventions/exceptions.md index b90d753a2f0..1068a5a202a 100644 --- a/specification/trace/semantic_conventions/exceptions.md +++ b/specification/trace/semantic_conventions/exceptions.md @@ -13,8 +13,9 @@ exceptions. ## Recording an Exception -An exception that escapes the scope of a span -SHOULD be recorded as an `Event` on that span. +An exception that escapes the scope of a span SHOULD be recorded +as an `Event` on that span +(of course, other exceptions that are deemed relevant may also be recorded). An exception is considered to have escaped the scope if the span is ended while the exception is still "in flight". Note: @@ -28,9 +29,9 @@ while the exception is still "in flight". Note: The name of the event MUST be `"exception"`. -Note that multiple events (on the same or different Spans) -might be logged for the same exception object instance. -E.g. one event might be logged in an instrumented exception constructor +Note that multiple events (on the same or different Spans) might be logged +for the same exception object instance. +For example, one event might be logged in an instrumented exception constructor and another event might be logged when an exception leaves the scope of a span.