Metadata-Version: 2.4
Name: apm-proxy
Version: 0.1.2
Summary: Typed Elastic APM proxy with NDJSON logging, forwarding, grouping, and debugging
License: MIT
Project-URL: Homepage, https://github.com/kesi03/apm-proxy
Project-URL: Source, https://github.com/kesi03/apm-proxy
Project-URL: Issues, https://github.com/kesi03/apm-proxy/issues
Keywords: elastic,apm,proxy,ndjson,observability,fastapi,telemetry
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: fastapi
Requires-Dist: uvicorn[standard]
Requires-Dist: python-dotenv
Requires-Dist: requests
Requires-Dist: pydantic>=2.0
Requires-Dist: rich
Requires-Dist: httpx
Requires-Dist: tomli; python_version < "3.11"

# **APM Proxy — Typed Elastic APM NDJSON Proxy**

A fully typed, FastAPI‑based Elastic APM proxy designed for **debugging**, **observability pipelines**, **traffic inspection**, and **local/offline APM analysis**.  
It acts as a drop‑in replacement for the Elastic APM intake API, with powerful enhancements:

### ⭐ Core Features
- **Full NDJSON capture** — persist raw APM events to disk for replay, audit, or offline analysis  
- **Header‑aware grouping** — group events by transaction, span, trace, or custom headers  
- **Full header forwarding** — preserves `traceparent`, `X-APM-*`, and all custom headers  
- **Typed Pydantic models** — parse NDJSON into structured Python objects  
- **Configurable logging** — console logging, file logging, and debug dumps  
- **Flexible configuration** — `.env`, custom `.env`, or structured TOML  
- **CLI runner** — `apm-proxy` command with reload, port override, and config selection  
- **Drop‑in APM intake compatibility** — forwards to Elastic APM or runs in capture‑only mode  
- **Zero‑config development mode** — instant startup with sensible defaults  
- **Safe offline mode** — inspect APM traffic without forwarding anything  
- **Full request header printing** — see exactly what your APM agents send  
- **Span + transaction correlation** — reconstruct traces from NDJSON  
- **Supports browser, Node, Python, Go, Java APM agents**  

This proxy is ideal for **debugging distributed traces**, **reverse‑engineering APM agents**, **building custom telemetry pipelines**, and **capturing APM traffic in development**.

---

## **1. Installation**

Clone the repository:

```bash
git clone https://github.com/your-org/apm-proxy.git
cd apm-proxy
```

Install in editable mode:

```bash
pip install -e .
```

This installs:

- The proxy package  
- The `apm-proxy` CLI command  
- All required dependencies  

---

## **2. Configuration**

The proxy supports **three configuration sources**:

### **A. Default `.env` file**

Place a `.env` file in the project root:

```env
APM_SERVER=https://apm.example.com
APM_TOKEN=secret-token
APM_FORWARD=true

APM_SAVE=true
APM_SAVE_DIR=./apm_logs
APM_LOG_PREFIX=events

APM_PRINT=false

APM_LOG_LEVEL=INFO
APM_LOG_TO_FILE=true
APM_LOG_FILE=apm_proxy.log

APM_PORT=8200
```

---

### **B. Custom `.env` file**

```bash
apm-proxy --env /path/to/custom.env
```

---

### **C. TOML configuration (recommended)**

```toml
[apm_server]
url = "https://apm.example.com"
token = "secret-token"
forward = true

[logs]
save = true
save_dir = "./apm_logs"
prefix = "events"

[console]
print_payloads = false

[logging]
level = "INFO"
to_file = true
file = "apm_proxy.log"

[grouping]
headers = ["X-APM-Transaction-ID", "X-APM-Span-ID"]

[proxy_server]
port = 8200
```

Start with TOML:

```bash
apm-proxy --config config.toml
```

---

### **Configuration Precedence**

1. **TOML overrides `.env`**
2. **CLI overrides both**

Example:

```bash
apm-proxy --env base.env --config prod.toml --port 9999
```

---

## **3. Startup Modes**

### **Default startup**

```bash
apm-proxy
```

Uses `.env` in project root.

---

### **Start with custom `.env`**

```bash
apm-proxy --env staging.env
```

---

### **Start with TOML**

```bash
apm-proxy --config config.toml
```

---

### **Override port**

```bash
apm-proxy --port 9000
```

---

### **Enable auto‑reload (development)**

```bash
apm-proxy --reload
```

---

### **Print raw NDJSON payloads**

```env
APM_PRINT=true
```

Or inline:

```bash
APM_PRINT=true apm-proxy
```

---

### **Enable debug logging**

```env
APM_LOG_LEVEL=DEBUG
```

---

### **Disable forwarding (local capture only)**

```env
APM_FORWARD=false
```

---

## **4. Typed NDJSON Models**

The proxy parses NDJSON events into typed Pydantic models:

- `Transaction`
- `Span`
- `Error`
- `Metricset`
- `Metadata`
- `NdjsonEvent` (generic wrapper)

This enables:

- Deterministic inspection  
- Enrichment  
- Filtering  
- Routing  
- Debugging  
- Custom processing pipelines  

Example:

```python
if event.is_transaction():
    tx = Transaction(transaction=event.raw["transaction"])
```

---

## **5. Logging & Debugging**

The proxy uses **Rich** for colored logs:

- Colored event types  
- Pretty tracebacks  
- Optional file logging  
- Log levels from `.env` or TOML  
- Full header dumps  
- Grouping header dumps  
- NDJSON payload dumps  

### **Log settings**

```toml
[logging]
level = "DEBUG"
to_file = true
file = "proxy.log"
```

### **Console payload printing**

```toml
[console]
print_payloads = true
```

---

## **6. NDJSON Capture**

Captured NDJSON is written with contextual headers:

```
# ---- Received: 2026-08-18T09:15:12.123Z ----
# ---- X-APM-Transaction-ID: abc123 ----
# ---- X-APM-Span-ID: def456 ----
{"metadata": ...}
{"transaction": ...}
{"span": ...}
```

This makes it ideal for:

- replay  
- offline analysis  
- debugging  
- trace reconstruction  
- custom pipelines  

---

## **7. Dependencies**

```toml
dependencies = [
  "fastapi",
  "uvicorn[standard]",
  "python-dotenv",
  "requests",
  "pydantic>=2.0",
  "rich",
  "httpx",
  "tomli; python_version<'3.11'"
]
```

### **Dependency Breakdown**

| Package | Purpose |
|--------|---------|
| **fastapi** | HTTP server |
| **uvicorn[standard]** | ASGI runtime |
| **python-dotenv** | `.env` loading |
| **requests** | Forwarding NDJSON |
| **pydantic>=2.0** | Typed NDJSON models |
| **rich** | Colored logs |
| **httpx** | Async forwarding |
| **tomllib / tomli** | TOML config support |

---

## **8. CLI Summary**

| Flag | Description |
|------|-------------|
| `--env PATH` | Use custom `.env` file |
| `--config PATH` | Use TOML config file |
| `--port N` | Override port |
| `--reload` | Enable auto‑reload |

---
