tailtriage_core/
config.rs1use serde::{Deserialize, Serialize};
2use std::path::Path;
3use std::sync::Arc;
4
5use crate::{LocalJsonSink, RunSink};
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
9#[serde(rename_all = "snake_case")]
10pub enum CaptureMode {
11 Light,
13 Investigation,
15}
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq)]
19pub struct CaptureLimits {
20 pub max_requests: usize,
22 pub max_stages: usize,
24 pub max_queues: usize,
26 pub max_inflight_snapshots: usize,
28 pub max_runtime_snapshots: usize,
30}
31
32impl Default for CaptureLimits {
33 fn default() -> Self {
34 Self {
35 max_requests: 100_000,
36 max_stages: 200_000,
37 max_queues: 200_000,
38 max_inflight_snapshots: 200_000,
39 max_runtime_snapshots: 100_000,
40 }
41 }
42}
43
44#[derive(Clone)]
45pub(crate) struct Config {
46 pub service_name: String,
47 pub service_version: Option<String>,
48 pub run_id: Option<String>,
49 pub mode: CaptureMode,
50 pub sink: Arc<dyn RunSink + Send + Sync>,
51 pub capture_limits: CaptureLimits,
52 pub strict_lifecycle: bool,
53}
54
55impl Config {
56 pub(crate) fn from_builder(builder: &TailtriageBuilder) -> Self {
57 Self {
58 service_name: builder.service_name.clone(),
59 service_version: builder.service_version.clone(),
60 run_id: builder.run_id.clone(),
61 mode: builder.mode,
62 sink: Arc::clone(&builder.sink),
63 capture_limits: builder.capture_limits,
64 strict_lifecycle: builder.strict_lifecycle,
65 }
66 }
67}
68
69#[derive(Debug, Clone, PartialEq, Eq)]
71pub enum BuildError {
72 EmptyServiceName,
74}
75
76impl std::fmt::Display for BuildError {
77 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
78 match self {
79 Self::EmptyServiceName => write!(f, "service_name cannot be empty"),
80 }
81 }
82}
83
84impl std::error::Error for BuildError {}
85
86#[derive(Clone)]
88pub struct TailtriageBuilder {
89 pub(crate) service_name: String,
90 pub(crate) service_version: Option<String>,
91 pub(crate) run_id: Option<String>,
92 pub(crate) mode: CaptureMode,
93 pub(crate) sink: Arc<dyn RunSink + Send + Sync>,
94 pub(crate) capture_limits: CaptureLimits,
95 pub(crate) strict_lifecycle: bool,
96}
97
98impl TailtriageBuilder {
99 pub(crate) fn new(service_name: impl Into<String>) -> Self {
100 Self {
101 service_name: service_name.into(),
102 service_version: None,
103 run_id: None,
104 mode: CaptureMode::Light,
105 sink: Arc::new(LocalJsonSink::new("tailtriage-run.json")),
106 capture_limits: CaptureLimits::default(),
107 strict_lifecycle: false,
108 }
109 }
110
111 #[must_use]
116 pub fn light(mut self) -> Self {
117 self.mode = CaptureMode::Light;
118 self
119 }
120
121 #[must_use]
125 pub fn investigation(mut self) -> Self {
126 self.mode = CaptureMode::Investigation;
127 self
128 }
129
130 #[must_use]
134 pub fn output(mut self, output_path: impl AsRef<Path>) -> Self {
135 self.sink = Arc::new(LocalJsonSink::new(output_path));
136 self
137 }
138
139 #[must_use]
141 pub fn sink<S>(mut self, sink: S) -> Self
142 where
143 S: RunSink + Send + Sync + 'static,
144 {
145 self.sink = Arc::new(sink);
146 self
147 }
148
149 #[must_use]
151 pub fn service_version(mut self, service_version: impl Into<String>) -> Self {
152 self.service_version = Some(service_version.into());
153 self
154 }
155
156 #[must_use]
160 pub fn run_id(mut self, run_id: impl Into<String>) -> Self {
161 self.run_id = Some(run_id.into());
162 self
163 }
164
165 #[must_use]
167 pub fn capture_limits(mut self, limits: CaptureLimits) -> Self {
168 self.capture_limits = limits;
169 self
170 }
171
172 #[must_use]
177 pub fn strict_lifecycle(mut self, strict_lifecycle: bool) -> Self {
178 self.strict_lifecycle = strict_lifecycle;
179 self
180 }
181
182 pub fn build(self) -> Result<crate::Tailtriage, BuildError> {
188 crate::Tailtriage::from_config(Config::from_builder(&self))
189 }
190}
191
192#[derive(Debug, Clone, PartialEq, Eq, Default)]
196pub struct RequestOptions {
197 pub request_id: Option<String>,
199 pub kind: Option<String>,
201}
202
203impl RequestOptions {
204 #[must_use]
206 pub fn new() -> Self {
207 Self::default()
208 }
209
210 #[must_use]
212 pub fn request_id(mut self, request_id: impl Into<String>) -> Self {
213 self.request_id = Some(request_id.into());
214 self
215 }
216
217 #[must_use]
219 pub fn kind(mut self, kind: impl Into<String>) -> Self {
220 self.kind = Some(kind.into());
221 self
222 }
223}