Metadata-Version: 2.4
Name: nanotelemetry
Version: 0.2.0
Summary: A tiny, dependency-free telemetry library: events, counters, gauges, and timing spans.
Author-email: dark.soul.test.1@gmail.com
License-Expression: MIT
License-File: LICENSE
Keywords: instrumentation,metrics,monitoring,observability,telemetry
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: System :: Monitoring
Classifier: Typing :: Typed
Requires-Python: >=3.9
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == 'dev'
Description-Content-Type: text/markdown

# nanotelemetry

A tiny, dependency-free telemetry library for Python. Record events, counters,
gauges, and timing spans, then flush them to one or more pluggable exporters.

- **Zero dependencies** — pure standard library.
- **Thread-safe** — share one client across threads.
- **Pluggable exporters** — console, in-memory, or your own.
- **Typed** — ships with `py.typed`.

## Install

```bash
pip install nanotelemetry
```

## Quickstart

```python
from nanotelemetry import Telemetry, ConsoleExporter

tel = Telemetry(
    service="my-app",
    exporters=[ConsoleExporter()],
    tags={"env": "prod"},
)

# Discrete events
tel.event("user.signup", plan="pro")

# Counters and gauges
tel.count("requests", 1, route="/home")
tel.gauge("queue.depth", 42)

# Time a block of code
with tel.span("db.query", table="users") as attrs:
    rows = run_query()
    attrs["rows"] = len(rows)

# ...or a whole function
@tel.timed("compute")
def compute():
    ...

tel.flush()   # send buffered events to exporters
```

Use it as a context manager to flush and close automatically:

```python
with Telemetry(service="my-app", exporters=[ConsoleExporter()]) as tel:
    tel.event("startup")
```

## Event kinds

| Method              | Kind    | `value` means            |
| ------------------- | ------- | ------------------------ |
| `event(name, **kw)` | `event` | (none)                   |
| `count(name, n)`    | `count` | the increment            |
| `gauge(name, x)`    | `gauge` | the reading              |
| `span(name)`        | `span`  | duration in seconds      |

Every event carries the client's `service` name plus any `tags` you configured,
merged with the per-call attributes.

## System info

Pass `include_system_info=True` to automatically tag every event with details
about the host it's running on — hostname, OS, architecture, Python version,
and PID:

```python
tel = Telemetry(service="my-app", include_system_info=True)
tel.event("startup")
# attributes now include: host, os, os_release, arch, python, python_impl, pid
```

It's collected once at construction and off by default. Any keys you set
explicitly in `tags` take precedence. You can also call the collector directly:

```python
from nanotelemetry import sysinfo
print(sysinfo())
# {'host': 'laptop', 'os': 'Darwin', 'arch': 'arm64', 'python': '3.12.1', ...}
```

## Batching

The client buffers events and auto-flushes once `batch_size` (default 100) is
reached. Set `batch_size=0` to disable auto-flush and call `flush()` yourself.

## Custom exporters

Subclass `Exporter` to send events anywhere:

```python
import json
import urllib.request
from nanotelemetry import Exporter

class HTTPExporter(Exporter):
    def __init__(self, url):
        self.url = url

    def export(self, events):
        payload = json.dumps([e.to_dict() for e in events]).encode()
        req = urllib.request.Request(
            self.url, data=payload, headers={"Content-Type": "application/json"}
        )
        urllib.request.urlopen(req)
```

## Development

```bash
pip install -e ".[dev]"
pytest
```

## License

MIT
