@rescript-tauri/plugin-log

Tauri 2.x ロギングプラグイン の ReScript バインディング。5 つのログレベル (error / warn / info / debug / trace) と、attachLogger / attachConsole 経由のログストリーム 購読を提供します。@tauri-apps/plugin-log v2.8.x の安定公開 API を 100% カバーします。

注釈

本パッケージは main ブランチで機能実装が完了しています。初回 npm 公開は 他のパッケージと同タイミングで予定されています。それまでは、ソースリポジトリ経由または workspace link で利用してください。

インストール

pnpm add @rescript-tauri/plugin-log @tauri-apps/plugin-log

@rescript-tauri/plugin-log@rescript-tauri/core@tauri-apps/plugin-log の両方を peerDependencies として宣言しているため、上流の各バージョンを呼び出し側で管理できます。

rescript.jsondependencies に本パッケージを追加します:

{
  "dependencies": [
    "@rescript-tauri/core",
    "@rescript-tauri/plugin-log"
  ]
}

Rust 側ではプラグイン crate を追加し、builder に登録します。tauri_plugin_log::Builder でレコードを受け取る sink (stdout / webview コンソール / ローテーションログファイル) とグローバルレベルフィルタを選択できます:

# src-tauri/Cargo.toml
[dependencies]
tauri-plugin-log = "2"
log = "0.4"
// src-tauri/src/main.rs
use tauri_plugin_log::{Target, TargetKind};

fn main() {
    tauri::Builder::default()
        .plugin(
            tauri_plugin_log::Builder::new()
                .targets([
                    Target::new(TargetKind::Stdout),
                    Target::new(TargetKind::Webview),
                    Target::new(TargetKind::LogDir { file_name: None }),
                ])
                .level(log::LevelFilter::Info)
                .build(),
        )
        .run(tauri::generate_context!())
        .expect("error while running app");
}

上記の 3 つの TargetKind バリアントが最もよく使われる組み合わせです。Stdout はホストターミナルへ出力し、Webview はレコードを転送して attachConsole が JS コンソールに反映できるようにし、LogDir はプラットフォーム固有の $APPLOG/<bundle>.log ファイルへ書き込みます。

Capability 設定

Tauri 2.x ではプラグインの権限をすべて明示的に許可する必要があります。ロギングに必要な最小セットは以下のとおりです:

{
  "$schema": "../gen/schemas/desktop-schema.json",
  "identifier": "default",
  "windows": ["main"],
  "permissions": [
    "core:default",
    "log:default"
  ]
}

log:default は本バインディングが公開するすべてのログ API (レベル関数 / attach ヘルパー / 内部の plugin:log|log IPC コマンド) をカバーします。

最小サンプル

open RescriptTauriPluginLog

let bootstrap = async () => {
  let _unlisten = await PluginLog.attachConsole()
  await PluginLog.info(
    "App started",
    ~options={file: "Main.res", line: 1},
  )
}

attachConsole は JS コンソール用のライターをログストリームに購読させます (stdout が見えない webview での開発時に便利です)。戻り値の unlistenunit => unit のコールバックで、呼び出すと購読を解除できます。

公開 API

7 つの関数すべてが PluginLog 配下で公開され、併せて LogLevel バリアントモジュールも公開されます:

シンボル

用途

error / warn / info / debug / trace

指定したレベルでレコードを出力します

attachLogger

すべてのレコードにコールバックを購読させます

attachConsole

すべてのレコードを JS コンソールへ転送します

LogLevel.{Trace, Debug, Info, Warn, Error}

数値レベル (1..5) を保持する @unboxed バリアント

logOptions

ログ呼び出しに渡せる、メタデータのオプショナルレコード

recordPayload

attachLogger のコールバックに渡される {level, message}

unlisten

attachLogger / attachConsole が返す unit => unit

レベル別関数

5 つのレベル関数はいずれも同じシグネチャを持ちます:

let error: (string, ~options: logOptions=?) => promise<unit>
let warn:  (string, ~options: logOptions=?) => promise<unit>
let info:  (string, ~options: logOptions=?) => promise<unit>
let debug: (string, ~options: logOptions=?) => promise<unit>
let trace: (string, ~options: logOptions=?) => promise<unit>

