サーバ/プロセスのメトリクスを使ったNagios/Mackerel/Consulのチェックコマンドを作るときに便利な metr を作った

Consulでちょっとしたヘルスチェックを追加したいと思ったのですが、例えば iowaitが高いかつuserは低いとき という条件を書こうとしたときに、「うっ。。!どう書けばいいんだ。。」となってしまったので、作りました。

github.com

これはなに

metr は次のような利用を想定したコマンドです

  • シェルスクリプトにホストやプロセスのメトリクスの値を使った条件を組み込む
  • Nagios pluginとして利用する
  • Mackerel check pluginにチェックコマンドとして利用する

使い方

インストールはHomebrew以外にdeb/rpmパッケージを用意しています。基本的にサーバにコマンドとしてインストールするのが良いでしょう

$ dpkg -i metr_0.5.1-1_amd64.deb

metr list

取得できるメトリクスは metr list で確認できます。また -p (--pid) でプロセスのPIDを指定すると、プロセスのメトリクスも対象にできます。

以下はMac上で実行しましたが、Linux上だともう少し取得できるメトリクスが増えます。

$ metr list
cpu (now:33.084577 %): Percentage of cpu used.
mem (now:66.468358 %): Percentage of RAM used.
swap (now:875823104 bytes): Amount of memory that has been swapped out to disk (bytes).
user (now:18.610422 %): Percentage of CPU utilization that occurred while executing at the user level.
system (now:14.143921 %): Percentage of CPU utilization that occurred while executing at the system level.
idle (now:67.245658 %): Percentage of time that CPUs were idle and the system did not have an outstanding disk I/O request.
nice (now:0.000000 %): Percentage of CPU utilization that occurred while executing at the user level with nice priority.
load1 (now:3.640000 ): Load avarage for 1 minute.
load5 (now:4.210000 ): Load avarage for 5 minutes.
load15 (now:4.600000 ): Load avarage for 15 minutes.
numcpu (now:8 ): Number of logical CPUs.
(metric measurement interval: 500 ms)
$ metr list -p `pgrep -n docker`
proc_cpu (now:1.820857 %): Percentage of the CPU time the process uses.
proc_mem (now:1.264739 %): Percentage of the total RAM the process uses.
proc_rss (now:217280512 bytes): Non-swapped physical memory the process uses (bytes).
proc_vms (now:7010299904 bytes): Amount of virtual memory the process uses (bytes).
proc_swap (now:0 bytes): Amount of memory that has been swapped out to disk the process uses (bytes).
proc_connections (now:0 ): Amount of connections(TCP, UDP or UNIX) the process uses.
cpu (now:22.000000 %): Percentage of cpu used.
mem (now:59.768772 %): Percentage of RAM used.
swap (now:781451264 bytes): Amount of memory that has been swapped out to disk (bytes).
user (now:14.925373 %): Percentage of CPU utilization that occurred while executing at the user level.
system (now:6.467662 %): Percentage of CPU utilization that occurred while executing at the system level.
idle (now:78.606965 %): Percentage of time that CPUs were idle and the system did not have an outstanding disk I/O request.
nice (now:0.000000 %): Percentage of CPU utilization that occurred while executing at the user level with nice priority.
load1 (now:1.360000 ): Load avarage for 1 minute.
load5 (now:1.610000 ): Load avarage for 5 minutes.
load15 (now:1.490000 ): Load avarage for 15 minutes.
numcpu (now:8 ): Number of logical CPUs.
(metric measurement interval: 500 ms)

metr cond ( alias: metr test )

metr condシェルスクリプトなどでメトリクスを条件に使いたいときなどに利用できます。

metr condtest コマンドと同じように、条件にマッチすると終了ステータス0 、マッチしないと 1 で終了します。

$ metr cond 'cpu < 20 and mem < 50' || somecommand

上記の場合、ホストのCPU使用率が20%以上かホストのメモリ使用率が50%以上のときに somecommand が実行されます。

ちなみに、利用できるオペレーターは

+, -, *, /, ==, !=, <, >, <=, >=, not, and, or, !, &&, || などです。

metr check

metr checkNagiosプラグインMackerelのチェック監視 とほぼ同じ終了ステータスの仕様になっています。

終了ステータス 意味
0 OK
1 WARNING
2 CRITICAL
3 UNKNOWN
$ metr check -w 'cpu > 10 or mem > 50' -c 'cpu > 50 and mem > 90'
METR WARNING: w(cpu > 10 or mem > 50) c(cpu > 50 and mem > 90)

