Every log from every system. One viewer.
Vercel, Stripe, AWS, GitHub Actions, Supabase, Sentry — and everything you build yourself — normalized into one searchable stream.
One schema. Every source.
Filters, alerts, and queries become source-agnostic the moment a log enters henexus.
Vercel JSON
- deployment_id: dpl_…
- region: iad1
- function_name: checkout
- duration_ms: 10042
Stripe JSON
- event: invoice.payment_failed
- customer: cus_K7…
- amount: 4900
- currency: usd
Supabase webhook
- table: orders
- type: INSERT
- record.id: f3a1…
- schema: public
- occurred_at: timestamptz
- service: string
- level: enum
- code: string
- title: string
- transaction_id: string
- status_code: int
- duration_ms: int
- … 17 more indexed columns
- structured_fields { … }
25 indexed columns. One JSONB overflow. Zero per-source tables.
15 connectors live on day one.
Plus a Python SDK to write your own.
AWS CloudWatch
pullVercel
pushGitHub Actions
hybridCockroach Cloud
pullAnthropic
pullOpenAI
pullLiveKit
pushSupabase
pushCloudflare Workers
pushHeroku
pushSentry
pushStripe
pushResend
pushApple App Store
pushTestFlight
hybridAn Excel-style log viewer that scales.
Three composable filter layers. Cursor-paginated. Trace-aware.
| Time | Nest | Service | Level | Code | Title | Duration | Trace ID |
|---|---|---|---|---|---|---|---|
| 14:03:17 | OptiAi | vercel | warn | 503 | GET /api/checkout — 503 timeout | 10042 | 0af7651916cd |
| 14:03:15 | OptiAi | stripe | error | fail | invoice.payment_failed | — | 1c5d3b2a44ef |
| 14:03:12 | OptiAi | supabase | info | 200 | row.insert on orders | 8 | 92aa7c1b5d80 |
| 14:03:09 | Marketing | resend | info | sent | email.delivered to user@… | — | d2f1e7a9c10b |
| 14:03:07 | OptiAi | aws | warn | 4xx | ALB target reset | 142 | 3b91e0c44a17 |
| 14:03:02 | OptiAi | github | info | ok | workflow_run completed | 38120 | 5e8a23ff29bd |
| 14:02:58 | Staging | sentry | error | Error | TypeError: Cannot read properties of undefined | — | 7c19be01f4a2 |
| 14:02:55 | OptiAi | cloudflare | info | 200 | GET /assets/main.js | 12 | a40d9b2c8e51 |
Three layers of filters
Saved predicates, ad-hoc field chips, and per-column type-to-filter — composable and deterministic.
Cursor pagination
Stable boundaries even when new entries arrive mid-scroll. Same API hen uses.
View correlated
One click on a trace ID filters the table to every related entry across services.
Write a custom connector in an afternoon.
The same Python SDK that powers our 15 built-ins is the one you use. Same shape. Same validation. Same sandbox.
- Pydantic v2 validation — unknown fields refused at construction.
- Runs sandboxed on EventBridge → Fargate. Egress allow-listed by credential binding.
- Same row shape as every built-in. Same viewer. Same filters.
- Bundled helpers for HMAC verification, JWT signing, redaction, stable digests.
from henexus_logs import Logger, Log, credential_store
import httpx
class AirflowLog(Log):
service = "airflow"
dag_id: str
task_id: str
run_id: str
def main():
logger = Logger.factory(connector_id="cn_airflow_prod", project_id="pj_acme")
since = logger.state.get("since", default="1970-01-01T00:00:00Z")
with credential_store("airflow-prod") as cred:
resp = httpx.get(f"{cred.base_url}/api/v1/events",
params={"since": since},
headers={"Authorization": f"Bearer {cred.token}"})
for e in resp.json()["events"]:
log = AirflowLog(title=f"{e['dag_id']} / {e['task_id']} — {e['state']}",
level="error" if e["state"]=="failed" else "info",
dag_id=e["dag_id"], task_id=e["task_id"], run_id=e["run_id"])
logger.save_unique(log, unique_by=["dag_id", "task_id", "run_id"])
Credentials that vanish on save.
- Envelope encryption. DEK-per-credential wrapped by tenant CMK in AWS KMS.
- No reveal. No copy. No export — ever. Not for the user who saved it. Not for admins.
- Lost a key? Rotate. There is no recovery path. Support can't help you read it back.
Before save
After save
You will not see this again. Rotate to replace.
Failure is loud. Success is silent.
Broken connectors show up in the same viewer you already watch.
Vercel webhook payload changed shape — 247 retries since 13:58
{
"missing": ["record.old_record"],
"unexpected": ["record.delta"],
"type_mismatch": [
{ "field": "record.id", "expected": "uuid", "got": "integer" }
]
}hen sees what you see — with your permissions.
- Opt-in per tenant. Off by default. Logs are high-signal — and high-stakes.
- Clustered before hen sees them. Cluster key on (service, level, fingerprint). One summary event per cluster, not per entry.
- No standing read. hen queries through your viewer's API with the asking user's permissions — every time.
hen
Error spike on /api/checkout 27 min ago correlates with deploy build #1842 (commit a501f06). The previous 12 deploys to this endpoint had p95 < 800 ms; this one is at 10,042 ms. Want me to draft an alert rule?
Coming next — automated response.
P1 ingestion is shipping with these in mind. Schemas and event paths are ready.
On-call scheduling
PagerDuty-style rotations, schedules, and escalation paths. Pages humans when alerts fire.
Heartbeat & uptime
Active probes of your services. Alert on missed beats or degraded responses.
Custom alert rules
Customer-defined event emitters that watch ingested logs and publish henexusEvents when conditions match.
One platform, one audit trail.
Every connector, credential, filter, and retention change goes to /portal/settings/audit.
Per-Nest, per-environment.
Every entry tagged with environment (prod / stg / tst / dev). Page-header selectors persist across screens.
Three roles, zero ambiguity.
Observer / Developer / Logs Administrator. No plaintext credential ever crosses a permission boundary.
Stop bouncing between dashboards.
Connect your stack in minutes. No credit card required.
Get Started Free