From 91355cbc14f60e2706bca798b9256ffb71e41657 Mon Sep 17 00:00:00 2001 From: Matthew Wear Date: Sat, 25 Jan 2020 00:58:31 -0800 Subject: [PATCH 01/14] Add semantic conventions for errors --- .../data-error-semantic-conventions.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 specification/data-error-semantic-conventions.md diff --git a/specification/data-error-semantic-conventions.md b/specification/data-error-semantic-conventions.md new file mode 100644 index 00000000000..a540b38287e --- /dev/null +++ b/specification/data-error-semantic-conventions.md @@ -0,0 +1,19 @@ +# Semantic conventions for errors + +This document defines semantic conventions for recording errors. + +## Recording an Error + +An error SHOULD be recorded as an `Event` on the span during which it occurred. +The name of the event MUST be `"error"`. + +## Attributes + +The table below indicates which attributes should be added to the `Event` and +their types. + +| Attribute name | Type | Notes and examples | Required? | +| :------------- | :--------- | :----------------------------------------------------------- | :-------- | +| error.type | String | The type of the error. E.g. "Exception", "OSError" | Yes | +| error.message | String | The error message. E.g. `"Division by zero"`, `"Can't convert 'int' object to str implicitly"` | Yes | +| error.stack | Array\ | A stack trace formatted as an array of strings. The stackframe at which the exeception occurred should be the first entry. E.g. `["Exception in thread \"main\" java.lang.RuntimeException: Test exception", " at com.example.GenerateTrace.methodB(GenerateTrace.java:13)", " at com.example.GenerateTrace.methodA(GenerateTrace.java:9)", " at com.example.GenerateTrace.main(GenerateTrace.java:5)" ]` | No | From 82522f44df750d5bef98c34a513383924d30e930 Mon Sep 17 00:00:00 2001 From: Matthew Wear Date: Tue, 28 Jan 2020 17:34:31 -0800 Subject: [PATCH 02/14] Update error.type description Co-Authored-By: Armin Ruech --- specification/data-error-semantic-conventions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/data-error-semantic-conventions.md b/specification/data-error-semantic-conventions.md index a540b38287e..eec35286670 100644 --- a/specification/data-error-semantic-conventions.md +++ b/specification/data-error-semantic-conventions.md @@ -14,6 +14,6 @@ their types. | Attribute name | Type | Notes and examples | Required? | | :------------- | :--------- | :----------------------------------------------------------- | :-------- | -| error.type | String | The type of the error. E.g. "Exception", "OSError" | Yes | +| error.type | String | The type of the error (its fully-qualified class name, if applicable). E.g. "java.net.ConnectException", "OSError" | Yes | | error.message | String | The error message. E.g. `"Division by zero"`, `"Can't convert 'int' object to str implicitly"` | Yes | | error.stack | Array\ | A stack trace formatted as an array of strings. The stackframe at which the exeception occurred should be the first entry. E.g. `["Exception in thread \"main\" java.lang.RuntimeException: Test exception", " at com.example.GenerateTrace.methodB(GenerateTrace.java:13)", " at com.example.GenerateTrace.methodA(GenerateTrace.java:9)", " at com.example.GenerateTrace.main(GenerateTrace.java:5)" ]` | No | From c25e9d7fc4157fd8cfe871eebbdfbcad8790c0f2 Mon Sep 17 00:00:00 2001 From: Matthew Wear Date: Wed, 1 Jul 2020 17:14:31 -0700 Subject: [PATCH 03/14] update semantic conventions for exceptions --- .../data-error-semantic-conventions.md | 19 ------------------ specification/trace/exceptions.md | 20 +++++++++++++++++++ 2 files changed, 20 insertions(+), 19 deletions(-) delete mode 100644 specification/data-error-semantic-conventions.md create mode 100644 specification/trace/exceptions.md diff --git a/specification/data-error-semantic-conventions.md b/specification/data-error-semantic-conventions.md deleted file mode 100644 index eec35286670..00000000000 --- a/specification/data-error-semantic-conventions.md +++ /dev/null @@ -1,19 +0,0 @@ -# Semantic conventions for errors - -This document defines semantic conventions for recording errors. - -## Recording an Error - -An error SHOULD be recorded as an `Event` on the span during which it occurred. -The name of the event MUST be `"error"`. - -## Attributes - -The table below indicates which attributes should be added to the `Event` and -their types. - -| Attribute name | Type | Notes and examples | Required? | -| :------------- | :--------- | :----------------------------------------------------------- | :-------- | -| error.type | String | The type of the error (its fully-qualified class name, if applicable). E.g. "java.net.ConnectException", "OSError" | Yes | -| error.message | String | The error message. E.g. `"Division by zero"`, `"Can't convert 'int' object to str implicitly"` | Yes | -| error.stack | Array\ | A stack trace formatted as an array of strings. The stackframe at which the exeception occurred should be the first entry. E.g. `["Exception in thread \"main\" java.lang.RuntimeException: Test exception", " at com.example.GenerateTrace.methodB(GenerateTrace.java:13)", " at com.example.GenerateTrace.methodA(GenerateTrace.java:9)", " at com.example.GenerateTrace.main(GenerateTrace.java:5)" ]` | No | diff --git a/specification/trace/exceptions.md b/specification/trace/exceptions.md new file mode 100644 index 00000000000..f2c275c911c --- /dev/null +++ b/specification/trace/exceptions.md @@ -0,0 +1,20 @@ +# Semantic conventions for exceptions + +This document defines semantic conventions for recording exceptions. + +## 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). E.g. "java.net.ConnectException", "OSError" | Yes | +| exception.message | String | The exception message. E.g. `"Division by zero"`, `"Can't convert 'int' object to str implicitly"` | Yes | +| stacktrace | String | A stack trace as a string in the natural representation in the language runtime. 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 | +| log.severity | String | The severity of the error E.g. `Fatal`, `Error`, `Warn`, etc. | From c642d00da90376dcdef3c679dfeed9dde4ff1196 Mon Sep 17 00:00:00 2001 From: Matthew Wear Date: Thu, 9 Jul 2020 16:05:59 -0700 Subject: [PATCH 04/14] add details for attributes; remove log.severity; add API details --- specification/trace/exceptions.md | 63 ++++++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 9 deletions(-) diff --git a/specification/trace/exceptions.md b/specification/trace/exceptions.md index f2c275c911c..c732c6f03bc 100644 --- a/specification/trace/exceptions.md +++ b/specification/trace/exceptions.md @@ -1,20 +1,65 @@ -# Semantic conventions for exceptions +# Exception Reporting -This document defines semantic conventions for recording exceptions. +This document defines semantic conventions and APIs for recording application +exceptions. ## 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 +## Semantic Conventions 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). E.g. "java.net.ConnectException", "OSError" | Yes | -| exception.message | String | The exception message. E.g. `"Division by zero"`, `"Can't convert 'int' object to str implicitly"` | Yes | -| stacktrace | String | A stack trace as a string in the natural representation in the language runtime. 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 | -| log.severity | String | The severity of the error E.g. `Fatal`, `Error`, `Warn`, etc. | +| Attribute name | Type | Notes and examples | Required? | +| :---------------- | :----- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------- | +| exception.type | String | The type of the exception (its fully-qualified class name, if applicable). 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 | +| stacktrace | String | A stack trace 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 | +| ---------- | ------------------------------------------------------------------- | +| Java | the return value of [Throwable.printStackTrace()][java-stacktrace] | +| Python | return value of [traceback.format_exc()][python-stacktrace] | +| Javascript | the return value of [error.stack][js-stacktrace] as returned by V8 | +| Ruby | the result of [Exception.backtrace][ruby-stacktrace] joined by "\n" | +| C# | the return value of [Exception.ToString()][csharp-stacktrace] | +| Go | the return value of [runtime.Stack][go-stacktrace] | + +Backends can use the language selected 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. + +## API + +To facilitate recording an exception languages SHOULD provide a +`Span.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 this +document. + +**Examples:** + +``` +RecordException(exception: Exception) +RecordException(type: String, message: String, stacktrace: String) +``` + +[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 From 4a1fbe8e7ccc61bfc69cdb0d54fdea37d53b470b Mon Sep 17 00:00:00 2001 From: Matthew Wear Date: Thu, 9 Jul 2020 16:34:03 -0700 Subject: [PATCH 05/14] rename exceptions.md -> exception-reporting.md --- .../{exceptions.md => exception-reporting.md} | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) rename specification/trace/{exceptions.md => exception-reporting.md} (82%) diff --git a/specification/trace/exceptions.md b/specification/trace/exception-reporting.md similarity index 82% rename from specification/trace/exceptions.md rename to specification/trace/exception-reporting.md index c732c6f03bc..0b998f08bc6 100644 --- a/specification/trace/exceptions.md +++ b/specification/trace/exception-reporting.md @@ -13,11 +13,11 @@ The name of the event MUST be `"exception"`. 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). 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 | -| stacktrace | String | A stack trace 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 | +| Attribute name | Type | Notes and examples | Required? | +| :---------------- | :----- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------- | +| exception.type | String | The type of the exception (its fully-qualified class name, if applicable). 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 | +| 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 @@ -35,7 +35,7 @@ to adopt them if they see fit. | C# | the return value of [Exception.ToString()][csharp-stacktrace] | | Go | the return value of [runtime.Stack][go-stacktrace] | -Backends can use the language selected methodology for generating a stacktrace +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. @@ -45,7 +45,7 @@ grained information from a stacktrace, if necessary. To facilitate recording an exception languages SHOULD provide a `Span.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 this +MUST record an exception as an `Event` with the conventions outlined in this document. **Examples:** From e77f002fa0e6bfd9801ffab38822727ba996aefd Mon Sep 17 00:00:00 2001 From: Matthew Wear Date: Thu, 9 Jul 2020 21:40:36 -0700 Subject: [PATCH 06/14] more accurately describe format for java --- specification/trace/exception-reporting.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specification/trace/exception-reporting.md b/specification/trace/exception-reporting.md index 0b998f08bc6..c7131da63de 100644 --- a/specification/trace/exception-reporting.md +++ b/specification/trace/exception-reporting.md @@ -28,8 +28,8 @@ to adopt them if they see fit. | Language | Format | | ---------- | ------------------------------------------------------------------- | -| Java | the return value of [Throwable.printStackTrace()][java-stacktrace] | -| Python | return value of [traceback.format_exc()][python-stacktrace] | +| Java | the contents of [Throwable.printStackTrace()][java-stacktrace] | +| Python | the return value of [traceback.format_exc()][python-stacktrace] | | Javascript | the return value of [error.stack][js-stacktrace] as returned by V8 | | Ruby | the result of [Exception.backtrace][ruby-stacktrace] joined by "\n" | | C# | the return value of [Exception.ToString()][csharp-stacktrace] | From 5aa3a75ac31e3b3ae0b39e65183066f671748170 Mon Sep 17 00:00:00 2001 From: Matthew Wear Date: Fri, 10 Jul 2020 15:43:11 -0700 Subject: [PATCH 07/14] alphabetize languages in stacktrace representation table --- specification/trace/exception-reporting.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/specification/trace/exception-reporting.md b/specification/trace/exception-reporting.md index c7131da63de..4a41017c3d0 100644 --- a/specification/trace/exception-reporting.md +++ b/specification/trace/exception-reporting.md @@ -28,12 +28,12 @@ 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] | -| Python | the return value of [traceback.format_exc()][python-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" | -| C# | the return value of [Exception.ToString()][csharp-stacktrace] | -| Go | the return value of [runtime.Stack][go-stacktrace] | Backends can use the language specified methodology for generating a stacktrace combined with platform information from the From e81f96a509507f3ad30b8cc11f5ac105c6eb570e Mon Sep 17 00:00:00 2001 From: Matthew Wear Date: Fri, 10 Jul 2020 15:45:09 -0700 Subject: [PATCH 08/14] prefer dynamic type over static type --- specification/trace/exception-reporting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/trace/exception-reporting.md b/specification/trace/exception-reporting.md index 4a41017c3d0..68aec5e5372 100644 --- a/specification/trace/exception-reporting.md +++ b/specification/trace/exception-reporting.md @@ -15,7 +15,7 @@ their types. | Attribute name | Type | Notes and examples | Required? | | :---------------- | :----- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------- | -| exception.type | String | The type of the exception (its fully-qualified class name, if applicable). E.g. "java.net.ConnectException", "OSError" | One of `exception.type` or `exception.message` is 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 | | 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 | From 137556e44bf74e6d76a17bd81943702a460cb9de Mon Sep 17 00:00:00 2001 From: Matthew Wear Date: Fri, 10 Jul 2020 15:50:38 -0700 Subject: [PATCH 09/14] add log.severity convention --- specification/trace/exception-reporting.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/specification/trace/exception-reporting.md b/specification/trace/exception-reporting.md index 68aec5e5372..ef5fb3fb78e 100644 --- a/specification/trace/exception-reporting.md +++ b/specification/trace/exception-reporting.md @@ -18,6 +18,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 | | 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 | +| log.severity | String | The severity of the exception E.g. `Fatal`, `Error`, `Warn`, etc. | No | ### Stacktrace Representation @@ -51,8 +52,8 @@ document. **Examples:** ``` -RecordException(exception: Exception) -RecordException(type: String, message: String, stacktrace: String) +RecordException(exception: Exception, severity: String) +RecordException(type: String, message: String, stacktrace: String, severity: String) ``` [gcp-error-reporting]: https://cloud.google.com/error-reporting/reference/rest/v1beta1/projects.events/report From 901dda1bc172db211e1a3c2cc90aff990da13a05 Mon Sep 17 00:00:00 2001 From: Matthew Wear Date: Tue, 14 Jul 2020 08:52:40 -0700 Subject: [PATCH 10/14] Revert "add log.severity convention" This reverts commit 137556e44bf74e6d76a17bd81943702a460cb9de. --- specification/trace/exception-reporting.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/specification/trace/exception-reporting.md b/specification/trace/exception-reporting.md index ef5fb3fb78e..68aec5e5372 100644 --- a/specification/trace/exception-reporting.md +++ b/specification/trace/exception-reporting.md @@ -18,7 +18,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 | | 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 | -| log.severity | String | The severity of the exception E.g. `Fatal`, `Error`, `Warn`, etc. | No | ### Stacktrace Representation @@ -52,8 +51,8 @@ document. **Examples:** ``` -RecordException(exception: Exception, severity: String) -RecordException(type: String, message: String, stacktrace: String, severity: String) +RecordException(exception: Exception) +RecordException(type: String, message: String, stacktrace: String) ``` [gcp-error-reporting]: https://cloud.google.com/error-reporting/reference/rest/v1beta1/projects.events/report From 7efe8d3e27e3d89328033e6d8e1c41d917faae0f Mon Sep 17 00:00:00 2001 From: Matthew Wear Date: Tue, 14 Jul 2020 09:01:33 -0700 Subject: [PATCH 11/14] rename stacktrace -> exception.stacktrace --- specification/trace/exception-reporting.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/specification/trace/exception-reporting.md b/specification/trace/exception-reporting.md index 68aec5e5372..5ddc526f2b1 100644 --- a/specification/trace/exception-reporting.md +++ b/specification/trace/exception-reporting.md @@ -13,11 +13,11 @@ The name of the event MUST be `"exception"`. 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 | -| 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 | +| 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 From 8c4502175c9760743055ed4436f4e913bda4d45d Mon Sep 17 00:00:00 2001 From: Matthew Wear Date: Thu, 16 Jul 2020 11:51:32 -0700 Subject: [PATCH 12/14] move file to semantic conventions directory --- .../exceptions.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename specification/trace/{exception-reporting.md => semantic_conventions/exceptions.md} (100%) diff --git a/specification/trace/exception-reporting.md b/specification/trace/semantic_conventions/exceptions.md similarity index 100% rename from specification/trace/exception-reporting.md rename to specification/trace/semantic_conventions/exceptions.md From 89b2548bcd5410f74358a258df84e5aa6105fb66 Mon Sep 17 00:00:00 2001 From: Matthew Wear Date: Thu, 16 Jul 2020 11:51:54 -0700 Subject: [PATCH 13/14] move RecordException to API --- specification/trace/api.md | 138 ++++++++++-------- .../trace/semantic_conventions/exceptions.md | 29 ++-- 2 files changed, 87 insertions(+), 80 deletions(-) diff --git a/specification/trace/api.md b/specification/trace/api.md index 114326a4112..e3ce6642de3 100644 --- a/specification/trace/api.md +++ b/specification/trace/api.md @@ -5,34 +5,35 @@ Table of Contents -* [Data types](#data-types) - * [Time](#time) - * [Timestamp](#timestamp) - * [Duration](#duration) -* [Tracer](#tracer) - * [Obtaining a tracer](#obtaining-a-tracer) - * [Tracer operations](#tracer-operations) -* [SpanContext](#spancontext) -* [Span](#span) - * [Span creation](#span-creation) - * [Determining the Parent Span from a Context](#determining-the-parent-span-from-a-context) - * [Add Links](#add-links) - * [Span operations](#span-operations) - * [Get Context](#get-context) - * [IsRecording](#isrecording) - * [Set Attributes](#set-attributes) - * [Add Events](#add-events) - * [Set Status](#set-status) - * [UpdateName](#updatename) - * [End](#end) - * [Span lifetime](#span-lifetime) -* [Status](#status) - * [StatusCanonicalCode](#statuscanonicalcode) - * [Status creation](#status-creation) - * [GetCanonicalCode](#getcanonicalcode) - * [GetDescription](#getdescription) - * [GetIsOk](#getisok) -* [SpanKind](#spankind) +- [Data types](#data-types) + - [Time](#time) + - [Timestamp](#timestamp) + - [Duration](#duration) +- [Tracer](#tracer) + - [Obtaining a tracer](#obtaining-a-tracer) + - [Tracer operations](#tracer-operations) +- [SpanContext](#spancontext) +- [Span](#span) + - [Span creation](#span-creation) + - [Determining the Parent Span from a Context](#determining-the-parent-span-from-a-context) + - [Add Links](#add-links) + - [Span operations](#span-operations) + - [Get Context](#get-context) + - [IsRecording](#isrecording) + - [Set Attributes](#set-attributes) + - [Add Events](#add-events) + - [Set Status](#set-status) + - [UpdateName](#updatename) + - [End](#end) + - [Record Exception](#record-exception) + - [Span lifetime](#span-lifetime) +- [Status](#status) + - [StatusCanonicalCode](#statuscanonicalcode) + - [Status creation](#status-creation) + - [GetCanonicalCode](#getcanonicalcode) + - [GetDescription](#getdescription) + - [GetIsOk](#getisok) +- [SpanKind](#spankind) @@ -57,15 +58,15 @@ The representation of those values is language specific. A timestamp is the time elapsed since the Unix epoch. -* The minimal precision is milliseconds. -* The maximal precision is nanoseconds. +- The minimal precision is milliseconds. +- The maximal precision is nanoseconds. #### Duration A duration is the elapsed time between two events. -* The minimal precision is milliseconds. -* The maximal precision is nanoseconds. +- The minimal precision is milliseconds. +- The maximal precision is nanoseconds. ## TracerProvider @@ -95,11 +96,11 @@ The `TracerProvider` MUST provide functions to: That API MUST accept the following parameters: - `name` (required): This name must identify the [instrumentation library](../overview.md#instrumentation-libraries) - (e.g. `io.opentelemetry.contrib.mongodb`) and *not* the instrumented library. + (e.g. `io.opentelemetry.contrib.mongodb`) and _not_ the instrumented library. In case an invalid name (null or empty string) is specified, a working default Tracer implementation as a fallback is returned rather than returning null or throwing an exception. - A library, implementing the OpenTelemetry API *may* also ignore this name and + A library, implementing the OpenTelemetry API _may_ also ignore this name and return a default instance for all calls, if it does not support "named" functionality (e.g. an implementation which is not even observability-related). A TracerProvider could also return a no-op Tracer here if application owners configure @@ -127,7 +128,7 @@ returned `Tracer`s and actively update their configuration if it changes. The tracer is responsible for creating `Span`s. -Note that `Tracers` should usually *not* be responsible for configuration. +Note that `Tracers` should usually _not_ be responsible for configuration. This should be the responsibility of the `TracerProvider` instead. ### Tracer operations @@ -216,12 +217,12 @@ a good name due to its high cardinality. For example, here are potential span names for an endpoint that gets a hypothetical account information: -| Span Name | Guidance | -| ----------------- | ------------ | -| `get` | Too general | -| `get_account/42` | Too specific | -| `get_account` | Good, and account_id=42 would make a nice Span attribute | -| `get_account/{accountId}` | Also good (using the "HTTP route") | +| Span Name | Guidance | +| ------------------------- | -------------------------------------------------------- | +| `get` | Too general | +| `get_account/42` | Too specific | +| `get_account` | Good, and account_id=42 would make a nice Span attribute | +| `get_account/{accountId}` | Also good (using the "HTTP route") | The `Span`'s start and end timestamps reflect the elapsed real time of the operation. @@ -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 @@ -613,55 +627,55 @@ Returns true if the canonical code of this `Status` is `Ok`, otherwise false. ## SpanKind `SpanKind` describes the relationship between the Span, its parents, -and its children in a Trace. `SpanKind` describes two independent +and its children in a Trace. `SpanKind` describes two independent properties that benefit tracing systems during analysis. The first property described by `SpanKind` reflects whether the Span -is a remote child or parent. Spans with a remote parent are -interesting because they are sources of external load. Spans with a +is a remote child or parent. Spans with a remote parent are +interesting because they are sources of external load. Spans with a remote child are interesting because they reflect a non-local system dependency. The second property described by `SpanKind` reflects whether a child -Span represents a synchronous call. When a child span is synchronous, +Span represents a synchronous call. When a child span is synchronous, the parent is expected to wait for it to complete under ordinary -circumstances. It can be useful for tracing systems to know this +circumstances. It can be useful for tracing systems to know this property, since synchronous Spans may contribute to the overall trace latency. Asynchronous scenarios can be remote or local. In order for `SpanKind` to be meaningful, callers should arrange that -a single Span does not serve more than one purpose. For example, a +a single Span does not serve more than one purpose. For example, a server-side span should not be used directly as the parent of another -remote span. As a simple guideline, instrumentation should create a +remote span. As a simple guideline, instrumentation should create a new Span prior to extracting and serializing the span context for a remote call. These are the possible SpanKinds: -* `SERVER` Indicates that the span covers server-side handling of a - synchronous RPC or other remote request. This span is the child of +- `SERVER` Indicates that the span covers server-side handling of a + synchronous RPC or other remote request. This span is the child of a remote `CLIENT` span that was expected to wait for a response. -* `CLIENT` Indicates that the span describes a synchronous request to - some remote service. This span is the parent of a remote `SERVER` +- `CLIENT` Indicates that the span describes a synchronous request to + some remote service. This span is the parent of a remote `SERVER` span and waits for its response. -* `PRODUCER` Indicates that the span describes the parent of an - asynchronous request. This parent span is expected to end before +- `PRODUCER` Indicates that the span describes the parent of an + asynchronous request. This parent span is expected to end before the corresponding child `CONSUMER` span, possibly even before the child span starts. In messaging scenarios with batching, tracing individual messages requires a new `PRODUCER` span per message to be created. -* `CONSUMER` Indicates that the span describes the child of an +- `CONSUMER` Indicates that the span describes the child of an asynchronous `PRODUCER` request. -* `INTERNAL` Default value. Indicates that the span represents an +- `INTERNAL` Default value. Indicates that the span represents an internal operation within an application, as opposed to an operations with remote parents or children. To summarize the interpretation of these kinds: | `SpanKind` | Synchronous | Asynchronous | Remote Incoming | Remote Outgoing | -|--|--|--|--|--| -| `CLIENT` | yes | | | yes | -| `SERVER` | yes | | yes | | -| `PRODUCER` | | yes | | maybe | -| `CONSUMER` | | yes | maybe | | -| `INTERNAL` | | | | | +| ---------- | ----------- | ------------ | --------------- | --------------- | +| `CLIENT` | yes | | | yes | +| `SERVER` | yes | | yes | | +| `PRODUCER` | | yes | | maybe | +| `CONSUMER` | | yes | maybe | | +| `INTERNAL` | | | | | diff --git a/specification/trace/semantic_conventions/exceptions.md b/specification/trace/semantic_conventions/exceptions.md index 5ddc526f2b1..daa204690a8 100644 --- a/specification/trace/semantic_conventions/exceptions.md +++ b/specification/trace/semantic_conventions/exceptions.md @@ -1,14 +1,22 @@ -# Exception Reporting +# Semantic Conventions for Exceptions -This document defines semantic conventions and APIs for recording application +This document defines semantic conventions for recording application exceptions. + + +- [Recording an Exception](#recording-an-exception) +- [Attributes](#attributes) + - [Stacktrace Representation](#stacktrace-representation) + + + ## 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"`. -## Semantic Conventions +## Attributes The table below indicates which attributes should be added to the `Event` and their types. @@ -40,21 +48,6 @@ 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. -## API - -To facilitate recording an exception languages SHOULD provide a -`Span.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 this -document. - -**Examples:** - -``` -RecordException(exception: Exception) -RecordException(type: String, message: String, stacktrace: String) -``` - [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 From 1ecd9ec104c8b4cf3ded584f30c20899cb765183 Mon Sep 17 00:00:00 2001 From: Matthew Wear Date: Thu, 16 Jul 2020 12:08:26 -0700 Subject: [PATCH 14/14] fix formatting --- specification/trace/api.md | 126 ++++++++++++++++++------------------- 1 file changed, 63 insertions(+), 63 deletions(-) diff --git a/specification/trace/api.md b/specification/trace/api.md index e3ce6642de3..15280db3a9f 100644 --- a/specification/trace/api.md +++ b/specification/trace/api.md @@ -5,35 +5,35 @@ Table of Contents -- [Data types](#data-types) - - [Time](#time) - - [Timestamp](#timestamp) - - [Duration](#duration) -- [Tracer](#tracer) - - [Obtaining a tracer](#obtaining-a-tracer) - - [Tracer operations](#tracer-operations) -- [SpanContext](#spancontext) -- [Span](#span) - - [Span creation](#span-creation) - - [Determining the Parent Span from a Context](#determining-the-parent-span-from-a-context) - - [Add Links](#add-links) - - [Span operations](#span-operations) - - [Get Context](#get-context) - - [IsRecording](#isrecording) - - [Set Attributes](#set-attributes) - - [Add Events](#add-events) - - [Set Status](#set-status) - - [UpdateName](#updatename) - - [End](#end) - - [Record Exception](#record-exception) - - [Span lifetime](#span-lifetime) -- [Status](#status) - - [StatusCanonicalCode](#statuscanonicalcode) - - [Status creation](#status-creation) - - [GetCanonicalCode](#getcanonicalcode) - - [GetDescription](#getdescription) - - [GetIsOk](#getisok) -- [SpanKind](#spankind) +* [Data types](#data-types) + * [Time](#time) + * [Timestamp](#timestamp) + * [Duration](#duration) +* [Tracer](#tracer) + * [Obtaining a tracer](#obtaining-a-tracer) + * [Tracer operations](#tracer-operations) +* [SpanContext](#spancontext) +* [Span](#span) + * [Span creation](#span-creation) + * [Determining the Parent Span from a Context](#determining-the-parent-span-from-a-context) + * [Add Links](#add-links) + * [Span operations](#span-operations) + * [Get Context](#get-context) + * [IsRecording](#isrecording) + * [Set Attributes](#set-attributes) + * [Add Events](#add-events) + * [Set Status](#set-status) + * [UpdateName](#updatename) + * [End](#end) + * [Record Exception](#record-exception) + * [Span lifetime](#span-lifetime) +* [Status](#status) + * [StatusCanonicalCode](#statuscanonicalcode) + * [Status creation](#status-creation) + * [GetCanonicalCode](#getcanonicalcode) + * [GetDescription](#getdescription) + * [GetIsOk](#getisok) +* [SpanKind](#spankind) @@ -58,15 +58,15 @@ The representation of those values is language specific. A timestamp is the time elapsed since the Unix epoch. -- The minimal precision is milliseconds. -- The maximal precision is nanoseconds. +* The minimal precision is milliseconds. +* The maximal precision is nanoseconds. #### Duration A duration is the elapsed time between two events. -- The minimal precision is milliseconds. -- The maximal precision is nanoseconds. +* The minimal precision is milliseconds. +* The maximal precision is nanoseconds. ## TracerProvider @@ -96,11 +96,11 @@ The `TracerProvider` MUST provide functions to: That API MUST accept the following parameters: - `name` (required): This name must identify the [instrumentation library](../overview.md#instrumentation-libraries) - (e.g. `io.opentelemetry.contrib.mongodb`) and _not_ the instrumented library. + (e.g. `io.opentelemetry.contrib.mongodb`) and *not* the instrumented library. In case an invalid name (null or empty string) is specified, a working default Tracer implementation as a fallback is returned rather than returning null or throwing an exception. - A library, implementing the OpenTelemetry API _may_ also ignore this name and + A library, implementing the OpenTelemetry API *may* also ignore this name and return a default instance for all calls, if it does not support "named" functionality (e.g. an implementation which is not even observability-related). A TracerProvider could also return a no-op Tracer here if application owners configure @@ -128,7 +128,7 @@ returned `Tracer`s and actively update their configuration if it changes. The tracer is responsible for creating `Span`s. -Note that `Tracers` should usually _not_ be responsible for configuration. +Note that `Tracers` should usually *not* be responsible for configuration. This should be the responsibility of the `TracerProvider` instead. ### Tracer operations @@ -217,12 +217,12 @@ a good name due to its high cardinality. For example, here are potential span names for an endpoint that gets a hypothetical account information: -| Span Name | Guidance | -| ------------------------- | -------------------------------------------------------- | -| `get` | Too general | -| `get_account/42` | Too specific | -| `get_account` | Good, and account_id=42 would make a nice Span attribute | -| `get_account/{accountId}` | Also good (using the "HTTP route") | +| Span Name | Guidance | +| ----------------- | ------------ | +| `get` | Too general | +| `get_account/42` | Too specific | +| `get_account` | Good, and account_id=42 would make a nice Span attribute | +| `get_account/{accountId}` | Also good (using the "HTTP route") | The `Span`'s start and end timestamps reflect the elapsed real time of the operation. @@ -627,55 +627,55 @@ Returns true if the canonical code of this `Status` is `Ok`, otherwise false. ## SpanKind `SpanKind` describes the relationship between the Span, its parents, -and its children in a Trace. `SpanKind` describes two independent +and its children in a Trace. `SpanKind` describes two independent properties that benefit tracing systems during analysis. The first property described by `SpanKind` reflects whether the Span -is a remote child or parent. Spans with a remote parent are -interesting because they are sources of external load. Spans with a +is a remote child or parent. Spans with a remote parent are +interesting because they are sources of external load. Spans with a remote child are interesting because they reflect a non-local system dependency. The second property described by `SpanKind` reflects whether a child -Span represents a synchronous call. When a child span is synchronous, +Span represents a synchronous call. When a child span is synchronous, the parent is expected to wait for it to complete under ordinary -circumstances. It can be useful for tracing systems to know this +circumstances. It can be useful for tracing systems to know this property, since synchronous Spans may contribute to the overall trace latency. Asynchronous scenarios can be remote or local. In order for `SpanKind` to be meaningful, callers should arrange that -a single Span does not serve more than one purpose. For example, a +a single Span does not serve more than one purpose. For example, a server-side span should not be used directly as the parent of another -remote span. As a simple guideline, instrumentation should create a +remote span. As a simple guideline, instrumentation should create a new Span prior to extracting and serializing the span context for a remote call. These are the possible SpanKinds: -- `SERVER` Indicates that the span covers server-side handling of a - synchronous RPC or other remote request. This span is the child of +* `SERVER` Indicates that the span covers server-side handling of a + synchronous RPC or other remote request. This span is the child of a remote `CLIENT` span that was expected to wait for a response. -- `CLIENT` Indicates that the span describes a synchronous request to - some remote service. This span is the parent of a remote `SERVER` +* `CLIENT` Indicates that the span describes a synchronous request to + some remote service. This span is the parent of a remote `SERVER` span and waits for its response. -- `PRODUCER` Indicates that the span describes the parent of an - asynchronous request. This parent span is expected to end before +* `PRODUCER` Indicates that the span describes the parent of an + asynchronous request. This parent span is expected to end before the corresponding child `CONSUMER` span, possibly even before the child span starts. In messaging scenarios with batching, tracing individual messages requires a new `PRODUCER` span per message to be created. -- `CONSUMER` Indicates that the span describes the child of an +* `CONSUMER` Indicates that the span describes the child of an asynchronous `PRODUCER` request. -- `INTERNAL` Default value. Indicates that the span represents an +* `INTERNAL` Default value. Indicates that the span represents an internal operation within an application, as opposed to an operations with remote parents or children. To summarize the interpretation of these kinds: | `SpanKind` | Synchronous | Asynchronous | Remote Incoming | Remote Outgoing | -| ---------- | ----------- | ------------ | --------------- | --------------- | -| `CLIENT` | yes | | | yes | -| `SERVER` | yes | | yes | | -| `PRODUCER` | | yes | | maybe | -| `CONSUMER` | | yes | maybe | | -| `INTERNAL` | | | | | +|--|--|--|--|--| +| `CLIENT` | yes | | | yes | +| `SERVER` | yes | | yes | | +| `PRODUCER` | | yes | | maybe | +| `CONSUMER` | | yes | maybe | | +| `INTERNAL` | | | | |