SlopScore
00 crowd

taillight (github.com/lasseh/taillight)

Real-time log viewer for syslog and application logs — filter, stream, and alert on events as they happen. Go backend with SSE streaming, Vue frontend, TimescaleDB storage, and pluggable notifications.
Go · ★ 34 · 2 forks · MIT · paperwork by the Cap'mmostly ai (inferred)light human (inferred)works-on-my-machine (inferred)other
listed 2 hours ago by lasseh · last checked 32 minutes ago · demo
The owner didn't write this. This repo never submitted itself. The Cap'm found it on a truffle trawl and wrote its paperwork from what GitHub already shows. Picked by hand by the Cap'm on 2026-09-11: a real-time syslog and application log viewer with a Go backend, Vue UI and live demo, "Built with Claude Code as an implementation aid". 33 stars; MIT license. The owner did not submit this. Votes count; awards don't until the owner claims it.

I'm not calling your project slop! Geeze, it's a joke... Do you own this repo?

Log in with GitHub as lasseh. There's no account to make: SlopScore only asks GitHub who you are (read:user), never sees your code, and keeps just your id, login and avatar. Then you can:

  • Keep it, on your terms. Commit your own slopscore.md (spec) and press Refresh. Your paperwork replaces the Cap'm's, and you can submit it for Slop of the Day.
  • Take it down. One click on Remove. It stays gone; the trawl never brings it back.

Log in with GitHub

Can't log in as the owner? Request a takedown. No login needed, and a trawled listing comes down right away.

GitHub says
Real-time log viewer for syslog and application logs — filter, stream, and alert on events as they happen. Go backend with SSE streaming, Vue frontend, TimescaleDB storage, and pluggable notifications.
website
https://demo.taillight.lasse.cloud
created
2026-02-16 · pushed 13 hours ago · 709 commits · 2 contributors
languages
Go 64%Vue 22%TypeScript 10%CSS 1%Python 1%PLpgSQL 1%
paperwork
code of conductcode of conduct filecontributingpull request templatelicensereadme 100% health
dependencies
⚠ 1 of 559 deps have known advisories · OSV.dev, checked 2 hours ago

Disclosures, inferred by the Cap'm

slopbucket
vibe-coded
category
other
ai_generated
mostly
human_touch
light
status
works-on-my-machine
language (detected)
cssgomakefileplpgsqlpythonshelltypescriptvue
license (detected)
mit

The Cap'm's log

The Cap'm wrote this paperwork, not the owner. This repo never submitted itself to SlopScore. The Cap'm picked it by hand: a real-time syslog and application log viewer with a Go backend, Vue UI and live demo, "Built with Claude Code as an implementation aid". It carries the MIT license. The disclosures above are his best guess from what GitHub shows.

Is this yours? Commit a real slopscore.md and press Refresh to replace this, or remove the listing in one click. There's no account to make: you log in with GitHub.

README (read the rest on GitHub)

taillight

License: MIT Go

Lightweight, real-time log viewer for network operations teams. Stream netlog (network device syslog), srvlog (server syslog), and application logs to your browser with a single Go binary and PostgreSQL.

Live Demo — try it without installing anything.

Home dashboard

Srvlog stream

More screenshots

Application log stream

Device detail

Volume

Why Taillight?

  • Real-time first — events are pushed to the browser via Server-Sent Events the moment they hit the database. Per-client server-side filtering means you only receive what you asked for.
  • Lightweight stack — PostgreSQL (TimescaleDB) + a single Go binary + rsyslog. No Elasticsearch, no JVM, no agent fleet to manage.
  • Three log feeds — netlog (network device syslog), srvlog (server syslog), and applog (HTTP ingest) each have independent streams, filtering, retention, and dashboards. All three are always on; optional subsystems (notifications, AI analysis, LDAP, Netbox) are the real toggles.
  • Multiple clients — a browser SPA in this repo, plus a terminal UI and SSH-served TUI in the companion taillight-tui repo — all consume the same SSE streams.
  • Built-in alerting — Slack, webhook, email (SMTP), and ntfy channels. First matching event fires immediately; repeats during a silence window collapse into a single digest, with per-channel rate limiting, circuit breakers, and bounded delivery retry.
  • Optional AI analysis — daily log briefings generated by a local Ollama LLM, surfacing anomalies and trends without sending data off-premise.

