Framework-agnostic metrics and structured log collection with hexagonal architecture
Project description
observabilipy
Framework-agnostic metrics and structured log collection with hexagonal architecture.
Develop observability features decoupled from your infrastructure. Use embedded storage (SQLite, in-memory) during development, then optionally expose endpoints for scraping by Prometheus, Grafana Alloy, or other observability platforms when you're ready.
Features
- Prometheus-style metrics -
/metricsendpoint in text format - Structured logs -
/logsendpoint in NDJSON (Grafana Alloy compatible) - Framework adapters - FastAPI, Django, generic ASGI
- Storage backends - In-memory, SQLite (with WAL), Ring buffer
- Retention policies - Automatic cleanup with EmbeddedRuntime
Installation
git clone https://github.com/PhilHem/observabilipy.git
cd observabilipy
uv sync
For framework support:
uv sync --extra fastapi
uv sync --extra django
Quick Start
from fastapi import FastAPI
from observability.adapters.frameworks.fastapi import create_observability_router
from observability.adapters.storage.in_memory import (
InMemoryLogStorage,
InMemoryMetricsStorage,
)
app = FastAPI()
log_storage = InMemoryLogStorage()
metrics_storage = InMemoryMetricsStorage()
app.include_router(create_observability_router(log_storage, metrics_storage))
Run with uvicorn and visit /metrics and /logs.
Recording Metrics and Logs
import time
from observability.core.models import LogEntry, MetricSample
# Record a log entry
await log_storage.write(
LogEntry(
timestamp=time.time(),
level="INFO",
message="User logged in",
attributes={"user_id": 123, "ip": "192.168.1.1"},
)
)
# Record a metric sample
await metrics_storage.write(
MetricSample(
name="http_requests_total",
timestamp=time.time(),
value=1.0,
labels={"method": "GET", "path": "/api/users"},
)
)
Storage Backends
| Backend | Use Case |
|---|---|
InMemoryLogStorage / InMemoryMetricsStorage |
Development and testing |
SQLiteLogStorage / SQLiteMetricsStorage |
Persistent storage with WAL mode for concurrent access |
RingBufferLogStorage / RingBufferMetricsStorage |
Fixed-size buffer for memory-constrained environments |
All backends implement the same port interfaces and are interchangeable.
Examples
See the examples/ directory:
| Example | Description |
|---|---|
| minimal_example.py | Dummy metrics and logs generator for testing |
| cgroups_example.py | Container CPU and memory metrics from cgroups v2 |
| fastapi_example.py | Basic FastAPI setup with in-memory storage |
| django_example.py | Django integration |
| asgi_example.py | Generic ASGI middleware |
| sqlite_example.py | Persistent storage with SQLite |
| ring_buffer_example.py | Fixed-size storage for constrained environments |
| embedded_runtime_example.py | Background retention cleanup |
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file observabilipy-0.10.0.tar.gz.
File metadata
- Download URL: observabilipy-0.10.0.tar.gz
- Upload date:
- Size: 73.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2b9804d8379f297cdb19beebe048c62397c9767fdf6159412703dcc6dd6e1e26
|
|
| MD5 |
0bdf2a0ac838353a4b265113ae969f7b
|
|
| BLAKE2b-256 |
d0e1e66f6cec2d581747fa680e9781286cc56fb8a9b0543ef3dba3e4b1845160
|
Provenance
The following attestation bundles were made for observabilipy-0.10.0.tar.gz:
Publisher:
release.yml on PhilHem/observabilipy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
observabilipy-0.10.0.tar.gz -
Subject digest:
2b9804d8379f297cdb19beebe048c62397c9767fdf6159412703dcc6dd6e1e26 - Sigstore transparency entry: 760558886
- Sigstore integration time:
-
Permalink:
PhilHem/observabilipy@55f2d64ad9b8b716a6e16d39946abc526ec83f84 -
Branch / Tag:
refs/tags/v0.10.0 - Owner: https://github.com/PhilHem
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@55f2d64ad9b8b716a6e16d39946abc526ec83f84 -
Trigger Event:
push
-
Statement type:
File details
Details for the file observabilipy-0.10.0-py3-none-any.whl.
File metadata
- Download URL: observabilipy-0.10.0-py3-none-any.whl
- Upload date:
- Size: 20.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4b15a49a590aa7a64122fc5c4f75a8e631a4de7414a6e96e1a94a252a8bc7861
|
|
| MD5 |
677cddd8f11e236a701c1e6100cd3cc6
|
|
| BLAKE2b-256 |
63dda6907ea90bd9d732e60eb23f438258093352b796d6dfb2f21bd3de31a51a
|
Provenance
The following attestation bundles were made for observabilipy-0.10.0-py3-none-any.whl:
Publisher:
release.yml on PhilHem/observabilipy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
observabilipy-0.10.0-py3-none-any.whl -
Subject digest:
4b15a49a590aa7a64122fc5c4f75a8e631a4de7414a6e96e1a94a252a8bc7861 - Sigstore transparency entry: 760558888
- Sigstore integration time:
-
Permalink:
PhilHem/observabilipy@55f2d64ad9b8b716a6e16d39946abc526ec83f84 -
Branch / Tag:
refs/tags/v0.10.0 - Owner: https://github.com/PhilHem
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@55f2d64ad9b8b716a6e16d39946abc526ec83f84 -
Trigger Event:
push
-
Statement type: