{"id":50699731,"url":"https://github.com/wunamesst/tailr","last_synced_at":"2026-06-09T09:00:33.950Z","repository":{"id":363328619,"uuid":"1248864224","full_name":"wunamesst/tailr","owner":"wunamesst","description":"A blazing-fast log tail \u0026 search server. Single binary, web UI, real-time streaming.","archived":false,"fork":false,"pushed_at":"2026-06-08T12:40:47.000Z","size":863,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-08T13:24:00.487Z","etag":null,"topics":["devops","log-search","log-tail","log-viewer","monitoring","rust","vue3","websocket"],"latest_commit_sha":null,"homepage":"https://tailr.flolib.com/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wunamesst.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-05-25T05:57:38.000Z","updated_at":"2026-06-08T12:40:51.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/wunamesst/tailr","commit_stats":null,"previous_names":["wunamesst/tailr"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/wunamesst/tailr","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wunamesst%2Ftailr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wunamesst%2Ftailr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wunamesst%2Ftailr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wunamesst%2Ftailr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wunamesst","download_url":"https://codeload.github.com/wunamesst/tailr/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wunamesst%2Ftailr/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34098952,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-09T02:00:06.510Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["devops","log-search","log-tail","log-viewer","monitoring","rust","vue3","websocket"],"created_at":"2026-06-09T09:00:16.047Z","updated_at":"2026-06-09T09:00:33.932Z","avatar_url":"https://github.com/wunamesst.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"frontend/public/logo-192x192.png\" alt=\"tailr\" width=\"120\"\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003etailr\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  A blazing-fast log tail \u0026 search server. Single binary, web UI, real-time streaming.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"#quickstart\"\u003eQuick Start\u003c/a\u003e •\n  \u003ca href=\"#features\"\u003eFeatures\u003c/a\u003e •\n  \u003ca href=\"#installation\"\u003eInstallation\u003c/a\u003e •\n  \u003ca href=\"#api\"\u003eAPI\u003c/a\u003e •\n  \u003ca href=\"#license\"\u003eLicense\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n## Features\n\n- **Real-time tail** — WebSocket-based live log streaming\n- **Multi-keyword filter** — AND logic, like `grep kw1 | grep kw2`\n- **Fast search** — mmap-based grep with regex support\n- **Log level detection** — Auto-detects ALERT/ERROR/WARN/INFO/DEBUG/TRACE\n- **Single binary** — No dependencies, no runtime, just run\n- **Web UI** — Built-in Vue 3 SPA, no separate frontend deployment\n- **Log rotation aware** — Detects inode changes, handles logrotate\n- **Self-upgrade** — One command to update to the latest version\n- **Multi-language UI** — English (default) and Chinese, with easy extensibility\n- **Cross-platform** — Linux (x86_64/ARM64), macOS\n\n## Quickstart\n\n```bash\n# Run with specific log directories\ntailr --log /var/log/app /var/log/nginx\n\n# Run with a single file\ntailr --log /var/log/syslog\n\n# Custom bind address\ntailr --log /var/log -b 127.0.0.1:8080\n```\n\nOpen `http://localhost:7700` in your browser.\n\n## Installation\n\n### Download binary\n\nDownload the latest binary from [GitHub Releases](https://github.com/wunamesst/tailr/releases).\n\n### Build from source\n\n```bash\n# Clone\ngit clone https://github.com/wunamesst/tailr.git\ncd tailr\n\n# Build frontend + Rust binary\nmake build\n\n# Or just run in dev mode\nmake dev\n```\n\n### Cross-compile for Linux (from macOS)\n\n```bash\nmake build-linux       # x86_64\nmake build-linux-arm   # aarch64\nmake release           # both + frontend\n```\n\nUses Docker with musl for static binaries (no glibc dependency).\n\n## CLI\n\n```\ntailr [OPTIONS]           # Start server (default)\ntailr upgrade [--check]   # Check/perform self-upgrade\n\nOptions:\n  -l, --log \u003cLOG\u003e...         Log directories or files to serve (can specify multiple)\n  -b, --bind \u003cBIND\u003e          Bind address [default: 0.0.0.0:7700]\n  -d, --daemon               Run as daemon in background\n      --stop                 Stop running daemon\n      --status               Show daemon status\n      --systemd              Print systemd service file and exit\n      --launchd              Print launchd plist file and exit (macOS)\n      --pid-file \u003cPID_FILE\u003e  Custom PID file path\n      --log-file \u003cLOG_FILE\u003e  Custom log file path for daemon mode\n  -h, --help                 Print help\n  -V, --version              Print version\n\nSubcommands:\n  upgrade             Check for updates and upgrade tailr to the latest version\n    -c, --check       Only check for updates without installing\n```\n\n**Priority:** CLI args \u003e `TAILR_LOG_DIR` env var \u003e `\u003cexe_dir\u003e/logs`\n\n### Daemon Mode\n\nRun tailr as a background daemon instead of using `nohup`:\n\n```bash\n# Start in daemon mode\ntailr --daemon --log /var/log/app /var/log/nginx\n\n# Check status\ntailr --status\n\n# Stop daemon\ntailr --stop\n```\n\n**PID/Log files** are stored in `~/.local/share/tailr/` by default. Customize with:\n\n```bash\ntailr --daemon --log /var/log/app \\\n  --pid-file /run/tailr.pid \\\n  --log-file /var/log/tailr.log\n```\n\n### System Service\n\n#### systemd (Linux)\n\n```bash\n# Generate and install service file\ntailr --systemd --log /var/log/app | sudo tee /etc/systemd/system/tailr.service\n\n# Enable and start\nsudo systemctl enable --now tailr\n\n# Check status\nsudo systemctl status tailr\n```\n\n#### launchd (macOS)\n\n```bash\n# Generate and install plist\ntailr --launchd --log /var/log/app \u003e ~/Library/LaunchAgents/com.tailr.plist\n\n# Load and start\nlaunchctl load ~/Library/LaunchAgents/com.tailr.plist\n\n# Check status\nlaunchctl list | grep tailr\n```\n\n### Self-Upgrade\n\n```bash\n# Check for updates\ntailr upgrade --check\n\n# Upgrade to latest version\ntailr upgrade\n```\n\n**Note:** The upgrade replaces the binary atomically. If tailr is running as a service, you'll need to restart it after upgrading.\n\n## Environment Variables\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `TAILR_LOG_DIR` | `\u003cexe_dir\u003e/logs` | Comma-separated log directories (fallback if no CLI args) |\n| `TAILR_BIND` | `0.0.0.0:7700` | Listen address |\n| `RUST_LOG` | — | Tracing filter (e.g. `tailr=debug`) |\n\n## API\n\n| Route | Method | Description |\n|-------|--------|-------------|\n| `/api/files` | GET | List log files (filtered: text files only) |\n| `/api/file/content` | GET | Paginated file content (`?path=\u0026offset=\u0026limit=`) |\n| `/api/file/tail` | GET | Last N lines (`?path=\u0026lines=`) |\n| `/api/file/info` | GET | File metadata + line count |\n| `/api/search` | GET | Grep search (`?path=\u0026q=\u0026regex=\u0026levels=\u0026context=\u0026limit=`) |\n| `/api/health` | GET | Status + uptime |\n| `/ws` | WS | Real-time log streaming |\n\n### WebSocket Protocol\n\n```json\n// Subscribe to a file\n{\"type\": \"subscribe\", \"path\": \"/var/log/app.log\"}\n\n// Receive new entries\n{\"type\": \"append\", \"path\": \"/var/log/app.log\", \"seq\": 42, \"entries\": [...]}\n\n// Catchup on reconnect\n{\"type\": \"catchup\", \"path\": \"/var/log/app.log\", \"entries\": [...], \"lastSeq\": 100}\n```\n\n## Development\n\n```bash\n# Terminal 1: Rust backend\ncargo run\n\n# Terminal 2: Vite dev server (with proxy)\ncd frontend \u0026\u0026 npm run dev\n```\n\nVite proxies `/api` and `/ws` to `http://localhost:7700`.\n\n### Testing\n\n```bash\nmake test              # Run all checks (clippy + vue-tsc)\nmake test-backend      # cargo test + cargo clippy\nmake test-frontend     # vue-tsc --noEmit\n```\n\n### Internationalization (i18n)\n\nThe web UI supports multiple languages:\n- **English (en-US)** — Default\n- **Chinese (zh-CN)** — 简体中文\n\n**Adding a new language:**\n1. Create a new locale file in `frontend/src/locales/` (e.g., `ja-JP.json`)\n2. Copy the structure from `en-US.json` and translate all strings\n3. Update `frontend/src/locales/index.ts` to include the new locale in the type definition\n4. Add the locale option to the language switcher in `SettingsPanel.vue`\n\nThe language preference is persisted in localStorage and auto-detected from the browser on first visit.\n\n## Architecture\n\n```\nsrc/main.rs           # CLI (clap), env vars, starts axum server\ncrates/\n  protocol/           # Shared types: LogEntry, WSMessage, LogLevel\n  tail-engine/        # File watching (notify), LineIndex (mmap)\n  search-engine/      # Grep-based search (grep-regex/grep-searcher)\n  server/             # Axum app: REST API, WebSocket, static files\nfrontend/             # Vue 3 + TypeScript + Vite SPA\n```\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwunamesst%2Ftailr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwunamesst%2Ftailr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwunamesst%2Ftailr/lists"}