Tracklyng — LLM cost tracking & observability. Capture LLM requests via OpenTelemetry GenAI instrumentation with a one-line install and zero call-site changes.
Project description
Tracklyng
Capture what can be logged from a real LLM request, with a one-line install in the client's app and zero changes to their call site.
pip install tracklyng
How it works
client app tracklyng lib Tracklyng
----------- -------------- ----------
tracklyng.init(api_key=...) ──▶ sets up OpenTelemetry tracer
turns on the GenAI instrumentation
(every provider SDK)
client.models.generate_content(...)
│ (real request still goes straight to the provider)
▼
OpenTelemetry instrumentation captures a span
│
▼
our SpanExporter ──────────────────────────────────▶ hosted ingestion endpoint
(+ token counts and host/location, lifted from the span & resource)
We do not maintain the monkey-patches ourselves — the
opentelemetry-instrumentation-* packages do. tracklyng.init() just stands up
the tracer, points the exporter at Tracklyng's managed ingestion endpoint, and
flips the instrumentation on. They emit the standard gen_ai.* OpenTelemetry
semantic conventions, so one span shape covers every provider. The exporter POSTs
each captured span as JSON to the hosted endpoint, where it is stored in
telemetry_spans.
Run it
Call tracklyng.init() once, before the first LLM request — the rest is the
provider SDK code you already have:
import os
import tracklyng
tracklyng.init(api_key="tlk_live_...") # the entire integration
# ...your existing, unmodified provider call:
from google import genai
client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
client.models.generate_content(
model="gemini-3.1-flash-lite",
contents="In one sentence, what is observability for LLM apps?",
)
pip install tracklyng
export GEMINI_API_KEY=your-real-key
python your_app.py # the captured span is sent to Tracklyng
The same tracklyng.init() covers every supported provider: an Azure OpenAI,
Anthropic, Bedrock, or Vertex AI call produces a span with the same gen_ai.*
keys.
Following Sentry's model for the credential: called with no api_key,
Tracklyng runs as a no-op (nothing is captured or sent) so it is safe to leave in
place across environments; a malformed key raises TracklyngConfigError at
init(); a well-formed key that turns out to be revoked is reported and the batch
dropped at export time, never crashing or blocking the host application.
Providers
tracklyng.init() switches on one OpenTelemetry instrumentation per LLM SDK we
ship. A client only produces spans for the SDKs they actually use; others are
skipped silently. Adding a provider = adding its instrumentor to
_enable_instrumentors.
| Provider | Instrumentation | Notes |
|---|---|---|
| OpenAI / Azure OpenAI | opentelemetry-instrumentation-openai |
one instrumentor covers both — AzureOpenAI is part of the openai SDK |
| Anthropic / Claude | opentelemetry-instrumentation-anthropic |
also covers Claude via the anthropic SDK's Bedrock client |
| AWS Bedrock | opentelemetry-instrumentation-bedrock |
patches the boto3 bedrock-runtime client |
| Vertex AI | opentelemetry-instrumentation-vertexai |
patches google-cloud-aiplatform |
| Google Gemini | opentelemetry-instrumentation-google-generativeai |
patches the unified google-genai SDK |
All five emit the same
gen_ai.*attributes, so the captured span shape is identical across providers — our exporter reads one set of keys regardless of which provider made the call.
Data captured
Prompt and response content is captured verbatim. Each span carries the full
gen_ai.*payload the instrumentation emits — including user messages, system instructions, and model completions (both the current semantic-convention attributes and event bodies). Nothing is redacted or stripped; the complete record is stored server-side intelemetry_spans.payload.
Because the library runs inside your application, anything your app sends to or receives from an LLM — including PII, PHI, or other regulated data — is part of the captured span. If you operate under GDPR/HIPAA or similar obligations, account for this prompt/response content in your data-processing assessment before enabling Tracklyng. (Earlier builds stripped content to metadata only; that behavior was removed — content is now persisted in full.)
Layout
| Path | What |
|---|---|
tracklyng/__init__.py |
exposes tracklyng.init() |
tracklyng/_capture.py |
OTel setup, instrumentor list, and the span exporter that POSTs each span to the ingestion endpoint |
tests/ |
unit tests for the span-to-record transform, the exporter, and init's failure modes |
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 tracklyng-0.1.1.tar.gz.
File metadata
- Download URL: tracklyng-0.1.1.tar.gz
- Upload date:
- Size: 15.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
71d750be50377531de1bd29b926909259db4ff8dd4cf52716f479615b1073774
|
|
| MD5 |
085b41f9aff369d66e3391c940d00312
|
|
| BLAKE2b-256 |
7d177fe524d0ee7eb1e38c44b641db85cc029a20638453ee1b1d27856e59805e
|
Provenance
The following attestation bundles were made for tracklyng-0.1.1.tar.gz:
Publisher:
publish.yml on loro-app/tracklyng
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tracklyng-0.1.1.tar.gz -
Subject digest:
71d750be50377531de1bd29b926909259db4ff8dd4cf52716f479615b1073774 - Sigstore transparency entry: 1781383812
- Sigstore integration time:
-
Permalink:
loro-app/tracklyng@f42f15f5e586fd9fd8bb92bb916d7c603fc91acc -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/loro-app
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f42f15f5e586fd9fd8bb92bb916d7c603fc91acc -
Trigger Event:
push
-
Statement type:
File details
Details for the file tracklyng-0.1.1-py3-none-any.whl.
File metadata
- Download URL: tracklyng-0.1.1-py3-none-any.whl
- Upload date:
- Size: 15.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4a9ac6ae6331d460d9319594c0778a49748c6b90385cec6c53c6b79fe9c835b9
|
|
| MD5 |
0b06f1e60db8fc0ab88423ad7fc3d4b6
|
|
| BLAKE2b-256 |
3592d445ba6de0c691690bb5373c3fe433b79f79cdd63f00bdf14cf123ce03a2
|
Provenance
The following attestation bundles were made for tracklyng-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on loro-app/tracklyng
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tracklyng-0.1.1-py3-none-any.whl -
Subject digest:
4a9ac6ae6331d460d9319594c0778a49748c6b90385cec6c53c6b79fe9c835b9 - Sigstore transparency entry: 1781383898
- Sigstore integration time:
-
Permalink:
loro-app/tracklyng@f42f15f5e586fd9fd8bb92bb916d7c603fc91acc -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/loro-app
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f42f15f5e586fd9fd8bb92bb916d7c603fc91acc -
Trigger Event:
push
-
Statement type: