procs: 新しいプロセス表示・検索ツール(macOS対応&機能追加)


はじめに

以前、「procs: 新しいプロセス表示・検索ツール」という記事を書いたのですが、macOSで動かないの?という声が若干ありました。
手元にmacOSが動く実機がないので無理だと思っていましたが、Travis CIのWebコンソールで何となく動作確認出来そうだったので、ちまちまと作業を進めて一段落したので公開します。
基本的な紹介は上の記事を参照してください。

あといろいろと機能追加もあるのでそちらも紹介します。
最後にmacOS対応にあたってRustのプロセス情報取得クレートを一通り調べたので、その結果をまとめておきます。

リポジトリ

Linux/macOS向けのバイナリはReleasesからダウンロードするか、
Rustがインストール済みでcargoコマンドが使える方は以下でインストールできます。

$ cargo install procs

macOS対応

一応今回の目玉ですが、先に書いた通り実機のターミナルで確認したことはないので、表示がとんでもないことになっている可能性はあります。
Travis CI上である程度値のチェック(psと合っているか)はしたのでそれほど変な値は出さないと思います。
実機で使ってみて不具合がありましたらGiuhubのIssueでも、ここのコメントでもいいので教えて下さい。
出来る限り対応したいと思います。

あとmacOSではroot権限なしに他ユーザのプロセス情報を取れないようなので、SUIDを立てる必要があります。
psも立てているようです)

$ sudo chown root [procs binary path]
$ sudo chmod u+s [procs binary path]

新機能

docker対応

プロセスがどのdockerコンテナに所属しているかを表示できます。

以下はdockerでgrowiを立てたサーバでprocs growiした結果です。
dockerコンテナ名もデフォルトで検索に引っかかるようにしているので、特定のコンテナのプロセスを探したいときに便利です。

pager対応

出力が端末サイズを越える場合に自動でpager(デフォルトではless)を使用するようにしました。
またlessの場合左右スクロールも効きます。

カラムの拡充

psコマンドで表示可能な情報はだいたい網羅しました。
psでは表示できない項目も主にメモリ周りでだいぶ増やしました。
macOS版は情報の取得方法が違うので、Linux版より少なくなっていますが、実用上はそれほど問題ないレベルと思います。

procs kind ps STANDARD FORMAT Description Linux macOS
Command args Command with all arguments o o
ContextSw -not supported- Context switch count o o
CpuTime cputime Cumulative CPU time o o
Docker -not supported- Docker container name o o
Eip eip Instruction pointer o
Esp esp Stack pointer o
Gid egid Group ID o o
GidFs fgid File system group ID o
GidReal rgid Real group ID o o
GidSaved sgid Saved group ID o o
Group egroup Group name o o
GroupFs fgroup File system group name o
GroupReal rgroup Real group name o o
GroupSaved sgroup Saved group name o o
MajFlt maj_flt Major page fault count o o
MinFlt min_flt Minor page fault count o o
Nice ni Nice value o o
Pid pid Process ID o o
Policy policy Scheduling policy o o
Ppid ppid Parent process ID o o
Priority pri Priority o o
Processor psr Currently assigned processor o
ReadBytes -not supported- Read bytes from storage o o
RtPriority rtprio Real-time priority o
Separator -not supported- Show for column separation o o
ShdPnd pending Pending signal mask for process o
SigBlk blocked Blocked signal mask o
SigCgt caught Caught signal mask o
SigIgn ignored Ignored signal mask o
SigPnd pending Pending signal mask for thread o
StartTime start_time Starting time o o
State s Process State o o
TcpPort -not supported- Bound TCP ports o o
Threads nlwp Thread count o o
Tty tty Controlling TTY o o
UdpPort -not supported- Bound UDP ports o o
Uid euid User ID o o
UidFs fuid File system user ID o
UidReal ruid Real user ID o o
UidSaved suid Saved user ID o o
UsageCpu %cpu CPU utilization o o
UsageMem %mem Memory utilization o o
User euser User name o o
UserFs fuser File system user name o
UserReal ruser Real user name o o
UserSaved suser Saved user name o o
VmData -not supported- Data size o
VmExe trs Text segments size o
VmHwm -not supported- Peak resident set size o
VmLib -not supported- Library code size o
VmLock -not supported- Locked memory size o
VmPeak -not supported- Peak virtual memory size o
VmPin -not supported- Pinned memory size o
VmPte -not supported- Page table entries size o
VmRss rss Resident set size o o
VmSize vsz Physical page size o o
VmStack -not supported- Stack size o
VmSwap -not supported- Swapped-out virtual memory size o
Wchan wchan Process sleeping kernel function o
WriteByte -not supported- Write bytes to storage o o

Rustのプロセス情報取得クレート

いろいろ調べた結果、Linux版はprocfs、macOS版はlibprocを使っていますが、採用しなかったクレート含めて状況(2019/2/22時点)を書いておきます。

procfs

Linux版で使っているクレートで、/procから情報取得します。
当初は/proc/*/statusが取れないなど、若干機能不足だったのでPRを出して入れてもらいました。

procinfo

procfsと同じく/procからの情報取得クレートです。
ダウンロード数も多くメジャーっぽいのですが、PIDの列挙ができなかったり
取れる情報が少なかったりで、こちらは採用しませんでした。

libproc

macOS版で使っているクレートで、libprocの薄いラッパーになっています。
macOSやBSDには/procがないので、プロセス情報はsysctlで取得することになります。
ただ、全部これで取得するのも大変ということか、プロセス情報を取得する高位のライブラリとして
libprocが提供されているようです。

こちらもいくつかのAPIが作りかけだったのでPRを出して入れてもらっているところです。
結構差分が多くて時間がかかりそうなので、現時点ではprocsのリポジトリ上に改変したライブラリを置いてリリースしました。
全ての差分が取り込まれたら、普通のライブラリ参照に戻す予定です。

sysctl

macOS/BSD向けのsysctlラッパーです。こちらも作りかけの感があり、組み込み型で返ってくるような呼び出しはできるのですが、配列で返ってくるものは取得不能のようでした。
そのため「最初に必要なPID一覧が得られない」という状況で、ここから全部作るのは大変すぎると思い、あきらめました。
どうしてもsysctlが必要な部分はlibc::sysctlを直接呼ぶことにしました。

sysinfo

これはLinux/macOS/Windows/Raspberryに対応したシステム情報取得クレートです。
当初はこれ一本でいけるかとも思ったのですが、マルチプラットフォームにする関係上、どのプラットフォームでも取得できる内容にならざるを得ず、かなり情報が足りなくてあきらめました。
ただ、macOS版の一部の情報(libprocで取れないもの)はここのソースコードが参考になりました。