statsig_rust/
statsig_metadata.rs1use crate::log_e;
2use lazy_static::lazy_static;
3use serde::Serialize;
4use serde_json::{json, Value};
5use std::collections::HashMap;
6use std::sync::RwLock;
7use uuid::Uuid;
8
9lazy_static! {
10 static ref STATSIG_METADATA: RwLock<StatsigMetadata> = RwLock::new(StatsigMetadata::new());
11}
12
13const TAG: &str = stringify!(StatsigMetadata);
14#[derive(Serialize, Clone)]
15#[serde(rename_all = "camelCase")]
16pub struct StatsigMetadata {
17 pub sdk_type: String,
18 pub sdk_version: String,
19
20 #[serde(rename = "sessionID")]
21 pub session_id: String,
22
23 #[serde(skip_serializing_if = "Option::is_none")]
24 pub os: Option<String>,
25
26 #[serde(skip_serializing_if = "Option::is_none")]
27 pub arch: Option<String>,
28
29 #[serde(skip_serializing_if = "Option::is_none")]
30 pub language_version: Option<String>,
31
32 #[serde(skip_serializing_if = "Option::is_none")]
33 #[serde(rename = "service_name")]
34 pub service_name: Option<String>,
35}
36
37#[derive(Serialize, Clone)]
38#[serde(rename_all = "camelCase")]
39pub struct StatsigMetadataWithLogEventExtras {
40 #[serde(flatten)]
41 pub base: StatsigMetadata,
42
43 pub flushing_interval_ms: u64,
44 pub batch_size: usize,
45 pub max_pending_batches: usize,
46 pub flush_type: String,
47}
48
49impl StatsigMetadata {
50 fn new() -> Self {
51 Self {
52 sdk_version: "0.5.2".to_string(),
53 sdk_type: "statsig-server-core".to_string(),
54 session_id: Uuid::new_v4().to_string(),
55 os: None,
56 arch: None,
57 language_version: None,
58 service_name: None,
59 }
60 }
61
62 pub fn update_values(sdk_type: String, os: String, arch: String, language_version: String) {
63 match STATSIG_METADATA.write() {
64 Ok(mut metadata) => {
65 metadata.sdk_type = sdk_type;
66 metadata.os = Some(os);
67 metadata.arch = Some(arch);
68 metadata.language_version = Some(language_version);
69 }
70 Err(e) => {
71 log_e!(TAG, "Failed to clone StatsigMetadata: {}", e.to_string());
72 }
73 }
74 }
75
76 pub fn update_service_name(service_name: Option<String>) {
77 match STATSIG_METADATA.write() {
78 Ok(mut metadata) => {
79 metadata.service_name = service_name;
80 }
81 Err(e) => {
82 log_e!(TAG, "Failed to clone StatsigMetadata: {}", e.to_string());
83 }
84 }
85 }
86
87 #[must_use]
88 pub fn get_constant_request_headers(sdk_key: &str) -> HashMap<String, String> {
89 let meta = Self::get_metadata();
90
91 HashMap::from([
92 ("STATSIG-API-KEY".to_string(), sdk_key.to_string()),
93 ("STATSIG-SDK-TYPE".to_string(), meta.sdk_type),
94 ("STATSIG-SDK-VERSION".to_string(), meta.sdk_version),
95 ("STATSIG-SERVER-SESSION-ID".to_string(), meta.session_id),
96 ])
97 }
98
99 #[must_use]
100 pub fn get_metadata() -> StatsigMetadata {
101 match STATSIG_METADATA.read() {
102 Ok(metadata) => metadata.clone(),
103 Err(e) => {
104 log_e!(TAG, "Failed to clone StatsigMetadata: {}", e.to_string());
105 StatsigMetadata::new()
106 }
107 }
108 }
109
110 #[must_use]
111 pub fn get_as_json() -> Value {
112 json!(StatsigMetadata::get_metadata())
113 }
114
115 #[must_use]
116 pub fn get_with_log_event_extras(
117 flushing_interval_ms: u64,
118 batch_size: usize,
119 max_pending_batches: usize,
120 flush_type: String,
121 ) -> StatsigMetadataWithLogEventExtras {
122 StatsigMetadataWithLogEventExtras {
123 base: StatsigMetadata::get_metadata(),
124 flushing_interval_ms,
125 batch_size,
126 max_pending_batches,
127 flush_type,
128 }
129 }
130}