-
Notifications
You must be signed in to change notification settings - Fork 93
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into ref/service-shared-response
* master: ref(system): Introduce a generic recipient type (#1622) feat(transaction): Normalize transaction name (#1621) feat(server): Track metrics for OpenTelemetry events (#1618) bug(replays): Increase reserved space in payload chunks (#1601) feat(protocol): Add OpenTelemetry Context (#1617)
- Loading branch information
Showing
14 changed files
with
592 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
use crate::types::{Annotated, Object, Value}; | ||
|
||
/// OpenTelemetry Context | ||
/// | ||
/// If an event has this context, it was generated from an OpenTelemetry signal (trace, metric, log). | ||
#[derive(Clone, Debug, Default, PartialEq, Empty, FromValue, IntoValue, ProcessValue)] | ||
#[cfg_attr(feature = "jsonschema", derive(JsonSchema))] | ||
pub struct OtelContext { | ||
/// Attributes of the OpenTelemetry span that maps to a Sentry event. | ||
/// | ||
/// <https://github.com/open-telemetry/opentelemetry-proto/blob/724e427879e3d2bae2edc0218fff06e37b9eb46e/opentelemetry/proto/trace/v1/trace.proto#L174-L186> | ||
#[metastructure(pii = "maybe", bag_size = "large")] | ||
attributes: Annotated<Object<Value>>, | ||
|
||
/// Information about an OpenTelemetry resource. | ||
/// | ||
/// <https://github.com/open-telemetry/opentelemetry-proto/blob/724e427879e3d2bae2edc0218fff06e37b9eb46e/opentelemetry/proto/resource/v1/resource.proto> | ||
#[metastructure(pii = "maybe", bag_size = "large")] | ||
resource: Annotated<Object<Value>>, | ||
|
||
/// Additional arbitrary fields for forwards compatibility. | ||
#[metastructure(additional_properties, retain = "true", pii = "maybe")] | ||
pub other: Object<Value>, | ||
} | ||
|
||
impl OtelContext { | ||
/// The key under which a runtime context is generally stored (in `Contexts`). | ||
pub fn default_key() -> &'static str { | ||
"otel" | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use crate::protocol::Context; | ||
|
||
use super::*; | ||
|
||
#[test] | ||
pub(crate) fn test_otel_context_roundtrip() { | ||
let json = r#"{ | ||
"attributes": { | ||
"app.payment.amount": 394.25, | ||
"rpc.grpc.status_code": "1", | ||
"rpc.method": "Charge", | ||
"rpc.service": "hipstershop.PaymentService", | ||
"rpc.system": "grpc" | ||
}, | ||
"resource": { | ||
"process.command": "/usr/src/app/index.js", | ||
"process.command_line": "/usr/local/bin/node /usr/src/app/index.js", | ||
"process.executable.name": "node", | ||
"process.pid": 1, | ||
"process.runtime.description": "Node.js", | ||
"process.runtime.name": "nodejs", | ||
"process.runtime.version": "16.18.0", | ||
"service.name": "paymentservice", | ||
"telemetry.sdk.language": "nodejs", | ||
"telemetry.sdk.name": "opentelemetry", | ||
"telemetry.sdk.version": "1.7.0" | ||
}, | ||
"other": "value", | ||
"type": "otel" | ||
}"#; | ||
let context = Annotated::new(Context::Otel(Box::new(OtelContext { | ||
attributes: Annotated::new(Object::from([ | ||
( | ||
"app.payment.amount".to_string(), | ||
Annotated::new(Value::F64(394.25)), | ||
), | ||
( | ||
"rpc.grpc.status_code".to_string(), | ||
Annotated::new(Value::String("1".to_string())), | ||
), | ||
( | ||
"rpc.method".to_string(), | ||
Annotated::new(Value::String("Charge".to_string())), | ||
), | ||
( | ||
"rpc.service".to_string(), | ||
Annotated::new(Value::String("hipstershop.PaymentService".to_string())), | ||
), | ||
( | ||
"rpc.system".to_string(), | ||
Annotated::new(Value::String("grpc".to_string())), | ||
), | ||
])), | ||
resource: Annotated::new(Object::from([ | ||
( | ||
"process.command".to_string(), | ||
Annotated::new(Value::String("/usr/src/app/index.js".to_string())), | ||
), | ||
( | ||
"process.command_line".to_string(), | ||
Annotated::new(Value::String( | ||
"/usr/local/bin/node /usr/src/app/index.js".to_string(), | ||
)), | ||
), | ||
( | ||
"process.executable.name".to_string(), | ||
Annotated::new(Value::String("node".to_string())), | ||
), | ||
("process.pid".to_string(), Annotated::new(Value::I64(1))), | ||
( | ||
"process.runtime.description".to_string(), | ||
Annotated::new(Value::String("Node.js".to_string())), | ||
), | ||
( | ||
"process.runtime.name".to_string(), | ||
Annotated::new(Value::String("nodejs".to_string())), | ||
), | ||
( | ||
"process.runtime.version".to_string(), | ||
Annotated::new(Value::String("16.18.0".to_string())), | ||
), | ||
( | ||
"service.name".to_string(), | ||
Annotated::new(Value::String("paymentservice".to_string())), | ||
), | ||
( | ||
"telemetry.sdk.language".to_string(), | ||
Annotated::new(Value::String("nodejs".to_string())), | ||
), | ||
( | ||
"telemetry.sdk.name".to_string(), | ||
Annotated::new(Value::String("opentelemetry".to_string())), | ||
), | ||
( | ||
"telemetry.sdk.version".to_string(), | ||
Annotated::new(Value::String("1.7.0".to_string())), | ||
), | ||
])), | ||
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()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
use once_cell::sync::Lazy; | ||
use regex::Regex; | ||
|
||
/// Contains multiple capture groups which will be used as a replace placeholder. | ||
/// | ||
/// This regex is inspired by one used for grouping: | ||
/// <https://github.com/getsentry/sentry/blob/6ba59023a78bfe033e48ea4e035b64710a905c6b/src/sentry/grouping/strategies/message.py#L16-L97> | ||
pub static TRANSACTION_NAME_NORMALIZER_REGEX: Lazy<Regex> = Lazy::new(|| { | ||
Regex::new( | ||
r#" | ||
(?x) | ||
(?P<uuid> | ||
\b | ||
[0-9a-fA-F]{8}- | ||
[0-9a-fA-F]{4}- | ||
[0-9a-fA-F]{4}- | ||
[0-9a-fA-F]{4}- | ||
[0-9a-fA-F]{12} | ||
\b | ||
) | | ||
(?P<sha1> | ||
\b[0-9a-fA-F]{40}\b | ||
) | | ||
(?P<md5> | ||
\b[0-9a-fA-F]{32}\b | ||
) | | ||
(?P<date> | ||
(?: | ||
(?:\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z))| | ||
(?:\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))| | ||
(?:\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z)) | ||
) | | ||
(?: | ||
\b(?:(Sun|Mon|Tue|Wed|Thu|Fri|Sat)\s+)? | ||
(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+ | ||
(?:[\d]{1,2})\s+ | ||
(?:[\d]{2}:[\d]{2}:[\d]{2})\s+ | ||
[\d]{4} | ||
) | | ||
(?: | ||
\b(?:(Sun|Mon|Tue|Wed|Thu|Fri|Sat),\s+)? | ||
(?:0[1-9]|[1-2]?[\d]|3[01])\s+ | ||
(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+ | ||
(?:19[\d]{2}|[2-9][\d]{3})\s+ | ||
(?:2[0-3]|[0-1][\d]):([0-5][\d]) | ||
(?::(60|[0-5][\d]))?\s+ | ||
(?:[-\+][\d]{2}[0-5][\d]|(?:UT|GMT|(?:E|C|M|P)(?:ST|DT)|[A-IK-Z])) | ||
) | ||
) | | ||
(?P<hex> | ||
\b0[xX][0-9a-fA-F]+\b | ||
) | | ||
(?P<int> | ||
\b\d{2,}\b | ||
) | ||
"#, | ||
) | ||
.unwrap() | ||
}); |
Oops, something went wrong.