Features

Streaming & Filtering

  • SSE push for netlog, srvlog, and application log events — no polling
  • Filter by host, facility, severity, program, service, component, and full-text search
  • Cursor-based pagination for historical queries

Dashboards & Analytics

  • Severity breakdown, top hosts, and recent high-severity events at a glance
  • Per-host volume charts with selectable time ranges
  • Per-device detail views for netlog, srvlog, and application logs
  • Continuous aggregates for fast dashboard queries

Application Log Ingest

  • POST /api/v1/applog/ingest — structured JSON batch endpoint
  • taillight-shipper — standalone binary that tails log files and ships them to the ingest API
  • pkg/logshipper — Go slog.Handler for shipping your application's own logs
  • taillight-sdk — Python logging.Handler for shipping logs from Python apps (pip install taillight-sdk)

Terminal UI & SSH access

  • A terminal UI client (taillight-tui) and an SSH server that hosts it (taillight-wish) live in the companion repo taillight-tui — both are HTTP/SSE clients of this API

Notifications

  • Slack, webhook, email (SMTP), and ntfy backends
  • Rule matching by hostname, programname, severity/facility/msgid (syslog), service/component/level (applog), and full-text search
  • Fingerprint model: first match fires immediately, repeats within a silence window accumulate into a single end-of-window digest, silence grows linearly on sustained firing up to silence_max
  • Optional coalesce batches simultaneous first-alert bursts into one message with a real count
  • Per-channel token-bucket rate limit, circuit breaker, and bounded retry (5s → 30s → 2m → 10m)
  • Notification log with delivery status, rendered payload, and Prometheus counters for evaluated/matched/sent/suppressed

AI Analysis

  • Scheduled daily reports via local Ollama LLM
  • Anomaly detection and trend summaries
  • On-demand analysis trigger via API
  • Applog daily brief for service owners: ranks services by new error signatures and rate change against a 7-day baseline, scoped per service
  • Postgres aggregates the logs first, so the model narrates a compact summary rather than raw lines — see api/internal/analyzer/README.md for how the pipeline works

Netbox Enrichment

  • On the netlog detail page, IP addresses, prefixes, AS numbers, interfaces, and the source device are looked up against Netbox and shown as cards alongside the event
  • Lookups happen lazily after the page renders — list views and live SSE never call Netbox
  • In-memory TTL cache (default 10 min, including negative results) keeps repeat detail-page visits free
  • Per-entity errors surface inline; if Netbox is unreachable or disabled the panel hides itself, the detail page is unaffected
  • Configurable auth scheme — legacy Token <key> (default) or OAuth-style Bearer <key>
  • Disabled by default; configure under netbox: in api/config.yml and provide the token via NETBOX_TOKEN

Themes

  • 19 built-in color themes — Tokyo Night, Dracula, Catppuccin, Nord, Solarized, Gruvbox, SynthWave 84, and more
  • 15 dark themes and 4 light themes
  • One-click switching from the settings menu, persisted to localStorage
  • Every theme includes matched chart colors for consistent data visualization

Operations

  • TimescaleDB hypertables with compression and configurable retention policies
  • Prometheus metrics (/metrics endpoint or dedicated metrics server)
  • Session-based auth with API key support (read, ingest, admin scopes)
  • Interactive API documentation at /api/docs (Scalar/OpenAPI)
  • Docker Compose one-command deployment
  • Juniper netlog reference data import (XLSX)

Architecture

  Netlog path (network devices):

  rsyslog ──ompgsql──► netlog_events ──pg_notify──► Listener (LISTEN/NOTIFY)
                       (TimescaleDB)                         │
                                                             ▼
                                                     NetlogBroker ──► SSE ──► Browser
                                                             │
                                                             ▼
                                                     NotificationEngine
                                                     (Slack/Webhook/Email/ntfy)

  Srvlog path (servers):

  rsyslog ──ompgsql──► srvlog_events ──pg_notify──► Listener (LISTEN/NOTIFY)
                       (TimescaleDB)                         │
                                                             ▼
                                                     SrvlogBroker ──► SSE ──► Browser
                                                             │
                                                             ▼
                                                     NotificationEngine
                                                     (Slack/Webhook/Email/ntfy)

  Application log path:

  HTTP POST ──► Ingest Handler ──► applog_events ──► AppLogBroker ──► SSE ──► Browser
  (API key)                        (TimescaleDB)           │
                                                           ▼
                                                   NotificationEngine

