Self-hosted admin panel for collecting, grouping, and analyzing errors and logs from your frontend or backend using the lightweight vij-sdk. Built with Next.js (App Router) and MongoDB.
- Real‑time dashboard with trends and breakdowns (severity, environment, origin)
- Log search, filtering, pagination, and details with stack preview
- Automatic error grouping with fingerprints
- Optional AI‑assisted summaries and suggested causes/fixes (Gemini)
- Simple REST API with permissive CORS for easy ingestion
- Node.js 18+ (or Bun), npm/yarn/pnpm
- MongoDB 6+ (local or Atlas)
- Redis (for rate limiting and dedup windows)
Set the required environment variables before running the server.
| Name | Required | Example | Purpose |
|---|---|---|---|
MONGODB_URI |
Yes | mongodb://localhost:27017/vij |
Database connection string |
NEXT_PUBLIC_BASE_URL |
Recommended in prod | https://vij.example.com |
Used by server components to form absolute API URLs |
GEMINI_API_KEY |
Optional | ya29... |
Enables AI summaries in the UI and API |
REDIS_URL |
Recommended | redis://localhost:6379 |
Enables rate limiting & ingestion dedup |
VIJ_RATE_LIMIT_PER_MIN |
Optional | 100 |
Max requests per minute per appId |
VIJ_DEDUP_WINDOW_MS |
Optional | 5000 |
Window for grouping identical errors at ingestion |
Examples (macOS/Linux):
export MONGODB_URI="mongodb://localhost:27017/vij"
# Optional:
export NEXT_PUBLIC_BASE_URL="http://localhost:3000" # In dev environment
export GEMINI_API_KEY="YOUR_KEY"
export REDIS_URL="redis://localhost:6379"
export VIJ_RATE_LIMIT_PER_MIN="100"
export VIJ_DEDUP_WINDOW_MS="5000"From this folder:
# pick your package manager
npm install
npm run dev
# or: yarn && yarn dev
# or: pnpm install && pnpm dev
# or: bun install && bun devOpen http://localhost:3000 to access the admin.
Install the SDK in your app (vij‑sdk on npm) and point it to this server’s /api/logs endpoint.
import { init, captureException, captureMessage, flush } from "vij-sdk";
init({
endpoint: "http://localhost:3000/api/logs",
appId: "demo-app",
environment: "development", // or "production"
batch: true,
flushIntervalMs: 3000,
maxBatchSize: 20
});
try {
throw new Error("Simulated crash in signup flow");
} catch (err) {
captureException(err, { feature: "signup" });
}
captureMessage("User clicked retry", { feature: "signup" }, "info");
await flush();You should see events appear in the dashboard immediately.
Any Node host works. For production:
- Build the app:
npm run build - Ensure envs are set (
MONGODB_URIrequired; setNEXT_PUBLIC_BASE_URLto your public URL) - Start:
npm run start
On platforms like Vercel, set the same envs in the project settings. AI summaries require GEMINI_API_KEY and will gracefully disable if not set.
-
POST /api/logs— accepts a single log or a batch- Single log shape:
appId(string, required)message(string, required)stack(string, optional)timestamp(ISO string, optional)metadata(object, optional)severity(error|warning|info, defaulterror)environment(production|development, defaultproduction)userAgent(string, optional)
- Batch shape:
{ "batch": true, "logs": [<single log> ...] }
- Limits: 10KB body, CORS
*, methodsPOST, OPTIONS, GET - Rate limiting: If
REDIS_URLis configured, requests are limited perappIdper minute (VIJ_RATE_LIMIT_PER_MIN). When exceeded, the API responds429with headers:x-vij-backoff: seconds to back off (e.g.,10)Retry-After: same as above for generic clients
- Deduplication: With Redis enabled, identical errors (same fingerprint of
message|stack) are collapsed withinVIJ_DEDUP_WINDOW_MS. The server:- Always increments the error group's
occurrenceCountand updateslastSeen - Inserts at most one
Logdocument per dedup window (sampling) - Returns headers on success when dedup/sampling occurred:
x-vij-dedup: 1,x-vij-sampled: 1
- Always increments the error group's
- Single log shape:
-
GET /api/logs— list/search logs- Query:
page,limit,appId,severity,environment,search,from,to,fingerprint,origin
- Query:
-
GET /api/stats— aggregates for the dashboard -
GET /api/groups— grouped errors- Query:
page,limit,appId,severity,environment
- Query:
- Ingestion:
/api/logsvalidates payloads, fingerprints errors, and writes to MongoDB - Grouping: errors with same
(message, stack)hash form a group with anoccurrenceCountcounter - Rate limiting: implemented via Redis counters per minute, returning
429with server‑driven backoff headers - Server‑side dedup: Redis keys collapse identical errors within a sliding window; only one sampled log is stored while the group counter increments
- AI: when
GEMINI_API_KEYis set, the service fetches a concise summary, suggested causes/fixes, and tags (cached per group) - UI: Next.js App Router renders a dashboard, charts, groups, and log details
- Connection error: verify
MONGODB_URIand that MongoDB is reachable - Empty dashboard: send test events with
vij-sdkand check/api/logsfor responses - Mixed local/prod URLs: set
NEXT_PUBLIC_BASE_URLin production to your public origin - AI not showing: ensure
GEMINI_API_KEYis set; otherwise AI features are disabled gracefully
MIT