Server status ...

magogi/prod/: mgf-logship-0.1.9 metadata and description

Simple index

Centralized log shipping for mgf-common consumers — a fail-open logging handler that batches canonical LogRecord JSON + statistics and POSTs them to a collector over a versioned, language-neutral wire protocol, plus a store-now stub collector. Sibling of mgf-common under the mgf.* namespace.

author Bassam Alsanie, mgf-logship contributors
classifiers
  • Development Status :: 3 - Alpha
  • Intended Audience :: Developers
  • License :: OSI Approved :: Apache Software License
  • Programming Language :: Python :: 3
  • Programming Language :: Python :: 3.11
  • Programming Language :: Python :: 3.12
  • Programming Language :: Python :: 3.13
  • Topic :: Software Development :: Libraries
  • Topic :: System :: Logging
  • Typing :: Typed
description_content_type text/markdown
keywords centralized-logs, log-shipping, logging, ndjson, observability
license Apache-2.0
license_file
  • LICENSE
  • NOTICE
project_urls
  • Homepage, https://codeberg.org/magogi-admin/mgf-logship
  • Issues, https://codeberg.org/magogi-admin/mgf-logship/issues
  • Changelog, https://codeberg.org/magogi-admin/mgf-logship/src/branch/main/CHANGELOG.md
requires_dist
  • mgf-common<1.0,>=0.42
  • fastapi>=0.110; extra == 'collector'
  • httpx>=0.27; extra == 'collector'
  • uvicorn>=0.30; extra == 'collector'
  • fastapi>=0.110; extra == 'dev'
  • httpx>=0.27; extra == 'dev'
  • import-linter>=2.0; extra == 'dev'
  • mgf-test-supervisor<0.2,>=0.1.3; extra == 'dev'
  • mypy>=1.10; extra == 'dev'
  • pytest-cov>=5.0; extra == 'dev'
  • pytest-timeout>=2.3; extra == 'dev'
  • pytest>=8.0; extra == 'dev'
  • ruff<0.16,>=0.4; extra == 'dev'
  • mgf-common[standards]<1.0,>=0.46; extra == 'standards'
  • fastapi>=0.110; extra == 'test'
  • httpx>=0.27; extra == 'test'
requires_python >=3.11

Because this project isn't in the mirror_whitelist, no releases from root/pypi are included.

File Tox results History
mgf_logship-0.1.9-py3-none-any.whl
Size
20 KB
Type
Python Wheel
Python
3
mgf_logship-0.1.9.tar.gz
Size
122 KB
Type
Source

mgf-logship

Centralized log shipping for the Magogi federation — the Layer-B half of the unified-logging program (see mgf-common/docs/inprogress/UNIFIED_LOGGING_DESIGN.md, decision D4: ship + protocol now, stub the server).

A consumer attaches LogShipper to its logging tree; it batches the canonical mgf-common LogRecord JSON (the same shape every runtime emits — OB-10), redacts each record, and POSTs them to a collector over a versioned, language-neutral wire protocol. A store-now stub collector (FastAPI + sqlite) is included so the protocol works end-to-end today; analysis and presentation are a later program.

Install

pip install mgf-logship                # shipper only (stdlib transport)
pip install mgf-logship[collector]     # + the FastAPI/sqlite stub collector

Ship logs from an app

import logging
from mgf.logship import LogShipper
from mgf.common.observability import current_log_stats  # optional stats shipping

shipper = LogShipper(
    "https://collector.internal",
    token="…",                       # Authorization: Bearer …
    stats_provider=current_log_stats,  # also ship LogStats every 30s
)
logging.getLogger().addHandler(shipper)
# … on shutdown: shipper.close()  (flushes the queue)

LogShipper is fail-open (a slow/down collector never blocks or crashes the app), bounded (the queue is capped; oldest dropped on overflow, counted in dropped_count), and redacts before ship (off-box data is scrubbed).

In production (env-driven, with app context)

The pattern the fleet uses (reference: mgf.fed._logging.bootstrap_logging, the mgf-fed CLI):

import logging, os
from mgf.common import bootstrap   # canonical app bootstrap (mgf-common)
from mgf.logship import LogShipper

def bootstrap_logging() -> None:
    url, token = os.environ.get("MGF_LOGSHIP_URL"), os.environ.get("MGF_LOGSHIP_INGEST_TOKEN")
    if not (url and token):
        return                      # opt-in: unconfigured ⇒ no-op, app unchanged
    bootstrap(app_name="myapp", app_version=__version__)   # ← see note below
    logging.getLogger().addHandler(
        LogShipper(url, token=token, app="myapp", env=os.environ.get("MGF_LOGSHIP_ENV", "prod"))
    )

Run the stub collector

from mgf.logship.collector import create_collector_app
app = create_collector_app(db_path="logship.db", token="…")
# uvicorn module:app

Endpoints: POST /ingest (NDJSON of LogRecords), POST /stats (a LogStats JSON), GET /health. It persists to sqlite and stops there.

The wire protocol

mgf.logship._protocol is the source of truth: SHIP_PROTOCOL_VERSION, the endpoint paths, the X-Logship-* headers, and the NDJSON framing. Deliberately HTTP + NDJSON so a Zig or TS shipper can talk to the same collector with nothing but a socket and a JSON encoder.

License

MIT — see LICENSE.