An open API service indexing awesome lists of open source software.

https://github.com/fiam/openrc-analyze


https://github.com/fiam/openrc-analyze

Last synced: about 2 months ago
JSON representation

Awesome Lists containing this project

README

          

# OpenRC Analyze

`openrc-analyze` instruments OpenRC service execution, captures a boot
or service-start trace into a portable bundle, and renders timing
reports from that bundle.

OpenRC 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).

Examples of distros that ship with or support OpenRC:

- [Alpine Linux](https://docs.alpinelinux.org/user-handbook/0.1a/Working/openrc.html), which documents OpenRC as Alpine's init system
- [Gentoo](https://wiki.gentoo.org/wiki/OpenRC/en), where OpenRC was developed and is invoked by default via sysvinit
- [Artix Linux](https://wiki.artixlinux.org/Main/Installation), which offers OpenRC as one of its supported init systems

Design notes live in [docs/PRD.md](docs/PRD.md).

## Workflow

The normal flow is:

- install the binary
- install the OpenRC hook
- check `status` to confirm the hook is installed and whether the current
boot log already contains analyzer markers
- reboot, or start the services you want to measure
- use `blame` with no input for a quick live view, or `capture` to save a
portable bundle
- `capture` writes a versioned JSON bundle from the live system
- `time` prints the kernel best guess, userspace time, and whether
`rc_parallel` was enabled
- `blame` renders an ASCII timeline and accepts positional service filters
- `plot` renders an SVG chart from the same data
- `healthcheck` adds post-start probes that emit extra markers such as
`ready` or `login`
- `deps` prints direct dependency data from a capture bundle
- `uninstall` cleanly removes the managed hook when you are done

The hook records service lifecycle events and `capture` normalizes them into a portable bundle. The bundle is the user-facing artifact.

## Install

Download a prebuilt archive from [GitHub Releases](https://github.com/fiam/openrc-analyze/releases).
Releases publish binaries for Linux, macOS, and Windows on amd64 and arm64.
Linux releases are available in both GNU and static musl variants.

On Alpine, prefer the `*-unknown-linux-musl` archive so the binary runs
without adding `gcompat`.

Or install locally with Cargo:

```sh
cargo install --path .
```

Or build a release binary directly:

```sh
cargo build --release
```

That produces `target/release/openrc-analyze`.

## Example Output

The fixture at `tests/fixtures/captures/minimal.capture.json` produces a
small but real `blame` report:

```text
Kernel ~100.0ms
Userspace 1.641s
Total 1.741s
Parallel: YES; slack 65.2ms.
Timeline 0.000s -> 1.741s

sysinit
dmesg 0.100s | # | 1.0ms

boot
buildkitd 0.578s | # | | 8.1ms
ready@0.818s

default
networking 0.959s | ### | 81.2ms
sshd 1.105s | ##################| 635.4ms
`- waited: networking (need); idle 65.2ms
```

The same input rendered with `plot`:

![Example SVG plot](docs/examples/minimal-plot.svg)

[Open the full SVG](docs/examples/minimal-plot.svg)

## Install The Hook

Install the managed OpenRC wrapper:

```sh
sudo openrc-analyze install
```

By default this manages `/usr/libexec/rc/sh/openrc-run.sh` and stores its state under `/var/lib/openrc-analyze`.

If you are enabling the hook from an uninstalled build artifact, invoke that
binary directly and pass the same absolute path to `--bin` so the managed
wrapper can call it later:

```sh
sudo /absolute/path/to/openrc-analyze \
install \
--bin /absolute/path/to/openrc-analyze
```

After enabling the hook, reboot or restart the services you want to measure.

If you upgrade `openrc-analyze` and the managed wrapper gains new behavior,
refresh the installed wrapper in place:

```sh
sudo openrc-analyze install --force
```

Check whether the managed hook is enabled and whether the current boot log
contains analyzer markers:

```sh
sudo openrc-analyze status
```

## How The Wrapper Works

`install` does not patch individual service scripts. It manages
`/usr/libexec/rc/sh/openrc-run.sh` instead:

- the original helper is preserved as `openrc-run.real.sh`
- the static prelude is extracted to
`/var/lib/openrc-analyze/openrc-run.prelude.sh`
- the managed wrapper emits lifecycle markers around OpenRC dispatch
- after a successful `start`, it also launches any configured
`healthcheck` probes in the background

`healthcheck add` and `healthcheck remove` only touch JSON config under
`/var/lib/openrc-analyze/healthchecks.d/`. They do not rewrite the managed
wrapper again.

## Overhead And Production Use

The managed wrapper adds a small but non-zero amount of overhead to service
actions because it emits a few lifecycle markers to `/dev/kmsg` around the
normal OpenRC dispatch path.

That overhead is usually low enough that leaving `openrc-analyze` installed
on production systems is reasonable if you want ongoing observability and
you are comfortable with the extra kernel log entries.

Configured `healthcheck` probes are the bigger variable. They run extra
commands after a successful `start`, potentially on a retry loop until the
service becomes usable or times out. Keep the base hook installed if it is
useful, but enable healthchecks deliberately and only for services where
the extra readiness signal is worth that added work.

## Healthchecks

Healthchecks let a service emit extra post-start milestones when it becomes
usable, not just when OpenRC reports that `start` finished.

Add a healthcheck for one service and one phase:

```sh
sudo openrc-analyze healthcheck add sshd \
--phase listening \
--interval 100ms \
--timeout 10s \
-- nc -z 127.0.0.1 22
```

Each service can have multiple phases, but only one command per phase.
For example, `sshd` can have both `listening` and `login`.
`healthcheck add` also checks that the target service exists under
`/etc/init.d` before saving the probe.

Use `--interval` to control the retry cadence explicitly.

List configured healthchecks:

```sh
sudo openrc-analyze healthcheck list
sudo openrc-analyze healthcheck list sshd
```

Run one configured healthcheck immediately to see whether it succeeds right
now:

```sh
sudo openrc-analyze healthcheck test sshd --phase listening
```

Remove one phase:

```sh
sudo openrc-analyze healthcheck remove sshd --phase listening
```

When a probe succeeds, `openrc-analyze` emits that phase as an extra
marker. If it times out, it emits `-timeout` instead.

## Capture And Inspect

For a quick live view of the current system, inspect the current `dmesg`
stream directly:

```sh
sudo openrc-analyze blame
```

Render a live SVG directly from the current system:

```sh
sudo openrc-analyze plot --output /tmp/boot.svg
```

Capture the current system into a portable bundle:

```sh
sudo openrc-analyze capture --output /tmp/openrc-capture.json
```

That capture also records the current `rc_parallel` setting from
`/etc/rc.conf` when available.

Print the overall startup summary:

```sh
openrc-analyze time --input /tmp/openrc-capture.json
```

Render an ASCII timing report:

```sh
openrc-analyze blame --input /tmp/openrc-capture.json
```

Filter to one service:

```sh
openrc-analyze blame --input /tmp/openrc-capture.json sshd
```

Filter to multiple services:

```sh
openrc-analyze blame --input /tmp/openrc-capture.json sshd chronyd
```

Filter to one runlevel:

```sh
openrc-analyze blame --input /tmp/openrc-capture.json --runlevel boot
```

Render an SVG chart:

```sh
openrc-analyze plot --input /tmp/openrc-capture.json --output /tmp/boot.svg
```

Plot one service:

```sh
openrc-analyze plot --input /tmp/openrc-capture.json sshd --output /tmp/sshd.svg
```

Inspect dependency data from the same bundle:

```sh
openrc-analyze deps /tmp/openrc-capture.json
openrc-analyze deps /tmp/openrc-capture.json sshd
openrc-analyze deps /tmp/openrc-capture.json --reverse net
```

## Uninstall The Hook

Restore the original OpenRC runner and remove analyzer-managed state:

```sh
sudo openrc-analyze uninstall
```

To also remove persistent healthcheck definitions:

```sh
sudo openrc-analyze uninstall --purge
```