diff --git a/CHANGELOG.md b/CHANGELOG.md index 6becf3446a..b2a90676f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ - Add `cardinality_limited` outcome with id `6`. ([#3389](https://github.com/getsentry/relay/pull/3389)) - Extract `cache.item_size` and `cache.hit` metrics. ([#3371]https://github.com/getsentry/relay/pull/3371) - Optionally convert segment spans to transactions for compatibility. ([#3375](https://github.com/getsentry/relay/pull/3375)) +- Add feature flag for replay video event types. ([#3402](https://github.com/getsentry/relay/pull/3402)) **Internal**: diff --git a/relay-dynamic-config/src/feature.rs b/relay-dynamic-config/src/feature.rs index 89a2c7864e..e12c8c19ec 100644 --- a/relay-dynamic-config/src/feature.rs +++ b/relay-dynamic-config/src/feature.rs @@ -10,6 +10,11 @@ pub enum Feature { /// Serialized as `organizations:session-replay`. #[serde(rename = "organizations:session-replay")] SessionReplay, + /// Enables ingestion of video-based Session Replays. + /// + /// Serialized as `organizations:session-replay-video`. + #[serde(rename = "organizations:session-replay-video")] + SessionReplayVideo, /// Enables data scrubbing of replay recording payloads. /// /// Serialized as `organizations:session-replay-recording-scrubbing`. diff --git a/relay-server/src/services/processor/replay.rs b/relay-server/src/services/processor/replay.rs index b11fb612c7..6f88cdb554 100644 --- a/relay-server/src/services/processor/replay.rs +++ b/relay-server/src/services/processor/replay.rs @@ -28,6 +28,7 @@ pub fn process( let project_state = &state.project_state; let replays_enabled = project_state.has_feature(Feature::SessionReplay); let scrubbing_enabled = project_state.has_feature(Feature::SessionReplayRecordingScrubbing); + let video_replay_enabled = project_state.has_feature(Feature::SessionReplayVideo); let meta = state.envelope().meta().clone(); let client_addr = meta.client_addr(); @@ -88,6 +89,11 @@ pub fn process( item.set_payload(ContentType::OctetStream, replay_recording); } ItemType::ReplayVideo => { + if !video_replay_enabled { + state.managed_envelope.drop_items_silently(); + return Ok(()); + } + let replay_video = handle_replay_video_item( item.payload(), &event_id, diff --git a/tests/integration/test_replay_videos.py b/tests/integration/test_replay_videos.py index e4fb8dba1b..45885189ba 100644 --- a/tests/integration/test_replay_videos.py +++ b/tests/integration/test_replay_videos.py @@ -18,7 +18,15 @@ def test_replay_recording_with_video( replay_id = "515539018c9b4260a6f999572f1661ee" relay = relay_with_processing() mini_sentry.add_basic_project_config( - project_id, extra={"config": {"features": ["organizations:session-replay"]}} + project_id, + extra={ + "config": { + "features": [ + "organizations:session-replay", + "organizations:session-replay-video", + ] + } + }, ) replay = generate_replay_sdk_event(replay_id) replay_events_consumer = replay_events_consumer(timeout=10) @@ -76,3 +84,43 @@ def test_replay_recording_with_video( replay_recordings_consumer.assert_empty() outcomes_consumer.assert_empty() replay_events_consumer.assert_empty() + + +def test_replay_recording_with_video_flag_disabled( + mini_sentry, + relay_with_processing, + replay_recordings_consumer, + outcomes_consumer, + replay_events_consumer, +): + project_id = 42 + replay_id = "515539018c9b4260a6f999572f1661ee" + relay = relay_with_processing() + mini_sentry.add_basic_project_config( + project_id, + extra={"config": {"features": ["organizations:session-replay"]}}, + ) + replay = generate_replay_sdk_event(replay_id) + replay_events_consumer = replay_events_consumer(timeout=10) + replay_recordings_consumer = replay_recordings_consumer() + outcomes_consumer = outcomes_consumer() + + _recording_payload = recording_payload(b"[]") + payload = msgpack.packb( + { + "replay_event": json.dumps(replay).encode(), + "replay_recording": _recording_payload, + "replay_video": b"hello, world!", + } + ) + + envelope = Envelope( + headers=[["event_id", replay_id], ["attachment_type", "replay_video"]] + ) + envelope.add_item(Item(payload=PayloadRef(bytes=payload), type="replay_video")) + + relay.send_envelope(project_id, envelope) + + replay_recordings_consumer.assert_empty() + outcomes_consumer.assert_empty() + replay_events_consumer.assert_empty()