Skip to content

cornus activity

サーバーのフライトレコードを読みます。サーバーと caretaker が何をしていたか、そして何を完了しなかったかです。

構文

sh
cornus activity [flags]

説明

デプロイに問題が起きたとき、何が起きたかを教えてくれるものは他にありません。cornus deploystatus が報告するのは 何が成り立っているかだけで、しかもランタイムがまだ覚えているものに限られます。サーバーのログは一時的で、コンテナとともに失われます。トレースはそもそも外部へ送られ、既定では無効です。

フライトレコードはそれらとは異なります。サーバーと caretaker が作業しながらデータディレクトリ配下のディスクに書き出すため、プロセス、コンテナ、そしてインシデントより長く残ります。

作業は begin/end のペア として記録されます。そのため有用な問いは「存在しないこと」で答えられます。begin があって end がないものは完了していません。

  • 終了していない プロセスのライフタイム は、クリーンにシャットダウンしなかったサーバーまたは caretaker です (SIGKILL、OOM、docker rm -f、パニック、ホストの再起動)。
  • 終了していない 9P マウント は、誰も所有していないまま残っている可能性のあるマウントポイントです。これらは次にサーバーが起動したときに自動的に解除されます。
  • 終了していない サービス は、プロセスが停止した時点でまだ動いていた監視下の子です。これらを合わせると、プロセスが停止した瞬間に何をしていたかのスナップショットに最も近いものになります。クラッシュを繰り返すサービスは、長い沈黙ではなく再起動ごとの 1 組として現れます。

起動ごとに固有のインスタンス ID を持つため、レコードは実行単位にまとまります。

server 02c22ece4a16 (exited cleanly)
  2026-07-26T03:53:19.985820864Z server    begin addr=127.0.0.1:5000
  2026-07-26T03:53:22.950323418Z server    end   [ok]

server 6c8ba5e0d63f (DID NOT EXIT CLEANLY)
  2026-07-26T03:53:23.973104203Z server    begin addr=127.0.0.1:5000
  2026-07-26T03:53:24.101339812Z 9p-mount  begin /var/lib/cornus/mounts/sess-1/m0 deployment=web

実行中のものは失敗ではなく running と表示されます。コマンドは、どのインスタンスが応答しているかを知っているためです。

フラグ

フラグ既定値説明
--server接続プロファイルリモート cornus サーバー URL。
--localオフサーバーに尋ねる代わりに、ディスクから直接レコードを読みます。
--sinceこの時刻以降のレコードのみ。RFC3339、または現在からの期間 (2h)。
--kindこの種類のみ: servercaretakerservice9p-mountbuilddeploy
--unfinishedオフbegin があって終了しなかったアクティビティのみ。
--follow-fオフレコードを出力し、その後も書き込まれるたびに出力し続けます。Ctrl-C で終了します。

--local が読むディレクトリは、グローバルな --data-dir / CORNUS_DATA から決まります。

レコードを追跡する

--follow は履歴を出力したあとも開いたままになり、書き込まれた各レコードをそのつど出力します。

sh
cornus activity --follow --kind 9p-mount     # マウントの発生と解除を監視する
cornus activity -f --since 5m                # 直近の履歴、そのままライブへ

履歴とライブの追跡は 1 回の読み取りから得られるため、「そこにあるもの」と「監視の開始」の間に書き込まれたものが失われることはありません。追跡する価値のあるレコードは、まさにマシンが忙しいときに書き込まれるので、これは重要です。Ctrl-C が通常の停止方法で、終了コードは 0 です。

追跡は cornus activity の 2 つの読み取り経路のどちらでも動作します。リモートでは、サーバーが GET /.cornus/v1/activity?follow=1 から Server-Sent Events をストリーミングします。長時間開いたままでほとんどアイドルな接続には、キープアライブと、中継機器がバッファリングしないメディアタイプが必要であり、SSE はその両方を定義しているためです。各レコードは 1 つの activity イベントとして届き、そのペイロードは一度きりの読み取りが返すのと同じ JSON オブジェクトです。したがって --output json --follow は、--output json で得られるのとまったく同じレコードの NDJSON フィードになります。--local の場合はファイルを直接追跡し、サーバーは介在しません。

インスタンス単位のグループ化はライブではできません。実行の判定はそれが終了して初めて分かるためです。そのため各行は、それを書き込んだプロセスとインスタンスを示します。

2026-07-26T03:53:24.101339812Z server/6c8ba5e0d63f 9p-mount  begin /var/lib/cornus/mounts/sess-1/m0 deployment=web
2026-07-26T03:53:31.884210553Z caretaker/1f2a0b7c9de4 service   begin mount-relay

--follow--unfinished は併用できません。「終了していない」はストリーム全体に対して解決されるもので、begin は対応する end が届くまでの間だけ終了していない状態です。そのためフィードとしては、次の行が偽にしてしまうレコードを出力することになり、それを取り消すものは何も出力されません。スナップショットが必要なら --follow なしで再実行するか、追跡したうえで begin/end の対応付けを自分で行ってください。

リモートからの読み取りと事後調査

既定では他のコマンドと同様に、設定されたサーバーに問い合わせます。操作する人がサーバーの動いていたマシン上にいることはほとんどないためです。

これでも事後調査の問いには答えられます。レコードは データディレクトリ 配下にあり、これは cornus のデプロイが永続化するもの (Helm chart のボリューム、コンテナ化されたサーバーのホストバインド、ホストインストールのストレージディレクトリ) だからです。つまり 後継の サーバーが前任のフライトを提供します。

sh
cornus activity --unfinished        # 直前の実行は何を残したか
cornus activity --since 2h --kind deploy

--local は、それでは対応できない唯一のケースを扱います。何も動いておらず、今後も戻ってこない場合です。

sh
# ホスト上、またはイメージの中で、サーバーを介さずに
docker run --rm -v /srv/cornus:/var/lib/cornus \
  ghcr.io/moriyoshi/cornus:latest activity --local

機械可読の出力

--output json はレコードそのものを出力するので、スクリプトやエージェントがフライトを直接読み取れます。

sh
cornus --output json activity --unfinished

各レコードはタイムスタンプ、書き込んだプロセスとインスタンス、種類とフェーズ、対象、そして end レコードでは結果を持ちます。recovered ステータスは、後続の実行がそのアクティビティを閉じたことを意味します。インシデントはクリーンな完了として書き換えられるのではなく、見えるまま残ります。

エージェントクライアントは cornus web の MCP エンドポイントから同じレコードに到達できます。ここでは activity_read ツール (since/kind/unfinished の同じフィルター) と cornus://activity/unfinished リソースが公開されています。リソースという形が重要です。これはアクションではなくコンテキストなので、クライアントは現在の未完了セットをファイルと同じように添付でき、挙動のおかしいデプロイについて尋ねられたエージェントは、直前のサーバーが飛行中に停止したことを最初から知った状態で始められます。どちらもレコードとともに liveInstance を返します。これがないと、応答しているプロセス自身の開いたままのライフタイムがクラッシュとして読まれてしまいます。追跡は CLI 専用です。レコーダーは事後に読むものだからです。

保持

ログはサイズ上限付きで、直前の世代を 1 つだけ保持します。レコーダーとして境界があるということです。上限は CORNUS_ACTIVITY_MAX_BYTES で設定します (既定 8 MiB)。

関連項目: cornus servecornus storageサーバーをコンテナで実行する

Released under the Apache-2.0 License.