A lightweight, reasoning-focused observability platform designed to collect logs and metrics, process them in real-time, and send automated alerts via Slack webhooks and email.
- API App: Ingests logs via HTTP API
- Processor App: Processes logs, aggregates metrics, detects anomalies
- Database: TimescaleDB (free, open source) - used only for time-series tables (logs, metrics) with automatic compression and retention. Alerts and API keys use regular PostgreSQL tables.
- Alerting: Automated alerts via Slack webhooks and email (Resend)
- Node.js 18+
- PostgreSQL 14+
- pnpm 10+
-
Clone and install dependencies:
pnpm install
-
Set up environment variables:
cp .env.example .env # Edit .env with your database URL and API keys -
Set up database:
cd packages/db pnpm db:generate # Generate migrations pnpm db:push # Apply migrations
-
Start the services:
# Terminal 1: API server cd apps/api pnpm dev # Terminal 2: Processor cd apps/processor pnpm dev # Terminal 3: Dashboard (optional) cd apps/web pnpm dev
The dashboard will be available at
http://localhost:3001(or next available port)
See .env.example for all available configuration options.
Key variables:
DATABASE_URL: PostgreSQL connection string (required)API_PORT: API server port (default: 3000)RESEND_API_KEY: Optional - Global Resend API key for email alerts. Can also be set per-channel. Uses Resend's free onboarding email domain by default.RESEND_FROM_EMAIL: Optional - Default "from" email (defaults toonboarding@resend.devfor free testing)
Note: Alert channels are configured via the API, not environment variables — see apps/api/src/routes/alert-channels.ts and packages/db/src/repositories/alert-channels.ts.
The easiest way to send logs is using the Tracer SDK:
import { TracerClient } from '@tracer/sdk';
const tracer = new TracerClient({
service: 'my-service',
apiUrl: 'http://localhost:3000',
apiKey: 'your-api-key-here', // Optional but recommended
});
tracer.info('User logged in', { userId: '123' });
tracer.error('Payment failed', { orderId: '456' });API Keys: Create API keys for authentication and service scoping:
# Create an API key
curl -X POST http://localhost:3000/api-keys \
-H "Content-Type: application/json" \
-d '{"name": "Production Key", "service": "api-service"}'
# Use the returned key in your SDK or requestsSee apps/express-example/ for a complete example application.
Create and manage API keys for authentication:
# Create a new API key
curl -X POST http://localhost:3000/api-keys \
-H "Content-Type: application/json" \
-d '{
"name": "Production Key",
"service": "api-service"
}'
# List all API keys
curl http://localhost:3000/api-keys
# Revoke an API key
curl -X DELETE http://localhost:3000/api-keys/1Note: The plain API key is only returned once when created. Store it securely!
Send logs directly to the API (with or without API key):
# Single log (without API key)
curl -X POST http://localhost:3000/logs \
-H "Content-Type: application/json" \
-d '{
"timestamp": "2024-01-01T12:00:00Z",
"level": "info",
"message": "User logged in",
"service": "api-service",
"metadata": { "user_id": "123" }
}'
# Single log (with API key)
curl -X POST http://localhost:3000/logs \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-api-key-here" \
-d '{
"timestamp": "2024-01-01T12:00:00Z",
"level": "info",
"message": "User logged in",
"service": "api-service"
}'
# Batch logs
curl -X POST http://localhost:3000/logs \
-H "Content-Type: application/json" \
-d '{
"logs": [
{
"timestamp": "2024-01-01T12:00:00Z",
"level": "error",
"message": "Database connection failed",
"service": "api-service"
},
{
"timestamp": "2024-01-01T12:00:01Z",
"level": "info",
"message": "Request completed",
"service": "api-service",
"metadata": { "latency": 150 }
}
]
}'curl http://localhost:3000/healthStart the web dashboard to view logs, metrics, and alerts in real-time:
cd apps/web
pnpm devOpen http://localhost:3001 (or the port shown) in your browser. The dashboard shows:
- Active alerts with severity indicators
- Recent metrics aggregated by service
- Recent logs with level indicators
- Auto-refreshes every 10 seconds
See apps/express-example/ for a complete example application demonstrating all SDK features.
- Log Ingestion: API receives logs and emits events to the event bus
- Processing: Processor subscribes to events, batches logs, and stores them
- Aggregation: Metrics are aggregated in 60-second windows
- Anomaly Detection: Detects error spikes, high latency, and service downtime
- Alerting: Automatically sends alerts via Slack webhooks and email
tracer/
├── apps/
│ ├── api/ # Log ingestion API
│ ├── processor/ # Log processing and alerting
│ ├── web/ # Next.js dashboard, with its own API routes (some
│ │ # read @tracer/db directly, others proxy to apps/api)
│ └── express-example/ # Example app demonstrating the SDK
├── packages/
│ ├── ai/ # AI-powered log summarization, root-cause analysis, chat agent
│ ├── core/ # Types, constants, event bus
│ ├── db/ # Database schema and repositories
│ ├── infra/ # Shared infrastructure (event bus)
│ └── sdk/ # Client SDK for sending logs
pnpm buildpnpm dev# Run all tests
pnpm test
# Run tests in watch mode
pnpm test:watch
# Run tests with UI
pnpm test:ui
# Run tests with coverage
pnpm test:coverage
# Run tests for a specific package
cd packages/core && pnpm testcd packages/db
pnpm db:push # Sync schema.ts directly to database (recommended for MVP)
pnpm db:studio # Open Drizzle Studio
# Alternative: Use migrations (for production/teams)
pnpm db:generate # Generate migration files after schema changes
pnpm db:migrate # Apply migration filesNote: For MVP, we use db:push which directly syncs the schema without migration files. This is simpler and faster for development.
Quick Summary: The platform is functionally complete and ready for MVP/internal use. For production/external users, consider adding:
- Rate limiting
- Request size limits
- Security headers
- Enhanced monitoring
- Structured logging
ISC