{"id":51299778,"url":"https://github.com/omarahm3/squirrel","last_synced_at":"2026-06-30T18:02:04.840Z","repository":{"id":43127618,"uuid":"463180591","full_name":"omarahm3/squirrel","owner":"omarahm3","description":"🐿️ Realtime logs sharing by just piping squirrel","archived":false,"fork":false,"pushed_at":"2022-04-09T02:54:30.000Z","size":6945,"stargazers_count":26,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-06-22T03:25:57.224Z","etag":null,"topics":["cli","go","golang","logging","logs"],"latest_commit_sha":null,"homepage":"https://github.com/omarahm3/squirrel","language":"Go","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/omarahm3.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}},"created_at":"2022-02-24T14:32:20.000Z","updated_at":"2023-09-08T18:32:04.000Z","dependencies_parsed_at":"2022-09-03T08:24:12.484Z","dependency_job_id":null,"html_url":"https://github.com/omarahm3/squirrel","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/omarahm3/squirrel","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omarahm3%2Fsquirrel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omarahm3%2Fsquirrel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omarahm3%2Fsquirrel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omarahm3%2Fsquirrel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/omarahm3","download_url":"https://codeload.github.com/omarahm3/squirrel/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omarahm3%2Fsquirrel/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34977672,"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-30T02:00:05.919Z","response_time":92,"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":["cli","go","golang","logging","logs"],"created_at":"2026-06-30T18:02:03.754Z","updated_at":"2026-06-30T18:02:04.834Z","avatar_url":"https://github.com/omarahm3.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🐿️ Squirrel\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)![GitHub Workflow Status (branch)](https://img.shields.io/github/workflow/status/omarahm3/squirrel/Release/master)[![Twitter: omarahm3](https://img.shields.io/twitter/follow/omarahm3.svg?style=social)](https://twitter.com/omarahm3)\n\nRealtime logs (or any stdout basically!) sharing by just piping squirrel.\n\n![web-view](https://user-images.githubusercontent.com/8606113/156921849-2ae60d76-be21-4271-adf3-fe20fd9a75f5.gif)\n![terminal-view](https://user-images.githubusercontent.com/8606113/156922080-5e881e4c-6999-4f18-a04b-5454bba7965f.gif)\n\n## Why?\n- I'm lazy\n- I wanted to learn Go\n- I wanted to implement a websocket server using Go\n- I wanted to be used on crossplatform without installing any extra dependencies (that's why not Nodejs or ink)\n- I'm tired of requesting people to send me snippets of logs, so that i can analyze, or grep the lines\n- I love CLI apps\n- Probably people will find this useful?\n- I wanted to use squirrel as a name of something xD\n- Because why not?\n\n## Setup\nCurrently can head over to [releases](https://github.com/omarahm3/squirrel/releases), and choose the suitable package for you. Currently this was tested on Ubuntu and OSX Monterey only though\n\nIf you're on Linux, then you can choose the package based on your distribution and install it, for example on Ubuntu/Debian:\n\n```bash\ncurl -fLO https://github.com/omarahm3/squirrel/releases/download/v\u003cVERSION\u003e/squirrel_\u003cVERSION\u003e_linux_amd64.deb\nsudo apt install -y ./squirrel_\u003cVERSION\u003e_linux_amd64.deb\n```\n\nIf you're on a different OS, then you can use download the compressed files, and move these files to your bin folder accordingly, for example on Ubuntu/Debian:\n\n```bash\ncurl -fLO https://github.com/omarahm3/squirrel/releases/download/v\u003cVERSION\u003e/squirrel_\u003cVERSION\u003e_Linux_x86_64.tar.gz\ntar xf squirrel_\u003cVERSION\u003e_Linux_x86_64.tar.gz\nmv ./squirrel ~/.local/bin/\n```\n\nOr if you have go installed, you can always install squirrel client as a Go package by doing so:\n\n```bash\ngo install github.com/omarahm3/squirrel/cmd/squirrel@latest\n```\n\n***Note**: Installing squirrel as a go package will install it as a development ready package, which is going to need to be configured either by Environment variables or passing options to the CLI, Refer to [configuration](#Configuration) section for more details*\n\n## Docker\nSquirrel is available as a docker image that you can use directly as well, run squirrel:\n\n```bash\n# Help command\ndocker run -i omarahm3/squirrel:latest squirrel -h\n# You can also pipe it like this\ncat myfile.txt | docker run -i omarahm3/squirrel:latest squirrel -o -u\n```\n\nSquirreld (daemon/server) is also available via docker, and high customizable using either flags, or environment variables, check [configuration](#Configuration) to know how to customize it accordingly\n\n```bash\n# Help command\ndocker run -i omarahm3/squirreld:latest squirreld -h\n# Configure it using flags\ndocker run -i omarahm3/squirreld:latest squirreld -domain=localhost -env=dev -log=debug -port=3000\n# or using environment variables\ndocker run -e DOMAIN=localhost -e APP_ENV=dev -e LOG_LEVEL=debug -e PORT=3000 -i omarahm3/squirreld:latest squirreld\n```\n\n## Squirreling\nSquirrel has no commands, the only way it can be used is via piping it to stdout of another command, for example \n\n```bash\n$ for i in $(seq 1 50); do echo \"Example Message #$i\"; sleep 1; done | squirrel -o -u\n\n➜ ID: [ 315c77cd-7ac1-4487-adf8-d205471f0771 ]\n➜ Link: [ https://squirrel-jwls9.ondigitalocean.app/client/315c77cd-7ac1-4487-adf8-d205471f0771 ]\n➜ Url is copied to your clipboard\n📢 Squirrel is waiting for listeners to begin piping stdout...\n\n```\n\nThis will print a shareable link and ID that you can use to send to the person you want to share the output of this for loop with, however squirrel will not start reading stdout till the other end is connected and ready to receive the actual output.\n\nThe other end (or maybe yourself) can then open the link and you'll begin to see that messages are coming in, which are the output of the for loop we just piped. Or if person prefer to use terminal, then another squirrel can be used in listening mode, but then `peer` option is must be supplied with the ID of the broadcaster:\n\n```bash\nsquirrel -l --peer=315c77cd-7ac1-4487-adf8-d205471f0771\n```\n\n## Configuration\nSquirrel can be configured by passing options/flags to the CLI, or for some options you can use ENV variables as well. Just note that ENV variables have more priority over flags.\nSquirrel can be run in 2 different modes too:\n- Broadcasting: which is the default behavior and the initial mode of squirrel where _broadcaster_ is piping squirrel to stdout\n- Listening: in which the other end _subscriber_ which is the one who is listening for _broadcaster_ messages \n\n### Client configuration\n**ENV Variables:**\n- `APP_ENV` - Set the app environment mode (`prod` or `dev` default is `prod`)\n- `DOMAIN` - Set the server domain in which CLI is going to send events to\n- `LOG_LEVEL` - Set the current log level of the CLI (default is `error`)\n\t- Log levels are:\n\t\t- error\n\t\t- warn\n\t\t- info\n\t\t- debug\n\n**Flags:**\n- `--env` - Set app environment mode (same as `APP_ENV`)\n- `--domain` - Set the server domain in which CLI is going to send events to (same as `DOMAIN`)\n- `--log` - Set the current log level of the CLI (same as `DOMAIN`)\n- `--peer` - Peer (broadcaster) ID that squirrel is going to listen to (must be supplied in listen mode `-l/--listen`)\n- `-l` or `--listen` - Set the current mode of the CLI to listen instead of broadcasting\n- `-o` or `--show-output` - Show the output of what is being piped to squirrel on the current session as well\n- `-u` or `--copy-url` - Copy shareable link to the clipboard\n\nYou can always run:\n```bash\nsquirrel -h\n```\nand see all of the available options\n\n## Squirreld (Server)\nThis package is built into 2 different applications, the main one and probably most of the users will be interested in is _squirrel_ which is the client/CLI, and the other one is _squirreld_ which is the server daemon that will be responsible of managing and routing broadcasters messages to their corresponding subscribers.\n\nSquirreld is a websocket server, that each of the broadcasters and subscribers is connecting to, so that they can exchange events between each other, that's is how we're making sure that stdout messages are exchanged in realtime from broadcasters to subscribers.\nCurrently server is hosted by me on one of Digitalocean servers, but this is subject to change indeed.\n\n## Squirreld Configuration\nAll of server configuration can be tweaked using ENV variables or passing flags to squirreld, here is the detailed options and ENV variables list:\n- `--env` or `APP_ENV` - Set server environment mode (`prod` or `dev` default is `prod`)\n- `--domain` or `DOMAIN` - Set the current server domain\n- `--log` or `LOG_LEVEL` - Set the current log level of the server (same as squirrel log levels)\n- `--port` or `PORT` - Set the current port that server is going to listen to (default is `3000`)\n- `--read-buffer-size` or `READ_BUFFER_SIZE` - Websocket server read buffer size (default is `0`)\n- `--write-buffer-size` or `WRITE_BUFFER_SIZE` - Websocket server write buffer size (default is `0`)\n- `--max-message-size` or `MAX_MESSAGE_SIZE` - Websocket server maximum message size (default is `1024`)\n\nSame as squirrel, ENV variables have more priority than flags as well.\n\n## Note\nThis is pretty immature Go project, i'm still learning Go by actually doing and maintaining this project, it gave me the opportunity to explore various topics that i want to get familiar with using Go such as backend (http, and websocket), templates, CLI, Go routines and channels ..etc\nContributions are more than welcome, i indeed would like to see how this project will scale.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fomarahm3%2Fsquirrel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fomarahm3%2Fsquirrel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fomarahm3%2Fsquirrel/lists"}