Skip to content

Commit

Permalink
Update body definition to include
Browse files Browse the repository at this point in the history
- type
- brief
- note
- stability
- examples
  • Loading branch information
MSNev committed Aug 30, 2024
1 parent f82621e commit f4a3c3e
Show file tree
Hide file tree
Showing 18 changed files with 418 additions and 63 deletions.
1 change: 1 addition & 0 deletions crates/weaver_forge/data/mobile-events.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ groups:
the `android.state` and `ios.state` fields. The `android.state` and `ios.state` attributes are
mutually exclusive.
body:
type: map
fields:
- id: ios.state
stability: experimental
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[{"attributes":[],"body":{"fields":[{"brief":"This attribute represents the state the application has transitioned into at the occurrence of the event.\n","name":"ios.state","note":"The iOS lifecycle states are defined in the [UIApplicationDelegate documentation](https://developer.apple.com/documentation/uikit/uiapplicationdelegate#1656902), and from which the `OS terminology` column values are derived.\n","requirement_level":{"conditionally_required":"if and only if `os.name` is `ios`"},"stability":"experimental","type":{"allow_custom_values":false,"members":[{"brief":"The app has become `active`. Associated with UIKit notification `applicationDidBecomeActive`.\n","deprecated":null,"id":"active","note":null,"stability":null,"value":"active"},{"brief":"The app is now `inactive`. Associated with UIKit notification `applicationWillResignActive`.\n","deprecated":null,"id":"inactive","note":null,"stability":null,"value":"inactive"},{"brief":"The app is now in the background. This value is associated with UIKit notification `applicationDidEnterBackground`.\n","deprecated":null,"id":"background","note":null,"stability":null,"value":"background"},{"brief":"The app is now in the foreground. This value is associated with UIKit notification `applicationWillEnterForeground`.\n","deprecated":null,"id":"foreground","note":null,"stability":null,"value":"foreground"},{"brief":"The app is about to terminate. Associated with UIKit notification `applicationWillTerminate`.\n","deprecated":null,"id":"terminate","note":null,"stability":null,"value":"terminate"}]}},{"brief":"This attribute represents the state the application has transitioned into at the occurrence of the event.\n","name":"android.state","note":"The Android lifecycle states are defined in [Activity lifecycle callbacks](https://developer.android.com/guide/components/activities/activity-lifecycle#lc), and from which the `OS identifiers` are derived.\n","requirement_level":{"conditionally_required":"if and only if `os.name` is `android`"},"stability":"experimental","type":{"allow_custom_values":false,"members":[{"brief":"Any time before Activity.onResume() or, if the app has no Activity, Context.startService() has been called in the app for the first time.\n","deprecated":null,"id":"created","note":null,"stability":null,"value":"created"},{"brief":"Any time after Activity.onPause() or, if the app has no Activity, Context.stopService() has been called when the app was in the foreground state.\n","deprecated":null,"id":"background","note":null,"stability":null,"value":"background"},{"brief":"Any time after Activity.onResume() or, if the app has no Activity, Context.startService() has been called when the app was in either the created or background states.","deprecated":null,"id":"foreground","note":null,"stability":null,"value":"foreground"}]}}]},"brief":"This event represents an occurrence of a lifecycle transition on Android or iOS platform.\n","event_namespace":"device.app","events":[],"id":"device.app.lifecycle","instrument":null,"lineage":{"source_file":"data/mobile-events.yaml"},"metric_name":null,"name":"device.app.lifecycle","note":"This event identifies the fields that are common to all lifecycle events for android and iOS using the `android.state` and `ios.state` fields. The `android.state` and `ios.state` attributes are mutually exclusive.\n","span_kind":null,"stability":"experimental","type":"event","unit":null},{"attributes":[{"brief":"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.\n","examples":"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)","name":"exception.stacktrace","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span.\n","name":"exception.escaped","note":"An exception is considered to have escaped (or left) the scope of a span,\nif that span is ended while the exception is still logically \"in flight\".\nThis may be actually \"in flight\" in some languages (e.g. if the exception\nis passed to a Context manager\u0027s `__exit__` method in Python) but will\nusually be caught at the point of recording the exception in most languages.\n\nIt is usually not possible to determine at the point where an exception is thrown\nwhether it will escape the scope of a span.\nHowever, it is trivial to know that an exception\nwill escape, if one checks for an active exception just before ending the span,\nas done in the [example for recording span exceptions](https://opentelemetry.io/docs/specs/semconv/exceptions/exceptions-spans/#recording-an-exception).\n\nIt follows that an exception may still escape the scope of the span\neven if the `exception.escaped` attribute was not set or set to false,\nsince the event might have been recorded at a time where it was not\nclear whether the exception will escape.","requirement_level":"recommended","stability":"stable","type":"boolean"},{"brief":"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.\n","examples":["java.net.ConnectException","OSError"],"name":"exception.type","requirement_level":{"conditionally_required":"Required if `exception.message` is not set, recommended otherwise."},"stability":"stable","type":"string"},{"brief":"The exception message.","examples":["Division by zero","Can\u0027t convert \u0027int\u0027 object to str implicitly"],"name":"exception.message","requirement_level":{"conditionally_required":"Required if `exception.type` is not set, recommended otherwise."},"stability":"stable","type":"string"}],"brief":"This document defines the attributes used to report a single exception associated with a span.\n","event_namespace":"other","events":[],"id":"trace-exception","instrument":null,"lineage":{"attributes":{"exception.escaped":{"inherited_fields":["brief","note","requirement_level","stability"],"source_group":"registry.exception"},"exception.message":{"inherited_fields":["brief","examples","note","stability"],"locally_overridden_fields":["requirement_level"],"source_group":"registry.exception"},"exception.stacktrace":{"inherited_fields":["brief","examples","note","requirement_level","stability"],"source_group":"registry.exception"},"exception.type":{"inherited_fields":["brief","examples","note","stability"],"locally_overridden_fields":["requirement_level"],"source_group":"registry.exception"}},"source_file":"data/trace-exception.yaml"},"metric_name":null,"name":null,"prefix":"exception","span_kind":null,"type":"event","unit":null}]
[{"attributes":[],"body":{"fields":[{"brief":"This attribute represents the state the application has transitioned into at the occurrence of the event.\n","name":"ios.state","note":"The iOS lifecycle states are defined in the [UIApplicationDelegate documentation](https://developer.apple.com/documentation/uikit/uiapplicationdelegate#1656902), and from which the `OS terminology` column values are derived.\n","requirement_level":{"conditionally_required":"if and only if `os.name` is `ios`"},"stability":"experimental","type":{"allow_custom_values":false,"members":[{"brief":"The app has become `active`. Associated with UIKit notification `applicationDidBecomeActive`.\n","deprecated":null,"id":"active","note":null,"stability":null,"value":"active"},{"brief":"The app is now `inactive`. Associated with UIKit notification `applicationWillResignActive`.\n","deprecated":null,"id":"inactive","note":null,"stability":null,"value":"inactive"},{"brief":"The app is now in the background. This value is associated with UIKit notification `applicationDidEnterBackground`.\n","deprecated":null,"id":"background","note":null,"stability":null,"value":"background"},{"brief":"The app is now in the foreground. This value is associated with UIKit notification `applicationWillEnterForeground`.\n","deprecated":null,"id":"foreground","note":null,"stability":null,"value":"foreground"},{"brief":"The app is about to terminate. Associated with UIKit notification `applicationWillTerminate`.\n","deprecated":null,"id":"terminate","note":null,"stability":null,"value":"terminate"}]}},{"brief":"This attribute represents the state the application has transitioned into at the occurrence of the event.\n","name":"android.state","note":"The Android lifecycle states are defined in [Activity lifecycle callbacks](https://developer.android.com/guide/components/activities/activity-lifecycle#lc), and from which the `OS identifiers` are derived.\n","requirement_level":{"conditionally_required":"if and only if `os.name` is `android`"},"stability":"experimental","type":{"allow_custom_values":false,"members":[{"brief":"Any time before Activity.onResume() or, if the app has no Activity, Context.startService() has been called in the app for the first time.\n","deprecated":null,"id":"created","note":null,"stability":null,"value":"created"},{"brief":"Any time after Activity.onPause() or, if the app has no Activity, Context.stopService() has been called when the app was in the foreground state.\n","deprecated":null,"id":"background","note":null,"stability":null,"value":"background"},{"brief":"Any time after Activity.onResume() or, if the app has no Activity, Context.startService() has been called when the app was in either the created or background states.","deprecated":null,"id":"foreground","note":null,"stability":null,"value":"foreground"}]}}],"type":"map"},"brief":"This event represents an occurrence of a lifecycle transition on Android or iOS platform.\n","event_namespace":"device.app","events":[],"id":"device.app.lifecycle","instrument":null,"lineage":{"source_file":"data/mobile-events.yaml"},"metric_name":null,"name":"device.app.lifecycle","note":"This event identifies the fields that are common to all lifecycle events for android and iOS using the `android.state` and `ios.state` fields. The `android.state` and `ios.state` attributes are mutually exclusive.\n","span_kind":null,"stability":"experimental","type":"event","unit":null},{"attributes":[{"brief":"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.\n","examples":"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)","name":"exception.stacktrace","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span.\n","name":"exception.escaped","note":"An exception is considered to have escaped (or left) the scope of a span,\nif that span is ended while the exception is still logically \"in flight\".\nThis may be actually \"in flight\" in some languages (e.g. if the exception\nis passed to a Context manager\u0027s `__exit__` method in Python) but will\nusually be caught at the point of recording the exception in most languages.\n\nIt is usually not possible to determine at the point where an exception is thrown\nwhether it will escape the scope of a span.\nHowever, it is trivial to know that an exception\nwill escape, if one checks for an active exception just before ending the span,\nas done in the [example for recording span exceptions](https://opentelemetry.io/docs/specs/semconv/exceptions/exceptions-spans/#recording-an-exception).\n\nIt follows that an exception may still escape the scope of the span\neven if the `exception.escaped` attribute was not set or set to false,\nsince the event might have been recorded at a time where it was not\nclear whether the exception will escape.","requirement_level":"recommended","stability":"stable","type":"boolean"},{"brief":"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.\n","examples":["java.net.ConnectException","OSError"],"name":"exception.type","requirement_level":{"conditionally_required":"Required if `exception.message` is not set, recommended otherwise."},"stability":"stable","type":"string"},{"brief":"The exception message.","examples":["Division by zero","Can\u0027t convert \u0027int\u0027 object to str implicitly"],"name":"exception.message","requirement_level":{"conditionally_required":"Required if `exception.type` is not set, recommended otherwise."},"stability":"stable","type":"string"}],"brief":"This document defines the attributes used to report a single exception associated with a span.\n","event_namespace":"other","events":[],"id":"trace-exception","instrument":null,"lineage":{"attributes":{"exception.escaped":{"inherited_fields":["brief","note","requirement_level","stability"],"source_group":"registry.exception"},"exception.message":{"inherited_fields":["brief","examples","note","stability"],"locally_overridden_fields":["requirement_level"],"source_group":"registry.exception"},"exception.stacktrace":{"inherited_fields":["brief","examples","note","requirement_level","stability"],"source_group":"registry.exception"},"exception.type":{"inherited_fields":["brief","examples","note","stability"],"locally_overridden_fields":["requirement_level"],"source_group":"registry.exception"}},"source_file":"data/trace-exception.yaml"},"metric_name":null,"name":null,"prefix":"exception","span_kind":null,"type":"event","unit":null}]
29 changes: 23 additions & 6 deletions crates/weaver_resolved_schema/src/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,37 @@
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use weaver_semconv::attribute::{AttributeType, Examples, RequirementLevel};
use weaver_semconv::body::{BodyFieldSpec, BodySpec};
use weaver_semconv::body::{BodyFieldSpec, BodySpec, BodyType};
use weaver_semconv::stability::Stability;

