Log Manager
Log Manager captures logs and traces from every project in a workspace hub, stores them in TimescaleDB with long retention, and turns bursts of errors into incidents with a failure graph. This page covers the standalone surface — the SDKs, OTLP ingest, the query language, the CLI and the public query API. Log Manager is a paid tier in early access; see pricing and the public API reference.
Quickstart
In the app, open Logs and create a project. Evolve mints a dedicated ingest key (scope logs:write), shows it exactly once, and gives you copy-paste snippets. Then install the SDK:
npm install @evolve/logs # JS / TS, Node 18+ pip install evolve-logs # Python 3.10+
JavaScript / TypeScript:
import { init } from '@evolve/logs';
init({
key: 'evk_...',
url: 'https://api.e-volv.io/api/public/v1/logs',
service: 'api',
});Python:
import evolve_logs
evolve_logs.init(
key='evk_...',
url='https://api.e-volv.io/api/public/v1/logs',
service='api',
)Both SDKs batch (200 events / 2 s / 512 KB), gzip, back off on 429 and 413, redact password|secret|token|authorization| cookie|set-cookie|api[-_]?key attributes, and propagate the traceparent across fetch, httpx and requests so a trace crosses every service it touches. Full references live in the JS SDK README and the Python SDK README.
OTLP endpoint
Any OpenTelemetry collector — or curl — can post OTLP/HTTP JSON to POST https://api.e-volv.io/api/public/v1/logs/otlp with the project key as a bearer token. Logs and traces are auto-detected; the resource’s service.name attribute picks the project:
curl -X POST "https://api.e-volv.io/api/public/v1/logs/otlp" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer evk_..." \
-d '{"resourceLogs":[{"resource":{"attributes":[{"key":"service.name","value":{"stringValue":"api"}}]},"scopeLogs":[{"logRecords":[{"timeUnixNano":"<unix-ns>","severityNumber":9,"body":{"stringValue":"hello from curl"}}]}]}]}'Ingest answers 202 after enqueueing — it never waits on storage. Batches are limited to 1 000 events or 5 MB per request.
Query language
Search uses a deliberately small filter grammar compiled to SQL, with at most one aggregation suffix:
level>=error service:api "connection timeout" attrs.region=ap-southeast-1 -attrs.retry:true | count by service, 5m
| Form | Means |
|---|---|
level>=error, level<=warn | Severity comparison using the OTel scale (trace 1 … fatal 21). |
service:api | Match a project. Known keys: level, service, trace, span. |
attrs.region=ap-southeast-1 | Match a dotted path inside the event attributes (JSONB). |
"connection timeout" | Quoted phrase → full-text match on the message. |
timeout | Bare word → trigram contains match on the message. |
-attrs.retry:true | A leading - negates any of the forms above. |
duration>=250 | Span filters only; meaningful against traces, not log events. |
One aggregation is allowed, at the end of the query:
| Form | Means |
|---|---|
| count by service, 5m | Event count grouped by the given columns, optionally time-bucketed. |
| p95 duration by service, 15m | p95 span latency grouped the same way. |
Bucket suffixes: 1m, 5m, 15m, 1h, 1d.
CLI
The zero-dependency evolve-logs CLI (Node 18+) talks to the public query API with a logs:read key:
# Follow live logs (SSE; one JSON event per line) evolve-logs tail --key evk_... --url https://api.e-volv.io [--project api] # Search with the query language; prints NDJSON, pages automatically evolve-logs search --key evk_... --url https://api.e-volv.io \ --q 'level>=error service:api "connection timeout"' \ [--from 2026-09-05T00:00:00Z] [--to 2026-09-05T01:00:00Z] # List incidents evolve-logs incidents --key evk_... --url https://api.e-volv.io
Without --from/--to, search covers the last 24 hours. The CLI ships in the repository at tools/logs-cli.
Public query API
The same search, dashboards and tail the app serves are keyed by API keys with the logs:read scope. The full route table is on the public API page; a search looks like:
curl "https://api.e-volv.io/api/public/v1/logs/query?q=level%3E%3Derror+service%3Aapi&limit=100" \ -H "Authorization: Bearer evk_..."
Retention and caps
| Limit | Included |
|---|---|
| Projects per hub | 50 |
| Ingest | 25 GB / month per workspace, pooled across projects |
| Over the cap | Oldest events are dropped first — never the newest |
| Raw log retention | 30 days hot, 90 days tiered |
| Traces, error groups and incidents | 180 days |
Dashboards read per-minute continuous aggregates, so volume, error rate and p95 latency stay fast at full retention. Error groups and incidents are kept for 180 days.