Netlog and Srvlog share the same pipeline but use separate tables, brokers, and retention policies. rsyslog writes to netlog_events or srvlog_events via ompgsql. A trigger fires pg_notify('<feed>_ingest', id). The Go backend holds a persistent LISTEN connection, fetches the full row, and the corresponding broker fans out to SSE clients with per-client filtering. Netlog events are enriched with Juniper reference data when available, and the netlog detail page additionally pulls device/IP/prefix/ASN/interface context from Netbox on demand.

Why two syslog feeds? Network devices (Juniper, Cisco, Arista) and servers (Linux, Docker, PostgreSQL) produce fundamentally different log profiles. Splitting them lets you apply independent retention policies, notification rules, and analysis. Both feeds (and applog) are always enabled; a feed you don't point logs at simply stays empty.

Application logs: apps POST JSON batches to /api/v1/applog/ingest. The handler inserts into applog_events and broadcasts directly to the AppLogBroker — no LISTEN/NOTIFY. The broker applies per-client filters and pushes matching events to SSE clients.

rsyslog Filtering

Network devices — especially Juniper gear — emit thousands of syslog messages per minute: chassis polls, SNMP traps, session logs, scheduler ticks, and routine daemon output. Taillight ships a modular rsyslog configuration that applies layered filters to drop the noise before it hits the netlog database.

Processing Pipeline

UDP/TCP input (514, 1514)
  → parse RFC 5424 structured data
  → capture critical severity (emerg/alert/crit) before any filtering
  → filter by msgid         (fastest — exact event name match)
  → route UI_COMMIT events  (Oxidized, commit log)
  → filter by programname   (daemon-level drops)
  → filter by facility      (local7 info noise)
  → filter by severity      (drop debug globally)
  → filter by hostname/IP   (optional per-host rules)
  → output to PostgreSQL, LibreNMS, per-host files, remote forwarding

Filter Layers

Filters are applied cheapest-first. Each layer has exception keywords — messages containing error, fail, critical, down, denied, or alarm pass through even if the event type is normally dropped.

Layer File Method Drops
msgid filters/05-by-msgid.conf Exact $msgid match Chassis polls, RPD scheduler, RT_FLOW sessions, SNMP traps, LLDP neighbor-up, PFE stats, license checks
Commit routing filters/06-ui-commit-trigger.conf $msgid match Routes UI_COMMIT to Oxidized and commit log
Program filters/10-by-programname.conf $programname match cron, ntpd, mib2d, dcd, lacpd, cosd, alarmd, sshd, pfed
Facility filters/30-by-facility.conf $syslogfacility local7 info-level messages
Severity filters/40-by-severity.conf $syslogseverity All debug (severity 7)
Hostname filters/50-by-hostname.conf $hostname/$fromhost-ip Nothing by default (examples only)

Juniper Device Setup

Devices must send RFC 5424 structured-data syslog for msgid-based filters to work:

set system syslog host <collector-ip> any notice
set system syslog host <collector-ip> port 514
set system syslog host <collector-ip> source-address <loopback-ip>
set system syslog host <collector-ip> structured-data

Customization

  • Add msgid filter: add a block to filters/05-by-msgid.conf
  • Add daemon filter: add a block to filters/10-by-programname.conf
  • Filter specific hosts: uncomment examples in filters/50-by-hostname.conf
  • Test changes: cd rsyslog && make test or docker compose run --rm test

See rsyslog/README.md for the full reference including deployment, PostgreSQL output setup, and Juniper configuration details.

Quickstart

Docker Compose

cp .env.example .env
docker compose up -d

This starts TimescaleDB, the API, rsyslog, and the frontend.

Service Host Port Variable
Frontend 3000 FRONTEND_HOST_PORT
API 8080 API_HOST_PORT
PostgreSQL 5432 POSTGRES_BIND
rsyslog (netlog) 1514 RSYSLOG_NETLOG_PORT
rsyslog (srvlog) 1515 RSYSLOG_SRVLOG_PORT

Create a user

docker compose exec api /app useradd --username admin --password admin

