Skip to main content

systemprompt_logging/services/
maintenance.rs

1//! Retention maintenance for the `logs` table.
2//!
3//! Copyright (c) systemprompt.io — Business Source License 1.1.
4//! See <https://systemprompt.io> for licensing details.
5
6use chrono::{DateTime, Utc};
7use systemprompt_database::DbPool;
8
9use crate::models::{LogEntry, LogFilter, LoggingError};
10use crate::repository::LoggingRepository;
11
12const CLEANUP_BATCH_ROWS: i64 = 5000;
13
14#[derive(Clone, Debug)]
15pub struct LoggingMaintenanceService {
16    repo: LoggingRepository,
17}
18
19impl LoggingMaintenanceService {
20    pub fn new(db_pool: &DbPool) -> Self {
21        Self {
22            repo: LoggingRepository::new(db_pool),
23        }
24    }
25
26    pub async fn get_recent_logs(&self, limit: i64) -> Result<Vec<LogEntry>, LoggingError> {
27        self.repo.get_recent_logs(limit).await
28    }
29
30    pub async fn get_filtered_logs(
31        &self,
32        filter: &LogFilter,
33    ) -> Result<(Vec<LogEntry>, i64), LoggingError> {
34        self.repo.get_logs_paginated(filter).await
35    }
36
37    pub async fn cleanup_old_logs(&self, older_than: DateTime<Utc>) -> Result<u64, LoggingError> {
38        let mut deleted = 0;
39        loop {
40            let batch = self
41                .repo
42                .purge_before(older_than, CLEANUP_BATCH_ROWS)
43                .await?;
44            deleted += batch;
45            if batch < u64::try_from(CLEANUP_BATCH_ROWS).unwrap_or(u64::MAX) {
46                return Ok(deleted);
47            }
48        }
49    }
50
51    pub async fn count_logs_before(&self, cutoff: DateTime<Utc>) -> Result<u64, LoggingError> {
52        self.repo.count_logs_before(cutoff).await
53    }
54
55    pub async fn clear_all_logs(&self) -> Result<u64, LoggingError> {
56        self.repo.clear_all_logs().await
57    }
58}