[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-81749":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":8,"htmlUrl":8,"language":9,"languages":8,"totalLinesOfCode":8,"stars":10,"forks":11,"watchers":12,"openIssues":13,"contributorsCount":13,"subscribersCount":13,"size":13,"stars1d":11,"stars7d":11,"stars30d":11,"stars90d":13,"forks30d":13,"starsTrendScore":14,"compositeScore":15,"rankGlobal":8,"rankLanguage":8,"license":16,"archived":17,"fork":17,"defaultBranch":18,"hasWiki":19,"hasPages":17,"topics":20,"createdAt":8,"pushedAt":8,"updatedAt":21,"readmeContent":22,"aiSummary":23,"trendingCount":13,"starSnapshotCount":13,"syncStatus":24,"lastSyncTime":25,"discoverSource":26},81749,"wbts","bruceowenga\u002Fwbts","bruceowenga",null,"Go",28,1,27,0,3,0.9,"MIT License",false,"main",true,[],"2026-06-12 02:04:19","# wbts — what broke the server?\n\n```\ncurl -fsSL https:\u002F\u002Fraw.githubusercontent.com\u002Fbruceowenga\u002Fwbts\u002Fmain\u002Fscripts\u002Finstall.sh | bash\n```\n\n```\n$ wbts --since 3h\n```\n\n![wbts TUI showing a scrollable incident timeline with color-coded events and an incident window](docs\u002Fscreenshots\u002Ftui-incident.png)\n\n`wbts` correlates logs from journald, dmesg, Docker events, Kubernetes, apt\u002Fdnf, and auth\ninto a single chronological timeline with an interactive TUI. Run it after an incident to\nreconstruct what happened without manually cross-referencing six different log sources.\n\n---\n\n## Installation\n\n```bash\ncurl -fsSL https:\u002F\u002Fraw.githubusercontent.com\u002Fbruceowenga\u002Fwbts\u002Fmain\u002Fscripts\u002Finstall.sh | bash\n\n# Or build from source\ngit clone https:\u002F\u002Fgithub.com\u002Fbruceowenga\u002Fwbts\ncd wbts && go build -o wbts .\u002Fcmd\u002Fwbts\n```\n\n## Usage\n\n```bash\n# Last 2 hours — launches interactive TUI when stdout is a terminal\nwbts --since 2h\n\n# Specific time range\nwbts --since \"2026-05-05 02:00\" --until \"2026-05-05 04:00\"\n\n# Filter to events involving a specific container\nwbts --since 1h --container app_web_1\n\n# Incident window summaries only (plain output)\nwbts --since 4h --summary\n\n# JSON output for piping to jq\nwbts --since 1h --json | jq '.[] | select(.Level >= 2)'\n\n# Plain output without TUI (for scripts, CI, piping)\nwbts --since 2h --no-tui\n\n# Check which log sources are accessible on this system\nwbts check-perms\n```\n\n## Interactive TUI\n\nWhen stdout is a terminal, `wbts` launches an interactive timeline viewer:\n\n| Key | Action |\n|---|---|\n| `↑` \u002F `k` | Scroll up |\n| `↓` \u002F `j` | Scroll down |\n| `e` \u002F `Enter` | Expand \u002F collapse raw log line |\n| `f` | Cycle level filter: All → Warn+ → Error+ → Crit |\n| `n` \u002F `p` | Jump to next \u002F previous incident window |\n| `g` \u002F `G` | Jump to top \u002F bottom |\n| `?` | Show help |\n| `q` \u002F `Esc` | Quit |\n\nPlain output is always available via `--no-tui`, `--json`, `--no-color`, `--summary`, or piping.\n\n![wbts TUI detail popup showing expanded raw log line for a selected event](docs\u002Fscreenshots\u002Ftui-detail.png)\n\n## Collectors\n\n| Collector | Source | What it captures |\n|---|---|---|\n| `journald` | `journalctl` | service starts\u002Fstops\u002Fcrashes, systemd failures, embedded log levels |\n| `dmesg` | kernel ring buffer | OOM kills, kernel panics, disk I\u002FO errors, CPU hogging |\n| `docker` | Docker socket API | container die\u002FOOM\u002Frestart, health check failures, image pulls |\n| `kubernetes` | `kubectl get events` | OOMKilling, BackOff, CrashLoopBackOff, NodeNotReady, Unhealthy |\n| `apt` | `\u002Fvar\u002Flog\u002Fapt\u002Fhistory.log` + rotated | package installs, upgrades, removals (Debian\u002FUbuntu) |\n| `dnf` | `\u002Fvar\u002Flog\u002Fdnf.rpm.log` + rotated | package installs, upgrades, removals (Fedora\u002FRHEL\u002FRocky) |\n| `auth` | `\u002Fvar\u002Flog\u002Fauth.log` + rotated | failed logins, accepted sessions, sudo commands, root sessions |\n| `rasdaemon` | `\u002Fvar\u002Flib\u002Frasdaemon\u002Fras-mc.db` | hardware ECC memory errors, CPU MCA events (correctable → Warn, uncorrectable → Critical) |\n| `ipmi` | `ipmitool sel elist` | PSU failures, thermal threshold crossings, fan failures, drive faults from the BMC SEL |\n\nAll file-based collectors automatically read rotated log files (`.1`, `.2.gz`, date-based)\nso pre-crash events are captured even after a server restart.\n\n> **Docker events buffer:** The Docker events API stores events in an in-memory ring buffer\n> (~1024 events). On busy systems running k3s or many containers, events older than\n> 30–60 minutes may not be available. Journald fills the gap for older container activity.\n\n> **Kubernetes events TTL:** k8s events have a default TTL of ~1 hour. Events older than\n> that may not be returned even if within your `--since` range.\n\n## Permissions\n\n`wbts` reads only — it never writes to logs or modifies system state.\n\n![wbts check-perms output showing available and unavailable collectors](docs\u002Fscreenshots\u002Fcheck-perms.png)\n\n```bash\n# Check what's accessible with your current user\nwbts check-perms\n\n# For full access without sudo (Debian\u002FUbuntu):\nsudo usermod -aG systemd-journal,adm,docker $USER\n\n# For \u002Fvar\u002Flog\u002Fsecure on Fedora\u002FRHEL (600 root:root, adm group does not help):\nsudo setfacl -m u:$USER:r \u002Fvar\u002Flog\u002Fsecure\n# or just: sudo wbts --since 2h\n```\n\n## Embedded log level detection\n\nMany services route all output to journald at INFO priority but embed their own severity\nin the message body. `wbts` detects and elevates these automatically:\n\n| Pattern | Example | Elevated to |\n|---|---|---|\n| `level=error` \u002F `\"level\":\"error\"` | Docker daemon, Logrus, Zap | `ERRO` |\n| ` ERR ` | cloudflared, HashiCorp tools | `ERRO` |\n| ` WRN ` | cloudflared | `WARN` |\n| `E0506 HH:MM:SS` | Kubernetes \u002F k3s (klog) | `ERRO` |\n| `W0506 HH:MM:SS` | Kubernetes \u002F k3s (klog) | `WARN` |\n| `[GIN] \\| 5xx \\|` | Gin HTTP framework (ollama, etc.) | `ERRO` |\n| `Forwarded alert: CRITICAL` | Alertmanager bridge | `CRIT` |\n| `msg=\"restarting container\"` | Docker daemon | `WARN` |\n\n## Shell completions\n\n```bash\n# bash\nwbts completion bash > \u002Fetc\u002Fbash_completion.d\u002Fwbts          # system-wide\nwbts completion bash > ~\u002F.bash_completion                    # current user\n\n# zsh\nwbts completion zsh > \"${fpath[1]}\u002F_wbts\"                   # system-wide\necho 'source \u003C(wbts completion zsh)' >> ~\u002F.zshrc            # current user\n\n# fish\nwbts completion fish > ~\u002F.config\u002Ffish\u002Fcompletions\u002Fwbts.fish\n\n# powershell\nwbts completion powershell >> $PROFILE\n```\n\n## Contributing\n\nSee [docs\u002Fcollectors.md](docs\u002Fcollectors.md) to learn how to write a collector.\nThe `pkg\u002Fevent` package is the stable public API — import it to build a third-party collector.\n\n## License\n\nMIT\n","wbts 是一个用于故障排查的工具，能够将来自 journald、dmesg、Docker 事件、Kubernetes、apt\u002Fdnf 和 auth 等多个日志源的日志整合成一个按时间顺序排列的时间线，并提供交互式的文本用户界面（TUI）。其核心功能包括通过命令行参数指定时间范围、过滤特定容器的事件、生成摘要或 JSON 输出等。技术上，wbts 使用 Go 语言编写，支持多种输出格式以适应不同的使用场景。该工具非常适合在服务器出现故障后快速定位问题原因，无需手动比对多个日志文件，极大提高了运维效率。",2,"2026-06-11 04:06:14","CREATED_QUERY"]