Skip to main content

scietex.log_aggregator_service

scietex.log_aggregator_service is a scietex.service worker that merges the per-worker log streams of the configured services into one shared stream. Each scietex.service worker writes its own stream (scietex:{service}:{instance_id}:log); this service tails all of them and copies every entry into a single target stream (scietex:log by default), stamping each entry with a source field ({service}:{instance_id}) so consumers can tell which worker emitted it.

The aggregator is the sole writer of the target stream, so it owns both the MAXLEN ~ trim and the whole-key EXPIRE. The API backend reads that stream for the system log viewer and no longer trims it.

Python ≥ 3.10 · License: MIT

How it works

per-worker log streams                     shared stream                viewer
scietex:{svc}:{inst}:log  ─┐
scietex:{svc2}:{inst}:log  ─┤  XREAD (multi-key)   ┌────────────────┐   GET /logs/          ─► LogViewer
scietex:{svcN}:{inst}:log  ─┘ ───────────────►    │ scietex:log    │   GET /logs/stream (SSE)   (Source col)
                                                   │ XADD MAXLEN ~  │
   ▲ each writer owns its stream                   │ EXPIRE ttl     │
   │ (worker heartbeat refreshes its TTL)          └────────────────┘
                                                   ▲ single owner
                                   ┌───────────────┴────────────────┐
                                   │ LogAggregatorService worker     │
                                   │ (reads scietex:{agg}:config)    │
                                   └─────────────────────────────────┘
  • A single supervisor loop (not one task per stream) tails every source with a multi-key XREAD, so the merge is natural and there is no task fan-out.
  • A periodic SCAN (scietex:{service}:*:log) picks up workers that appear or disappear; the source set is rebuilt in place.
  • The target stream's TTL is refreshed on a timer (Valkey EXPIRE sets a TTL on the key; XADD does not refresh it).
  • The aggregator's own service is excluded from the source set, so its logs do not loop back into the stream it writes.

Installation

pip install scietex.log_aggregator_service

This pulls in scietex.service[valkey] (the worker framework and its Valkey transport).

Quick start

1. Write a configuration file

The service reads log_aggregator.yml from a log_aggregator/ subdirectory of its config directory. Create it by hand, or let the service generate defaults on first run. The file is the bootstrap layer of a four-layer merge: constructor defaults < log_aggregator.yml < the framework's config.yml snapshot < the remote log_aggregator section. Each layer is a field-level patch — a key absent from a layer inherits the layer below, null clears it back to the constructor default, and a value sets it:

source_services:
  - ModbusService
exclude_services:
  - LogAggregatorService
target_stream: scietex:log
max_len: 100000
ttl_seconds: 604800
batch_size: 200
block_ms: 1000
scan_interval: 15.0

2. Run the service

start-log-aggregator --conf-dir /etc/scietex

The service resolves its config directory automatically when --conf-dir is omitted. It runs in the foreground until it receives SIGINT or SIGTERM.

3. Register it with the backend

The backend is the config authority: register the service so it can deliver the log_aggregator section (source services, target stream, max_len, ttl):

curl -X POST http://localhost:8000/api/v1/services/discovered/LogAggregatorService/register

Configuration at a glance

The defaults below are the constructor (L0) values: a field absent from every layer, or explicitly cleared with null, resolves to the value shown.

Setting Default Meaning
source_services [] Service names whose per-worker log streams are aggregated
exclude_services [] Names removed from the source set (self-exclusion)
target_stream scietex:log Shared stream the aggregator writes
max_len 100000 MAXLEN ~ applied on each write (0 disables)
ttl_seconds 604800 Whole-key TTL refreshed on a timer (0 disables)
batch_size 200 Entries per XREAD
block_ms 1000 XREAD block timeout
scan_interval 15.0 Seconds between source-set SCANs

Development

Dependencies are managed with uv; checks and tests run through tox:

uv sync --all-extras
uv run tox                    # format, lint, type, py314
uv run tox -e py314           # tests only

Metadata

Release files for scietex.log-aggregator-service 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for scietex.log-aggregator-service 0.3.0
File Size Uploaded Provenance
scietex_log_aggregator_service-0.3.0.tar.gz 17.6 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for scietex.log-aggregator-service 0.3.0
File Interpreter ABI Platform
scietex_log_aggregator_service-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 30.9 kB

Release files / scietex_log_aggregator_service-0.3.0.tar.gz

Download URL scietex_log_aggregator_service-0.3.0.tar.gz
Size 17.6 kB
Tags Source
SHA-256 checksum
How to use checksums
c75e4bf112ec9b4eda617892971e0985f6f027a0654317b023c07f432f721f68
BLAKE2b-256 checksum
How to use checksums
72595896ba784d649a290f84943350158d8c5036444b46a39f20e38bd7ebb5a7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 9, 2026.

Transparency log

Release files / scietex_log_aggregator_service-0.3.0-py3-none-any.whl

Download URL scietex_log_aggregator_service-0.3.0-py3-none-any.whl
Size 13.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
48e46da1728d007f5bcc9f9d70cedcc12895ef0b04d4dd787b7bcbc649352c2b
BLAKE2b-256 checksum
How to use checksums
057e04727637c3847b5b765d5ce1dc29ea5902e7d00fea920783a38eaef2e953
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 9, 2026.

Transparency log

Security for scietex.log-aggregator-service 0.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for scietex_log_aggregator_service-0.3.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 9, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page