/// A `Body` definition.
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq, Hash, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct Body {
/// The body specification.
/// Identifies the type of the body. It can be "map", "string".
pub r#type: BodyType,
/// A brief description of the body.
#[serde(skip_serializing_if = "String::is_empty")]
#[serde(default)]
pub brief: String,
/// A more elaborate description of the body.
/// It defaults to an empty string.
#[serde(skip_serializing_if = "String::is_empty")]
#[serde(default)]
pub note: String,
/// Specifies the stability of the body.
#[serde(skip_serializing_if = "Option::is_none")]
pub stability: Option<Stability>,
/// Sequence of example values for the body or single example
/// value. They are required only for string types. Example values
/// must be of the same type of the body. If only a single example is
/// provided, it can directly be reported without encapsulating it
/// into a sequence/dictionary.
#[serde(skip_serializing_if = "Option::is_none")]
pub examples: Option<Examples>,
/// Identifies the definition of the "fields" of the body when the body type is "map".
#[serde(skip_serializing_if = "Option::is_none")]
pub fields: Option<Vec<BodyField>>,
// Not yet defined in the spec or implemented in the resolver
// The body value when there are no fields
// #[serde(skip_serializing_if = "Option::is_none")]
// pub value: Option<Value>
}

/// A `BodyField` definition.
Expand Down
13 changes: 7 additions & 6 deletions crates/weaver_resolved_schema/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
//! Error types and utilities.

