{"id":17681195,"url":"https://github.com/arcage/multi_log_reader","last_synced_at":"2025-03-30T19:14:17.416Z","repository":{"id":76228757,"uuid":"88866853","full_name":"arcage/multi_log_reader","owner":"arcage","description":"Concurrently reading multiple text files which are growing and may be rotated.","archived":false,"fork":false,"pushed_at":"2017-08-28T06:42:19.000Z","size":5,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-05T21:41:06.779Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Crystal","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/arcage.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}},"created_at":"2017-04-20T13:10:12.000Z","updated_at":"2018-02-07T16:41:47.000Z","dependencies_parsed_at":"2023-03-11T21:59:41.223Z","dependency_job_id":null,"html_url":"https://github.com/arcage/multi_log_reader","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arcage%2Fmulti_log_reader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arcage%2Fmulti_log_reader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arcage%2Fmulti_log_reader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arcage%2Fmulti_log_reader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arcage","download_url":"https://codeload.github.com/arcage/multi_log_reader/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246365650,"owners_count":20765548,"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":[],"created_at":"2024-10-24T09:10:29.129Z","updated_at":"2025-03-30T19:14:17.384Z","avatar_url":"https://github.com/arcage.png","language":"Crystal","readme":"# MultiLogReader for Crystal\n\nConcurrently reading multiple text files which are growing and may be rotated, such as unix system log files.\n\nThis provides almost same functions as [LogReader](https://github.com/arcage/crystal-logreader), but can read multiple files concurrently.\n\nOf course, it works even with only one input file.\n\n## Installation\n\nAdd this to your application's `shard.yml`:\n\n```yaml\ndependencies:\n  multi_log_reader:\n    github: arcage/multi_log_reader\n```\n\n## Usage\n\n```crystal\nrequire \"multi_log_reader\"\n\n# puts lines from 2 input files.\nMultiLogReader.new(\"a.log\", \"b.log\").each do |line|\n  puts line\nend\n\n# expands file names from the patterns for `Dir.glob`\nMultiLogReader.new(\"*.log\", \"*_log\").each do |line|\n  puts line\nend\n```\n\nFor each input file:\n\n- When the current file reaches EOF, this will wait new line added to the file. (like tail -f command)\n- Even when the current file is rotated, this will trace new file and continue reading lines.\n\n`MultiLogReader#each` will stop when all input files are missed. Here, \"file is missed\" means no readable file exists with given filename.\n\nExcept from avobe, it will continue to read new input.\n\nIf you want to stop it, you have to do that forcibly by using Ctrl+C, kill command etc.\n\n### Callbacks\n\nYou can set a `Proc(String, Void)` type callback by `MultiLogReader.on_missing_file=`.\nWhenever one of the input files is missed, the proc will be called with file path string of that file.\n\nSimilarly, you can set a `Proc(Void)` type callback by `MultiLogReader.on_missing_all=`.\nThis proc will be called when all input files are missed(before exiting `MultiLogReader#each`).\n\n```crystal\nrequire \"multi_log_reader\"\n\nMultiLogReader.on_missing_file = -\u003e(path : String) {\n  STDERR.puts \"[MultiLogReader] Input file #{path} is gone.\"\n}\n\nMultiLogReader.on_missing_all = -\u003e() {\n  STDERR.puts \"[MultiLogReader] All input files are gone.\"\n}\n\nMultiLogReader.new(\"*_log\").each do |line|\n  puts line\nend\n```\n\n## Contributors\n\n- [arcage](https://github.com/arcage) ʕ·ᴥ·ʔAKJ - creator, maintainer\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farcage%2Fmulti_log_reader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farcage%2Fmulti_log_reader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farcage%2Fmulti_log_reader/lists"}