Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions sentry-types/src/protocol/client_report/list.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//! Module with code for representing the underlying list of client reports.

use std::collections::HashMap;

use serde::ser::SerializeSeq as _;
use serde::{Serialize, Serializer};

use super::{DataCategory, DiscardReason};

#[derive(Debug)]
pub(super) struct ClientReportList(HashMap<ReasonCategory, u64>);

#[derive(Debug, Serialize)]
struct ClientReportItem {
#[serde(flatten)]
reason_category: ReasonCategory,
quantity: u64,
}

/// A reason/category pair. Used to key the discarded events.
#[derive(Debug, Serialize, PartialEq, Eq, Hash, Clone, Copy)]
struct ReasonCategory {
reason: DiscardReason,
category: DataCategory,
}

impl ClientReportList {
/// Insert an item into the list.
///
/// Records `quantity` discarded events in the given data `category` for the given discard
/// `reason`. If there is already a record for that (`category`, `reason`) pair, we increment
/// the quantity of the existing pair, accordingly.
pub(super) fn add(&mut self, category: DataCategory, reason: DiscardReason, quantity: u64) {
let reason_category = ReasonCategory { category, reason };
let val = self.0.entry(reason_category).or_default();
*val = val.saturating_add(quantity);
}

fn iter(&self) -> impl Iterator<Item = ClientReportItem> + '_ {
self.0
.iter()
.map(|(&reason_category, &quantity)| ClientReportItem {
reason_category,
quantity,
})
}

fn len(&self) -> usize {
self.0.len()
}
}

impl Serialize for ClientReportList {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let seq = serializer.serialize_seq(Some(self.len()))?;

self.iter()
.try_fold(seq, |mut seq, item| {
seq.serialize_element(&item).map(|()| seq)
})?
.end()
}
}
60 changes: 60 additions & 0 deletions sentry-types/src/protocol/client_report/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//! Module containing types related to [Client Reports].
//!
//! [Client Reports]: https://develop.sentry.dev/sdk/telemetry/client-reports/

use std::time::SystemTime;

use serde::Serialize;

use self::list::ClientReportList;
use crate::utils;

mod list;

/// A [client report].
///
/// [client report]: https://develop.sentry.dev/sdk/telemetry/client-reports/
#[derive(Debug, Serialize)]
pub struct ClientReport {
#[serde(with = "utils::ts_seconds_float")]
timestamp: SystemTime,
discarded_events: ClientReportList,
}

impl ClientReport {
/// Insert an item into the `discarded_events` list.
///
/// Records `quantity` discarded events in the given data `category` for the given discard
/// `reason`. If there is already a record for that (`category`, `reason`) pair, we increment
/// the quantity of the existing pair, accordingly.
pub fn add_discarded_event(
&mut self,
category: DataCategory,
reason: DiscardReason,
quantity: u64,
) {
self.discarded_events.add(category, reason, quantity);
}
}

/// The reason why a telemetry item was discarded.
///
/// Valid discard reasons are listed in the [develop docs]; this enum may only define a subset of
/// these data categories, but we will add further categories as we begin using them in the SDK.
///
/// [develop docs]: https://develop.sentry.dev/sdk/telemetry/client-reports/#discard-reasons-1
#[derive(Debug, Serialize, PartialEq, Eq, Hash, Clone, Copy)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum DiscardReason {}

/// The category of data which was dropped.
///
/// Valid categories are listed in the [develop docs]; this enum may only define a subset of these
/// valid data categories, but we will add further categories as we begin using them in the SDK.
///
/// [develop docs]: https://develop.sentry.dev/sdk/foundations/transport/rate-limiting/#definitions
#[derive(Debug, Serialize, PartialEq, Eq, Hash, Clone, Copy)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum DataCategory {}
1 change: 1 addition & 0 deletions sentry-types/src/protocol/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub const LATEST: u16 = 7;
pub use v7 as latest;

mod attachment;
mod client_report;
mod envelope;
mod monitor;
mod session;
Expand Down
1 change: 1 addition & 0 deletions sentry-types/src/protocol/v7.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub use uuid::Uuid;
use crate::utils::{display_from_str_opt, ts_rfc3339_opt, ts_seconds_float};

pub use super::attachment::*;
pub use super::client_report::ClientReport;
pub use super::envelope::*;
pub use super::monitor::*;
pub use super::session::*;
Expand Down
Loading