@runtime-judgement/forwarder
v0.1.0
Published
OTLP fan-out proxy — forwards traces to Runtime Judgement and your existing collector
Downloads
76
Maintainers
Readme
@runtime-judgement/forwarder
An OTLP HTTP proxy that fans out traces to Runtime Judgement and your existing collector — zero app code changes required, drop it in as a sidecar.
Architecture
Your app
│ OTLP/HTTP
▼
rj-forwarder :4317
├──► Runtime Judgement (runtime-judgement.app/api/ingest/otlp/v1/traces)
│ └── non-blocking: RJ failure never blocks your upstream
└──► Your existing collector (otel-collector:4318) [optional]Installation
# One-shot via npx (no install needed)
npx @runtime-judgement/forwarder --rj-key=rj_live_...
# Or install globally
npm install -g @runtime-judgement/forwarder
rj-forwarder --rj-key=rj_live_...Usage
# Minimal — forward to RJ only
RJ_API_KEY=rj_live_... npx @runtime-judgement/forwarder
# With your existing collector
RJ_API_KEY=rj_live_... npx @runtime-judgement/forwarder \
--port 4317 \
--upstream http://otel-collector:4318
# All options
npx @runtime-judgement/forwarder \
--rj-key=rj_live_... # API key (overrides RJ_API_KEY env var)
--port=4317 # Port to listen on (default: 4317)
--upstream=http://host:4318 # Your existing OTLP collector (optional)
--rj-endpoint=https://... # Override RJ ingest URL (optional)
--verbose=true # Log every forwarded requestOptions reference
| Flag | Env var | Default | Description |
|---|---|---|---|
| --rj-key | RJ_API_KEY | — (required) | Runtime Judgement API key |
| --port | — | 4317 | Port to listen on |
| --upstream | — | — | Your existing OTLP collector base URL |
| --rj-endpoint | — | https://runtime-judgement.app/api/ingest/otlp/v1/traces | Override RJ ingest endpoint |
| --verbose | — | false | Log every request |
Docker
Add the forwarder as a sidecar in your docker-compose.yml:
services:
app:
build: .
environment:
OTEL_EXPORTER_OTLP_ENDPOINT: http://rj-forwarder:4317
depends_on:
- rj-forwarder
rj-forwarder:
image: node:20-alpine
command: >
npx @runtime-judgement/forwarder
--port=4317
--upstream=http://otel-collector:4318
environment:
RJ_API_KEY: ${RJ_API_KEY}
ports:
- "4317:4317"
otel-collector:
image: otel/opentelemetry-collector:latest
# ... your existing collector configGitHub Actions
Run the forwarder as a background service in CI so traces from your test suite flow to Runtime Judgement:
jobs:
test:
runs-on: ubuntu-latest
services:
otel-collector:
image: otel/opentelemetry-collector:latest
ports:
- 4318:4318
steps:
- uses: actions/checkout@v4
- name: Start RJ forwarder
run: |
npx @runtime-judgement/forwarder \
--port 4317 \
--upstream http://localhost:4318 \
--verbose=true &
# Give it a moment to bind
sleep 2
env:
RJ_API_KEY: ${{ secrets.RJ_API_KEY }}
- name: Run tests
run: npm test
env:
OTEL_EXPORTER_OTLP_ENDPOINT: http://localhost:4317
- name: Stop forwarder
if: always()
run: kill $(lsof -t -i:4317) || trueProgrammatic API
import { startForwarder } from "@runtime-judgement/forwarder"
const { close, port } = startForwarder({
rjApiKey: "rj_live_...",
port: 4317,
upstream: "http://otel-collector:4318",
verbose: true,
})
// Later:
close()ForwarderConfig
type ForwarderConfig = {
rjApiKey: string // Required. Runtime Judgement API key.
port?: number // Default: 4317
host?: string // Default: "0.0.0.0"
rjEndpoint?: string // Default: https://runtime-judgement.app/api/ingest/otlp/v1/traces
upstream?: string // Optional. Your existing OTLP collector base URL.
verbose?: boolean // Default: false
}Failure semantics
- RJ unavailable: the upstream still receives the trace. RJ forwarding errors are caught and logged (when
--verbose), never propagated to the sender. - Upstream unavailable: the sender still gets HTTP 200. Upstream errors are caught and logged (when
--verbose). - Sender always gets 200 with
{"partialSuccess":{}}— the same response an OTLP-compliant collector returns.
License
MIT
