portkey_sdk/service/logs.rs
1use std::future::Future;
2
3#[cfg(feature = "tracing")]
4use crate::TRACING_TARGET_SERVICE;
5use crate::client::PortkeyClient;
6use crate::error::Result;
7use crate::model::{
8 CreateLogExportRequest, CreateLogExportResponse, DownloadLogExportResponse, ExportTaskResponse,
9 InsertLogRequest, InsertLogResponse, ListLogExportsParams, ListLogExportsResponse, LogExport,
10 UpdateLogExportRequest, UpdateLogExportResponse,
11};
12
13/// Service trait for managing log exports.
14///
15/// This trait provides methods for creating, retrieving, starting, canceling,
16/// and downloading log exports from Portkey.
17///
18/// # Example
19///
20/// ```rust,no_run
21/// use portkey_sdk::{PortkeyConfig, Result};
22/// use portkey_sdk::service::LogsService;
23/// use portkey_sdk::builder::AuthMethod;
24/// use portkey_sdk::model::{CreateLogExportRequest, GenerationsFilter, LogExportField};
25///
26/// #[tokio::main]
27/// async fn main() -> Result<()> {
28/// let client = PortkeyConfig::builder()
29/// .with_api_key("your-portkey-api-key")
30/// .with_auth_method(AuthMethod::virtual_key("your-virtual-key"))
31/// .build_client()?;
32///
33/// // Create a log export
34/// let filters = GenerationsFilter {
35/// time_of_generation_min: Some("2024-10-20".to_string()),
36/// time_of_generation_max: Some("2024-10-30".to_string()),
37/// ..Default::default()
38/// };
39///
40/// let request = CreateLogExportRequest {
41/// workspace_id: Some("workspace-123".to_string()),
42/// filters,
43/// requested_data: vec![
44/// LogExportField::Id,
45/// LogExportField::TraceId,
46/// LogExportField::CreatedAt,
47/// ],
48/// description: Some("Export for October 2024".to_string()),
49/// };
50///
51/// let export = client.create_log_export(request).await?;
52/// println!("Created export: {}", export.id);
53///
54/// // Start the export
55/// client.start_log_export(&export.id).await?;
56///
57/// // Retrieve export status
58/// let status = client.get_log_export(&export.id).await?;
59/// println!("Export status: {:?}", status.status);
60///
61/// // Download when ready
62/// let download = client.download_log_export(&export.id).await?;
63/// println!("Download URL: {}", download.signed_url);
64///
65/// Ok(())
66/// }
67/// ```
68pub trait LogsService {
69 /// Creates a new log export.
70 ///
71 /// # Arguments
72 ///
73 /// * `request` - The export configuration with filters and requested fields
74 ///
75 /// # Returns
76 ///
77 /// Returns a `CreateLogExportResponse` with the export ID and total count.
78 ///
79 /// # Errors
80 ///
81 /// Returns an error if the API request fails or the response cannot be parsed.
82 fn create_log_export(
83 &self,
84 request: CreateLogExportRequest,
85 ) -> impl Future<Output = Result<CreateLogExportResponse>>;
86
87 /// Retrieves a log export by ID.
88 ///
89 /// # Arguments
90 ///
91 /// * `export_id` - The unique identifier of the export
92 ///
93 /// # Returns
94 ///
95 /// Returns a `LogExport` with full export details.
96 ///
97 /// # Errors
98 ///
99 /// Returns an error if the export is not found or the API request fails.
100 fn get_log_export(&self, export_id: &str) -> impl Future<Output = Result<LogExport>>;
101
102 /// Starts processing a log export.
103 ///
104 /// # Arguments
105 ///
106 /// * `export_id` - The unique identifier of the export to start
107 ///
108 /// # Returns
109 ///
110 /// Returns an `ExportTaskResponse` with status message.
111 ///
112 /// # Errors
113 ///
114 /// Returns an error if the export cannot be started or the API request fails.
115 fn start_log_export(&self, export_id: &str)
116 -> impl Future<Output = Result<ExportTaskResponse>>;
117
118 /// Cancels a running log export.
119 ///
120 /// # Arguments
121 ///
122 /// * `export_id` - The unique identifier of the export to cancel
123 ///
124 /// # Returns
125 ///
126 /// Returns an `ExportTaskResponse` with status message.
127 ///
128 /// # Errors
129 ///
130 /// Returns an error if the export cannot be canceled or the API request fails.
131 fn cancel_log_export(
132 &self,
133 export_id: &str,
134 ) -> impl Future<Output = Result<ExportTaskResponse>>;
135
136 /// Downloads a completed log export.
137 ///
138 /// # Arguments
139 ///
140 /// * `export_id` - The unique identifier of the export to download
141 ///
142 /// # Returns
143 ///
144 /// Returns a `DownloadLogExportResponse` with a pre-signed URL.
145 ///
146 /// # Errors
147 ///
148 /// Returns an error if the export is not ready or the API request fails.
149 fn download_log_export(
150 &self,
151 export_id: &str,
152 ) -> impl Future<Output = Result<DownloadLogExportResponse>>;
153
154 /// Inserts one or more custom logs.
155 ///
156 /// # Arguments
157 ///
158 /// * `request` - Either a single log or multiple logs to insert
159 ///
160 /// # Returns
161 ///
162 /// Returns an `InsertLogResponse` with status and log IDs.
163 ///
164 /// # Errors
165 ///
166 /// Returns an error if the API request fails or the response cannot be parsed.
167 fn insert_log(
168 &self,
169 request: InsertLogRequest,
170 ) -> impl Future<Output = Result<InsertLogResponse>>;
171
172 /// Updates an existing log export.
173 ///
174 /// # Arguments
175 ///
176 /// * `export_id` - The unique identifier of the export to update
177 /// * `request` - The updated export configuration
178 ///
179 /// # Returns
180 ///
181 /// Returns an `UpdateLogExportResponse` with the updated export ID and count.
182 ///
183 /// # Errors
184 ///
185 /// Returns an error if the export is not found or the API request fails.
186 fn update_log_export(
187 &self,
188 export_id: &str,
189 request: UpdateLogExportRequest,
190 ) -> impl Future<Output = Result<UpdateLogExportResponse>>;
191
192 /// Lists all log exports with optional workspace filter.
193 ///
194 /// # Arguments
195 ///
196 /// * `params` - Optional parameters for filtering exports
197 ///
198 /// # Returns
199 ///
200 /// Returns a `ListLogExportsResponse` with all matching exports.
201 ///
202 /// # Errors
203 ///
204 /// Returns an error if the API request fails or the response cannot be parsed.
205 fn list_log_exports(
206 &self,
207 params: Option<ListLogExportsParams>,
208 ) -> impl Future<Output = Result<ListLogExportsResponse>>;
209}
210
211impl LogsService for PortkeyClient {
212 async fn create_log_export(
213 &self,
214 request: CreateLogExportRequest,
215 ) -> Result<CreateLogExportResponse> {
216 #[cfg(feature = "tracing")]
217 tracing::debug!(
218 target: TRACING_TARGET_SERVICE,
219 workspace_id = ?request.workspace_id,
220 requested_data_count = request.requested_data.len(),
221 "Creating log export"
222 );
223
224 let response = self
225 .send_json(reqwest::Method::POST, "/logs/exports", &request)
226 .await?;
227 let response = response.error_for_status()?;
228 let export_response: CreateLogExportResponse = response.json().await?;
229
230 Ok(export_response)
231 }
232
233 async fn get_log_export(&self, export_id: &str) -> Result<LogExport> {
234 #[cfg(feature = "tracing")]
235 tracing::debug!(
236 target: TRACING_TARGET_SERVICE,
237 export_id = %export_id,
238 "Retrieving log export"
239 );
240
241 let path = format!("/logs/exports/{}", export_id);
242 let response = self.send(reqwest::Method::GET, &path).await?;
243 let response = response.error_for_status()?;
244 let export: LogExport = response.json().await?;
245
246 Ok(export)
247 }
248
249 async fn start_log_export(&self, export_id: &str) -> Result<ExportTaskResponse> {
250 #[cfg(feature = "tracing")]
251 tracing::debug!(
252 target: TRACING_TARGET_SERVICE,
253 export_id = %export_id,
254 "Starting log export"
255 );
256
257 let path = format!("/logs/exports/{}/start", export_id);
258 let response = self.send(reqwest::Method::POST, &path).await?;
259 let response = response.error_for_status()?;
260 let task_response: ExportTaskResponse = response.json().await?;
261
262 Ok(task_response)
263 }
264
265 async fn cancel_log_export(&self, export_id: &str) -> Result<ExportTaskResponse> {
266 #[cfg(feature = "tracing")]
267 tracing::debug!(
268 target: TRACING_TARGET_SERVICE,
269 export_id = %export_id,
270 "Canceling log export"
271 );
272
273 let path = format!("/logs/exports/{}/cancel", export_id);
274 let response = self.send(reqwest::Method::POST, &path).await?;
275 let response = response.error_for_status()?;
276 let task_response: ExportTaskResponse = response.json().await?;
277
278 Ok(task_response)
279 }
280
281 async fn download_log_export(&self, export_id: &str) -> Result<DownloadLogExportResponse> {
282 #[cfg(feature = "tracing")]
283 tracing::debug!(
284 target: TRACING_TARGET_SERVICE,
285 export_id = %export_id,
286 "Downloading log export"
287 );
288
289 let path = format!("/logs/exports/{}/download", export_id);
290 let response = self.send(reqwest::Method::GET, &path).await?;
291 let response = response.error_for_status()?;
292 let download_response: DownloadLogExportResponse = response.json().await?;
293
294 Ok(download_response)
295 }
296
297 async fn insert_log(&self, request: InsertLogRequest) -> Result<InsertLogResponse> {
298 #[cfg(feature = "tracing")]
299 tracing::debug!(
300 target: TRACING_TARGET_SERVICE,
301 "Inserting custom log(s)"
302 );
303
304 let response = self
305 .send_json(reqwest::Method::POST, "/logs", &request)
306 .await?;
307 let response = response.error_for_status()?;
308 let insert_response: InsertLogResponse = response.json().await?;
309
310 Ok(insert_response)
311 }
312
313 async fn update_log_export(
314 &self,
315 export_id: &str,
316 request: UpdateLogExportRequest,
317 ) -> Result<UpdateLogExportResponse> {
318 #[cfg(feature = "tracing")]
319 tracing::debug!(
320 target: TRACING_TARGET_SERVICE,
321 export_id = %export_id,
322 workspace_id = ?request.workspace_id,
323 "Updating log export"
324 );
325
326 let path = format!("/logs/exports/{}", export_id);
327 let response = self
328 .send_json(reqwest::Method::PUT, &path, &request)
329 .await?;
330 let response = response.error_for_status()?;
331 let update_response: UpdateLogExportResponse = response.json().await?;
332
333 Ok(update_response)
334 }
335
336 async fn list_log_exports(
337 &self,
338 params: Option<ListLogExportsParams>,
339 ) -> Result<ListLogExportsResponse> {
340 #[cfg(feature = "tracing")]
341 tracing::debug!(
342 target: TRACING_TARGET_SERVICE,
343 workspace_id = ?params.as_ref().and_then(|p| p.workspace_id.as_ref()),
344 "Listing log exports"
345 );
346
347 let response = if let Some(p) = params
348 && let Some(workspace_id) = p.workspace_id
349 {
350 self.send_with_params(
351 reqwest::Method::GET,
352 "/logs/exports",
353 &[("workspace_id", workspace_id.as_str())],
354 )
355 .await?
356 } else {
357 self.send(reqwest::Method::GET, "/logs/exports").await?
358 };
359
360 let response = response.error_for_status()?;
361 let list_response: ListLogExportsResponse = response.json().await?;
362
363 Ok(list_response)
364 }
365}