上記の場合、ホストのCPU使用率が10%を超えたかメモリ使用率を50%を超えたときに WARNING(終了ステータス 1)、CPU使用率が50%を超えた、かつメモリ使用率を90%を超えたときに CRITICAL (終了ステータス 2)となります。

というわけで

簡単にメトリクスを利用したチェックコマンドが作れます。楽したいときなど、是非使ってみてください。


以下、余談です。

vmstatの1行目は何を表しているか( metr--interval オプション)

RedHatのCustmer Portalの「Vmstat の出力結果はどのように解釈すれば良いですか?」という質問の回答によると

このレポートの最初の行には、コンピューターが最後に再起動してからの平均値が記載されます。

とあります。

procps-ngのvmstatのソースコードをみてみます。値はgetstat関数で取得しているのですが、具体的には /proc/stat の値を読み取っています。

https://gitlab.com/procps-ng/procps/blob/master/proc/sysinfo.c#L532

そしてmain loopに入る前に1行出力しています。

https://gitlab.com/procps-ng/procps/blob/master/vmstat.c#L306-361

以降はmain loop内で差分をsleep前後の値の差分を利用しています。

つまり、1行目と2行目以降で値の特性が違うということになります。そして大抵欲しいのは2行目以降の値になります。

metr は上記の(sleepで実現している)時間間隔を -i (--interval) としてmsで指定できるようにしています(デフォルトは500msです)。

vmstatでもvmstat 1 2 | tail -1 とすれば1秒間隔の差分での計測値を取得することができます。

metr だともう少し簡単に取得できて、かつ複数のメトリクスで条件などを組みやすいという感じです。

ちなみにmackarel-agentも同じように前後の計測の差分で計測しているようです。

https://github.com/mackerelio/mackerel-agent/blob/c9db8018714023fef9c8ba7eac20471e8a1b297a/metrics/linux/cpuusage.go#L44-L70

Sheer Heart Attack のコアライブラリとして組み込んだ

私は先行して、Sheer Heart Attackというデバッグ用ツールを作っています。

k1low.hatenablog.com

両ツールはメトリクスの取得という点では同じなので、今回、 metr をコアライブラリとしてSheer Heart Attackに組み込むことで実装の共通化もしました。

[BREAKING] Use github.com/k1LoW/metr by k1LoW · Pull Request #21 · k1LoW/sheer-heart-attack · GitHub

metrを拡張していくことでSheer Heart Attackも自動でパワーアップするという寸法です。

metrの読み方

いつものように metrics を短くしただけなんですけど、なんとも読みづらい箇所で省略したなと。。

「メタァ」とか「メトロ」とかで呼んでいます。まあ、呼ぶことはないと思うので大丈夫かな。。

標準入力の指定の文字列に色をつけるツール colr

Go Conference ‘19 Summer in Fukuokaでも少し紹介したcolrです。

github.com

これはなに

まずは以下のスクリーンキャストをご覧ください

f:id:k1LoW:20190813073706g:plain

colrtail -F /path/to/access.log のようなログにカジュアルに色をつけるツールです。

$ tail -F /var/log/nginx/access.log | colr POST GET 404 500 search

のように何個でもカラーにしたい文字列を指定できます。

これだけです

色の指定もできませんし、その他のオプションもありません。 colr の後に引数としてカラーにしたい文字列を並べるだけです。

実は正規表現っぽい文字列を渡すと正規表現マッチに変更してくれますが、それでも使い方は変わりません。

これだけの機能、ただその分、何も考えずに利用できます。

是非ご利用ください。単純なツールですがなにげに重宝します。

Windowsにも対応しています!


以下余談です。

grep --color で色をつけてもパイプで繋ぐと色が消える。その仕組み

colr の紹介をすると「それ grep --color でいいんじゃ?」と言われます。「いや、私は絞込みたいわけではないんだよ」となるのですが、今回は別の話です。

例えば

$ tail -F /var/log/nginx/access.log | grep POST --color

とすると POST に色がつきますが、

$ tail -F /var/log/nginx/access.log | grep POST --color | grep search

とすると POST の色が消えてしまいます。

ちなみにこれを回避する方法は grep POST --color=always とすればいいのですが、パイプで繋ぐとなぜ色が消えるのか考えてみました。

ターミナル上で色をつける仕組み

ターミナルで色をつける仕組みは特殊なエスケープコードを使って文字列を囲むことで実現しています。

