let Jev score OpenTelemetry logs before a bigger LLM sees them
Health checks. Cache hits. A payment failure hiding in the middle. If every OpenTelemetry log goes into a reasoning model, you pay for noise before the investigation starts. Jev Logs is a small open-source layer that pu
Health checks. Cache hits. A payment failure hiding in the middle. If every OpenTelemetry log goes into a reasoning model, you pay for noise before the investigation starts.
Jev Logs is a small open-source layer that puts TypeSafeβs Jev in front of those logs. Jev makes the first decision: how useful is this record, how urgent is it, and does it deserve a more expensive model?
I wrote it. MIT licensed. Independent not a TypeSafe, Vercel, or OpenTelemetry product.
reachjalil
/
jevlogs
Open-source Jev log triage for OpenTelemetry. Score the signal before expensive LLM analysis.
Jev Logs
A little intelligence between your logs and your LLM bill.
Score, prioritize, and route OpenTelemetry logs with Jev. Keep the signal. Keep your stack
Website Β· Guide Β· llms.txt Β· npm Β· Feedback
Meet your log filterβs smarter friend
Health checks. Cache hits. A payment failure hiding in the middle. Sending every event to a reasoning model adds cost before the investigation even starts.
Jev Logs makes the first decision: how useful is this log, how urgent is it, and does it deserve deeper analysis? It uses TypeSafeβs Jev through the Vercel AI SDK, with a small TypeScript API and an OpenTelemetry exporter wrapper.
| A small layer | What you get |
|---|---|
| Score the signal | A 0β100 diagnostic-value score, priority, and actionable probability. |
| Keep your pipeline | Wrap your existing exporter; preserve resource, scope, timestamps, and trace context. |
| Start with visibility | Annotation mode keeps every record and attaches jev.* attributes. |
| Spend |
What Jev actually returns
Jev is built for structured choices, not paragraphs. For each log, Jev Logs asks it for:
- a diagnostic value (0β100)
- a priority (
critical,high,normal,low) - an actionable probability
- a route:
analyzeorretain
Your archive still gets every record. The analysis branch only needs the ones Jev (or a rule, or a conservative fallback) says are worth it.
A log may skip deeper analysis only when all three are true: priority is low, value is 25 or below, and actionable probability is under 0.1. Errors, jev.protected records, timeouts, and provider failures stay eligible. Nothing in the SDK deletes your logs.
Try Jev Logs in one command
Offline demo. No key. No network.
npx jevlogs
0 / 100 low RETAIN GET /health returned 200 in 2ms
25 / 100 low RETAIN Cache hit for product:482
100 / 100 critical ANALYZE Payment capture failed after three retries
75 / 100 high ANALYZE Database connection pool at 94% capacity
That walkthrough uses fixed answers so you can see the shape. It does not call Jev.
Real Jev, still on your machine:
export AI_GATEWAY_API_KEY=your-vercel-ai-gateway-key
npx jevlogs --live --sample
npx jevlogs --live --file ./app.log --limit 20
--live alone starts a local OTLP HTTP/JSON receiver on http://127.0.0.1:4318/v1/logs. Point your app at it; Jev Logs prints one JSON decision per record and can forward annotated batches to the collector you already run. Node.js 22+.
Score a log from TypeScript
npm install jevlogs
import { createJevLogs } from "jevlogs";
const jev = createJevLogs();
const decision = await jev.triage({
body: "Database connection pool at 94% capacity",
severityText: "WARN",
});
console.log(decision);
// value Β· priority Β· route Β· actionableProbability Β· reason
Skip health checks without spending a Jev call:
const jev = createJevLogs({
rules: [{ name: "health", match: "^GET /health", route: "retain" }],
});
Already on OpenTelemetry?
Wrap the exporter you have. Annotation mode keeps every log and attaches jev.* attributes.
import {
LoggerProvider,
BatchLogRecordProcessor,
ConsoleLogRecordExporter,
} from "@opentelemetry/sdk-logs";
import { JevLogExporter } from "jevlogs";
const provider = new LoggerProvider({
processors: [
new BatchLogRecordProcessor({
exporter: new JevLogExporter({
exporter: new ConsoleLogRecordExporter(),
mode: "annotate",
}),
maxExportBatchSize: 16,
}),
],
});
Keep that archive processor. Add a second exporter with mode: "analysis-only" when you actually want to drop low-value records from the LLM path. Annotation alone does not cut the bill β the downstream pipeline has to honor route.
Why Jev, not βanother LLM passβ
A second giant completion per log is the thing this is trying to avoid. Jevβs published rate is cheap structured evaluation (TypeSafe lists $0.042/M input, free output). You pay Jev for a small decision, then pay GPT-class analysis only for the selected slice.
The README has an illustrative table: 1M logs/month, if 10% still need analysis, a $1,000 GPT-4.1-style bill models down to about $129 including Jev triage. That is not a measured production result. Measure incident recall on your logs before you filter.
What this is not
No hosted dashboard. No log storage. No Collector plugin. No root-cause write-up. Preview software: jevlogs on npm, TypeScript first, CI on the repo. Jev itself is a hosted model via Vercel AI Gateway; this repo is the integration.
Links
- GitHub: reachjalil/jevlogs
- Guide: jevlogs.com/guide
- npm:
jevlogs
If you try it, I want feedback on the Jev scoring/routing shape and whether wrapping an exporter is the right split vs the local receiver. Issues with sanitized examples are welcome.
Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.
