{"id":13587074,"url":"https://github.com/maxpert/drep","last_synced_at":"2025-05-02T18:31:38.263Z","repository":{"id":44342774,"uuid":"273801738","full_name":"maxpert/drep","owner":"maxpert","description":"dynamic regular expression print","archived":false,"fork":false,"pushed_at":"2022-07-10T03:52:39.000Z","size":36,"stargazers_count":90,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-07T04:51:15.069Z","etag":null,"topics":["filtering","logging","rust","rust-lang","tool"],"latest_commit_sha":null,"homepage":"","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/maxpert.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":"2020-06-20T23:40:40.000Z","updated_at":"2025-03-02T18:01:15.000Z","dependencies_parsed_at":"2022-07-14T12:01:44.712Z","dependency_job_id":null,"html_url":"https://github.com/maxpert/drep","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxpert%2Fdrep","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxpert%2Fdrep/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxpert%2Fdrep/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maxpert%2Fdrep/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/maxpert","download_url":"https://codeload.github.com/maxpert/drep/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252088519,"owners_count":21692810,"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","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":["filtering","logging","rust","rust-lang","tool"],"created_at":"2024-08-01T15:06:00.348Z","updated_at":"2025-05-02T18:31:35.665Z","avatar_url":"https://github.com/maxpert.png","language":"Rust","readme":"[![Rust](https://github.com/maxpert/drep/workflows/Rust/badge.svg)](https://github.com/maxpert/drep/actions) [![Version](https://img.shields.io/github/v/release/maxpert/drep)](https://github.com/maxpert/drep/releases)\n\n# drep is dynamic regular expression print\n\n`drep` is `grep` with dynamic reloadable filter expressions. This allows filtering stream of \nlogs/lines, while changing filters on the fly.\n\nFilter is either a regex or plain text match, provided via input file.  \nHere is an example usage:\n\n```bash\ntail -f /var/log/nginx/error.log | drep -f /etc/drep/filters\n```\n\nUsually you will end up using this with your servers:\n\n```bash\njava -jar my-server.jar | drep -f server-filters\n```\n\nor \n\n```bash\n./uwsgi -s :8080 -w my_app  | drep -f server-filters\n```\n\n## Filter file syntax\n\nEach line of the filters file is an expression that starts with `~`, `=`, `!=`, or `!~`. The matches will be done \nin the order filters written in the file, and if a filter matches subsequent filters won't be executed. \n\n - Any line that starts with `!~` implies does not match regex, e.g: `!~\"time\": \\d+.\\d{0,2}`\n - Any line that starts with `~` implies match regex, e.g: `~\"time\": \\d+.\\d{3,}`\n - Any line that starts with `!=` implies does not contain text, e.g: `!=INFO`\n - Any line that starts with `=` implies contain text, e.g: `=\"total-duration\"`\n\nEverything else is ignored, as you can see from plain text.\nFor regular expression documentation please refer to [this document](https://docs.rs/regex/1.3.9/regex/). \n\n## Why?\n\nWhile `grep --line-buffered` can do something similar changing regex on the fly is not possible. \nChange filter regex on the fly is extremely useful in server/process environments where it's not possible to restart \nthe process just to change the `grep` filter. \n\nBuilding on unix philosophy `drep` does only one job well, given bunch of filter from an input file \nit can filter input lines to stdout.\n\n## Features\n\n - Lightweight on CPU, and memory (~3MB memory foot print, and 2 threads in total).\n - Watch and reload filters file.\n - No GC pauses and memory safe (Written in Rust).\n - Plain text \u0026 regex matching (with negation support).\n \n## Usage example\n\nGiven following simple `fizzbuzz.py`:\n\n```python\nimport time\n\ni = 1\nwhile True:\n    fb = \"\"\n    if i % 3 == 0:\n        fb = \"fizz\"\n    if i % 5 == 0:\n        fb = \"{}buzz\".format(fb)\n\n    if fb:\n        print(\"{}. {}\".format(i, fb), flush=True)\n\n    i = i + 1\n    time.sleep(0.1)\n```\n\nWe can launch and pipe it's output `python fizzbuzz.py | drep -f filters`. Now if the contents of `filters` are:\n\n```\n~\\sfizz\\n\n``` \n\ndrep will only emit logs with fizz. e.g.\n\n```\n642. fizz\n648. fizz\n651. fizz\n654. fizz\n...\n```\n\nWhile keeping the process running without exiting you can just modify `filters` to:\n\n```\n~\\sbuzz\\n\n```\n\nThis will change the drep output on the fly to only emit buzz:\n```\n805. buzz\n815. buzz\n820. buzz\n...\n```\n\n## Building\n\nJust clone the repo and run `cargo build --release`.\n","funding_links":[],"categories":["Rust","Logging"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaxpert%2Fdrep","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmaxpert%2Fdrep","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaxpert%2Fdrep/lists"}