Skip to content

License

The License Receiver is a lightweight service that tracks 10x Engine node usage for billing in air-gapped and on-premise deployments where engines cannot reach the Log10x SaaS backend.

When Do I Need This?

Deployment Mode Metrics Destination Billing License Receiver Needed?
SaaS prometheus.log10x.com Automatic No
On-prem (connected) Your TSDB + billing.log10x.com Automatic No
On-prem (air-gapped) Your TSDB only Manual Yes

SaaS Customers

If your engines can reach prometheus.log10x.com, you don't need the License Receiver. Usage tracking is automatic.

Architecture

The License Receiver accepts the same Prometheus Remote Write format that engines already send - no engine code changes required. It filters for billing-relevant metrics and stores them locally.

%%{init: {'theme': 'dark', 'themeVariables': { 'primaryColor': '#101519', 'primaryTextColor': '#fff', 'primaryBorderColor': '#272d33', 'lineColor': '#4ade80', 'background': '#01080f'}}}%%
graph LR
    Engine["🔧 Engines"] -->|Prometheus RW| LR["📋 License Receiver"]
    LR --> DB["💾 Database"]
    LR -->|GET /report| Report["📄 Report"]
    Report -->|Quarterly| Billing["☁️ Log10x"]

    classDef default fill:#101519,stroke:#272d33,color:#fff,stroke-width:1px,rx:8,ry:8
    classDef engine fill:#10b981,stroke:#059669,color:#fff,stroke-width:2px
    classDef receiver fill:#6366f1,stroke:#4f46e5,color:#fff,stroke-width:2px
    classDef storage fill:#0891b2,stroke:#0e7490,color:#fff,stroke-width:2px
    classDef external fill:#ea580c,stroke:#c2410c,color:#fff,stroke-width:2px
    classDef report fill:#f59e0b,stroke:#d97706,color:#000,stroke-width:2px

    class Engine engine
    class LR receiver
    class DB storage
    class Billing external
    class Report report

Data Flow

  1. 🔧 Engines send metrics using standard Prometheus Remote Write (same as SaaS)
  2. 📋 License Receiver filters to billing-relevant metrics only (tenx_pipeline_up, tenx_pipeline_info)
  3. 💾 Stores in database (SQLite for simple deployments, PostgreSQL for HA)
  4. 📄 Generates P90 reports for quarterly billing reconciliation
  5. 🗑️ Auto-cleanup removes data older than 90 days

How It Works

Node-Based Billing

Log10x uses node-based pricing - you pay based on the P90 (90th percentile) of active collector nodes over a 30-day period.

What Gets Tracked

The License Receiver only captures billing-relevant metrics:

Metric Purpose Sensitive Data?
tenx_pipeline_up Node is alive No
tenx_pipeline_info Node metadata (pipeline name) No
Node ID Unique identifier No (UUID)
Timestamp When heartbeat received No

No Log Content

The License Receiver never sees log content, PII, or sensitive data. Only aggregated node counts.

Soft Enforcement

The License Receiver uses soft enforcement - engines continue to work even if over the licensed tier:

  • Engines are never blocked
  • Over-limit usage is logged
  • Quarterly reports show actual usage vs. licensed tier
  • Contract terms handle reconciliation

Deployment

Deploy the License Receiver as a standalone service in your infrastructure.

docker run -d \
  --name license-receiver \
  -p 8080:8080 \
  -v license-data:/data \
  -e STORE_TYPE=sqlite \
  -e SQLITE_PATH=/data/license.db \
  log10x/license-receiver:latest
version: '3.8'
services:
  license-receiver:
    image: log10x/license-receiver:latest
    ports:
      - "8080:8080"
    environment:
      - STORE_TYPE=sqlite
      - SQLITE_PATH=/data/license.db
      - CLEANUP_ENABLED=true
      - CLEANUP_RETENTION=2160h  # 90 days
    volumes:
      - license-data:/data
    restart: unless-stopped

volumes:
  license-data:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: license-receiver
spec:
  replicas: 1
  selector:
    matchLabels:
      app: license-receiver
  template:
    metadata:
      labels:
        app: license-receiver
    spec:
      containers:
      - name: license-receiver
        image: log10x/license-receiver:latest
        ports:
        - containerPort: 8080
        env:
        - name: STORE_TYPE
          value: sqlite
        - name: SQLITE_PATH
          value: /data/license.db
        volumeMounts:
        - name: data
          mountPath: /data
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
        readinessProbe:
          httpGet:
            path: /health
            port: 8080
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: license-receiver-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: license-receiver
spec:
  selector:
    app: license-receiver
  ports:
  - port: 8080
    targetPort: 8080
# Download
curl -L https://github.com/log-10x/backend/releases/download/v1.0/license-receiver-linux-amd64 \
  -o /usr/local/bin/license-receiver
chmod +x /usr/local/bin/license-receiver

# Run
license-receiver -config /etc/log10x/license-receiver.yaml

Configuration

