1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
use std::{collections::HashMap, time::SystemTime};

use super::v7::{DebugMeta, TraceId};
use crate::utils::ts_rfc3339;

use serde::{Deserialize, Serialize, Serializer};
use uuid::Uuid;

fn serialize_id<S: Serializer>(uuid: &Uuid, serializer: S) -> Result<S::Ok, S::Error> {
    serializer.serialize_some(&uuid.as_simple())
}
#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
/// Metadata about the transaction associated with the profile
pub struct TransactionMetadata {
    #[serde(serialize_with = "serialize_id")]
    /// Transaction ID
    pub id: Uuid,
    /// Transaction Name
    pub name: String,
    /// Trace ID
    pub trace_id: TraceId,
    /// Transaction start timestamp in nanoseconds relative to the start of the profiler
    pub relative_start_ns: u64,
    /// Transaction end timestamp in nanoseconds relative to the start of the profiler
    pub relative_end_ns: u64,
    /// ID of the thread in which the transaction started
    #[serde(default)]
    pub active_thread_id: u64,
}

#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq, Hash)]
/// Single frame of a Sample
pub struct RustFrame {
    /// Instruction address
    pub instruction_addr: String,
}

#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
/// Single sample of a profile
pub struct Sample {
    /// ID of the relative stack
    pub stack_id: u32,
    /// Thread ID
    pub thread_id: u64,
    /// Timestamp at which this sample was collected relative to the start of the profiler
    pub elapsed_since_start_ns: u64,
}

#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
/// Thread metadata
pub struct ThreadMetadata {
    #[serde(default, skip_serializing_if = "Option::is_none")]
    /// Thread name
    pub name: Option<String>,
}

#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
/// Collected Profile
pub struct Profile {
    /// list of samples in a profile
    pub samples: Vec<Sample>,
    /// List of stacks: each stacks is a vec of indexed frames
    pub stacks: Vec<Vec<u32>>,
    /// List of frames
    pub frames: Vec<RustFrame>,
    /// Thread metadata
    pub thread_metadata: HashMap<String, ThreadMetadata>,
}

#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
/// Operating System metadata
pub struct OSMetadata {
    /// OS Name
    pub name: String,
    /// OS Version
    pub version: String,

    #[serde(default, skip_serializing_if = "Option::is_none")]
    /// Build number
    pub build_number: Option<String>,
}

#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
/// Runtime metadata
pub struct RuntimeMetadata {
    /// Runtime name (rustc)
    pub name: String,
    /// Runtime version
    pub version: String,
}

#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
/// Device metadata
pub struct DeviceMetadata {
    /// Architecture
    pub architecture: Option<String>,
}

#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
/// Profile format version
pub enum Version {
    #[serde(rename = "1")]
    /// First version
    V1,
}

#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
/// Represents a Profile Envelope ItemType
pub struct SampleProfile {
    /// Format version of the SampleProfile
    pub version: Version,

    #[serde(skip_serializing_if = "Option::is_none")]
    /// Debug meta information
    pub debug_meta: Option<DebugMeta>,

    /// Device metadata information
    pub device: DeviceMetadata,
    /// OS metadata information
    pub os: OSMetadata,
    #[serde(skip_serializing_if = "Option::is_none")]
    /// Runtime metadata information
    pub runtime: Option<RuntimeMetadata>,

    #[serde(default, skip_serializing_if = "String::is_empty")]
    /// Environment
    pub environment: String,
    #[serde(serialize_with = "serialize_id")]
    /// Event ID or Profile ID
    pub event_id: Uuid,
    /// Platform
    pub platform: String,
    /// Collected profile
    pub profile: Profile,
    /// Release
    pub release: String,
    #[serde(with = "ts_rfc3339")]
    /// Timestamp at which the profiler started
    pub timestamp: SystemTime,

    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    /// List of transactions associated with this profile
    pub transactions: Vec<TransactionMetadata>,
}