MacのSSD寿命診断(S.M.A.R.T.)アプリをRust×Tauriで自作|Crucial外付け対応録
作成日:
更新日:

MacのSSD寿命診断(S.M.A.R.T.)アプリをRust×Tauriで自作|Crucial外付け対応録


🔧 論旨

長年愛用している Mac の内蔵 SSD や、Time Machine バックアップ用の外付けポータブル SSD が「今あと何 % くらい寿命が残っていて、何度で動いているのか」は、macOS 標準の「ディスクユーティリティ」をいくら眺めても「検証済み」のひと言しか出ず、具体的な消耗度までは分かりません。かといってターミナルで毎回 smartctl -a disk0 の英語の数字羅列を読むのも味気ないものです。

結論からお伝えすると、Rust 製の軽量デスクトップ基盤 『Tauri』 と smartmontools を組み合わせて 日本語版 S.M.A.R.T. 診断アプリ『smart-monitor-mac』 を AI と自作し、2 台の 27 インチ iMac と外付け SSD で実機テストを行ったことで、「通電 50,520 時間の旧 iMac で寿命が 170% と出てしまう初期値 200 仕様の罠」 と 「USB 外付け『Crucial X9 Pro For Mac』が Unknown Drive になる壁」 の両方を完全に突破できました。本記事では、Electron・Tauri・SwiftUI の実測サイズ比較から、市販の定番ソフト『DriveDx』と 1% の狂いもなく一致させた寿命計算ロジックまで包み隠さず公開します。

🔧 合わせて読みたい深まる関連情報
Crucial X9 Pro For Mac 外付けポータブルSSD (1TB / 2TB / 4TB・USB 3.2 Gen 2 最大1,050MB/s)

Crucial X9 Pro For Mac 外付けポータブルSSD (1TB / 2TB / 4TB・USB 3.2 Gen 2 最大1,050MB/s)

🔧 対象となる方
  • 愛用の Mac(とくに長年稼働している Intel iMac 等)や 外付けポータブル SSD の「本当の残り寿命(%)と温度・総書き込み量」を日本語で見やすく管理したい 方

  • デスクトップアプリを自作する際、Electron・Tauri(Rust)・SwiftUI のどれを選ぶべきか(ファイル容量・デザイン自由度・ビルド速度の違い) を知りたい方

  • USB 接続の外付け SSD で Device Model が消えて Unknown Drive になったり、Apple 純正 SSD の寿命が 100% を超えて計算されたりする技術的な原因 を解決したい方

Electron・Tauri・Swiftの容量と速度比較

今回の開発では、最初に Gemini API へ直結するダークテーマのチャットアプリ(mac-chat-app)と、続いて日本語 S.M.A.R.T. 診断アプリ(smart-monitor-mac)を Rust + Web フロントエンドの『Tauri』 で構築し、その後の一連の常駐ツール群を 『SwiftUI』 で構築して両方を使い比べました。実際に Mac 上でビルドして分かった 3 大方式のリアルな違いがこちらです。

比較項目Electron(従来型Web系)Tauri(Rust + WebKit)SwiftUI(Apple純正ネイティブ)
完成 .app の容量目安約 150MB 〜 300MB 以上約 5MB 〜 10MB(Universal時 15〜20MB)約 1MB 〜 3MB(極限まで軽量)
画面描画の仕組みChromium ブラウザ丸ごと同梱macOS標準 WebKit(Safariエンジン)を間借りmacOS純正のネイティブUI部品を直接描画
デザインの自由度◎ HTML/CSS で自在◎ CSSグラデーションやリッチな装飾が容易◯ OS標準の整った表・グラフが得意
初回フルビルド時間数十秒(npm パッケージ取得大)やや長い(数百個のRustクレートを一括コンパイル)数秒〜十数秒(単体パッケージなら爆速)
RAMDisk ビルド指定--cache 等で個別設定CARGO_TARGET_DIR 環境変数で指定--scratch-path 引数で確実に分離
質問するおじさん

