Loading…
Loading…
Explains the automated service for archiving raw logs to object storage, pruning old data from the database, and managing data retention policies.
The Raw Log Archive Service is an automated background process responsible for managing the lifecycle of raw request logs and aggregated data. Its primary function is to prevent unbounded database growth by tiering older log data to a configured object store and eventually purging it, according to configurable retention policies.
This service operates through three distinct, scheduled jobs:
s2r_f5_request_log and s2r_debug_trace) from the primary database to an object store.The service is driven by a combination of application configuration properties and dynamic system settings stored in the database. It can be configured to operate in two modes: archiving to an object store before cleaning the database, or simply deleting logs from the database directly.
IMPORTANT
This service operates in a single-tenant context, running its tasks for the default tenant only. It does not use the per-tenant job runner, as retention settings are not currently defined on a per-tenant basis.
The service's functions are executed by three independent, scheduled tasks. Each task has its own schedule and can also be triggered manually via an API. Concurrency is managed internally; if a scheduled or manual run is triggered while a previous run of the same task is still in progress, the new run is skipped.
This task runs on a schedule (default: every 15 minutes) to manage raw logs that have exceeded their database retention period. Its behavior depends on the raw_log_storage_mode system setting and whether an object store is configured.
flowchart TD
subgraph Archiving Process
direction LR
A[Start Archiving] --> B{Object Store Mode?};
B -- "db_and_gcs" --> C[Find logs older than<br/>`raw_log_db_retention_days`];
C --> D{Batch of 500 rows};
D -- For each row --> E[Upload Gzipped JSON<br/>to Object Store];
E -- Success --> F[Null payload columns in DB,<br/>set object key];
E -- Failure --> G[Increment retry counter<br/>(max 5 attempts)];
B -- "db_only" or disabled --> H[Delete logs from DB older than<br/>`raw_log_db_retention_days`];
end
subgraph Parallel Sweeps
direction TB
S1[Start Sweeps] --> S2[Sweep `s2r_generic_request_log`];
S1 --> S3[Sweep `s2r_generic_ingest_dlq`];
end
A --> S1;Archive Mode (db_and_gcs)
When raw_log_storage_mode is set to db_and_gcs and an object store is enabled, the service performs the following steps:
s2r_traffic_log (an alias for s2r_f5_request_log) and s2r_debug_trace that are older than the raw_log_db_retention_days setting and have not yet been archived.ARCHIVE_BATCH_SIZE).f5-request-log/<instance_id>/<yyyy>/<MM>/<dd>/<log_id>.json.gzdebug-trace/<yyyy>/<MM>/<dd>/<correlation_id>/<trace_id>.json.gzgcs_uri column to the object key, records the current time in archived_at, and nullifies the large payload and header columns (request_payload, response_payload, etc.) to reclaim database space.archive_attempts counter for that row. A row will be retried on subsequent runs until it succeeds or the attempt count reaches 5 (MAX_ARCHIVE_ATTEMPTS).Delete-Only Mode (db_only)
If raw_log_storage_mode is db_only, or if the object store adapter is not enabled, the service simply deletes rows from s2r_traffic_log and s2r_debug_trace that are older than raw_log_db_retention_days. No data is sent to the object store.
Other Log Sweeps
In parallel with the main archiving flow, this task also cleans two other tables on every run:
s2r_generic_request_log: Deletes rows older than generic_raw_log_retention_days (default: 60).s2r_generic_ingest_dlq: Deletes rows older than a fixed 7 days.These sweeps are always deletions and are performed in chunks of 500 rows (GENERIC_DELETE_CHUNK_SIZE).
This task runs on a longer schedule (default: every 6 hours) to permanently delete old archives from the object store.
s2r_traffic_log and s2r_debug_trace whose archived_at timestamp is older than the raw_log_gcs_retention_days setting (default: 365).EXPIRY_PAGE_SIZE), with a cap of 5000 (EXPIRY_MAX_PER_RUN) expirations per run to limit impact.gcs_uri column. The service can correctly parse both modern bare object keys and legacy `<REDACTED-BUCKET-URI> URI formats.This daily task (default: every 24 hours) cleans up old data from various aggregated data tables to keep them from growing indefinitely.
s2r_observed_traffic_hourly, s2r_observed_topology, and s2r_f5_traffic_hourly that are older than the aggregation_retention_days setting (default: 365).s2r_spec_refinement_sample that are older than a fixed 30 days.The service's three main tasks can be triggered manually via API endpoints. This is useful for forcing an immediate cleanup or for operational diagnostics. When a task is triggered while another instance of the same task is already running, the new request is skipped.
Triggers a single run of the log archiving and sweeping process.
runArchive(){"status": "SKIPPED", "reason": "already_running"}Example Success Response Payload
{
"status": "DONE",
"storageMode": "db_and_gcs",
"usedGcs": true,
"dbRetentionDays": 14,
"f5LogsArchived": 500,
"f5LogsDeleted": 0,
"debugTracesArchived": 27,
"debugTracesDeleted": 0,
"genericRawLogRetentionDays": 60,
"genericRawLogsDeleted": 1250,
"genericIngestDlqRetentionDays": 7,
"genericIngestDlqDeleted": 88,
"time": "2023-10-27T10:00:00.123456Z"
}
Response Fields
| Field | Type | Description |
|---|---|---|
status | String | DONE on completion, or SKIPPED if already running. |
storageMode | String | The configured raw_log_storage_mode (db_and_gcs or db_only). |
usedGcs | Boolean | true if logs were archived to the object store. |
dbRetentionDays | Integer | The value of raw_log_db_retention_days used for this run. |
f5LogsArchived | Integer | Number of s2r_traffic_log rows archived to the object store. |
f5LogsDeleted | Integer | Number of s2r_traffic_log rows deleted directly (in db_only mode). |
debugTracesArchived | Integer | Number of s2r_debug_trace rows archived to the object store. |
debugTracesDeleted | Integer | Number of s2r_debug_trace rows deleted directly (in db_only mode). |
genericRawLogRetentionDays | Integer | The value of generic_raw_log_retention_days used for this run. |
genericRawLogsDeleted | Integer | Number of rows deleted from s2r_generic_request_log. |
genericIngestDlqRetentionDays | Integer | The fixed retention period (in days) for the generic ingest DLQ. |
genericIngestDlqDeleted | Integer | Number of rows deleted from s2r_generic_ingest_dlq. |
time | String | The ISO 8601 timestamp when the run completed. |
Triggers a single run of the object store expiry process.
runGcsExpiry(){"status": "SKIPPED", "reason": "already_running"}Response Fields
| Field | Type | Description |
|---|---|---|
status | String | DONE on completion, or SKIPPED if already running. |
gcsRetentionDays | Integer | The value of raw_log_gcs_retention_days used for this run. |
f5LogsExpired | Integer | Number of archived s2r_traffic_log rows and objects deleted. |
debugTracesExpired | Integer | Number of archived s2r_debug_trace rows and objects deleted. |
time | String | The ISO 8601 timestamp when the run completed. |
Triggers a single run of the aggregation table pruning process.
runAggregationPrune(){"status": "SKIPPED", "reason": "already_running"}Response Fields
| Field | Type | Description |
|---|---|---|
status | String | DONE on completion, or SKIPPED if already running. |
aggregationRetentionDays | Integer | The value of aggregation_retention_days used for this run. |
deletedObservedTrafficHourly | Integer | Number of rows deleted from s2r_observed_traffic_hourly. |
deletedObservedTopology | Integer | Number of rows deleted from s2r_observed_topology. |
deletedTrafficHourly | Integer | Number of rows deleted from s2r_f5_traffic_hourly. |
specRefinementSampleRetentionDays | Integer | The fixed retention period (in days) for s2r_spec_refinement_sample. |
deletedSpecRefinementSamples | Integer | Number of rows deleted from s2r_spec_refinement_sample. |
time | String | The ISO 8601 timestamp when the run completed. |
The service is configured through a mix of application properties (for scheduling) and system settings stored in the s2r_system_setting table (for retention policies).
These properties configure the scheduler's timing and can be set via environment variables or other standard Spring Boot configuration methods.
| Name | Type | Default | Description |
|---|---|---|---|
s2r.archive.scheduler.enabled | Boolean | true | Master switch to enable or disable all scheduled tasks in this service. |
s2r.archive.scheduler.initial-delay-ms | Long | 60000 | Delay in milliseconds before the first run of each task after startup. |
s2r.archive.scheduler.archive-delay-ms | Long | 900000 | Delay in milliseconds between runs of the log archiving task (15 minutes). |
s2r.archive.scheduler.expiry-delay-ms | Long | 21600000 | Delay in milliseconds between runs of the archive expiry task (6 hours). |
s2r.archive.scheduler.aggregation-prune-delay-ms | Long | 86400000 | Delay in milliseconds between runs of the aggregation pruning task (24 hours). |
These settings are read from the s2r_system_setting database table and control the retention logic. They can be adjusted at runtime without restarting the application.
| Name | Type | Default | Description |
|---|---|---|---|
raw_log_storage_mode | String | db_and_gcs | Storage mode. db_and_gcs archives to object store then cleans DB. db_only deletes from DB directly. |
raw_log_db_retention_days | Integer | 14 | Number of days to keep raw log payloads in the database before they are archived or deleted. |
raw_log_gcs_retention_days | Integer | 365 | Number of days to keep logs in the object store after they have been archived. |
generic_raw_log_retention_days | Integer | 60 | Number of days to keep rows in the s2r_generic_request_log table before deletion. |
aggregation_retention_days | Integer | 365 | Number of days to keep data in hourly aggregation tables (s2r_observed_traffic_hourly, s2r_f5_traffic_hourly, s2r_observed_topology). |
| Condition | Trigger | Impact and Resolution |
|---|---|---|
| Task already running | A manual or scheduled trigger occurs while the same task is already in progress. | The new run is skipped. The manual API trigger returns {"status": "SKIPPED", "reason": "already_running"}. This is normal and prevents resource contention. |
| Object store not enabled | The ObjectStore adapter is not configured (e.g., S2R_RAW_ARCHIVE_BUCKET is not set). | The service logs a warning on startup and runs in "DELETE-ONLY" mode. The runArchive task will set usedGcs: false in its response and delete logs directly from the database instead of archiving them. |
| Individual log archive fails | Network issue, permissions error, or other transient problem during object store upload. | The service logs a warning with the log ID and error message. It increments the archive_attempts counter for the database row. The row will be retried on the next run. After 5 failed attempts, the row will no longer be considered for archiving. |
| Archive expiry query fails | The database query to find expired rows times out or fails. | The service logs a warning. The current runGcsExpiry task for that table (s2r_traffic_log or s2r_debug_trace) is aborted. The process will retry on the next scheduled run. |
| Individual archive expiry fails | An object cannot be deleted from the store, or the DB row cannot be deleted after object deletion. | The service logs a warning with the log ID and error, then continues to the next row in the batch. This prevents one failed item from blocking the entire expiry run. If an entire page of rows fails to be processed, the run is aborted. |
| Generic log sweep fails | A DELETE statement for a chunk of rows in s2r_generic_request_log or s2r_generic_ingest_dlq fails. | The service logs a warning and stops the sweep for that table for the current run. Any chunks already deleted remain so. The sweep will resume from the beginning on the next run. |
| Aggregation prune statement fails | A DELETE statement on an aggregation table fails (e.g., due to a lock). | The service logs a warning and continues to the next aggregation table. The failed deletion will be retried on the next daily run. |