From 38e8b95c64567a24f3e519589df5fa653d03df92 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 15 Feb 2023 15:29:23 +0100 Subject: [PATCH 1/8] Added cloud_resource context --- .../src/protocol/contexts/cloud_resource.rs | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 relay-general/src/protocol/contexts/cloud_resource.rs diff --git a/relay-general/src/protocol/contexts/cloud_resource.rs b/relay-general/src/protocol/contexts/cloud_resource.rs new file mode 100644 index 00000000000..97d788cda9e --- /dev/null +++ b/relay-general/src/protocol/contexts/cloud_resource.rs @@ -0,0 +1,58 @@ +use crate::types::{Annotated}; + +/// Cloud Resource Context +/// +/// This context describes the cloud resource the event originated from. +/// +/// Example: +/// +/// ```json +/// { +/// "contexts": { +/// "cloud_resource": { +/// "cloud.provider": "aws", +/// "cloud.platform": "aws_ec2", +/// "cloud.account.id": "499517922981", +/// "cloud.region": "us-east-1", +/// "cloud.availability_zone": "us-east-1e", +/// "host.id": "i-07d3301208fe0a55a", +/// "host.type": "t2.large" +/// } +/// } +/// } +/// ``` +#[derive(Clone, Debug, Default, PartialEq, Empty, FromValue, IntoValue, ProcessValue)] +#[cfg_attr(feature = "jsonschema", derive(JsonSchema))] +pub struct CloudResourceContext { + + /// Name of the cloud provider. + pub cloud_provider: Annotated, + + /// The cloud account ID the resource is assigned to. + #[metastructure(pii = "maybe")] + pub cloud_account_id: Annotated, + + /// The geographical region the resource is running. + pub cloud_region: Annotated, + + /// The zone where the resource is running. + pub cloud_availability_zone: Annotated, + + /// The cloud platform in use. + /// The prefix of the service SHOULD match the one specified in cloud_provider. + pub cloud_platform: Annotated, + + /// Unique host ID. + #[metastructure(pii = "maybe")] + pub host_id: Annotated, + + /// Machine type of host. + pub host_type: Annotated, +} + +impl CloudResourceContext { + /// The key under which a runtime context is generally stored (in `Contexts`). + pub fn default_key() -> &'static str { + "cloud_resource" + } +} From f4eaff62364881373571ddbdf34a9410ac01c091 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 15 Feb 2023 15:49:40 +0100 Subject: [PATCH 2/8] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc7098ef2bf..975b19b26c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - Add count transactions toward root project. ([#1734](https://github.com/getsentry/relay/pull/1734)) - Add or remove the profile ID on the transaction's profiling context. ([#1801](https://github.com/getsentry/relay/pull/1801)) - Implement a new sampling algorithm with factors and multi-matching. ([#1790](https://github.com/getsentry/relay/pull/1790) +- Add CloudResource Context ([#1854](https://github.com/getsentry/relay/pull/1854)) **Bug Fixes**: From adf9cf9dec40b307a59b26bab10557ab5c01b5c3 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 15 Feb 2023 16:06:07 +0100 Subject: [PATCH 3/8] Linting --- .../src/protocol/contexts/cloud_resource.rs | 3 +- relay-general/src/protocol/contexts/mod.rs | 7 +- .../test_fixtures__event_schema.snap | 67 +++++++++++++++++++ 3 files changed, 74 insertions(+), 3 deletions(-) diff --git a/relay-general/src/protocol/contexts/cloud_resource.rs b/relay-general/src/protocol/contexts/cloud_resource.rs index 97d788cda9e..a895d4ef655 100644 --- a/relay-general/src/protocol/contexts/cloud_resource.rs +++ b/relay-general/src/protocol/contexts/cloud_resource.rs @@ -1,4 +1,4 @@ -use crate::types::{Annotated}; +use crate::types::Annotated; /// Cloud Resource Context /// @@ -24,7 +24,6 @@ use crate::types::{Annotated}; #[derive(Clone, Debug, Default, PartialEq, Empty, FromValue, IntoValue, ProcessValue)] #[cfg_attr(feature = "jsonschema", derive(JsonSchema))] pub struct CloudResourceContext { - /// Name of the cloud provider. pub cloud_provider: Annotated, diff --git a/relay-general/src/protocol/contexts/mod.rs b/relay-general/src/protocol/contexts/mod.rs index 858e3d81521..e853818a7f3 100644 --- a/relay-general/src/protocol/contexts/mod.rs +++ b/relay-general/src/protocol/contexts/mod.rs @@ -22,6 +22,8 @@ mod trace; pub use trace::*; mod otel; pub use otel::*; +mod cloud_resource; +pub use cloud_resource::*; use crate::types::{Annotated, FromValue, Object, Value}; use crate::user_agent::{ClientHints, RawUserAgentInfo}; @@ -58,8 +60,10 @@ pub enum Context { Reprocessing(Box), /// Response information. Response(Box), - /// OpenTelemetry information + /// OpenTelemetry information. Otel(Box), + /// Cloud resource information. + CloudResource(Box), /// Additional arbitrary fields for forwards compatibility. #[metastructure(fallback_variant)] Other(#[metastructure(pii = "true")] Object), @@ -83,6 +87,7 @@ impl Context { Context::Monitor(_) => Some(MonitorContext::default_key()), Context::Response(_) => Some(ResponseContext::default_key()), Context::Otel(_) => Some(OtelContext::default_key()), + Context::CloudResource(_) => Some(CloudResourceContext::default_key()), Context::Other(_) => None, } } diff --git a/relay-general/tests/snapshots/test_fixtures__event_schema.snap b/relay-general/tests/snapshots/test_fixtures__event_schema.snap index 3095ea9f03d..46e9d687d65 100644 --- a/relay-general/tests/snapshots/test_fixtures__event_schema.snap +++ b/relay-general/tests/snapshots/test_fixtures__event_schema.snap @@ -2421,6 +2421,73 @@ expression: "relay_general::protocol::event_json_schema()" } ] }, + "CloudResourceContext": { + "description": " Cloud Resource Context\n\n If an event originated in a cloud environment (like AWS, GCP).", + "anyOf": [ + { + "type": "object", + "properties": { + "cloud_provider": { + "description": " Name of the cloud provider", + "default": null, + "type": [ + "string", + "null" + ] + }, + "cloud_account_id": { + "description": " The cloud account ID the resource is assigned to.", + "default": null, + "type": [ + "string", + "null" + ] + }, + "cloud_region": { + "description": " The geographical region the resource is running.", + "default": null, + "type": [ + "string", + "null" + ] + }, + "cloud_availability_zone": { + "description": " The zone where the resource is running.", + "default": null, + "type": [ + "string", + "null" + ] + }, + "cloud_platform": { + "description": " The cloud platform in use.", + "default": null, + "type": [ + "string", + "null" + ] + }, + "host_id": { + "description": " Unique host ID.", + "default": null, + "type": [ + "string", + "null" + ] + }, + "host_type": { + "description": " Machine type of host.", + "default": null, + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + ] + }, "PosixSignal": { "description": " POSIX signal with optional extended data.\n\n On Apple systems, signals also carry a code in addition to the signal number describing the\n signal in more detail. On Linux, this code does not exist.", "anyOf": [ From c9fcc7f6c362300ada5a9685a269d485a868458c Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Thu, 16 Feb 2023 09:00:41 +0100 Subject: [PATCH 4/8] Added roundtrip test --- .../src/protocol/contexts/cloud_resource.rs | 89 +++++++++--- .../test_fixtures__event_schema.snap | 137 +++++++++--------- 2 files changed, 139 insertions(+), 87 deletions(-) diff --git a/relay-general/src/protocol/contexts/cloud_resource.rs b/relay-general/src/protocol/contexts/cloud_resource.rs index a895d4ef655..1d6ea56f441 100644 --- a/relay-general/src/protocol/contexts/cloud_resource.rs +++ b/relay-general/src/protocol/contexts/cloud_resource.rs @@ -1,4 +1,4 @@ -use crate::types::Annotated; +use crate::types::{Annotated, Object, Value}; /// Cloud Resource Context /// @@ -7,46 +7,53 @@ use crate::types::Annotated; /// Example: /// /// ```json -/// { -/// "contexts": { -/// "cloud_resource": { -/// "cloud.provider": "aws", -/// "cloud.platform": "aws_ec2", -/// "cloud.account.id": "499517922981", -/// "cloud.region": "us-east-1", -/// "cloud.availability_zone": "us-east-1e", -/// "host.id": "i-07d3301208fe0a55a", -/// "host.type": "t2.large" -/// } -/// } +/// "cloud_resource": { +/// "cloud.account.id": "499517922981", +/// "cloud.provider": "aws", +/// "cloud.platform": "aws_ec2", +/// "cloud.region": "us-east-1", +/// "cloud.vavailability_zone": "us-east-1e", +/// "host.id": "i-07d3301208fe0a55a", +/// "host.type": "t2.large" /// } /// ``` #[derive(Clone, Debug, Default, PartialEq, Empty, FromValue, IntoValue, ProcessValue)] #[cfg_attr(feature = "jsonschema", derive(JsonSchema))] pub struct CloudResourceContext { - /// Name of the cloud provider. - pub cloud_provider: Annotated, - /// The cloud account ID the resource is assigned to. #[metastructure(pii = "maybe")] + #[metastructure(field = "cloud.account.id")] pub cloud_account_id: Annotated, + /// Name of the cloud provider. + #[metastructure(field = "cloud.provider")] + pub cloud_provider: Annotated, + + /// The cloud platform in use. + /// The prefix of the service SHOULD match the one specified in cloud_provider. + #[metastructure(field = "cloud.platform")] + pub cloud_platform: Annotated, + /// The geographical region the resource is running. + #[metastructure(field = "cloud.region")] pub cloud_region: Annotated, /// The zone where the resource is running. + #[metastructure(field = "cloud.availability_zone")] pub cloud_availability_zone: Annotated, - /// The cloud platform in use. - /// The prefix of the service SHOULD match the one specified in cloud_provider. - pub cloud_platform: Annotated, - /// Unique host ID. #[metastructure(pii = "maybe")] + #[metastructure(field = "host.id")] pub host_id: Annotated, /// Machine type of host. + #[metastructure(field = "host.type")] pub host_type: Annotated, + + /// Additional arbitrary fields for forwards compatibility. + #[metastructure(additional_properties, retain = "true", pii = "maybe")] + pub other: Object, } impl CloudResourceContext { @@ -55,3 +62,45 @@ impl CloudResourceContext { "cloud_resource" } } + +#[cfg(test)] +mod tests { + use crate::protocol::Context; + + use super::*; + + #[test] + pub(crate) fn test_cloud_resource_context_roundtrip() { + let json = r#"{ + "cloud.account.id": "499517922981", + "cloud.provider": "aws", + "cloud.platform": "aws_ec2", + "cloud.region": "us-east-1", + "cloud.availability_zone": "us-east-1e", + "host.id": "i-07d3301208fe0a55a", + "host.type": "t2.large", + "other": "value", + "type": "cloudresource" +}"#; + let context = Annotated::new(Context::CloudResource(Box::new(CloudResourceContext { + cloud_account_id: Annotated::new("499517922981".into()), + cloud_provider: Annotated::new("aws".into()), + cloud_platform: Annotated::new("aws_ec2".into()), + cloud_region: Annotated::new("us-east-1".into()), + cloud_availability_zone: Annotated::new("us-east-1e".into()), + host_id: Annotated::new("i-07d3301208fe0a55a".into()), + host_type: Annotated::new("t2.large".into()), + other: { + let mut map = Object::new(); + map.insert( + "other".to_string(), + Annotated::new(Value::String("value".to_string())), + ); + map + }, + }))); + + assert_eq!(context, Annotated::from_json(json).unwrap()); + assert_eq!(json, context.to_json_pretty().unwrap()); + } +} diff --git a/relay-general/tests/snapshots/test_fixtures__event_schema.snap b/relay-general/tests/snapshots/test_fixtures__event_schema.snap index 46e9d687d65..d766c2fbb13 100644 --- a/relay-general/tests/snapshots/test_fixtures__event_schema.snap +++ b/relay-general/tests/snapshots/test_fixtures__event_schema.snap @@ -800,6 +800,73 @@ expression: "relay_general::protocol::event_json_schema()" } ] }, + "CloudResourceContext": { + "description": " Cloud Resource Context\n\n This context describes the cloud resource the event originated from.\n\n Example:\n\n ```json\n \"cloud_resource\": {\n \"cloud.account.id\": \"499517922981\",\n \"cloud.provider\": \"aws\",\n \"cloud.platform\": \"aws_ec2\",\n \"cloud.region\": \"us-east-1\",\n \"cloud.vavailability_zone\": \"us-east-1e\",\n \"host.id\": \"i-07d3301208fe0a55a\",\n \"host.type\": \"t2.large\"\n }\n ```", + "anyOf": [ + { + "type": "object", + "properties": { + "cloud.account.id": { + "description": " The cloud account ID the resource is assigned to.", + "default": null, + "type": [ + "string", + "null" + ] + }, + "cloud.availability_zone": { + "description": " The zone where the resource is running.", + "default": null, + "type": [ + "string", + "null" + ] + }, + "cloud.platform": { + "description": " The cloud platform in use.\n The prefix of the service SHOULD match the one specified in cloud_provider.", + "default": null, + "type": [ + "string", + "null" + ] + }, + "cloud.provider": { + "description": " Name of the cloud provider.", + "default": null, + "type": [ + "string", + "null" + ] + }, + "cloud.region": { + "description": " The geographical region the resource is running.", + "default": null, + "type": [ + "string", + "null" + ] + }, + "host.id": { + "description": " Unique host ID.", + "default": null, + "type": [ + "string", + "null" + ] + }, + "host.type": { + "description": " Machine type of host.", + "default": null, + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + ] + }, "CodeId": { "type": "string" }, @@ -839,6 +906,9 @@ expression: "relay_general::protocol::event_json_schema()" { "$ref": "#/definitions/OtelContext" }, + { + "$ref": "#/definitions/CloudResourceContext" + }, { "type": "object", "additionalProperties": true @@ -2421,73 +2491,6 @@ expression: "relay_general::protocol::event_json_schema()" } ] }, - "CloudResourceContext": { - "description": " Cloud Resource Context\n\n If an event originated in a cloud environment (like AWS, GCP).", - "anyOf": [ - { - "type": "object", - "properties": { - "cloud_provider": { - "description": " Name of the cloud provider", - "default": null, - "type": [ - "string", - "null" - ] - }, - "cloud_account_id": { - "description": " The cloud account ID the resource is assigned to.", - "default": null, - "type": [ - "string", - "null" - ] - }, - "cloud_region": { - "description": " The geographical region the resource is running.", - "default": null, - "type": [ - "string", - "null" - ] - }, - "cloud_availability_zone": { - "description": " The zone where the resource is running.", - "default": null, - "type": [ - "string", - "null" - ] - }, - "cloud_platform": { - "description": " The cloud platform in use.", - "default": null, - "type": [ - "string", - "null" - ] - }, - "host_id": { - "description": " Unique host ID.", - "default": null, - "type": [ - "string", - "null" - ] - }, - "host_type": { - "description": " Machine type of host.", - "default": null, - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - ] - }, "PosixSignal": { "description": " POSIX signal with optional extended data.\n\n On Apple systems, signals also carry a code in addition to the signal number describing the\n signal in more detail. On Linux, this code does not exist.", "anyOf": [ From 9de16cf12161b9bf0819a7fa39dc2946bd1c0a67 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Fri, 17 Feb 2023 08:32:19 +0100 Subject: [PATCH 5/8] Update CHANGELOG.md Co-authored-by: Oleksandr <1931331+olksdr@users.noreply.github.com> --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c6f58ea6f3c..1443cb69e93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ - Add count transactions toward root project. ([#1734](https://github.com/getsentry/relay/pull/1734)) - Add or remove the profile ID on the transaction's profiling context. ([#1801](https://github.com/getsentry/relay/pull/1801)) - Implement a new sampling algorithm with factors and multi-matching. ([#1790](https://github.com/getsentry/relay/pull/1790) -- Add CloudResource Context ([#1854](https://github.com/getsentry/relay/pull/1854)) +- Add Cloud Resource context. ([#1854](https://github.com/getsentry/relay/pull/1854)) **Bug Fixes**: From 19b2845b1c71362ab1960e6eaba9d3c946f9dd4f Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Fri, 17 Feb 2023 08:32:29 +0100 Subject: [PATCH 6/8] Update relay-general/src/protocol/contexts/cloud_resource.rs Co-authored-by: Oleksandr <1931331+olksdr@users.noreply.github.com> --- relay-general/src/protocol/contexts/cloud_resource.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relay-general/src/protocol/contexts/cloud_resource.rs b/relay-general/src/protocol/contexts/cloud_resource.rs index 1d6ea56f441..f72871bcf88 100644 --- a/relay-general/src/protocol/contexts/cloud_resource.rs +++ b/relay-general/src/protocol/contexts/cloud_resource.rs @@ -1,6 +1,6 @@ use crate::types::{Annotated, Object, Value}; -/// Cloud Resource Context +/// Cloud Resource Context. /// /// This context describes the cloud resource the event originated from. /// From 551c3cea36525f11f371220f9b610ea220be2ae9 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Fri, 17 Feb 2023 08:32:35 +0100 Subject: [PATCH 7/8] Update relay-general/src/protocol/contexts/cloud_resource.rs Co-authored-by: Oleksandr <1931331+olksdr@users.noreply.github.com> --- relay-general/src/protocol/contexts/cloud_resource.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relay-general/src/protocol/contexts/cloud_resource.rs b/relay-general/src/protocol/contexts/cloud_resource.rs index f72871bcf88..84fedb5a4e9 100644 --- a/relay-general/src/protocol/contexts/cloud_resource.rs +++ b/relay-general/src/protocol/contexts/cloud_resource.rs @@ -47,7 +47,7 @@ pub struct CloudResourceContext { #[metastructure(field = "host.id")] pub host_id: Annotated, - /// Machine type of host. + /// Machine type of the host. #[metastructure(field = "host.type")] pub host_type: Annotated, From fe2e4a27928475a76085c99b8f6a7479b72a1655 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Fri, 17 Feb 2023 08:46:01 +0100 Subject: [PATCH 8/8] Updated fixture --- .../tests/snapshots/test_fixtures__event_schema.snap | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/relay-general/tests/snapshots/test_fixtures__event_schema.snap b/relay-general/tests/snapshots/test_fixtures__event_schema.snap index d766c2fbb13..dcab159c011 100644 --- a/relay-general/tests/snapshots/test_fixtures__event_schema.snap +++ b/relay-general/tests/snapshots/test_fixtures__event_schema.snap @@ -801,7 +801,7 @@ expression: "relay_general::protocol::event_json_schema()" ] }, "CloudResourceContext": { - "description": " Cloud Resource Context\n\n This context describes the cloud resource the event originated from.\n\n Example:\n\n ```json\n \"cloud_resource\": {\n \"cloud.account.id\": \"499517922981\",\n \"cloud.provider\": \"aws\",\n \"cloud.platform\": \"aws_ec2\",\n \"cloud.region\": \"us-east-1\",\n \"cloud.vavailability_zone\": \"us-east-1e\",\n \"host.id\": \"i-07d3301208fe0a55a\",\n \"host.type\": \"t2.large\"\n }\n ```", + "description": " Cloud Resource Context.\n\n This context describes the cloud resource the event originated from.\n\n Example:\n\n ```json\n \"cloud_resource\": {\n \"cloud.account.id\": \"499517922981\",\n \"cloud.provider\": \"aws\",\n \"cloud.platform\": \"aws_ec2\",\n \"cloud.region\": \"us-east-1\",\n \"cloud.vavailability_zone\": \"us-east-1e\",\n \"host.id\": \"i-07d3301208fe0a55a\",\n \"host.type\": \"t2.large\"\n }\n ```", "anyOf": [ { "type": "object", @@ -855,7 +855,7 @@ expression: "relay_general::protocol::event_json_schema()" ] }, "host.type": { - "description": " Machine type of host.", + "description": " Machine type of the host.", "default": null, "type": [ "string",