use serde::{Deserialize, Serialize};
use weaver_semconv::body::BodySpec;

use crate::attribute::AttributeRef;
use crate::error::Error::{AttributeNotFound, CompoundError, NotImplemented};
use crate::error::Error::{AttributeNotFound, CompoundError, InvalidBody};

/// Errors emitted by this crate.
#[derive(thiserror::Error, Debug, Clone, Deserialize, Serialize)]
Expand All @@ -24,10 +25,10 @@ pub enum Error {
CompoundError(Vec<Error>),

/// A generic error identifying a feature that has not yet been implemented.
#[error("Not Implemented: {message}")]
NotImplemented {
/// A message describing the feature that has not been implemented.
message: String,
#[error("Unsupported BodySpec")]
InvalidBody {
/// The body specification that is not supported.
body: BodySpec,
},
}

Expand All @@ -52,7 +53,7 @@ impl Error {
.flat_map(|e| match e {
CompoundError(errors) => errors,
e @ AttributeNotFound { .. } => vec![e],
e @ NotImplemented { .. } => vec![e],
e @ InvalidBody { .. } => vec![e],
})
.collect(),
)
Expand Down
2 changes: 1 addition & 1 deletion crates/weaver_resolved_schema/src/signal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ pub struct MultivariateMetric {
#[derive(Serialize, Deserialize, Debug, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct Event {
/// The name of the event.
/// The name of the event
name: String,
/// References to attributes defined in the catalog.
#[serde(skip_serializing_if = "Vec::is_empty")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"Linux"
],
"requirement_level": "recommended",
"note": "This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.platform`). If unavailable, the legacy `navigator.platform` API SHOULD NOT be used instead and this attribute SHOULD be left unset in order for the values to be consistent. The list of possible values is defined in the [W3C User-Agent Client Hints specification](https://wicg.github.io/ua-client-hints/#sec-ch-ua-platform). Note that some (but not all) of these values can overlap with values in the [`os.type` and `os.name` attributes](./os.md). However, for consistency, the values in the `browser.platform` attribute should capture the exact value that the user agent provides.\n"
"note": "This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.platform`). \n"
},
{
"name": "browser.mobile",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@
]
}
}
]
],
"type": "map"
},
"brief": "This event represents an occurrence of a lifecycle transition on Android or iOS platform.\n",
"event_namespace": "device.app",
Expand Down
Loading

0 comments on commit f4a3c3e

Please sign in to comment.