Repository: getsentry/sentry-rust (rust)

Issue:
[Structured logging] Stringify u64 attributes
### How do you use Sentry?

Sentry SaaS (sentry.io)

### SDK version

latest

### Steps to reproduce

Log something with an attribute with a value higher than max i64 and lower than max u64

### Expected result

Correct attribute value in Sentry, matching the one that is logged to the console.

### Actual result

serde serializes it as float and there can be loss of precision.
We should make sure that these values are actually serialized as string instead.

Pull request description:
fix(logs): stringify u64 attributes greater than `i64::MAX`
Previously we were serializing these as floats which could lead to unnecessary precision loss.
Closes #845 

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fa5db80..ac98b5c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
 # Changelog
 
+## Unreleased
+
+### Fixes
+
+- fix(logs): stringify u64 attributes greater than `i64::MAX` (#846) by @lcian
+
 ## 0.40.0
 
 ### Breaking changes
diff --git a/sentry-types/src/protocol/v7.rs b/sentry-types/src/protocol/v7.rs
index f7c76ae..6871d79 100644
--- a/sentry-types/src/protocol/v7.rs
+++ b/sentry-types/src/protocol/v7.rs
@@ -2217,6 +2217,10 @@ impl Serialize for LogAttribute {
                 if let Some(i) = n.as_i64() {
                     state.serialize_field("value", &i)?;
                     state.serialize_field("type", "integer")?;
+                } else if let Some(u) = n.as_u64() {
+                    // Converting to a f64 could lead to precision loss
+                    state.serialize_field("value", &u.to_string())?;
+                    state.serialize_field("type", "string")?;
                 } else if let Some(f) = n.as_f64() {
                     state.serialize_field("value", &f)?;
                     state.serialize_field("type", "double")?;


Test patch:
diff --git a/sentry-types/tests/test_protocol_v7.rs b/sentry-types/tests/test_protocol_v7.rs
index 88a567c..5638d31 100644
--- a/sentry-types/tests/test_protocol_v7.rs
+++ b/sentry-types/tests/test_protocol_v7.rs
@@ -1536,8 +1536,12 @@ mod test_logs {
             (3.1.into(), r#"{"value":3.1,"type":"double"}"#),
             ("lol".into(), r#"{"value":"lol","type":"string"}"#),
             (false.into(), r#"{"value":false,"type":"boolean"}"#),
-            // Special case
+            // Special cases
             (Value::Null.into(), r#"{"value":"null","type":"string"}"#),
+            (
+                (u64::MAX - 1).into(),
+                r#"{"value":"18446744073709551614","type":"string"}"#,
+            ),
             // Unsupported types (for now)
             (
                 json!(r#"[1,2,3,4]"#).into(),