en.wikipedia.org

例えば、文字列を赤くするためには以下のような文字列を標準出力に出力します(iTerm2想定)。

fmt.Println("\x1b[31;1mHello, World!\x1b[0m")

ターミナルは、上記エスケープコード付き文字列を「色つけの指示付きの文字列」と解釈してエスケープコード部分を省いて色をつけた形で表示します。

つまり、色をつけているのはターミナルです。

エスケープコードを解釈するのがターミナルでない場合(パイプにつなげたりリダイレクトでファイルに保存する場合)、エスケープコードは「ただの文字列として解釈されてしまう = 不必要な文字列がついている状態」となるわけです。

上記を回避するために grep --color ではターミナル(擬似端末)かどうかを判断してエスケープコードの出力を制御しているようです。grep --color=always はその判定処理をスキップしているわけですね。

ちなみに、擬似端末判定処理について、Golangだと github.com/mattn/go-isatty が有名だと思います。

github.com

colrは色をつけるツール

colr はシンプルに色をつけるためだけのツールです。色をつけなければ何もしないただリソースを消費するだけのコマンドになってしまいます。

なので、「 colr を利用するときは、どうしても色をつけたいのだろう」と考え、(利用カラーリングライブラリにはターミナル判定処理がついているのですが、)上記の擬似判定処理をスキップしています。

これで、どう使っても色がつくようになりました。

おすすめ

Goならわかるシステムプログラミング

Goならわかるシステムプログラミング

Goなどでクロスコンパイルしたワンバイナリなソフトウェアを最小工数でdeb/RPMパッケージにしてくれるNFPMが便利

みなさんはdeb/RPMパッケージを作ったことはありますか?

私はtcpdpのパッケージ作成ではじめて作りました。具体的にはここらへんです。

tcpdpはlibpcapに依存していることもあり、DockerでUbuntu/CentOSの環境を作ってその上でコンパイルして、合わせてdeb/RPMパッケージ化までするようにしています。

本来Goはクロスコンパイルができるので、コンパイルしてできたバイナリをdeb/RPMパッケージにできればいいわけです。

ただ、意外にdeb/RPMパッケージをするための前準備が面倒です。

debパッケージであればcontrolファイルを書かないといけないですし、RPMパッケージであればspecファイルを書く必要があります。それぞれ覚えているほど書く機会はないので毎回ググるはめに。

ビルド方法にもお作法があります。これもあまり覚えていませんがディレクトリ構成などいろいろ面倒だった記憶があります。。

いくらワンバイナリとはいえaptやyumで管理できるメリットは大きいので、できればdeb/RPMパッケージも用意したいのですが、上記のような面倒さから億劫になっていました。

NFPM

ここで見つけたのがNFPMです。

github.com

NFPMはGoReleaserのorg配下にあり、GoReleaser( .goreleaser.yml )からも呼び出せるようになっています。むしろGoReleaser経由の方法を紹介します。

実際にcgrpsの設定を元に説明します。

cgrps/.goreleaser.yml at master · k1LoW/cgrps · GitHub

builds ディレクティブで id を付与する

まず、builds ディレクティブでビルド方法を指定すると思いますが、こちらで id を付与して nfpms ディレクティブで指定できるようにします。

builds:
-
  id: cgrps-linux 👈
  env:
  - CGO_ENABLED=0
  goos:
    - linux
  goarch:
    - amd64

ちょっと古い .goreleaser.yml の書き方だと id の指定は必要ありませんが、これの機会に指定しておきましょう。

nfpms ディレクティブを追加する

nfpms ディレクティブを追加します。

cgrpsでは以下のようにしています。

nfpms:
  -
    id: cgrps-nfpms
    name_template: "{{ .ProjectName }}_{{ .Version }}-1_{{ .Arch }}"
    builds:
    - cgrps-linux 👈
    homepage: https://github.com/k1LoW/cgrps
    maintainer: Ken'ichiro Oyama <k1lowxb@gmail.com>
    description: cgrps is a set of commands for checking cgroups.
    license: MIT
    formats:
      - deb
      - rpm
    bindir: /usr/bin
    epoch: 1

詳しくは GoReleaserのNFPMの設定のドキュメント をご覧ください。

nfpms.builds には、先ほどの builds.id を指定します。

UbuntuCentOSで利用するdeb/RPMパッケージであれば、Linux用にコンパイルする設定を書いた builds.id を指定することになると思います。

goreleaserコマンドを実行

設定は、これで終わりです。

