{"id":49226262,"url":"https://github.com/fiam/openrc-analyze","last_synced_at":"2026-04-24T07:35:19.619Z","repository":{"id":350925024,"uuid":"1208068956","full_name":"fiam/openrc-analyze","owner":"fiam","description":null,"archived":false,"fork":false,"pushed_at":"2026-04-12T20:27:22.000Z","size":148,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-12T21:06:32.273Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/fiam.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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-04-11T19:21:30.000Z","updated_at":"2026-04-12T20:27:17.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/fiam/openrc-analyze","commit_stats":null,"previous_names":["fiam/openrc-analyze"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/fiam/openrc-analyze","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fiam%2Fopenrc-analyze","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fiam%2Fopenrc-analyze/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fiam%2Fopenrc-analyze/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fiam%2Fopenrc-analyze/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fiam","download_url":"https://codeload.github.com/fiam/openrc-analyze/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fiam%2Fopenrc-analyze/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32214420,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-24T03:15:14.334Z","status":"ssl_error","status_checked_at":"2026-04-24T03:15:11.608Z","response_time":64,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":[],"created_at":"2026-04-24T07:35:14.133Z","updated_at":"2026-04-24T07:35:19.603Z","avatar_url":"https://github.com/fiam.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# OpenRC Analyze\n\n`openrc-analyze` instruments OpenRC service execution, captures a boot\nor service-start trace into a portable bundle, and renders timing\nreports from that bundle.\n\nOpenRC itself is a dependency-based init system for Unix-like systems. See the official [OpenRC site](https://openrc.net/) and the [OpenRC source repository](https://github.com/OpenRC/openrc).\n\nExamples of distros that ship with or support OpenRC:\n\n- [Alpine Linux](https://docs.alpinelinux.org/user-handbook/0.1a/Working/openrc.html), which documents OpenRC as Alpine's init system\n- [Gentoo](https://wiki.gentoo.org/wiki/OpenRC/en), where OpenRC was developed and is invoked by default via sysvinit\n- [Artix Linux](https://wiki.artixlinux.org/Main/Installation), which offers OpenRC as one of its supported init systems\n\nDesign notes live in [docs/PRD.md](docs/PRD.md).\n\n## Workflow\n\nThe normal flow is:\n\n- install the binary\n- install the OpenRC hook\n- check `status` to confirm the hook is installed and whether the current\n  boot log already contains analyzer markers\n- reboot, or start the services you want to measure\n- use `blame` with no input for a quick live view, or `capture` to save a\n  portable bundle\n- `capture` writes a versioned JSON bundle from the live system\n- `time` prints the kernel best guess, userspace time, and whether\n  `rc_parallel` was enabled\n- `blame` renders an ASCII timeline and accepts positional service filters\n- `plot` renders an SVG chart from the same data\n- `healthcheck` adds post-start probes that emit extra markers such as\n  `ready` or `login`\n- `deps` prints direct dependency data from a capture bundle\n- `uninstall` cleanly removes the managed hook when you are done\n\nThe hook records service lifecycle events and `capture` normalizes them into a portable bundle. The bundle is the user-facing artifact.\n\n## Install\n\nDownload a prebuilt archive from [GitHub Releases](https://github.com/fiam/openrc-analyze/releases).\nReleases publish binaries for Linux, macOS, and Windows on amd64 and arm64.\nLinux releases are available in both GNU and static musl variants.\n\nOn Alpine, prefer the `*-unknown-linux-musl` archive so the binary runs\nwithout adding `gcompat`.\n\nOr install locally with Cargo:\n\n```sh\ncargo install --path .\n```\n\nOr build a release binary directly:\n\n```sh\ncargo build --release\n```\n\nThat produces `target/release/openrc-analyze`.\n\n## Example Output\n\nThe fixture at `tests/fixtures/captures/minimal.capture.json` produces a\nsmall but real `blame` report:\n\n```text\nKernel ~100.0ms\nUserspace 1.641s\nTotal 1.741s\nParallel: YES; slack 65.2ms.\nTimeline 0.000s -\u003e 1.741s\n\nsysinit\n  dmesg                0.100s |   #                                            | 1.0ms\n\nboot\n  buildkitd            0.578s |                #     |                         | 8.1ms\n                             ready@0.818s\n\ndefault\n  networking           0.959s |                          ###                   | 81.2ms\n  sshd                 1.105s |                              ##################| 635.4ms\n                             `- waited: networking (need); idle 65.2ms\n```\n\nThe same input rendered with `plot`:\n\n![Example SVG plot](docs/examples/minimal-plot.svg)\n\n[Open the full SVG](docs/examples/minimal-plot.svg)\n\n## Install The Hook\n\nInstall the managed OpenRC wrapper:\n\n```sh\nsudo openrc-analyze install\n```\n\nBy default this manages `/usr/libexec/rc/sh/openrc-run.sh` and stores its state under `/var/lib/openrc-analyze`.\n\nIf you are enabling the hook from an uninstalled build artifact, invoke that\nbinary directly and pass the same absolute path to `--bin` so the managed\nwrapper can call it later:\n\n```sh\nsudo /absolute/path/to/openrc-analyze \\\n  install \\\n  --bin /absolute/path/to/openrc-analyze\n```\n\nAfter enabling the hook, reboot or restart the services you want to measure.\n\nIf you upgrade `openrc-analyze` and the managed wrapper gains new behavior,\nrefresh the installed wrapper in place:\n\n```sh\nsudo openrc-analyze install --force\n```\n\nCheck whether the managed hook is enabled and whether the current boot log\ncontains analyzer markers:\n\n```sh\nsudo openrc-analyze status\n```\n\n## How The Wrapper Works\n\n`install` does not patch individual service scripts. It manages\n`/usr/libexec/rc/sh/openrc-run.sh` instead:\n\n- the original helper is preserved as `openrc-run.real.sh`\n- the static prelude is extracted to\n  `/var/lib/openrc-analyze/openrc-run.prelude.sh`\n- the managed wrapper emits lifecycle markers around OpenRC dispatch\n- after a successful `start`, it also launches any configured\n  `healthcheck` probes in the background\n\n`healthcheck add` and `healthcheck remove` only touch JSON config under\n`/var/lib/openrc-analyze/healthchecks.d/`. They do not rewrite the managed\nwrapper again.\n\n## Overhead And Production Use\n\nThe managed wrapper adds a small but non-zero amount of overhead to service\nactions because it emits a few lifecycle markers to `/dev/kmsg` around the\nnormal OpenRC dispatch path.\n\nThat overhead is usually low enough that leaving `openrc-analyze` installed\non production systems is reasonable if you want ongoing observability and\nyou are comfortable with the extra kernel log entries.\n\nConfigured `healthcheck` probes are the bigger variable. They run extra\ncommands after a successful `start`, potentially on a retry loop until the\nservice becomes usable or times out. Keep the base hook installed if it is\nuseful, but enable healthchecks deliberately and only for services where\nthe extra readiness signal is worth that added work.\n\n## Healthchecks\n\nHealthchecks let a service emit extra post-start milestones when it becomes\nusable, not just when OpenRC reports that `start` finished.\n\nAdd a healthcheck for one service and one phase:\n\n```sh\nsudo openrc-analyze healthcheck add sshd \\\n  --phase listening \\\n  --interval 100ms \\\n  --timeout 10s \\\n  -- nc -z 127.0.0.1 22\n```\n\nEach service can have multiple phases, but only one command per phase.\nFor example, `sshd` can have both `listening` and `login`.\n`healthcheck add` also checks that the target service exists under\n`/etc/init.d` before saving the probe.\n\nUse `--interval` to control the retry cadence explicitly.\n\nList configured healthchecks:\n\n```sh\nsudo openrc-analyze healthcheck list\nsudo openrc-analyze healthcheck list sshd\n```\n\nRun one configured healthcheck immediately to see whether it succeeds right\nnow:\n\n```sh\nsudo openrc-analyze healthcheck test sshd --phase listening\n```\n\nRemove one phase:\n\n```sh\nsudo openrc-analyze healthcheck remove sshd --phase listening\n```\n\nWhen a probe succeeds, `openrc-analyze` emits that phase as an extra\nmarker. If it times out, it emits `\u003cphase\u003e-timeout` instead.\n\n## Capture And Inspect\n\nFor a quick live view of the current system, inspect the current `dmesg`\nstream directly:\n\n```sh\nsudo openrc-analyze blame\n```\n\nRender a live SVG directly from the current system:\n\n```sh\nsudo openrc-analyze plot --output /tmp/boot.svg\n```\n\nCapture the current system into a portable bundle:\n\n```sh\nsudo openrc-analyze capture --output /tmp/openrc-capture.json\n```\n\nThat capture also records the current `rc_parallel` setting from\n`/etc/rc.conf` when available.\n\nPrint the overall startup summary:\n\n```sh\nopenrc-analyze time --input /tmp/openrc-capture.json\n```\n\nRender an ASCII timing report:\n\n```sh\nopenrc-analyze blame --input /tmp/openrc-capture.json\n```\n\nFilter to one service:\n\n```sh\nopenrc-analyze blame --input /tmp/openrc-capture.json sshd\n```\n\nFilter to multiple services:\n\n```sh\nopenrc-analyze blame --input /tmp/openrc-capture.json sshd chronyd\n```\n\nFilter to one runlevel:\n\n```sh\nopenrc-analyze blame --input /tmp/openrc-capture.json --runlevel boot\n```\n\nRender an SVG chart:\n\n```sh\nopenrc-analyze plot --input /tmp/openrc-capture.json --output /tmp/boot.svg\n```\n\nPlot one service:\n\n```sh\nopenrc-analyze plot --input /tmp/openrc-capture.json sshd --output /tmp/sshd.svg\n```\n\nInspect dependency data from the same bundle:\n\n```sh\nopenrc-analyze deps /tmp/openrc-capture.json\nopenrc-analyze deps /tmp/openrc-capture.json sshd\nopenrc-analyze deps /tmp/openrc-capture.json --reverse net\n```\n\n## Uninstall The Hook\n\nRestore the original OpenRC runner and remove analyzer-managed state:\n\n```sh\nsudo openrc-analyze uninstall\n```\n\nTo also remove persistent healthcheck definitions:\n\n```sh\nsudo openrc-analyze uninstall --purge\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffiam%2Fopenrc-analyze","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffiam%2Fopenrc-analyze","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffiam%2Fopenrc-analyze/lists"}