ラベル引数 ~options はオプションです。指定するとメッセージと一緒に Rust 側で記録される、呼び出しごとのメタデータを付与できます:

await PluginLog.warn(
  "queue draining slowly",
  ~options={
    file: "Worker.res",
    line: 42,
    keyValues: Dict.fromArray([
      ("queue", "ingest"),
      ("backlog", "1872"),
    ]),
  },
)

logOptions のフィールド:

フィールド

備考

file

string (オプション)

呼び出し元のソースファイル

line

int (オプション)

ソースの行番号

keyValues

Dict.t<string> (オプション)

レコードに付与する、自由形式の構造化フィールド

@rescript/coreDict.t<string> は出力時に素の JS オブジェクトへマッピングされ、上流プラグインがそれを構造化フィールドのペイロードとして読み取ります。

LogLevel.t バリアント

LogLevel は上流の数値 enum を @as(N) 付きの @unboxed バリアントとして公開します。ランタイム表現は素の整数ですが、ReScript 側ではコンストラクタ名で扱えます:

PluginLog.LogLevel.Trace   // @as(1)
PluginLog.LogLevel.Debug   // @as(2)
PluginLog.LogLevel.Info    // @as(3)
PluginLog.LogLevel.Warn    // @as(4)
PluginLog.LogLevel.Error   // @as(5)

コンストラクタ

ワイヤ値

Trace

1

Debug

2

Info

3

Warn

4

Error

5

recordPayload.level には switch を使って網羅的にマッチさせてください。上流で新しいレベルが追加された場合、ケースが漏れているとコンパイラが警告します。

attachLogger / attachConsole

let attachLogger: (recordPayload => unit) => promise<unlisten>
let attachConsole: unit => promise<unlisten>

attachLogger は Rust 側が出力するすべてのレコードに対してコールバックを実行します。record.level でパターンマッチします:

let unlisten = await PluginLog.attachLogger(record => {
  let label = switch record.level {
  | Error => "ERROR"
  | Warn => "WARN"
  | Info => "INFO"
  | Debug => "DEBUG"
  | Trace => "TRACE"
  }
  Console.log(label ++ ": " ++ record.message)
})

// ...later
unlisten()

attachConsole はレベルに応じてレコードを console.log / console.warn / console.error に振り分ける便利ヘルパーです。Rust 側のログを webview の devtools にミラーしたいけれど振り分けを自分で書きたくない、というときに使えます。

両関数は promise<unlisten> を返します。購読が有効になったとみなす前に 必ず promise を await し、不要になったら戻り値の unlisten() を 1 回呼んでください。複数のリスナーを並列に attach できますが、重複排除はされません。

注意点

ログ呼び出しは async — await が必要

5 つのレベル関数は unit ではなく promise<unit> を返します。await を忘れるとエラーが黙って飲み込まれ、プロセス終了とレースする可能性があります:

// ❌ may be dropped if the program exits immediately
let _ = PluginLog.info("starting")

// ✅
await PluginLog.info("starting")

配送を待つ必要がない場合は、promise を明示的に _ignore に束縛し、呼び出し側に意図が伝わるようにしてください。

attachLogger / attachConsoleMocks.mockIPC ではテストできない

この 2 つの attach ヘルパーは通常の IPC コマンドブリッジではなく __TAURI_INTERNALS__.transformCallback 経由で購読するため、Mocks.mockIPC ではインターセプトできません。ログストリーミングを検証するランタイムテストでは globalThis.__TAURI_INTERNALS__ を直接 stub します。動作する実装例は packages/plugin-log/tests/runtime/plugin_log.test.mjs を参照してください。

レベル関数 (error / warn / info / debug / trace) 自体は通常の Tauri IPC (plugin:log|log) を経由するため、Mocks.mockIPC で モック可能 です

互換性

項目

対応バージョン

上流 @tauri-apps/plugin-log

^2.0.0 (peer)

Rust tauri-plugin-log

2.x

@rescript-tauri/core

^0.1.0 (peer)

ReScript

>=12.0.0

@rescript/core

>=1.6.0

対応 OS

Linux / macOS / Windows

関連リンク