Configure the HTTP server, storage backend, data retention, and metric filtering.

Environment Variables

Configure the License Receiver using environment variables for containerized deployments.

Variable Default Description
LICENSE_RECEIVER_LISTEN :8080 HTTP listen address
STORE_TYPE sqlite Storage backend (sqlite or postgres)
SQLITE_PATH /data/license.db SQLite database path
POSTGRES_URL - PostgreSQL connection string
CLEANUP_ENABLED true Enable automatic data cleanup
CLEANUP_RETENTION 2160h Data retention period (90 days)
METRICS_ALLOW_LIST tenx_pipeline_up,... Metrics to capture
REPORT_SIGN_KEY - HMAC key for signing reports
LOG_LEVEL info Log verbosity

Config File

For more complex setups, use a YAML configuration file with the -config flag.

# /etc/log10x/license-receiver.yaml
server:
  listen: ":8080"

store:
  type: sqlite  # or postgres
  sqlite:
    path: /data/license.db
  postgres:
    url: postgres://user:pass@host:5432/license
    max_connections: 10

cleanup:
  enabled: true
  retention: 2160h  # 90 days
  interval: 24h     # daily cleanup

metrics:
  allow_list:
    - tenx_pipeline_up
    - tenx_pipeline_info

Storage Backends

Choose a storage backend based on your deployment requirements and scale.

Best for single-node, air-gapped deployments.

store:
  type: sqlite
  sqlite:
    path: /data/license.db

Pros: Zero dependencies, simple backup, low resource usage

Cons: Single-node only, not suitable for HA

Best for high-availability or when you already have PostgreSQL.

store:
  type: postgres
  postgres:
    url: postgres://license:secret@postgres:5432/license?sslmode=require
    max_connections: 20

Pros: High availability, handles large scale (1000+ nodes)

Cons: Requires PostgreSQL infrastructure

Engine Configuration

Configure your 10x Engines to send metrics to the License Receiver.

Point your engines to the License Receiver instead of prometheus.log10x.com:

# 10x Engine config
backendEndpoint: http://license-receiver:8080/
export TENX_BACKEND_ENDPOINT=http://license-receiver:8080/
docker run -e TENX_BACKEND_ENDPOINT=http://license-receiver:8080/ \
  log10x/engine:latest

No Engine Changes

The engine sends the exact same Prometheus Remote Write format. Just change the endpoint URL.

API Reference

Full API documentation for integrating with the License Receiver programmatically.

See the License API documentation for endpoint details.

Usage Reports

Export usage data for quarterly billing reconciliation with Log10x.

Generating Reports

Use the report API to generate usage summaries for any period up to 90 days.

# 30-day report (default)
curl "http://license-receiver:8080/api/v1/report?customer_id=acme-corp"

# 90-day report with daily breakdown
curl "http://license-receiver:8080/api/v1/report?customer_id=acme-corp&period=90&include_daily=true"

# Save to file
curl -o usage-report-q1-2026.json \
  "http://license-receiver:8080/api/v1/report?customer_id=acme-corp&period=90"

Quarterly Reconciliation

Submit usage reports to Log10x at the end of each billing period.

  1. Generate a 90-day report at quarter end
  2. Export the JSON file
  3. Submit to Log10x via your account manager or support portal
  4. Invoice adjusted based on actual usage vs. contracted tier

Troubleshooting

Common issues and their solutions when running the License Receiver.

Engines Not Connecting
Cause Solution
Wrong endpoint URL Verify TENX_BACKEND_ENDPOINT points to license receiver
Network/firewall Ensure engines can reach license receiver on port 8080
Service not running Check docker ps or systemctl status license-receiver
No Data in Reports
Cause Solution
Metrics filtered out Check METRICS_ALLOW_LIST includes tenx_pipeline_up
Wrong customer_id Verify engines send correct customer_id label
Data cleaned up Check CLEANUP_RETENTION setting
Database Errors
Cause Solution
SQLite locked Ensure only one instance writes to the database
Disk full Check available disk space in data volume
PostgreSQL connection Verify connection string and network access

Source Code

The License Receiver is open source and available on GitHub.

Resource Link
Source Code backend/services/license-receiver
Docker Image log10x/license-receiver
Issues GitHub Issues

FAQ

Answers to common questions about the License Receiver.

Do I need this if I'm using the SaaS Console?

No. The License Receiver is only needed for air-gapped deployments where engines cannot reach prometheus.log10x.com.

What data leaves my infrastructure?

None. The License Receiver stores everything locally. You manually export reports quarterly.

Can I use my existing Prometheus instead?

Yes, for observability. But for billing in air-gapped environments, you need the License Receiver because Log10x cannot query your Prometheus.

What happens if I'm over my licensed tier?

Nothing blocks. Engines continue working. Over-limit usage is tracked and reconciled quarterly per your contract terms.

How is the P90 calculated?

Daily: Count distinct nodes with at least one heartbeat that day. P90: 90th percentile of daily counts over the period.