Skip to content

Commit c4d7e6f

Browse files
committed
ref(replay): Run geo info normalization on the replay user
1 parent fabbfe9 commit c4d7e6f

File tree

4 files changed

+159
-155
lines changed

4 files changed

+159
-155
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
- Add a config option to add default tags to all Relay Sentry events. ([#3944](https://github.com/getsentry/relay/pull/3944))
1414
- Automatically derive `client.address` and `user.geo` for standalone spans. ([#4047](https://github.com/getsentry/relay/pull/4047))
1515
- Add support for uploading compressed (gzip, xz, zstd, bzip2) minidumps. ([#4029](https://github.com/getsentry/relay/pull/4029))
16+
- Add user geo information to Replays. ([#4088](https://github.com/getsentry/relay/pull/4088))
1617
- Configurable span.op inference. ([#4056](https://github.com/getsentry/relay/pull/4056))
1718

1819
**Internal:**

relay-event-normalization/src/replay.rs

+48-16
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ use relay_event_schema::processor::{self, ProcessingState, Processor};
66
use relay_event_schema::protocol::{Contexts, IpAddr, Replay};
77
use relay_protocol::Annotated;
88

9+
use crate::event::normalize_user_geoinfo;
910
use crate::normalize::user_agent;
10-
use crate::trimming;
1111
use crate::user_agent::RawUserAgentInfo;
12+
use crate::{trimming, GeoIpLookup};
1213

1314
/// Replay validation or normalization error.
1415
///
@@ -82,11 +83,17 @@ pub fn validate(replay: &Replay) -> Result<(), ReplayError> {
8283
pub fn normalize(
8384
replay: &mut Annotated<Replay>,
8485
client_ip: Option<StdIpAddr>,
85-
user_agent: &RawUserAgentInfo<&str>,
86+
user_agent: RawUserAgentInfo<&str>,
87+
geoip_lookup: Option<&GeoIpLookup>,
8688
) {
8789
let _ = processor::apply(replay, |replay_value, meta| {
8890
normalize_platform(replay_value);
8991
normalize_ip_address(replay_value, client_ip);
92+
if let Some(geoip_lookup) = geoip_lookup {
93+
if let Some(user) = replay_value.user.value_mut() {
94+
normalize_user_geoinfo(geoip_lookup, user);
95+
}
96+
}
9097
normalize_user_agent(replay_value, user_agent);
9198
normalize_type(replay_value);
9299
normalize_array_fields(replay_value);
@@ -124,7 +131,7 @@ fn normalize_ip_address(replay: &mut Replay, ip_address: Option<StdIpAddr>) {
124131
);
125132
}
126133

127-
fn normalize_user_agent(replay: &mut Replay, default_user_agent: &RawUserAgentInfo<&str>) {
134+
fn normalize_user_agent(replay: &mut Replay, default_user_agent: RawUserAgentInfo<&str>) {
128135
let headers = match replay
129136
.request
130137
.value()
@@ -139,11 +146,11 @@ fn normalize_user_agent(replay: &mut Replay, default_user_agent: &RawUserAgentIn
139146
let user_agent_info = if user_agent_info.is_empty() {
140147
default_user_agent
141148
} else {
142-
&user_agent_info
149+
user_agent_info
143150
};
144151

145152
let contexts = replay.contexts.get_or_insert_with(Contexts::new);
146-
user_agent::normalize_user_agent_info_generic(contexts, &replay.platform, user_agent_info);
153+
user_agent::normalize_user_agent_info_generic(contexts, &replay.platform, &user_agent_info);
147154
}
148155

149156
fn normalize_platform(replay: &mut Replay) {
@@ -165,7 +172,8 @@ mod tests {
165172
use std::net::{IpAddr, Ipv4Addr};
166173

167174
use chrono::{TimeZone, Utc};
168-
use relay_protocol::{assert_annotated_snapshot, get_value};
175+
use insta::{assert_debug_snapshot, assert_json_snapshot};
176+
use relay_protocol::{assert_annotated_snapshot, get_value, SerializableAnnotated};
169177
use uuid::Uuid;
170178

171179
use relay_event_schema::protocol::{
@@ -253,7 +261,7 @@ mod tests {
253261
let payload = include_str!("../../tests/fixtures/replay.json");
254262

255263
let mut replay: Annotated<Replay> = Annotated::from_json(payload).unwrap();
256-
normalize(&mut replay, None, &RawUserAgentInfo::default());
264+
normalize(&mut replay, None, RawUserAgentInfo::default(), None);
257265

258266
let contexts = get_value!(replay.contexts!);
259267
assert_eq!(
@@ -290,37 +298,61 @@ mod tests {
290298
let mut replay: Annotated<Replay> = Annotated::from_json(payload).unwrap();
291299

292300
// No user object and no ip-address was provided.
293-
normalize(&mut replay, None, &RawUserAgentInfo::default());
301+
normalize(&mut replay, None, RawUserAgentInfo::default(), None);
294302
assert_eq!(get_value!(replay.user), None);
295303

296304
// No user object but an ip-address was provided.
297305
let ip_address = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
298-
normalize(&mut replay, Some(ip_address), &RawUserAgentInfo::default());
306+
normalize(
307+
&mut replay,
308+
Some(ip_address),
309+
RawUserAgentInfo::default(),
310+
None,
311+
);
299312

300313
let ipaddr = get_value!(replay.user!).ip_address.as_str();
301314
assert_eq!(Some("127.0.0.1"), ipaddr);
302315
}
303316

304317
#[test]
305-
fn test_set_ip_address_missing_user_ip_address() {
306-
let ip_address = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
318+
fn test_set_ip_address_missing_user_ip_address_and_geo() {
319+
let lookup = GeoIpLookup::open("tests/fixtures/GeoIP2-Enterprise-Test.mmdb").unwrap();
320+
let ip_address = IpAddr::V4(Ipv4Addr::new(2, 125, 160, 216));
307321

308322
// IP-Address set.
309323
let payload = include_str!("../../tests/fixtures/replay_missing_user_ip_address.json");
310324

311325
let mut replay: Annotated<Replay> = Annotated::from_json(payload).unwrap();
312-
normalize(&mut replay, Some(ip_address), &RawUserAgentInfo::default());
326+
normalize(
327+
&mut replay,
328+
Some(ip_address),
329+
RawUserAgentInfo::default(),
330+
Some(&lookup),
331+
);
313332

314-
let ipaddr = get_value!(replay.user!).ip_address.as_str();
315-
assert_eq!(Some("127.0.0.1"), ipaddr);
333+
let user = &replay.value().unwrap().user;
334+
assert_json_snapshot!(SerializableAnnotated(user), @r###"
335+
{
336+
"id": "123",
337+
"email": "[email protected]",
338+
"ip_address": "2.125.160.216",
339+
"username": "user",
340+
"geo": {
341+
"country_code": "GB",
342+
"city": "Boxford",
343+
"subdivision": "England",
344+
"region": "United Kingdom"
345+
}
346+
}
347+
"###);
316348
}
317349

318350
#[test]
319351
fn test_loose_type_requirements() {
320352
let payload = include_str!("../../tests/fixtures/replay_failure_22_08_31.json");
321353

322354
let mut replay: Annotated<Replay> = Annotated::from_json(payload).unwrap();
323-
normalize(&mut replay, None, &RawUserAgentInfo::default());
355+
normalize(&mut replay, None, RawUserAgentInfo::default(), None);
324356

325357
let user = get_value!(replay.user!);
326358
assert_eq!(user.ip_address.as_str(), Some("127.1.1.1"));
@@ -444,7 +476,7 @@ mod tests {
444476
let json = format!(r#"{{"dist": "{}"}}"#, "0".repeat(100));
445477
let mut replay = Annotated::<Replay>::from_json(json.as_str()).unwrap();
446478

447-
normalize(&mut replay, None, &RawUserAgentInfo::default());
479+
normalize(&mut replay, None, RawUserAgentInfo::default(), None);
448480
assert_annotated_snapshot!(replay, @r#"{
449481
"platform": "other",
450482
"dist": "0000000000000000000000000000000000000000000000000000000000000...",

relay-server/src/services/processor.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1835,7 +1835,11 @@ impl EnvelopeProcessorService {
18351835
&self,
18361836
state: &mut ProcessEnvelopeState<ReplayGroup>,
18371837
) -> Result<(), ProcessingError> {
1838-
replay::process(state, &self.inner.global_config.current())?;
1838+
replay::process(
1839+
state,
1840+
&self.inner.global_config.current(),
1841+
self.inner.geoip_lookup.as_ref(),
1842+
)?;
18391843
if_processing!(self.inner.config, {
18401844
self.enforce_quotas(state)?;
18411845
});

0 commit comments

Comments
 (0)