Generate test data

Development/demo tooling: the main binary ships three load generators (loadgen-netlog, loadgen-srvlog, loadgen-applog) for seeding a fresh instance with realistic events.

# Netlog events — network device logs (direct SQL insert)
docker compose exec api /app loadgen-netlog -n 100 --delay 100ms --jitter 200ms

# Netlog events via rsyslog (full pipeline)
docker compose exec api /app loadgen-netlog -n 100 --syslog rsyslog:514 --delay 100ms

# Srvlog events — server logs (direct SQL insert)
docker compose exec api /app loadgen-srvlog -n 100 --delay 100ms --jitter 200ms

# Srvlog events via rsyslog (full pipeline)
docker compose exec api /app loadgen-srvlog -n 100 --syslog rsyslog:514 --delay 100ms

# Application log events (HTTP ingest)
docker compose exec api /app loadgen-applog -n 100 --batch 1 \
  --endpoint http://localhost:8080/api/v1/applog/ingest

Log Shipper

taillight-shipper is a standalone binary that tails log files and pipes stdin, shipping structured log entries to the ingest API. Use it to onboard any application that writes to files or stdout.

pkg/logshipper is a Go slog.Handler — add it to your application to ship logs directly from code without an external process.

See cmd/taillight-shipper/ for configuration and usage.

Terminal UI & SSH access

The terminal UI client (taillight-tui) and the SSH server that hosts it (taillight-wish) live in the companion repository taillight-tui. Both are HTTP/SSE clients of this API — see that repo for installation, configuration, and usage.

Configuration

.env — per-deployment settings

Variable Default Description
POSTGRES_PASSWORD taillight Database password
POSTGRES_BIND 127.0.0.1:5432 Bind address and port for PostgreSQL (host:port). Set to 0.0.0.0:5432 for remote access or change the port to avoid conflicts.
API_HOST_PORT 8080 Host port for the API
RSYSLOG_NETLOG_PORT 1514 Host port for netlog syslog input (514 in production)
RSYSLOG_SRVLOG_PORT 1515 Host port for srvlog syslog input (515 in production)
FRONTEND_HOST_PORT 3000 Host port for the web UI
LOG_LEVEL info debug, info, warn, error
AUTH_ENABLED false Enable authentication
REAL_IP_HEADER (empty) Trusted client-IP header set by your reverse proxy (e.g. X-Real-IP). Empty = trust only the TCP peer. Set it behind nginx or clients are attributed to the proxy IP.
API_URL (empty) Frontend API URL (empty = same-origin)

api/config.yml — application tuning

CORS origins, connection pool sizes, retention policies, notification engine, SMTP, AI analysis, and Netbox enrichment. See config.yml.example for all options.

Environment variables always override config file values (Viper priority: defaults → config.yml → env vars).

Local Development

API:

cd api
cp config.yml.example config.yml
make build && make test && make lint

Frontend:

cd frontend
npm install && npm run dev

CLI commands:

Command Description
serve Start the HTTP/SSE server
migrate Run database migrations (up/down/version)
loadgen-netlog Generate netlog test events (Juniper, Cisco, Arista)
loadgen-srvlog Generate srvlog test events (Linux, Docker, PostgreSQL)
loadgen-applog Generate application log test events
useradd Create a user account
apikey Manage API keys
import Import Juniper netlog reference data (XLSX)
version Print the build version

Importing Juniper Reference Data

Copy the XLSX files into the container, then run the import:

docker compose cp System_Log_Messages_Junos_OS_25.4R1.xlsx api:/tmp/
docker compose cp System_Log_Messages_Junos_OS_Evolved_25.4R1.xlsx api:/tmp/

docker compose exec api /app import --file /tmp/System_Log_Messages_Junos_OS_25.4R1.xlsx --os junos
docker compose exec api /app import --file /tmp/System_Log_Messages_Junos_OS_Evolved_25.4R1.xlsx --os junos-evolved

Or upload directly to a running server via the admin API. Requires an API key with the admin scope (apikey command) and accepts os=junos or os=junos-evolved:

curl -X POST 
Scan report · 2026-09-11
  • Prohibited terms or links
  • Repository eligibility
  • slopscore.md paperwork
  • Content policy
  • Risk review

0 comments

log in to comment.

report this listinglog in to report