試しに以下のコマンドを実行すると dist/ ディレクトリにdeb/RPMパッケージが作成されていると思います。

$ goreleaser --snapshot --skip-publish --rm-dist

あとはいつものように goreleaser コマンドを実行することでリリースが完了します。

NFPMでは何をしているのか?

では実際にNFPMでは何をしているのか気になったので、ソースコードを見てみました。

愚直にspecファイルを書いてrpmbuildコマンドを叩いていました *1

ある意味安心な実装でしたので、みなさんも是非ご利用ください。

*1:なので、実はMacではbrew install rpmが必要です

tblsがデータソースとしてCloud Spannerに対応した

約1,000円の資金を投じて作りました。

Cloud Spannerのスキーマをtblsで出力するとどのようになるのか

例えば、 https://github.com/k1LoW/tbls/blob/master/testdata/spanner.sqlSQLで作成したデータベーススキーマから以下のようなドキュメントが生成されます。

https://github.com/k1LoW/tbls/tree/master/sample/spanner

使い方

tblsの他のRDBMSと使い方は変わりません。Cloud SpannerのDSNは

spanner://[ProjectID]/[InstanceID]/[databaseID]

となっています。ADCの設定がされていて( gcloud auth application-default login していて)、データベースへのアクセス権限があれば、もう tbls doc でのドキュメント生成が可能なはずです。

サービスアカウントのクレデンシャルファイルがあれば、?creds=[GOOGLE_APPLICATION_CREDENTIALS] をDSNに付与する形での対応も可能です。

$ tbls doc spanner://[ProjectID]/[InstanceID]/[databaseID]?creds=spanner_client_secrets.json

Cloud Spannerの運用にtblsを利用すると何が嬉しいのか

「Cloud SpannerはGCP上にスキーマ情報を確認できるWebUIがあるので特にいらない」となるかと思います。

ただ、以下の点でCloud Spannerの運用にtblsを使うメリットがあると考えています。

1. .tbls.yml を使ってテーブルコメント/カラムコメントをドキュメントにでき、CIを回せる

.tbls.yml によるコメントの付与は、MySQLPostgreSQLといったRDBMSにおいては「 ALTER TABLE する必要なく、コメント運用ができる」というメリットをうたっていましたが、Cloud Spannerにはそもそもテーブルコメント/カラムコメントというものがないようです。

tblsであれば、 .tbls.yml の comments ディレクティブで各テーブル各カラムコメントを付与して、さらに tbls lint を使ってCIを回せばコメントの追加漏れがなくなる*1、など、スキーマの長期運用においてメリットがあると考えています。

2. .tbls.yml で設計上テーブル間をINTERLEAVEにしない判断をしたが、実は存在するテーブル間の関係をドキュメントにでき、CIを回せる

tblsではINTERLEAVEで親子関係になっているテーブルについて、リレーションがあると判断してその情報をドキュメントに追加します。

INTERLEAVEについては以下のドキュメントをご覧ください。

cloud.google.com

一方で、何かしらの理由でINTERLEAVEで親子関係にはしていないものの、論理的にはテーブル間に関係があるということはあります。

tblsはそれらについても .tbls.yml の relations ディレクティブでテーブル間の関係をドキュメントに追加できます。そして tbls lint を使ったチェックが可能です*2

これもMySQLPostgreSQLといったRDBMSにおいては「外部キー制約がないがテーブル間の関係があるということをドキュメント化できる」というようにメリットをうたっていたのですが、Cloud SpannerのINTERLEAVEの特性をみると外部キー制約よりも積極的にインターリーブ しない という選択がありそうなので、「制約はないけど実は関係がある」というような情報を付与するのにtblsはメリットがありそうです。

というわけで

Amazon Redshiftに続き、Cloud Spannerもちゃんとプロダクションで使ったことがないので是非フィードバックが欲しいと考えています。

既にCloud Spannerをガンガン使っている皆さま、是非使ってみてください。

*1:コメントがないカラムやテーブルに対してチェックができる requireTableComment や requireColumnComment があります

*2:リレーションのないテーブルをチェックできる unrelatedTable があります

google/gopacket + libpcap で作るツールのパケットバッファ戦略

tcpdpの中のお話です

パケットを一時的に保持するバッファ

google/gopacket/pcap パッケージでパケットを取得するようなツールを作る場合、2つのバッファを持つことになります。

  1. libpcapが持つバッファ
  2. google/gopacketが持つバッファ(バッファ付きチャネル)。1000で固定。

