Official Kyrontha Lens SDK — buffered async log shipping to lens.kyrontha.io
Project description
kyrontha-lens
Official Python SDK for Kyrontha Lens — buffered, async, fire-and-forget log shipping.
- Non-blocking. Logging never waits for the network. A daemon thread flushes batches every 5s or every 50 events.
- Doesn't crash your app. A Lens outage drops events after retry; your code keeps running.
- Drains on shutdown. Hooks
atexit,SIGTERM,SIGINTso the last few seconds of logs aren't lost on container restart. - Zero runtime dependencies. Uses stdlib
urllib,json,threading,loggingonly.
Install
# Once published to PyPI:
pip install kyrontha-lens
# Until then (early access from our git repo):
pip install "git+https://dev.azure.com/jblamba/Kyrontha%20Lens/_git/Kyrontha%20Lens#subdirectory=sdk/python"
Python 3.9+ required.
Get an API key
In Kyrontha Lens, go to Connections → Connect via SDK, name your connection, and copy the API key shown on screen. The first event you ship will auto-promote the connection from "awaiting first event" to "connected".
Quick start
import os
from kyrontha_lens import KyronthaLogger
log = KyronthaLogger(
api_key=os.environ["KYRONTHA_KEY"],
source="checkout-api",
)
log.info("order placed", order_id=42, user_id="u-123")
log.error("payment failed", order_id=42, reason="declined")
# For short-lived scripts: drain before exit so the in-flight POST has time
# to complete. Long-running services don't need this — atexit handles it.
log.flush()
stdlib logging integration
Most idiomatic for any Python app already using logging:
import logging, os
from kyrontha_lens import KyronthaHandler
logging.basicConfig(level=logging.INFO, handlers=[
logging.StreamHandler(),
KyronthaHandler(api_key=os.environ["KYRONTHA_KEY"], source="checkout-api"),
])
log = logging.getLogger(__name__)
log.info("order placed", extra={"order_id": 42, "user_id": "u-123"})
log.error("payment failed", extra={"order_id": 42, "reason": "declined"})
The handler ships every record's extra={...} fields as structured meta. Standard LogRecord attributes (pathname, lineno, funcName, etc.) are stripped to avoid noise.
structlog integration
structlog renders to stdlib logging by default — so the same KyronthaHandler works:
import logging, os, structlog
from kyrontha_lens import KyronthaHandler
logging.basicConfig(level=logging.INFO, handlers=[
logging.StreamHandler(),
KyronthaHandler(api_key=os.environ["KYRONTHA_KEY"], source="checkout-api"),
])
structlog.configure(
processors=[
structlog.stdlib.add_log_level,
structlog.processors.TimeStamper(fmt="iso"),
structlog.stdlib.render_to_log_kwargs, # forward as `extra=`
],
logger_factory=structlog.stdlib.LoggerFactory(),
)
log = structlog.get_logger()
log.info("order placed", order_id=42, user_id="u-123")
Loguru integration
Loguru's logger.add(handler) accepts any logging.Handler:
import os
from loguru import logger
from kyrontha_lens import KyronthaHandler
logger.add(KyronthaHandler(api_key=os.environ["KYRONTHA_KEY"], source="checkout-api"))
logger.info("order placed", order_id=42)
API
KyronthaLogger(api_key, *, endpoint=None, source=None, ...)
| kwarg | type | default | notes |
|---|---|---|---|
api_key |
str |
(required) | From a Lens SDK connection |
endpoint |
str | None |
https://lens.kyrontha.io/api/ingest |
Override for self-hosted Lens |
source |
str | None |
KYRONTHA_SOURCE env, or 'app' |
Shows in the Source column of the Lens UI |
flush_interval_s |
float |
5.0 |
Background flush cadence (seconds) |
flush_batch_size |
int |
50 |
Buffer size that forces an immediate flush |
max_retries |
int |
3 |
Per-batch, exponential backoff (250ms → 500ms → 1s) |
on_error |
Callable[[Exception], …] |
prints to stderr | Pass lambda e: None to silence |
Methods
| Method | Notes |
|---|---|
log(level, message, **meta) |
Generic — level is any string, lower-cased before send |
fatal/error/warn/info/debug |
Convenience for the standard levels |
flush(timeout=10.0) |
Force-flush — call before short-lived scripts exit |
close(timeout=10.0) |
Stop the background worker and drain |
How it works
- Every
log()call appends to an in-memory buffer — synchronous, no I/O. - A daemon thread flushes the buffer to
POST /api/ingesteveryflush_interval_s. The buffer also flushes immediately when it hitsflush_batch_size. - The Lens backend tags every event with the
connection_idlinked to your API key, so the View logs button on your connection card filters precisely. - On graceful shutdown (
atexit,SIGTERM,SIGINT) the SDK drains the buffer one last time.
Failure modes
- Lens unreachable / 5xx: retried up to
max_retrieswith exponential backoff, then dropped. Youron_errorcallback is invoked. The host app continues. - API key revoked / 4xx: dropped immediately (retry won't help). Your
on_errorcallback is invoked. - Process killed with SIGKILL or
os._exit(0): events still in the buffer are lost. Uselog.flush()before exiting if you can't tolerate that.
License
Proprietary. © Kyrontha. Reach out for commercial use.
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 kyrontha_lens-0.1.1.tar.gz.
File metadata
- Download URL: kyrontha_lens-0.1.1.tar.gz
- Upload date:
- Size: 8.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
04e7391a30db468d059ca49dedf3ade1a8a90d3550d16940715654540abe9495
|
|
| MD5 |
1ad176eecb77d749b58fc37c2bec4a80
|
|
| BLAKE2b-256 |
596f136d6a8a0c348c0fab78c936dc7327e2bdc3ee647f99b2cfd684cb53a5ca
|
File details
Details for the file kyrontha_lens-0.1.1-py3-none-any.whl.
File metadata
- Download URL: kyrontha_lens-0.1.1-py3-none-any.whl
- Upload date:
- Size: 9.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9a13fbe8025100d1153b6659fe787e821daaa278b5b56c9b24ca4b9f74ee9a70
|
|
| MD5 |
9e0522fd910d2f7366926f130854e501
|
|
| BLAKE2b-256 |
e27091d0376f7844c756d45750d5955f6b53da4919355c2ab278a874fe2a6a95
|