ほぉ〜!同じ Web デザインの画面を作るんでも、Electron だと Chrome ブラウザを丸ごと 1 個アプリの中に詰め込むけぇ 200MB 超えの巨体になるのに、Rust の Tauri なら 5〜10MB で済むんか!でもなんで Rust の最初のビルドだけは時間がかかるん?C 言語みたいに #include が多いけぇ?

解説ナビゲーター

いいところに気づかれましたね!厳密には C 言語の見出し宣言(#include)そのもののせいではなく、Tauri がウィンドウ制御・非同期処理(tokio)・JSON 解析(serde)など 数百個の外部ライブラリ(クレート)のソースコードを初回にまとめて厳格チェック&機械語コンパイルして 1 つの実行ファイルへ静的結合するから なんです。2 回目以降は変更した差分だけなので数秒で終わりますよ!

なお、Rust のビルド中間ファイルは数 GB に膨らむため、SSD の寿命を削らないよう .zshrc(および GUI アプリから呼ぶ場合はビルドコマンド直前)に export CARGO_TARGET_DIR="/Volumes/RAMDisk/$USER/cargo-target" を指定して 16GB RAM ディスク上へ逃がすのが鉄則です(※RAM ディスクなので Mac 再起動後の初回だけはフルビルドになりますが、SSD への書き込み摩耗は完全にゼロになります)。また --target universal-apple-darwin(または Intel 機向けの x86_64-apple-darwin)で .dmg を書き出せば、別マシンの Intel iMac へそのまま持っていって動かすことができます。


通電5万時間iMacで見抜いた寿命170%表示の罠

初期値200と閾値100から導く真の残り寿命70%

現行メイン機の iMac 20,1(2020 年モデル・NVMe 接続 Apple SSD)では、NVMe 標準の Percentage Used(使用率 %)から素直に 100 - 使用率 で残り寿命を表示できました。

ところが、書き出した .dmg をサブ機の iMac 15,1(Late 2014 モデル:通電時間 50,520 時間[丸 5.7 年相当!]・電源投入 76,534 回) へコピーして起動した瞬間、なんと画面に 「推定寿命(残り):170%」 というあり得ない数字が飛び出してきたのです。

原因を解剖して市販のプロ向け定番ソフト『DriveDx』の表示(173 Wear Leveling Count: 70% OK)と突き合わせた結果、S.M.A.R.T. の正規化値(VALUE)の「満点と寿命ライン」の奥深い仕様 が判明しました。

iMac 15,1(通電50,520時間・VALUE=170)で判明した寿命計算式の3段階進化
なぜ数字がズレたのか?
170% → 85% の誤判定
失敗①・②:生値そのまま/単純200割り
  • 生値そのまま:VALUEの「170」をそのまま出し「残り170%」に破綻
  • 100丸め:100超えを100%に丸めると「5万時間使ったのに消耗ゼロ」と誤認
  • 単純割り算:新品200スタートと見て「170÷200=85%」にするとまだ甘すぎる
DriveDxと完全一致:残り70%
最終正解:限界閾値(THRESH=100)考慮式
  • Apple純正AHCI SSD(Samsung OEM等)は「開始値 200・寿命限界値(THRESH)100」
  • 実際に使える有効寿命の幅は「200 − 100 = 100ポイント」
  • 現在170なら30ポイント消費済み = 真の残り寿命は「(170−100)÷(200−100)=70%」

つまり、50,520 時間・76,534 回起動という過酷な年月を走り抜いてなお、有効寿命の 70% を残している(30% しか摩耗していない) という当時の Apple 純正採用 SSD の凄まじい耐久性が証明されると同時に、単純な割り算ではなく 「現在値から限界閾値(THRESH)までの残りマージン」 を計算しなければならないことが分かりました。

閾値欠落JSONの特例補正とリビジョン刻印術

さらに実機テストでもう 1 つ厄介な罠がありました。上記の閾値計算式((value - thresh) / (start - thresh))をコードに入れたのに、iMac 15,1 実機ではまだ「85%」のまま変わらなかったのです。

調べた結果、理由は 2 つ ありました。

🔧 🛠️ 実機移植テストで潰した2つの隠れバグ
  1. smartctl -j の JSON 出力で thresh が空になる環境への特例オーバーライド : 環境やブリッジによっては、裏側の S.M.A.R.T. 出力 JSON 内で thresh(閾値)が 0 または欠落して返ることがあります。するとプログラムが「閾値データが無いから単純な 170 ÷ 200 = 85% に戻そう」とフォールバックしていました。そこで 「Apple 製 SSD かつ正規化 value > 100 の属性(ID 173 等)で thresh が未取得の場合は、仕様上の閾値 100(開始値 200)を強制適用する」 オーバーライド処理を入れたことで、確実に 70% と算出されるようになりました。

  2. 同名 .dmg の上書きミス・キャッシュを防ぐ「リビジョン番号の常時表示」 : 2 台の Mac 間で smart-monitor-mac.dmg を何度もやり取りしていると、ファイル名が同じせいで古いバイナリを開いてしまい「プログラムの問題なのか、古いアプリを見ているだけなのか」が切り分けられなくなります。配布ファイル名(_0.1.2_x64.dmg)だけでなく、アプリのウィンドウタイトルバー自体にも必ず v0.1.2 (Rev.3) のようにリビジョン番号を刻印する のが、個人開発で時間を溶かさない鉄則です。


外付けCrucial SSDの名前消失と寿命取得突破

Thunderbolt接続とUSB接続の決定的な壁

内蔵 SSD の次は、外付けポータブル SSD の健康診断です。ここで 「Thunderbolt 接続」と「一般的な USB 接続」の間には、macOS ドライバ上の決定的な壁 があります。

  • Thunderbolt 3 / 4 接続の外付け SSD(例:『SanDisk Professional PRO-G40』): Thunderbolt は中身が PCIe バス直結(トンネリング)のため、macOS からは内蔵 NVMe SSD とまったく同じように認識され、特別な工夫なしで製品名・温度・総書き込み量・残り寿命のすべてがスッと読み取れます。
  • USB 3.2 接続の外付け SSD(例:『Crucial X9 Pro For Mac』): macOS 標準の USB マスストレージドライバはセキュリティと互換性の都合上、S.M.A.R.T. コマンドの通り道に厳しい制限をかけています。また USB 変換ブリッジチップの仕様によっては完全にブロックされる機種もあります。
SanDisk Professional PRO-G40 SSD 4TB / 2TB (Thunderbolt 3 & USB 3.2 Gen 2 両対応)

SanDisk Professional PRO-G40 SSD 4TB / 2TB (Thunderbolt 3 & USB 3.2 Gen 2 両対応)

USB情報からの製品名補完と属性ID202の活用

実際に iMac 15,1 の Time Machine 用に繋いでいた USB ポータブル SSD 『Crucial X9 Pro For Mac(1TB)』 を自作アプリで開いてみたところ、最初は左サイドバーの名前が Unknown Drive と表示されてしまいました。

しかし生の S.M.A.R.T. テーブルを詳しく観察すると、嬉しい驚きがありました。USB 変換チップの影響で Device Model: [No Information Found] と製品名文字列だけが空欄になっていたものの、温度や寿命データ自体は USB 経由でもしっかり届いており、下部の属性 ID 202 (Percent_Lifetime_Remain) に現在の残り寿命 99(99%)が記録されていた のです!

USB外付けSSDの『Unknown Drive』解消とマルチ属性寿命判定パイプライン
Step 1
物理ディスク列挙と名称取得

smartctlで Device Model が空欄(Unknown)の場合は、macOSの diskutil / IOKit 側から「Crucial X9 Pro For Mac」の正式名称を補完します。

Step 2
規格・メーカー別の寿命ID走査

NVMeの percentage_used に加え、Crucial系(ID 202: Percent_Lifetime_Remain)やApple/Samsung系(ID 173: Wear_Leveling_Count)を優先順位付きで抽出します。

Step 3
正規化&日本語ダッシュボード表示

200スタート・閾値100補正を通した正確な「推定残り寿命(%)・現在温度(℃)・通電時間・電源投入回数」を1画面に描画します。

smartctl単体で欠ける製品名をmacOS側のdiskutil情報で補完し、メーカー別の寿命属性IDを網羅スキャンします

Rust バックエンドの寿命算出・製品名フォールバック関数のコアロジック(エラーハンドリング・境界値クランプ済み)は以下の通りです。

// src-tauri/src/smart_parser.rs(抜粋:NVMe・Crucial ID 202・Apple OEM 200開始/閾値100対応)
use serde::Serialize;

#[derive(Serialize, Clone, Debug)]
pub struct DiskHealthSummary {
    pub device_node: String,
    pub model_name: String,
    pub temperature_c: Option<i64>,
    pub power_on_hours: Option<u64>,
    pub power_cycles: Option<u64>,
    pub remaining_life_pct: Option<u8>,
}

/// ATA S.M.A.R.T. 属性リストからメーカー別の残り寿命(%)を安全に算出
pub fn calc_ata_remaining_life(attrs: &[(u32, String, i64, Option<i64>)], is_apple_ssd: bool) -> Option<u8> {
    // 優先探索対象: 202 (Crucial等 Percent_Lifetime_Remain), 173 (Apple/Samsung Wear_Leveling_Count),
    // 177 (Wear_Leveling_Count), 231 (SSD_Life_Left), 233 (Media_Wearout_Indicator)
    let target_ids = [202_u32, 173, 177, 231, 233];

    for tid in target_ids {
        if let Some((_, _, val, raw_thresh)) = attrs.iter().find(|(id, _, _, _)| *id == tid) {
            if *val <= 0 {
                return Some(0);
            }
            // Apple純正AHCI SSD等で開始値が200(現在値が100超え)かつJSON上のthreshが0/欠落している場合の特例補正
            if *val > 100 || (is_apple_ssd && tid == 173) {
                let start = 200_i64;
                let thresh = match raw_thresh {
                    Some(t) if *t > 0 && *t < start => *t,
                    _ => 100_i64,
                };
                let span = (start - thresh).max(1);
                let pct = ((*val - thresh) * 100) / span;
                return Some(pct.clamp(0, 100) as u8);
            }
            // 通常の100満点開始属性(Crucial ID 202 = 99 など)
            if let Some(t) = raw_thresh {
                if *t > 0 && *t < 100 {
                    let span = (100 - *t).max(1);
                    let pct = ((*val - *t) * 100) / span;
                    return Some(pct.clamp(0, 100) as u8);
                }
            }
            return Some((*val).clamp(0, 100) as u8);
        }
    }
    None
}

この改良を入れた結果、iMac 20,1 の内蔵 NVMe、iMac 15,1 の 5 万時間稼働 SSD(70%)、そして USB 接続の『Crucial X9 Pro For Mac』(製品名も正しく表示され残り寿命 99%)のすべてが一目で診断できるようになりました。

ノルウェージャンフォレストキャット

『Unknown Drive』って出てた迷子の外付け SSD さんに、ちゃんと本当のお名前と「寿命 99% 元気でち!」っていう健康診断書がついたでちね!

解説ナビゲーター

はい!なお他社PCへアプリを配る場合は、受け入れ側にも brew install smartmontools が入っていることと、個人ビルドの未署名 .app は初回のみ Control キーを押しながらクリックして「開く」 を選ぶ点を覚えておくとスムーズですよ!

【Intel Mac増設用】Crucial iMac 27インチ(2019/2020)・ノートPC用 メモリ DDR4-2666 SO-DIMM (16GB×2 / 32GB×2)

【Intel Mac増設用】Crucial iMac 27インチ(2019/2020)・ノートPC用 メモリ DDR4-2666 SO-DIMM (16GB×2 / 32GB×2)


まとめ:愛機と外付けSSDの健康を数値で見守る

SSD はハードディスクのように異音の前兆を出さず、寿命が尽きると突然リードオンリーや認識不能になる記憶装置です。「RAM ディスクで日々の無駄な書き込み摩耗を防ぎつつ、自作の S.M.A.R.T. モニターで内蔵 SSD とバックアップ用外付け SSD の『真の残り寿命(%)と温度』を定期的にチェックする」——この習慣があれば、5 万時間を超えるベテラン Mac でも安心してデータを守り抜けます。

ご自身の Mac でも軽量な日本語 S.M.A.R.T. 診断ダッシュボードを自作してみたい方は、以下のコピペ用プロンプトをご活用ください(事前準備として brew install smartmontools のみ実行しておいてください)。

🔧 🤖 『日本語S.M.A.R.T.寿命診断Macアプリ』をAIに作らせるコピペ用プロンプト

※メーカーごとに異なる S.M.A.R.T. 属性 ID や diskutil 製品名補完、境界値クランプを正確に実装させるため、必ず 『Gemini 4 Argon』(または同等以上の最上位推論モデル)を選択して実行してください。

以下の記事の設計を参考に、macOS上で内蔵SSDおよび外付けSSDの健康状態を日本語で一覧表示する軽量デスクトップアプリ『SmartMonitorMac』を作成してください(Tauri v2[Rust]またはSwiftUIのどちらでも私の環境に合う方を事前確認して提案してください)。
参照URL: https://lab.chihouzakki.com/blog/review/rust-tauri-smart-ssd-health-monitor-crucial-imac-diy/

【実装ルールと安全要件(厳守)】
1. 物理ディスク一覧(/dev/disk0, /dev/disk1 ...)を自動検出し、選択したディスクについて `/opt/homebrew/sbin/smartctl` または `/usr/local/sbin/smartctl`(`-j -a`)を実行して「モデル名」「健康ステータス」「現在温度(℃)」「総書き込み量(TBW換算)」「通電時間」「電源投入回数」「推定残り寿命(%)」を美しいダークテーマの日本語パネルで表示してください(smartctl未導入時は分かりやすい導入案内を表示しクラッシュさせないこと)。
2. USB接続の外付けSSD(Crucial X9 Pro For Mac等)で smartctl 側の model_name が空欄や Unknown になる場合に備え、`diskutil info -plist` の MediaName / VolumeName から正式な製品名を自動補完してください。
3. 残り寿命(%)の算出は、NVMeの `percentage_used`(100 - used)に加え、ATA属性の ID 202(Crucial等 Percent_Lifetime_Remain)、ID 173 / 177(Apple/Samsung等 Wear_Leveling_Count)、ID 231 / 233 に対応し、特にApple純正AHCI SSDのように正規化値が100を超える(200開始・閾値100)個体では `(value - thresh) / (200 - thresh)`(thresh欠落時は100を適用)でDriveDxと同等の正確な残り寿命(0〜100%にクランプ)を算出してください。
4. ウィンドウのタイトルバーに必ずアプリのリビジョン番号(例: v0.1.2)を表示し、ビルド中間生成物はSSDを摩耗させないよう RAMDisk(Rustなら CARGO_TARGET_DIR=/Volumes/RAMDisk/$USER/cargo-target、Swiftなら --scratch-path /Volumes/RAMDisk/$USER/swift-build/...、未マウント時は /tmp)へ出力してください。

大切なデータと愛機のストレージ寿命を賢く見守って、安心・快適な Mac ライフを続けていきましょう!

大切なデータの詰まった外付けSSDを頼もしく見守るノルウェージャンフォレストキャット

▲ 5万時間走ったベテランSSDも外付けSSDも、健康診断でバッチリ安心!