パケットは加工されつつ上記のバッファを経由して、最後にgopacketからパケットを受けとることになります。

そしてバッファには、以下のような特徴があります。

  • libpcapが持つバッファが溢れたらパケットロスが発生します
  • gopacketのバッファサイズは固定です
  • libpcapは ImmediateMode がOFFだと、libpcapが持つバッファにある程度パケットを貯めてからまとめて返します

上記特徴からみても、ツールが正しく動くようにするためには いかにlibpcapのバッファを溢れさせないか が重要になってきます。

パケットロスを回避する戦略

そして、取れる戦略(とその戦略をとった場合のデメリット)は2つです。

  1. libpcapが持つバッファを大きくする ( bufferSize の調整 )
    • デメリット: bufferSize の分、最初に確保されるメモリ量が大きくなる
  2. libpcapからできるだけ早くパケットを回収する ( 例えば、immediateMode の有効化
    • デメリット: immediateMode が無効状態よりもCPUリソースを消費する

例えば tcpdp の場合、gopacketからパケット取得した後の、「パケットを加工して構造化ログに吐き出す機構」がボトルネックになります。まあ、そうですよね。

つまり、libpcap -> gopacket -> tcpdp の最後の処理に一番時間がかかります。パイプラインの最後の出口が詰まってしまう感じです。

これはもうどうしようもなさそうではあるのですが、もし

  • パケットの流量に波がある
  • パケットのピーク流量が一定時間発生しかなくて、それさえ耐えれば、以降の通常のパケット処理は十分処理可能である

と予想されるのであれば、「ツール内にlibpcap、gopacketに続く3つ目のバッファを持って、そのバッファに処理待ちパケットを溜め込む」という選択肢が取れます。 つまり戦略2です。

f:id:k1LoW:20190813115633p:plain

tcpdpだと internalBufferLength というパラメータで指定するのですが、これは単なるバッファ付きチャネルです。

図で言うとlibpcapからガンガンパケットを回収して、早々にtcpdpのバッファに溜めてしまいます。

そして、そのバッファに溜まったパケットを逐次処理していきます。tcpdpのバッファが溢れるまではパケットロスが生まれないという仕組みです。

まとめ

google/gopacket + libpcapで作るパケットのバッファリングの仕組みと、パケットロスを発生させないようにするバッファ戦略について紹介しました。

正直、結構戦略としては苦しいものなのですが、tcpdpだとパケットはシーケンシャルに処理しないといけなかったりするのでいまのところこのような実装になっています。

何かもっと良い方法があれば教えてください。

tail -F /path/to/access.log のようなストリームに対して何度でもgrepを試行錯誤できるツール filt を作った

filtというツールを作りました

github.com

これはなに

まずは以下のスクリーンキャストをご覧ください

f:id:k1LoW:20190730230540g:plain

tail -F /path/to/access.log のようなログの流れを止めてはgrepをして、止めてはgrepのコマンドを変更してしています。

その間、実は裏では実際のストリームは止めていません。

つまり、ストリームのパイプ先に まずfiltを指定しておく ことで、ストリーム自体は止めずに、パイプ先のコマンドを 後で何度でも 変更できます。

grepsedawkが下手なので何度も試行したい

私はgrepsedawkなどのコマンドを一発で指定できるほど練度が高くないので、コマンドを組み立てるために何度も Ctrl+C でキャンセルしては再実行の繰り返しをしていました。

最近は sternHarvest などでKubernetesのPodのログを流すことをもあるのですが、ログが流れ出すまでちょっと時間がかかります。それに対して毎回キャンセルして再度コマンド組み直しというのは結構ストレスです。

filt を使ってこの試行錯誤の敷居を下げることで、手早くコマンドを組み立てられるし、カジュアルにコマンドを組み立て直すこともできます。

そして、「まずはログを流しておく」「いろいろフィルタしてログをみる」というログを見る良い習慣にもつながると考えました。

使い方

MacでのインストールはHomebrewが利用可能です。

$ brew install k1LoW/tap/filt

filt コマンドが使えるようになったら、あとは、tail -F などのストリームにパイプでつなげるだけです。

$ tail -F /var/log/nginx/access.log | filt

上記のように直接パイプで filt を指定するのがオススメです。

流れているログに対して「grepでフィルタリングしたいな」と思ったら EnterCtrl+C を押します。すると、ログの流れが止まりプロンプトが出て入力待ち状態にになります。

そのプロンプトに grep -v GET などのコマンドを入れて Enter を押すと、今度は tail -F /var/log/nginx/access.log | grep -v GET でフィルタリングされたログをが流れます。

もう一度フィルタするコマンド入れ替えたいときは、またEnterCtrl+C を押すことでログの流れが止まりプロンプトが出てきます。

これの繰り返しです。

tail -F なストリーム自体を終了したいときはプロンプトが出ているときに exit と入力して Enter を押すか、 Ctrl+C を押してください。

filtを作ってから

私が「まずはログを流しておく」ようになりました。

Ctrl+C を押したらまた最初からログが流れてくるのを待たないといけないのか」というような心理的な障壁もないので、カジュアルにコマンドを組み立てなおして、「今欲しい情報だけが流す」ようになりました(それまでは目で一生懸命眺めることがあった)。

以前作ったevryなども指定できます。

k1low.hatenablog.com

結構、開発体験が変わるのでおすすめです。是非使ってみてください。

Songmu/timeoutからコマンドの停止処理部分を理解しつつ切り出してk1LoW/execを作っている #gocon

Go Conference'19 Summer in Fukuoka、私の中でもう少し続いています。

exec.CommandContext は "孫プロセスがあった場合にそれが止まらない"

songmuさんの発表は聞きたいなと思っていたのですが、40分間これでもかと知見が込められた発表でした。ツール作るマンとしてはいろいろ心に留めておきたいことばかりでした。

その中でも「コマンドを停止する」の章は、実はスライドレベルでいうと2回目なのですが(ヒント: Go Conference 2019 Spring)、やはり直接聞くと「ごめんなさいごめんなさい」という気持ちになりました。

というのも、私はよく以下のように exec.CommandContext を書くのですが、

cmd := exec.CommandContext(ctx, "bash", "-c", commandStr)

ctxのキャンセルに任せてしてしまって、孫プロセスになるcommandStrを放置している。。。

GoConでコマンドの停止処理について、スライド資料とともにコードレベルでしっかりと解説してもらったので、これはしっかりと書いていこうと思いました。

とはいえ、いろんなところに exec.CommandContext をばらまいてしまっている。。。

k1LoW/exec

というわけで、勉強と実益を兼ねて、os/execと同じ書き方ができつつも、孫プロセスを見捨てないk1LoW/execを作りはじめています。

github.com

使い方はos/execと全く同じです。os/execにinterfeceがあるわけではありませんが、os/execと同じメソッドは全て用意しているので、そのまま切り替えて使えます。

import (
    // "os/exec"
    "github.com/k1LoW/exec"
)

また、k1LoW/exec.Command の返り値も *os/exec.Cmd のままです。

ただ、さきほどと同じように書いても、

cmd := exec.CommandContext(ctx, "bash", "-c", commandStr)

ctxがキャンセルした時には孫プロセスのcommandStrにもちゃんとシグナルが渡ります。

つまり os/execgithub.com/k1LoW/execに差し替えれば解決!! というのを目指しています。

import "github.com/Songmu/timeout"

k1LoW/execのコマンド停止処理部分は、発表で学んだ内容 = Songmu/timeoutのコマンド停止処理部分が ほぼそのまま です。実質Songmu/timeoutをライブラリとしてimportしている感じです。

それでも書いて良かった点は、テストコードを自分なりに書いてos/execとの違いを確認したことです。

os/exec.CommandContext ではFAILになるのに、k1LoW/exec.CommandContext ではSUCCESSになるというのは「なるほどー!!」となる瞬間でした。これは発表を聞いただけの理解の時とは違いました。具体的に手を動かして良かったです。

これから

k1LoW/execでは、あと以下の2つを実現したいと思っています。

Windowsサポート

Songmu/timeoutWindowsもしっかりサポートしており、かつテストもとてもわかりやすく書かれています。これを参考にWindowsのコマンド停止処理までしっかりと移植しつつ、WindowsのテストやCIの書き方を学んでいきます。

KillAfter/KillAfterCancelのサポート

KillAfter/KillAfterCancelSongmu/timeoutにある実装です。 コマンドの停止処理のお作法であるSIGTERM -> SIGKILLの流れ を、出来るだけ今のos/execなインターフェースを崩さずに実装しようと思っています。こちらは、あとは書くだけかなと思っています。

というわけで

songmuさん、知見のつまった発表ありがとうございました。ぜひ、またお会いしましたらよろしくお願いします。

残りの実装も書いていきます。