compute_rust_sentry/
types.rs

1use std::collections::HashMap;
2
3use fastly::Request;
4use serde::Serialize;
5use time::OffsetDateTime;
6
7#[derive(Serialize)]
8pub struct EventPayload {
9    pub event_id: String,
10    #[serde(rename = "type")]
11    pub event_type: String,
12    pub timestamp: OffsetDateTime,
13    pub platform: Platform,
14    pub level: Level,
15    pub transaction: Option<String>,
16    pub server_name: Option<String>,
17    pub release: Option<String>,
18    pub environment: Option<String>,
19    pub exception: Vec<Exception>,
20    pub request: Option<RequestMetadata>,
21}
22
23#[derive(Serialize)]
24pub struct Exception {
25    #[serde(rename = "type")]
26    name: String,
27    value: String,
28}
29
30#[derive(Serialize)]
31pub struct RequestMetadata {
32    method: String,
33    url: String,
34    headers: HashMap<String, String>,
35    env: HashMap<String, String>,
36}
37
38#[derive(Serialize)]
39#[serde(rename_all = "lowercase")]
40pub enum Platform {
41    C,
42    Native,
43    Other,
44}
45
46#[derive(Serialize)]
47#[serde(rename_all = "lowercase")]
48pub enum Level {
49    Fatal,
50    Error,
51    Warning,
52    Info,
53    Debug,
54}
55
56impl Default for EventPayload {
57    fn default() -> Self {
58        EventPayload {
59            event_id: uuid::Uuid::new_v4().to_string(),
60            event_type: "event".to_string(),
61            timestamp: OffsetDateTime::now_utc(),
62            platform: Platform::Other,
63            level: Level::Fatal,
64            transaction: None,
65            server_name: Some(std::env::var("FASTLY_HOSTNAME").unwrap()),
66            release: Some(std::env::var("FASTLY_SERVICE_VERSION").unwrap()),
67            environment: Some(std::env::var("FASTLY_SERVICE_ID").unwrap()),
68            exception: Vec::new(),
69            request: None,
70        }
71    }
72}
73
74impl<T: std::error::Error> From<T> for EventPayload {
75    fn from(error: T) -> Self {
76        EventPayload {
77            exception: vec![Exception {
78                name: format!("{:?}", error)
79                    .chars()
80                    .take_while(|&ch| ch != '(' && ch != ' ')
81                    .collect::<String>(),
82                value: error.to_string(),
83            }],
84            ..Default::default()
85        }
86    }
87}
88
89impl From<&Request> for RequestMetadata {
90    fn from(request: &Request) -> Self {
91        let mut headers = HashMap::new();
92
93        request.get_header_names().for_each(|k| {
94            headers.insert(
95                k.to_string(),
96                request.get_header(k).unwrap().to_str().unwrap().to_string(),
97            );
98        });
99
100        let mut env = HashMap::new();
101
102        if let Some(addr) = request.get_client_ip_addr() {
103            env.insert("REMOTE_ADDR".to_string(), addr.to_string());
104        }
105
106        RequestMetadata {
107            method: request.get_method().to_string(),
108            url: request.get_url().to_string(),
109            headers,
110            env,
111        }
112    }
113}