# 変更履歴 バージョンは CalVer (`YY.M.PATCH`) で、番号からは破壊的変更かどうかが読み取れない。 **互換性を壊す変更は「⚠️ 破壊的変更」として各版の先頭に置く。** ## 未リリース ### ⚠️ 破壊的変更 - **64 MiB の上限をレコード全体とファイルヘッダ全体に適用する。** 以前は activity ごとの長さだけを検査し、合計や拡張チェーンで上限を超えても 受理していた。`--lenient` でもこの上限は緩めない。 変換後の出力にも同じ上限を適用し、超過したレコードを成功扱いで書き出さない。 従来の上限を迂回する受け入れに戻すオプションはない。 - **独自出力の品質に `not_finite` (`Quality::NotFinite`) を追加した。** NaN・無限大を正常値として扱わない。ライブラリで `Quality` を網羅的に match する 場合はこの分岐を追加する。生値の文字列は保持し、派生値は値なしとする。 - **`sadf -O hz=` は u32 に収まらない値を拒否する。** 以前は上位ビットが失われ、 別の周波数で変換していた。生成元の正しい HZ を `1..=4294967295` から指定する。 - **`summarize` / `compare` の `--format` を `table` / `json` / `ndjson` に限定した。** 未対応形式でも表を成功扱いで返していた。以前の `sadf-json` 指定は `json` に、 表が必要な場合は `table` に置き換える。 - **`show` の互換形式では `--timezone` / `--utc` を拒否する。** 指定を外すと、表示・絞り込みとも `sar` はローカル時刻、`sadf-*` は UTC になる。 タイムゾーンを選ぶ場合は独自の `table` / `json` / `csv` / `ndjson` を使う。 - **TUI の終了キーを `q` から `Esc` に変更した。** 通常画面で `Esc` を押すと終了する。 選択画面・ヘルプ・絞り込み入力中の `Esc` は通常画面に戻る操作のまま。 `Ctrl-C` でも従来どおり終了できる。`q` に戻すオプションはない。 - **`detect` の既定テキストを、優先度順の最大5系列・各3件の時刻に絞った。** 代表例の観測値と判定理由を添え、背景の所見は優先度順に最大3件表示する。 省略件数・比較基準の留保・評価不能理由は残す。全件の詳細は `--verbose`、 全フィールドは `--format json` / `--format ndjson` で取得できる。 - `detect` の日本語を見直し、「根拠の充足度」を「判断に使えるデータ」、 「評価の網羅度」を「評価できた範囲」と表記する。判定理由の長い文を分け、 代表例にはその検出自体の時刻を添える。JSON のキーと判定条件は変えない。 「最小有意変化量」も平易な表現に変更し、ディスク応答時間と受信パケット破棄の 説明を短い文に分けた。観測値や閾値などの数値は保持する。 - ライブラリの `OpenOptions` に `legacy_endian`、`StructSource` に `PackedLegacy` を追加した。 構造体を全フィールド指定で作る場合は `legacy_endian: None` または `..Default::default()` を加える。 `StructSource` を網羅的に match している場合は新しい分岐を追加する。既存 CLI の指定方法は変わらない。 - **`detect` の `text` を既定で要約にした。** エピソードを 1 件ずつ並べるのをやめ、 **見出しの系列ごとにまとめて**「何が何件・いつ鳴ったか」を出す。検出 1 件ごとの内訳 (系列・平均の取り方・条件の根拠文・観測値の列挙・比較基準の数値) と、検出パターンごとに 固定の「考えられる解釈」も本文から外した。**従来どおりの全文は `--verbose`** で出る (出力は以前と 1 文字も変わらない)。`--format json` / `--format ndjson` は 指定によらず全フィールドを出すので影響を受けない。 実測で **1 日分の実ファイルが 3019 行 → 244 行** (111 エピソード / 23 系列) - 落としたのは**繰り返しだけ**である。比較基準の出所・評価の網羅度・注意は要約でも出る。 系列ごとのまとまりには、**その系列で鳴った時刻・回ごとの優先度・採取回数**が並び (8 件を超えたら件数を出して打ち切る)、**同時に別の系列が鳴ったエピソードは `+N 系列`** として残る。「この所見では確かめていないこと」はエピソード本文から外したが、 **指標ごとに 1 度だけ末尾へ集約して必ず出す** (エピソードが 111 件あっても 1 度)。 系列に固有の留保 (中央値そのものが固定条件の内側、基準が異変側へ寄っている疑い) も 要約に残る ### ⚠️ 破壊的変更 (続き) - **`detect` の出力言語を実行環境から決めるようにした。** これまでは常に日本語だった。 **日本語のままにするには `--lang ja`** を付けるか、`LANG=ja_JP.UTF-8` のような ロケールを設定する。判定の順は `--lang` → `RESARCH_LANG` → `LC_ALL` / `LC_MESSAGES` / `LANG` → `LANGUAGE` → ローカルタイムゾーン (日本なら日本語) → 英語。 **ロケール環境変数はタイムゾーンより強い** (ロケールは「どの言語で読みたいか」の 宣言そのもので、タイムゾーンは「どこにいるか」でしかない)。 `LC_ALL=C` は `LANGUAGE` より強く、英語で確定する (スクリプトが決定的な出力を得る慣行) - **ライブラリとして使っている場合、表示文字列の API が変わった。** CLI だけを使うなら 影響しない。`Priority::label` / `SufficiencyLevel::label` / `SufficiencyBasis::label` / `NotEvaluated::label` / `ObservationOrigin::label` / `MeanBasis::label` / `Pattern::label` / `DetectRoute::label` / `BasisOrigin::label` / `Dispersion::label` / `FixedComparison::label` は **`&'static str` ではなく `Text` (日英の対) を返す**。 `.get(lang)` を挟めば従来の文字列が取れる。 `SufficiencySpread::label` / `RouteStatus::label` / `ReportBoundary::label` / `ShiftDirection::as_str` / `TemporalSupport::describe_span` / `describe_duration` / `describe_detection` / `boundary_phrase` / `SeriesEvaluation::{observed, excluded, absent}` は **引数に `Lang` が増えた**。`CatalogEntry` の `label` / `interpretations` / `not_established` / `FixedCondition::rationale` も `Text` になった - `DetectOptions` に `lang` フィールドが増えた (`..Default::default()` で組んでいれば 英語になる)。`Assessment` は組み立てに使った言語を `lang` で持つ ### 追加 - **`report` で対話的な HTML レポートを保存できる。** `resarch report sa01 sa02 -o report.html` で生成し、ブラウザでホスト・起動区間・ 指標と時間範囲を選べる。グラフのドラッグで拡大し、検知一覧から前後30分へ移動できる。 複数指標の時間軸をそろえ、採取値の確認、欠測理由、全期間集計、評価不能の内訳も表示する。 外部通信やサーバは不要。指定したタイムゾーンで表示し、既存ファイルは上書きしない。 `--activity` で埋め込むデータを絞れる。既存の SVG 出力は維持する。 - **独自出力の `A_MEMORY` に、`MemAvailable` を使わない旧来の見積もりを 4 列足した。** `memused_pct` の直後に並び、独自出力 (`show` / `summarize` / `compare` / TUI) に出る。 互換出力 (`sar` / `sadf` / `sa2sar`) には出ない - `kbmemused_nocache` (kB) … `kbmemtotal − kbmemfree − kbbuffers − kbcached`。 空き・buffers・cache の合計が総量を超えて負になるときは 0 - `memused_nocache_pct` (%) … `kbmemused_nocache / kbmemtotal × 100` - `kbmemfree_withcache` (kB) … `kbmemfree + kbbuffers + kbcached`。総量で頭打ちにしない - `memused_withcache_pct` (%) … `(kbmemtotal − kbmemfree) / kbmemtotal × 100`。 sysstat 11.7.4 より前の `%memused` と同じ式 - 入力の 4 項目は旧世代のファイルにもあるので、`kbavail` を記録しない世代 (RHEL / CentOS 7 の sysstat 10.1.5 など) でも値が出る。式は世代で変えない - **`kbavail` の代わりではない。** 空きの正確な見積もりは `kbavail` (カーネルの `MemAvailable`) で、`kbmemused` / `memused_pct` はこれまでどおり `kbavail` から求める。 `kbavail` の無い世代では独自出力で値なしのままで、新しい列の値では埋めない。 buffers と cache を除く見積もりは `MemAvailable` が無かった時代の近似で、`Cached` に 含まれる共有メモリ・tmpfs まで空きとして数え、回収できる slab を数えない - `detect` と `summarize` の判定には使わない。`kbavail` の無い世代では、 `summarize` の `memory-available-low` も `detect` の `%memused` の固定条件も、 従来どおり評価できないと報告する - 読み方は `docs/usage.ja.md` の「メモリの使用量をどう読むか」 - `skill-install` で配布する AI 向けスキルで、言語指定に対応するコマンドの `--lang en` を必須にした。JSON / NDJSON も対象とし、実行例にも明記した。 スキル自体の説明・本文・実行例のコメントも英語に統一した。 - **`make sar-upstream-all` を追加した。** 公式 Git 133版と回収した旧ソース48版の 計181ケースを固定 manifest で管理し、版ごとのイメージ作成・採取・同版 sar 描画・ reSARch の EOF 検証と描画を自動実行する。ハッシュ検証、再開、失敗後の継続に対応。 manifest 更新スクリプトで新規の公式リリースも追加できる。 181件すべての実採取・末尾一致・描画を確認し、sa / 同版sarテキスト / 来歴 / SHA-256を Git管理に追加。収録した全181ファイルを通常の `cargo test` でも走査・デコードする。 EOF一致だけで成功にせず、未知activityの読み飛ばしも失敗として検出する。 - **sysstat 11.7.1 のactivity magic更新漏れに対応した。** 原典と翌版を比較して確認した 17種類を、生成版と形式が一致する場合だけ正しい配置へ対応付ける。独自出力・集計で 統計を読み取れるようにし、現行sar互換出力は本家の表示規則を維持する。 - **登録済み28形式すべてに読み取り経路を追加した。** sysstat 6.1.1〜6.1.2 の `0x2168`、旧モノリシック22形式、sysstat 2.2 の選択列形式を含む。 原典の配置を実測し、旧24リリースの実採取と両ABI・エンディアンの独立 fixture で検証。 欠落・単位不明の値を取得不可にし、古いカーネルの PAGE / IO を現代の単位で誤表示しない。 保存されないABI・時刻情報の仮定と、配列・指標の制限は `docs/format/09-legacy-generations.md`。 原典未入手のリリースへの対応を保証するものではない。 - **CentOS 3.9/4.9 (`0x2163`)・5.11 (`0x2169`) の sa 読み取りに対応した。** モノリシック形式を直接デコードし、各採取ファイルの exact EOF と統計値を検証。 既存の表示・集計経路を使い、未記録フィールドは取得不可として保持する。 CPU 別 IRQ の旧配列と PID 付きパイプ入力はデコード対象外。 `0x2163` の long 幅は既定 8 バイト(ライブラリの `OpenOptions.legacy_long_bytes` で 4 を指定可能)。 自動採取でもこの 3 ケースの走査・描画を検証する。 - **`make sar-all` で記録済みの全20ケースを自動採取できるようにした。** 既存5ディストリビューション・sysstat公式リリース4世代に、CentOS Vaultの11ケース (3.9〜8.5、6.5 / 7.5を含む) を追加。`make sar-centos` でCentOSのみ実行できる。 `sa` / 本家 `sar` テキスト / 来歴 / SHA-256 / ケース別ログを保存し、 採取失敗とreSARchの読み取り未対応を分けて一覧化する。 - **`--sar-profile sysstat-10.1.5-el7` で RHEL / CentOS 7 の `sar` の出力を再現できるようにした。** `sa2sar` と `sar` 互換入口で使える。RHEL 7 のホストの `sa2` が書いた `sarDD` と バイト単位で一致する (実ホストの 29 日分で確認) - これまでは常に本家 12.8.0 の書式で出していたため、CentOS 7 のレポートとは列 (`-B` の `%vmeff`、`-d` の `rd_sec/s … svctm`、`-R` ブロックなど) も、 値の求め方 (CPU `all` 行、平均の整数除算、オフライン CPU の扱い) も一致しなかった - **既定は変わらない** (`current` = `sysstat-12.8.0`)。版はファイルから自動では選ばない - 読めるのは `format_magic` 0x2171 のファイルだけ (本家 10.1.5 と同じ) - `sar` 互換入口では文法も el7 になる (`-h` はヘルプ、`-R` がある、`-I XALL` / 番号指定)。 10.1.5 に無いオプションは usage エラー - `-R` のページ換算に使うページサイズは `--sar-page-size` (既定 4096) で指定する。 ファイルに記録されない値のため - `sadf` はプロファイルを持たない。指定すると出力する前にエラーにする - 仕様と検証手順は `docs/format/05-sysstat-10.1.5-el7.md` - **本家 `sar` が読む環境変数 2 つに対応した。** 互換出力 (`sar` / `sa2sar` / `show --format sar`) だけに効く - `S_TIME_FORMAT=ISO` … バナー行の日付を `MM/DD/YY` から `YYYY-MM-DD` にする。 本家と同じ完全一致判定なので `iso` のような綴りは効かない。 時刻側は本家では `%X` → `%H:%M:%S` に変わるが、reSARch はロケールを持たず 元から `%H:%M:%S` なので差が出ない - `S_REPEAT_HEADER=` … 列見出しを出し直すまでの行数。 **標準出力が端末でないときだけ**見られる (本家と同じ `else if`)。 端末のときは代わりにウィンドウの高さ (`rows - 2`) を使う - `sadf` には効かない。本家が `sadf` で `S_F_PREFD_TIME_OUTPUT` を立てないため - `detect --verbose` を追加した (上記の全文表示) - **`detect` を日本語 / 英語の 2 言語に対応させた。** 指標名・検出の説明文・ 考えられる解釈・確かめていないこと・評価の網羅度・注意まで、 `text` と SVG のすべてを訳してある。`--lang ja` / `--lang en` で明示指定できる - `detect --format json` / `--format ndjson` のエピソードに `headline_series` と `headline_metric_label` を足した。どの検出が見出しになったかを、 見出し文字列を解析せずに取れる - **TUI に時系列グラフ。** 表の上に、選択中の activity / item / 列の 1 系列を折れ線で 描く。線は不連続と欠測のところで切れ、飛び越えて結ばない (その間を観測していないため)。 1 点も描けないときは空の軸ではなく理由を出す。表で選んでいる時刻には赤い縦線が立ち、 グラフに出している列は表の見出しも線と同じ色になる - **TUI の列操作。** `c` で表に出す列とグラフの列を選ぶ。全時刻で値が出なかった列は 既定で表から外し、外した数をタイトルに出す (黙って消さない)。`[` / `]` でグラフの列を 送る (表に出ている列だけを辿る)。`shift` + `←` / `→` で表を横に送り、 タイトルに `9-18/23 列` と位置を出す - TUI の列幅を、列名の長さではなく**全サンプルの値の桁**で決めるようにした。 値が短い列が無駄に幅を取らなくなり、行をスクロールしても幅が揺れない ### 変更 - **TUI の MEMORY タブの既定グラフを「メモリ使用率の比較」にした。** 使用率の 3 つの 見積もりを 0〜100% の同じ軸に重ねる (題名は `A_MEMORY / - / メモリ使用率の比較 (percent)`) - 「buffers/cache を除く」(`memused_nocache_pct`、シアン)、「MemAvailable 基準」 (`memused_pct`、緑)、「buffers/cache を含む」(`memused_withcache_pct`、マゼンタ)。 「含む」と「除く」の差が buffers と cache の分、「除く」と「MemAvailable 基準」の差が 共有メモリ・tmpfs・回収できる slab などの影響になる - 凡例は色付きの印と名前でグラフ枠の上辺に出す。幅が足りなければ短い名前 (除く / MemAvailable / 含む) にし、それでも入らなければ下辺の左へ移す - 値の無い系列は線を引かず、凡例に灰色で理由を添える。全時刻で「その世代に無い」なら 「(記録なし)」(`kbavail` を記録しない世代の「MemAvailable 基準」がこれ)、 欠測など別の理由が混じるなら「(値なし)」。0 の線も代わりの値も描かない - 表の見出しは、グラフに線を引いている列がそれぞれ線と同じ色になる - `[` / `]` の巡回の先頭に比較グラフが入る。`]` で単一列のグラフへ進み、`[` で戻る。 `c` の一覧でカーソルを動かして確定するとその列だけのグラフになり、 動かさずに確定すれば比較グラフのまま - `?` のヘルプにも 3 系列の読み方と、`kbmemfree` が小さいだけではメモリ不足と 言えないことを足した - **TUI の MEMORY タブで、表の下 (キーヒントの上) に新しい 4 列の説明を出す。** 列ごとに「何を空き (または使用中) と数えた値か」と式を 1 行で書き、最後に 「どれも buffers/cache を一律に扱う近似で、正確な空きは `kbavail`」と添える - 列名は表の見出しと同じ表記で、グラフに線を引いている列は線と同じ色になる。 `c` で表から外した列の説明は出さない - 幅が足りなければ全行を短い版にそろえ、それも入らなければ「列の説明は ? のヘルプ」の 1 行にする (説明を途中で切って列名との対応を崩さない) - 説明を並べると表が 5 行を切る低い端末では 1 行の要約に畳み、それも入らなければ出さない - `?` のヘルプにも列ごとの式を載せた - **`show --format table` と TUI の表で、メモリの列が 4 つ増えて並びが変わる。** 上記の派生列が `memused_pct` の直後に入り、`kbbuffers` 以降が右へずれる。 JSON / NDJSON はキーが増えるだけ、CSV は縦持ちなので行が増えるだけでヘッダは変わらない。 互換出力は変わらない - **TUI のキーから大文字を廃止した。** `g` / `G` → `home` / `end`、 表の列選択 `C` はグラフの列選択 `c` に統合。`shift` の有無で別の操作になると、 打ち間違いが「別の機能が動く」形で出るため - TUI のグラフの X 軸の目盛りを、画面幅に入るだけ刻むようにした (表示範囲が 1 時間を超えたら秒を落として `HH:MM` にする) - Windows 版の `skill-install` が書き出す `SKILL.md` の改行を、ほかの OS と同じ LF にした (これまでは CRLF)。Claude Code / Codex の読み込みには影響しない - ソースから入れたときの `make uninstall` は、`INSTALL_PATH` のバイナリだけを消すようにした。 `make install` が書き出したスキル (`~/.claude/skills/resarch` など) は残るので、 要らなければ手で消す。スキルの置き場所はエージェントごとに違い、別の方法で入れた reSARch のスキルまで消してしまうため ### 修正 - `0x216c`〜`0x216f` のコメントで、終端 NUL と後続の格納領域を本文に含める問題を修正した。 コメントは最初の NUL または63バイトまでとし、互換6形式で余分な文字を出さない。 - activity 配列を持つ旧形式で、16以上の未知レコード種別を誤って拒否する問題を修正した。 旧形式の規則に従って統計として読み、自己記述形式では従来どおり拒否する。 - SVG の `-O oneday` で、軸の先頭から24時間を超える観測を落とす問題を修正した。 本家と同じく24時間を最小長とし、長い入力では最後の選択済みサンプルまで描く。 - 再起動で CPU 数が変わるファイルを集計するとき、起動区間の CPU 数と 実行待ちタスクの判定に RESTART の申告値を反映する。 - `sadf -g` の positional の間隔・件数指定が無視される問題を修正した。 軸とデータ点の両走査に適用し、間引いたサンプルをレートの差分基準にしない。 件数は起動区間ごとに数え直し、再起動をまたいで線をつながない。 - ライブラリのゲージの持ち越し・線形補間で、NaN・無限大を補完元に使う問題を修正した。 除外理由のある値も候補にせず、使える観測値が無い区間は値なしとして返す。 - ゲージの線形補間で、奇数秒の区間の中点を整数秒に切り捨てる問題を修正した。 epoch の大小によらず、1 秒区間でも中点の 0.5 秒を保持する。 - 旧形式の IRQ 件数が RESTART 後に増える入力で、変換時に増加分を落としていた問題を修正。 全レコードの最大件数を変換後の列数に使い、不足する列は従来どおりゼロで埋める。 現行形式の列数上限 4096 を超える入力は、出力前に拒否する。 - `detect` の偶数標本の中央値と、独自集計・継続判定・ホスト比較・検出根拠の平均が、 有限な極端値の中間加算・乗算で無限大になる問題を修正した。 中央値は最小の非正規化数も保持し、平均は通常値の演算順を維持する。 - 時間重み付き分位点が、2^53 を超える重みの丸めで別の標本を選ぶ問題を修正した。 宣言した分位の十進表記から整数順位を求め、重み0の標本は順位に含めない。 - 独自のディスク派生値でも、説明できないカウンタ逆行を欠落として扱う。 合計は u128 で保持し、互換出力の折り返し演算は維持する。 - 区間長0のゲージは瞬時値として保持し、前後の継続判定の接続や比較の時間重みに使わない。 - TUI の item・列選択を開いたまま端末を縮めてもパニックしない。 極端な epoch の1秒差を保持し、軸ラベルの加算をあふれさせない。 極端な有限値は描画座標を縮尺変換し、Y軸の目盛を元の単位の指数表記で示す。 - `sadf -c` で、0x2173 の未知 activity・未知 magic の件数が RESTART 後に変わっても、 レコード内件数を前置して読み戻せるファイルを生成する。 正の CPU 数が不明な RESTART は、無効な CPU 数0を書かず変換エラーにする。 - `sadf -x` の文字列に XML 1.0 の禁止文字が含まれる場合は置換文字にし、 タブ・改行・復帰は文字参照で保持する。 - 独自出力・集計の経過時間0のカウンタ区間を `non_positive_elapsed` として除外する。 再起動を跨ぐ独自出力の `elapsed_cs` も0に揃える。瞬時値は保持し、互換出力の 0csを1csに補完する規則は維持する。 - 日を跨ぐ入力でも日内の `--from` / `--to` を毎日適用する。夏時間の巻き戻りで 窓へ入り直す場合も、窓外の時間を含む差分を集計しない。 - Unix の独自出力で POSIX 形式・空文字の `TZ` を無視していた問題を修正した。 - activityヘッダの申告ストライドの末尾が切断されている場合、未知領域でも拒否する。 - 旧形式の稼働時間換算は中間積の桁あふれで値を失わない。変換先に収まらない場合は 時刻0を書かずエラーにする。 - 起動時刻・時刻差・比較バケット・SVGの日境界で極端な時刻の桁あふれを防ぐ。 暦へ変換できない互換出力の時刻は1970年へ置き換えず元のepoch秒で示す。 - `tui --lenient` の不完全な入力を画面と診断に明示し、終了コードを非ゼロにする。 - `extra_desc` の本体が途中で終わった場合、切り詰めエラーに実際に残っている本体の バイト数を表示する。以前は残りがあっても常に 0 と表示していた。 - `detect` でデバイスの消失・再出現による系列内の観測の穴が、無関係な系列の エピソードまで分割していた。全系列に及ぶ不連続は、再起動などの根拠がある場合に限定した。 - `detect` の報告範囲で epoch 秒と日内時刻を混在させた場合の範囲外判定と、 夏時間の切り替えで存在しない時刻・繰り返す時刻を含む区間の重なり判定を修正した。 - `detect --baseline-scope window` で、範囲外に採取された瞬時値が比較基準に混ざらないようにした。 判定手順の変更に伴い、検出器の版を `resarch-detect/2` に更新した。 - **`compare --host NAME=DIR` が複数ホストのデータから先頭だけを選び、残りを黙って捨てていた。** ホスト名・OS・アーキテクチャの異なるグループが混在する場合はエラーにし、 ホストごとに入力を分けるよう案内する。 - **`compare` の JSON / NDJSON に、比較した起動区間と異なるカーネル版・CPU 数が出ることがあった。** カーネル更新や CPU 数の変更を含む入力では、グループの先頭ファイルではなく、 選択した起動区間のファイルから識別情報を取るようにした。 - **`sar -d` / `sadf` の `%util` と `aqu-sz` が、本家と丸め境界で 1 桁ずれることがあった。** 保存単位から表示単位へ縮める係数を掛け算 (`× 0.1`、`× 0.001`) で当てていたため。 本家と同じ割り算にした (実データで `%util` が本家 1.28 に対し 1.29 と出ていた) - **`sar` テキストの列見出しが再表示されていなかった。** `sar -A` / `sa2sar` の ような CPU ビットマップを使う出力では、本家は**既定のパイプ出力でも** 一定行ごとに見出しを出し直す。reSARch はブロック先頭の 1 回しか出していなかった。 **`sa2sar` / `sar -A` の出力に見出し行が増える** (実ファイル 29 本で 1 本あたり 平均 26 行)。値・列・行順は変わらない - 原因は本家の `lines` の数え方。ビットマップを持つ activity (`A_CPU` / `A_IRQ` / `A_PWR_CPU` / `A_PWR_FREQ` / `A_NET_SOFT`) は **印字行数ではなく `count_bits(cpu_bitmap)` を足す**。`-P ALL` と `-A` は ビットマップ全体を `~0` で埋めるので、実 CPU 数ではなく常に 8200 (`BITMAP_SIZE(NR_CPUS)` バイト × 8) になり、既定の 86400 行を 11 サンプルで 越える。本家 sysstat が同じファイルから作ったテキストと**見出しの行番号が 完全一致**することを実データで確認した - 併せて、全 item が `-z` や名前フィルタで落ちたレコードでも見出しは出すようにした (本家は item ループの前で見出しを書くため)。`Average:` ブロックの見出し有無も 本家の `dish` の持ち越し規則に合わせた - **UTF-8 として読めない引数を渡すと panic していた** (終了コード 101)。 Linux のファイル名はバイト列なので、そうしたパスも実在しうる。 独自サブコマンド (`info` / `show` / `summarize` / `detect` など) はそのまま読めるようにし、 引数を文字列として解析する `sar` / `sadf` 互換入口ではエラーメッセージを出して 終了コード 1 で止まるようにした - `sadf -g -O oneday` の 24 時間軸が `-T` / `-t` を無視して UTC 固定で切っていた。 他のラベルと同じ時刻基準で切るようにした - TUI のグラフが、その世代に無い列を初期選択して「描画できる観測がありません」に 当たることがあった。値の出る最初の列を選ぶようにした - `sadf -c` の警告 2 つが事実と違うことを書いていたので直した。変換結果は変わらない - レコード内件数 0 を書いたときの警告が「reSARch の読み取り側は 0 を拒否する」と 書いていた。実際には reSARch も本家 `sar` もそのまま読める - 構造を解釈できない activity を素通ししたときの警告が、どの場合も 「本家 `sadf -c` は exit 1 で中断する」と書いていた。中断するのは未知の ID だけで、 既知の ID の未知 magic では本家は中断せずに変換を続ける - 64bit の Windows で `S_REPEAT_HEADER` に `int` を超える値 (`2147483648` など) を 与えると、本家 (64bit の Linux) と違う間隔で列見出しを出し直していた。 C の `long` の幅を実行環境の ABI から取っていたため (Windows では 64bit でも 32bit)。 本家が動く Linux と同じく、ポインタと同じ幅で読むようにした - Windows で互換出力の「読み手のローカル時刻」が `TZ` を無視していた。`-t` を付けない `sar` の時刻とバナーの日付、`-s` / `-e` の比較、`sadf -T` の時刻、`sadf -g -O oneday` の 日の区切りが、`TZ=America/New_York` のような指定があっても OS のタイムゾーンで出ていた。 Windows の `chrono::Local` が `TZ` を読まないため。`TZ` が IANA 名ならそのタイムゾーンで 開くようにし、Linux / macOS (本家の `localtime()` と同じく `TZ` に従う) と同じ時刻にした。 `TZ` が無いときは従来どおり OS のタイムゾーンを使う。Linux / macOS の出力は変わらない ## v26.9.102 ### ⚠️ 破壊的変更 — 独自サブコマンドの時刻表示が UTC からローカルタイムゾーンへ `show` / `summarize` / `detect` / `compare` / `tui` の日時が、**実行環境の ローカルタイムゾーン**で出るようになった (これまでは UTC 固定)。 ``` 旧: 起動区間 0 2019-06-30 05:39:33Z → 2019-06-30 05:39:34Z 新: 起動区間 0 2019-06-30 14:39:33+09:00 → 2019-06-30 14:39:34+09:00 ``` **従来どおり UTC で出すには `--utc` (または `--timezone utc`) を付ける。** テキスト出力を機械処理している箇所があれば、この指定が要る。 ```bash resarch summarize sa01 --utc # 従来の …Z 表記 resarch detect sa01 --timezone utc resarch show sa01 --timezone Asia/Tokyo # 実行環境によらず固定 ``` 同じ基準が `--from` / `--to` の `hh:mm[:ss]` の解釈にも効く。 `--from 09:00` は「実行環境のローカル 09:00」になった。 10 桁の epoch 秒で指定した場合はこれまでどおりタイムゾーンの影響を受けない。 **影響しないもの**: - 互換出力 (`resarch sar` / `resarch sadf` / `resarch sa2sar`) — 本家 sysstat の 規則のまま。全文比較テストも変わっていない - 機械可読形式の epoch 秒 (`show --format json` / `ndjson` / `csv` の `start_epoch` / `end_epoch`) - `info` / `identify` — ファイルヘッダに書かれた値をそのまま出すコマンド ### 追加 - **独自サブコマンドに `--timezone `。** `--utc` はその別名で、 同時指定はエラー。タイムゾーン名は IANA 名 (`Asia/Tokyo`) で出し、特定できない 環境では数値オフセット (`+09:00`) になる - `detect --format json` / `--format ndjson` に `report_timezone`。 `--from` / `--to` をどの壁時計として読んだかを示す