[PR #22] [MERGED] feat(logs): add structured log aggregator for Docker container observability #23

Closed
opened 2026-03-02 05:12:34 +03:00 by kerem · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/gotempsh/temps/pull/22
Author: @dviejokfs
Created: 2/26/2026
Status: Merged
Merged: 2/28/2026
Merged by: @dviejokfs

Base: mainHead: feat/add-logging


📝 Commits (4)

  • cfb52a8 feat(logs): add structured log aggregator with Docker container log collection
  • fb078e8 fix(logs): use i32 project IDs, restore BuildKit build logs, and add log history UI
  • b963847 chore: add new configuration for flate2 crate and update .gitignore
  • 4eb4006 feat(logs): introduce structured log aggregator and frontend log history viewer

📊 Changes

57 files changed (+9189 additions, -584 deletions)

View changed files

📝 CHANGELOG.md (+4 -0)
📝 Cargo.lock (+70 -496)
📝 Cargo.toml (+5 -3)
📝 README.md (+1 -0)
📝 _typos.toml (+3 -2)
📝 crates/temps-auth/src/permissions.rs (+6 -0)
📝 crates/temps-cli/Cargo.toml (+1 -0)
📝 crates/temps-cli/src/commands/build.rs (+18 -4)
📝 crates/temps-cli/src/commands/doctor.rs (+2 -6)
📝 crates/temps-cli/src/commands/serve/console.rs (+32 -0)
📝 crates/temps-deployer/src/docker.rs (+63 -11)
📝 crates/temps-deployer/src/lib.rs (+7 -0)
📝 crates/temps-deployments/Cargo.toml (+1 -0)
📝 crates/temps-deployments/src/jobs/deploy_image.rs (+21 -0)
📝 crates/temps-deployments/src/jobs/pull_external_image.rs (+8 -2)
📝 crates/temps-deployments/src/jobs/verify_local_image.rs (+2 -10)
📝 crates/temps-deployments/src/utils/docker_inspect.rs (+3 -3)
📝 crates/temps-deployments/tests/nodejs_integration_test.rs (+13 -21)
📝 crates/temps-entities/src/lib.rs (+4 -0)
crates/temps-entities/src/log_chunks.rs (+28 -0)

...and 37 more files

📄 Description

Summary

Closes #21

Adds a new temps-log-aggregator crate that provides comprehensive structured log aggregation for Docker containers deployed on the platform.

  • Real-time collection: Streams logs from Docker containers discovered via sh.temps.* labels, with reconnect resilience, container-gone detection, and bounded retries
  • Compressed storage: NDJSON chunks compressed with zstd, stored on filesystem (default) or S3
  • Dual-path search: TimescaleDB index for fast ERROR/WARN queries; archive scan with decompression for full-text search across all levels
  • Live tail: SSE streaming endpoint with project/service/level filtering
  • Retention: Configurable automatic cleanup (30d chunks, 7d events) plus manual purge with audit logging
  • Security: LogsRead / LogsDelete permission guards on all endpoints

Changes

New crate: temps-log-aggregator (8,200+ lines)

  • parser.rs — Docker JSON log parsing, plain-text level detection, structured field extraction
  • storage/ — Pluggable storage backends (filesystem, S3) with zstd compression
  • services/chunk_writer.rs — Per-container buffering with 1MB / 30s flush triggers
  • services/collector.rs — Docker log streaming with resilience (last_seen_ts tracking, container-gone detection, max consecutive errors)
  • services/metadata.rs — TimescaleDB operations for log_chunks and log_events
  • services/search.rs — Dual-path search routing (index vs archive), field filters, pagination
  • services/tail.rs — Broadcast-based live tail with filter matching
  • services/retention.rs — Chunk cleanup by age with storage deletion
  • handlers/ — HTTP endpoints: POST /logs/search, GET /logs/context, GET /logs/tail (SSE), DELETE /projects/{id}/logs
  • plugin.rs — Platform integration: startup scan, Docker events listener, retention scheduler

Modified crates

  • temps-deployer: Added labels: HashMap<String, String> to DeployRequest, applied to container creation
  • temps-deployments: Populates sh.temps.project_id, sh.temps.deployment_id, sh.temps.environment_id, sh.temps.service, sh.temps.namespace labels
  • temps-auth: Added LogsDelete permission to all 5 locations (enum, Display, from_str, all(), Role::permissions)
  • temps-entities: Added log_chunks and log_events Sea-ORM entities
  • temps-migrations: Added m20260225_000001_create_log_aggregator_tables migration
  • temps-cli: Reads TEMPS_LOG_STORAGE_BACKEND and S3 config env vars, registers plugin

Test Coverage

101 tests (was 89 before this session, +12 new):

Category Count Highlights
Parser 11 JSON/plain-text parsing, Docker timestamps, level detection
Types 7 LogLevel, LogStream, RetentionConfig, UUID determinism
Storage 12 Filesystem CRUD, S3 key construction, range reads
Chunk Writer 11 Buffering, flush, multi-container, auto-flush at 1MB, 1000-line compression roundtrip
Search 21 Service/env/deploy filtering, full-text, field filters, time ranges, 1000-line archive simulation
Tail 6 Filter matching, broadcast subscription
Metadata 4 insert_log_events_from_lines (indexable filtering), list_distinct_projects
Handlers 16 Search, context, SSE tail, purge, pagination, auth (401), permission guards (403 Reader/purge, 200 Reader/search)
Error/Plugin 4 Display formatting, plugin name

No regressions: temps-auth (102 passed), temps-deployer (39 passed)


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/gotempsh/temps/pull/22 **Author:** [@dviejokfs](https://github.com/dviejokfs) **Created:** 2/26/2026 **Status:** ✅ Merged **Merged:** 2/28/2026 **Merged by:** [@dviejokfs](https://github.com/dviejokfs) **Base:** `main` ← **Head:** `feat/add-logging` --- ### 📝 Commits (4) - [`cfb52a8`](https://github.com/gotempsh/temps/commit/cfb52a8955a1dbefe33f3b61f050b265b6df1cc8) feat(logs): add structured log aggregator with Docker container log collection - [`fb078e8`](https://github.com/gotempsh/temps/commit/fb078e8237550d370fc3901ebd82a9f987e86700) fix(logs): use i32 project IDs, restore BuildKit build logs, and add log history UI - [`b963847`](https://github.com/gotempsh/temps/commit/b96384782da414b894c8924af198a98a5a9256a7) chore: add new configuration for flate2 crate and update .gitignore - [`4eb4006`](https://github.com/gotempsh/temps/commit/4eb4006928e5ec3ce5b028aa31315949033ceec0) feat(logs): introduce structured log aggregator and frontend log history viewer ### 📊 Changes **57 files changed** (+9189 additions, -584 deletions) <details> <summary>View changed files</summary> 📝 `CHANGELOG.md` (+4 -0) 📝 `Cargo.lock` (+70 -496) 📝 `Cargo.toml` (+5 -3) 📝 `README.md` (+1 -0) 📝 `_typos.toml` (+3 -2) 📝 `crates/temps-auth/src/permissions.rs` (+6 -0) 📝 `crates/temps-cli/Cargo.toml` (+1 -0) 📝 `crates/temps-cli/src/commands/build.rs` (+18 -4) 📝 `crates/temps-cli/src/commands/doctor.rs` (+2 -6) 📝 `crates/temps-cli/src/commands/serve/console.rs` (+32 -0) 📝 `crates/temps-deployer/src/docker.rs` (+63 -11) 📝 `crates/temps-deployer/src/lib.rs` (+7 -0) 📝 `crates/temps-deployments/Cargo.toml` (+1 -0) 📝 `crates/temps-deployments/src/jobs/deploy_image.rs` (+21 -0) 📝 `crates/temps-deployments/src/jobs/pull_external_image.rs` (+8 -2) 📝 `crates/temps-deployments/src/jobs/verify_local_image.rs` (+2 -10) 📝 `crates/temps-deployments/src/utils/docker_inspect.rs` (+3 -3) 📝 `crates/temps-deployments/tests/nodejs_integration_test.rs` (+13 -21) 📝 `crates/temps-entities/src/lib.rs` (+4 -0) ➕ `crates/temps-entities/src/log_chunks.rs` (+28 -0) _...and 37 more files_ </details> ### 📄 Description ## Summary Closes #21 Adds a new `temps-log-aggregator` crate that provides comprehensive structured log aggregation for Docker containers deployed on the platform. - **Real-time collection**: Streams logs from Docker containers discovered via `sh.temps.*` labels, with reconnect resilience, container-gone detection, and bounded retries - **Compressed storage**: NDJSON chunks compressed with zstd, stored on filesystem (default) or S3 - **Dual-path search**: TimescaleDB index for fast ERROR/WARN queries; archive scan with decompression for full-text search across all levels - **Live tail**: SSE streaming endpoint with project/service/level filtering - **Retention**: Configurable automatic cleanup (30d chunks, 7d events) plus manual purge with audit logging - **Security**: `LogsRead` / `LogsDelete` permission guards on all endpoints ## Changes ### New crate: `temps-log-aggregator` (8,200+ lines) - `parser.rs` — Docker JSON log parsing, plain-text level detection, structured field extraction - `storage/` — Pluggable storage backends (filesystem, S3) with zstd compression - `services/chunk_writer.rs` — Per-container buffering with 1MB / 30s flush triggers - `services/collector.rs` — Docker log streaming with resilience (last_seen_ts tracking, container-gone detection, max consecutive errors) - `services/metadata.rs` — TimescaleDB operations for log_chunks and log_events - `services/search.rs` — Dual-path search routing (index vs archive), field filters, pagination - `services/tail.rs` — Broadcast-based live tail with filter matching - `services/retention.rs` — Chunk cleanup by age with storage deletion - `handlers/` — HTTP endpoints: POST /logs/search, GET /logs/context, GET /logs/tail (SSE), DELETE /projects/{id}/logs - `plugin.rs` — Platform integration: startup scan, Docker events listener, retention scheduler ### Modified crates - **temps-deployer**: Added `labels: HashMap<String, String>` to `DeployRequest`, applied to container creation - **temps-deployments**: Populates `sh.temps.project_id`, `sh.temps.deployment_id`, `sh.temps.environment_id`, `sh.temps.service`, `sh.temps.namespace` labels - **temps-auth**: Added `LogsDelete` permission to all 5 locations (enum, Display, from_str, all(), Role::permissions) - **temps-entities**: Added `log_chunks` and `log_events` Sea-ORM entities - **temps-migrations**: Added `m20260225_000001_create_log_aggregator_tables` migration - **temps-cli**: Reads `TEMPS_LOG_STORAGE_BACKEND` and S3 config env vars, registers plugin ## Test Coverage **101 tests** (was 89 before this session, +12 new): | Category | Count | Highlights | |----------|-------|-----------| | Parser | 11 | JSON/plain-text parsing, Docker timestamps, level detection | | Types | 7 | LogLevel, LogStream, RetentionConfig, UUID determinism | | Storage | 12 | Filesystem CRUD, S3 key construction, range reads | | Chunk Writer | 11 | Buffering, flush, multi-container, auto-flush at 1MB, 1000-line compression roundtrip | | Search | 21 | Service/env/deploy filtering, full-text, field filters, time ranges, 1000-line archive simulation | | Tail | 6 | Filter matching, broadcast subscription | | Metadata | 4 | insert_log_events_from_lines (indexable filtering), list_distinct_projects | | Handlers | 16 | Search, context, SSE tail, purge, pagination, auth (401), permission guards (403 Reader/purge, 200 Reader/search) | | Error/Plugin | 4 | Display formatting, plugin name | No regressions: `temps-auth` (102 passed), `temps-deployer` (39 passed) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
kerem closed this issue 2026-03-02 05:12:34 +03:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/temps#23
No description provided.