{"id":24703090,"url":"https://github.com/niniyas/tailon","last_synced_at":"2025-10-09T09:30:33.848Z","repository":{"id":43243369,"uuid":"511154813","full_name":"NiNiyas/tailon","owner":"NiNiyas","description":"Webapp for looking at and searching through files and streams. Fork of https://github.com/gvalkov/tailon","archived":false,"fork":false,"pushed_at":"2024-01-02T12:10:10.000Z","size":15374,"stargazers_count":29,"open_issues_count":3,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-02T23:11:31.524Z","etag":null,"topics":["golang","log-viewer","logviewer","tailon"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/NiNiyas.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"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}},"created_at":"2022-07-06T13:45:54.000Z","updated_at":"2024-12-25T05:03:00.000Z","dependencies_parsed_at":"2024-06-19T05:23:11.867Z","dependency_job_id":"fce8dad9-07fc-46b2-b71d-72cdd98bb93a","html_url":"https://github.com/NiNiyas/tailon","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/NiNiyas/tailon","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NiNiyas%2Ftailon","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NiNiyas%2Ftailon/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NiNiyas%2Ftailon/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NiNiyas%2Ftailon/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NiNiyas","download_url":"https://codeload.github.com/NiNiyas/tailon/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NiNiyas%2Ftailon/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279001135,"owners_count":26083022,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-09T02:00:07.460Z","response_time":59,"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":["golang","log-viewer","logviewer","tailon"],"created_at":"2025-01-27T05:51:59.935Z","updated_at":"2025-10-09T09:30:30.617Z","avatar_url":"https://github.com/NiNiyas.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Tailon [![Apache License](https://img.shields.io/badge/license-Apache-blue.svg)](https://github.com/NiNiyas/tailon/blob/master/LICENSE) [![GitHub release](https://img.shields.io/github/release/NiNiyas/tailon.svg)](https://github.com/NiNiyas/tailon/releases)\r\n\r\n\u003cp align=\"center\"\u003e\r\n  \u003cimg src=\"images/tailon.png\"\u003e\r\n\u003c/p\u003e\r\n\r\nFork of [gvalkov/tailon](https://github.com/gvalkov/tailon).\r\n\r\nTailon is a webapp for looking at and searching through files and streams. \\\r\nIn a nutshell, it is a fancy web wrapper around the following commands:\r\n\r\n```\r\ntail -f\r\ntail -f | grep\r\ntail -f | awk\r\ntail -f | sed\r\n```\r\n\r\nWhat sets tailon apart from other similar projects is:\r\n\r\n* Fully self-contained executable. Just download (or build) and run.\r\n* Responsive and minimal user-interface.\r\n\r\n## Install\r\n\r\n### Docker\r\n#### docker run\r\n\r\n```\r\ndocker run --rm ghcr.io/niniyas/tailon:beta --help\r\n```\r\n\r\n#### docker compose\r\n```\r\nversion: \"3.9\"\r\nservices:\r\n  tailon:\r\n    container_name: Tailon\r\n    image: ghcr.io/niniyas/tailon:beta\r\n    ports:\r\n      - 8080:8080\r\n    volumes:\r\n      - /var/log/syslog:/syslog\r\n      - /var/log/log1:/log1\r\n      - .tailon/config:/config  # If you need to load from config file, put your config.toml in this folder.\r\n    command: -b :8080 \"group=Syslog,alias=syslog,/syslog\" \"group=group1,/log1/*.log\"\r\n    command: -c /config/config.toml # If you need to load from config file\r\n```\r\n\r\n### Releases\r\n\r\nDownload a build for your platform from the [releases](https://github.com/NiNiyas/tailon/releases) page.\r\n\r\n## Changelog\r\n\r\nSee [changelog](CHANGELOG.md).\r\n\r\n## Usage\r\n\r\nTailon is a command-line program that starts a local HTTP server, which in turn streams the output of commands such as `tail` and `grep`. \\\r\nIt can be configured from its command-line interface or through the convenience of a [toml](https://github.com/toml-lang/toml) config file. \\\r\nSome options, like adding new commands, are only available through the configuration file.\r\n\r\nTo get started, run tailon with the list of files that you wish to monitor.\r\n\r\n```\r\ntailon /var/log/apache/access.log /var/log/apache/error.log /var/log/messages\r\n```\r\n\r\nTailon can serve single files, globs or whole directory trees. \\\r\nTailon’s server-side functionality is summarized entirely in its help message:\r\n\r\n[//]: # (run \"make README.md\" to update the next section with the output of tailon --help)\r\n\r\n[//]: # (BEGIN HELP)\r\n```\r\nUsage: tailon -c \u003cconfig file\u003e\r\nUsage: tailon [options] \u003cfilespec\u003e [\u003cfilespec\u003e ...]\r\n\r\nTailon is a webapp for looking at and searching through files and streams.\r\n\r\n  -a, --allow-download         Allow file downloads. (default true)\r\n  -b, --bind string            Listen on the specified address and port (default \":8080\")\r\n  -c, --config string          Config.toml file location.\r\n  -h, --help                   Show this help message and exit\r\n  -e, --help-config            Show configuration file help and exit\r\n      --history-lines int      No. of history lines to tail.\r\n      --lines-to-tail int      No. of lines to tail. (default 100)\r\n  -r, --relative-root string   Webapp relative root. (default \"/\")\r\n\r\nTailon can be configured through a config file or with command-line flags.\r\n\r\nThe command-line interface expects one or more filespec arguments, which\r\nspecify the files to be served. The expected format is:\r\n\r\n  [alias=name,group=name]\u003cspec\u003e\r\n\r\nwhere \u003cspec\u003e can be a file name, glob or directory. The optional 'alias='\r\nand 'group=' specifiers change the display name of the files in the UI and\r\nthe group in which they appear.\r\n\r\nA file specifier points to a single, possibly non-existent file. The file\r\nname in the UI can be overwritten with 'alias='. For example:\r\n\r\n  tailon alias=error.log,/var/log/apache/error.log\r\n\r\nA glob evaluates to the list of files that match a shell file name pattern.\r\nThe pattern is evaluated each time the file list is refreshed. An 'alias='\r\nspecifier overwrites the parent directory of each matched file in the UI.\r\n\r\n  tailon \"/var/log/apache/*.log\" \"alias=nginx,/var/log/nginx/*.log\"\r\n\r\nIf a directory is given, all files under it are served recursively.\r\n\r\n  tailon /var/log/apache/ /var/log/nginx/\r\n\r\nExample usage:\r\n  tailon file1.txt file2.txt file3.txt\r\n  tailon alias=messages,/var/log/messages \"/var/log/*.log\"\r\n  tailon -b localhost:8080,localhost:8081 -c config.toml\r\n\r\nFor information on usage through the configuration file, please refer to the\r\n'--help-config' option.\r\n```\r\n[//]: # (END HELP)\r\n\r\n### Config File\r\nTailon can be configured through a TOML config file. \\\r\nThe config file allows more configurability than the command-line interface.\r\n\r\n```\r\n  # The \u003ctitle\u003e of the index page.\r\n  title = \"Tailon\"\r\n\r\n  # The root of the web application.\r\n  relative-root = \"/\"\r\n\r\n  # The addresses to listen on. Can be an address:port combination or an unix socket.\r\n  listen-addr = [\":8080\"]\r\n\r\n  # Allow download of know files (only those matched by a filespec).\r\n  allow-download = true\r\n\r\n  # Commands that will appear in the UI.\r\n  allow-commands = [\"tail\", \"grep\", \"grep -v\", \"sed\", \"awk\"]\r\n\r\n  title = \"Tailon\"\r\n  relative-root = \"/\"\r\n  listen-addr = [\":8080\"]\r\n  allow-download = true\r\n  lines-of-history = 0\r\n  lines-to-tail = 100\r\n  allow-commands = [\"tail\", \"grep\", \"grep -v\", \"sed\", \"awk\"]\r\n\r\n  [files]\r\n    file1 = \"alias=test,group=test_group,log.log\"\r\n    file2 = \"alias=test1,group=test_group1,log.log\"\r\n\r\n  [commands]\r\n    [commands.tail]\r\n    action = [\"tail\", \"-n\", \"$lines\", \"-F\", \"$path\"]\r\n\r\n    [commands.grep]\r\n    stdin = \"tail\"\r\n    action = [\"grep\", \"-e\", \"$script\"]\r\n    default = \".*\"\r\n\r\n    [commands.sed]\r\n    stdin = \"tail\"\r\n    action = [\"sed\", \"-u\", \"-e\", \"$script\"]\r\n    default = \"s/.*/\u0026/\"\r\n\r\n    [commands.awk]\r\n    stdin = \"tail\"\r\n    action = [\"awk\", \"--sandbox\", \"$script\"]\r\n    default = \"{print $0; fflush()}\"\r\n\r\n    [commands.\"grep -v\"]\r\n    stdin = \"tail\"\r\n    action = [\"grep\", \"-v\", \"--text\", \"--line-buffered\", \"--color=never\", \"-e\", \"$script\"]\r\n    default = \"^$\"\r\n```\r\n\r\n### Labels\r\n\r\nTailon will automatically convert the following to labels:\r\n\r\n#### Log levels\r\n\r\n- EMERGENCY\r\n- ALERT\r\n- CRITICAL\r\n- ERROR\r\n- WARNING\r\n- WARN\r\n- NOTICE\r\n- INFO\r\n- DEBUG\r\n\r\n#### HTTP Methods\r\n\r\n- GET\r\n- POST\r\n- PUT\r\n- HEAD\r\n- DELETE\r\n- PATCH\r\n- OPTIONS\r\n- CONNECT\r\n- TRACE\r\n\r\n#### Others\r\n- FAILED\r\n- FAILURE\r\n\r\n## Security\r\n\r\nTailon runs commands on the server it is installed on. While commands that\r\naccept a script argument (such as awk, sed and grep) should be invulnerable to\r\nshell injection, they may still allow for arbitrary command execution and\r\nunrestricted access to the filesystem.\r\n\r\nTo clarify this point, consider the following input to the sed command:\r\n\r\n```\r\ns/a/b'; cat /etc/secrets\r\n```\r\n\r\nThis will result in an error, as tailon does not invoke commands through a\r\nshell. On the other hand, the following command is a perfectly valid sed script\r\nthat has the same effect as the above attempt for shell injection:\r\n\r\n```\r\nr /etc/secrets\r\n```\r\n\r\nThe default set of enabled commands - tail, grep and awk - should be safe to\r\nuse. GNU awk is run in [sandbox](http://www.gnu.org/software/gawk/manual/html_node/Options.html#index-g_t_0040code_007b_002dS_007d-option-277) mode, which prevents scripts from accessing your\r\nsystem, either through the `system()` builtin or by using input redirection.\r\n\r\nBy default, tailon is accessible to anyone who knows the server address and\r\nport.\r\n\r\n\r\n## Development\r\n\r\n### Requirements\r\n\r\nIf you are on Windows, use WSL2. Install [Ubuntu](https://apps.microsoft.com/store/detail/ubuntu/9PDXGNCFSCZV) from Microsoft Store.\r\n\r\n- GO: v1.18. I followed [this](https://www.digitalocean.com/community/tutorials/how-to-install-go-on-ubuntu-20-04) guide.\r\n- Node.js: v16.*. I followed [this](https://github.com/nodesource/distributions/blob/master/README.md) guide.\r\n- Make: `sudo apt-get install make`\r\n- [entr](https://github.com/eradman/entr): `sudo apt-get install entr`\r\n\r\n\r\n```\r\ngit clone https://github.com/NiNiyas/tailon.git\r\ncd tailon\r\nexport GOROOT=/usr/local/go\r\nexport GOPATH=$HOME/go\r\nexport PATH=$PATH:$GOROOT/bin\r\ngo get\r\n```\r\n\r\n**Note**: The paths above might be different for you. Set this accordingly.\r\n\r\n### Frontend\r\n\r\nThe web interface is a written in plain ES5 with the help of some Vue.js. A\r\nsimple makefile is used to bundle and compress the frontend assets. To work on\r\nthe frontend, make sure you're building with the `dev` build tag:\r\n\r\n```\r\ngo build -tags dev\r\n```\r\n\r\nThis will ensure that the `tailon` binary is reading assets from the\r\n`frontend/dist` directory instead of from `frontend/assets_vfsdata.go`. To\r\ncompile the web assets, use `make all` or `make all BUILD=dev` in case you want\r\nto simply concatenate files instead of also compressing them.\r\n\r\nThe `make watch` goal can be used to continuously update the bundles as you make\r\nchanges to the sources. This requires [entr](#requirements).\r\n\r\nNote that the minified frontend bundles are committed in order to avoid people\r\nwanting to work only on the backend from having to pull the full `node_modules`.\r\n\r\nTo build frontend, I have included a simple [build_frontend](https://github.com/NiNiyas/tailon/blob/master/build_frontend.sh) script. \\\r\nMake it executable with `sudo chmod +x build_frontend.sh` and run it `./build_frontend.sh`.\r\n\r\n### Backend\r\n\r\nThe backend is written in straightforward go that tries to do as much as\r\npossible using only the standard library.\r\n\r\n#### Alpine Linux build\r\n\r\n- INFO: http://krolow.com.br/til/go-compile-binary-not-running-in-alpine-and-busybox/\r\n\r\n`CGO_ENABLED=0 go build -tags netgo -a -v`\r\n\r\n\r\n## Backlog\r\n\r\nSee [TODO](TODO.md).\r\n\r\n## Known Bugs\r\n\r\n- When toolbar is hidden, last few lines are not visible in Fennec FDroid 101.1.1 build#1011120 8092b4e74+ and possibly other Firefox versions as well. Works fine on Bromite.\r\n\r\n### Testing\r\n\r\nThe project has unit-tests, which you can run with `go test` and integration\r\ntests which you can run with `cd tests; pytest`. \\\r\nAlternatively, you can run both with `make test`.\r\n\r\nThe integration tests are written in Python and use `pytest` and `aiohttp` to\r\ninteract with a running `tailon` instance. \\\r\nTo run the integration tests, you first need to install the needed dependencies:\r\n\r\n**Note**: Python testing is broken. I have commented out the line in [Makefile](Makefile), I will take a look at it when I have time.\r\n\r\n```shell\r\n# Option 1: Using a virtualenv\r\npython3 -m venv path/to/venv\r\nsource path/to/venv/bin/activate\r\npython3 -m pip install -r tests/requirements.txt\r\n\r\n# Option 2: User site-packages\r\npython3 -m pip install --user -r tests/requirements.txt\r\n```\r\n\r\n### Contribute\r\n\r\nPlease do contribute! Issues and pull requests are welcome. I could use some help.\r\n\r\n\u003c!--## What about the other tailon project?\r\n\r\nThis project is a full rewrite of the original [tailon](https://github.com/gvalkov/tailon-legacy) with the following goals in mind:\r\n\r\n* Reduce maintenance overhead (especially on the frontend).\r\n* Remove unwanted features and fix poor design choices.\r\n* Learn more about Go and Vue.js.\r\n\r\nIn terms of tech, the following has changed:\r\n\r\n* Backend from Python+Tornado to Go.\r\n* Frontend from a very-custom Typescript solution to a simple ES5 + Vue.js app.\r\n* Simplified asset pipeline (a short Makefile).\r\n* Config file is now toml based.\r\n* Fully self-contained executable.\r\n\r\n\r\n## Similar Projects\r\n\r\n* [clarity](https://github.com/tobi/clarity)\r\n* [errorlog](http://www.psychogenic.com/en/products/Errorlog.php)\r\n* [log.io](http://logio.org/)\r\n* [rtail](http://rtail.org/)\r\n* [tailon](https://github.com/gvalkov/tailon-legacy) --\u003e\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fniniyas%2Ftailon","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fniniyas%2Ftailon","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fniniyas%2Ftailon/lists"}