ここでは Lumitrace の使い方を短く分かりやすくまとめます。
まずは最小のコマンドで動かして、出力形式の雰囲気を掴みます。
同梱の sample を最小のコマンドで実行します(テキストは stdout に出ます):
lumitrace sample/sample.rb
プログラム本体の stdout はそのまま出力され、続けて Lumitrace のテキストが表示されます。
テキスト出力の形式:
### path/to/file.rb
12|
! が付きます。...
#=> ... で表示され、複数回実行された場合は (3rd run) が付きます。COLUMNS または IO.console.winsize)に合わせて省略されます。出力例(stdout):
n0=2, n1=5, n2=11
[false, false, true]
{count: 3, max: 11, min: 2}
{even: [2], odd: [5, 11]}
"3 items, max=11"
=== Lumitrace Results (text) ===
### sample/sample.rb
1| require './sample/sample2' #=> true
2| require './sample/sample3' #=> true
3|
4| def score(n)
5| base = n + 1 #=> 3 (3rd run)
6| scaled = Sample2.scale(base) #=> 6 (3rd run)
7| squares = Sample3.series(n) #=> [1, 4] (3rd run)
8| squares.sum + scaled #=> 11 (3rd run)
9| end
10|
11| labels = []
12| totals = []
13|
14| 3.times do
15| n = it #=> 2 (3rd run)
16| total = score(n) #=> 11 (3rd run)
17| labels << Sample2.format("n#{n}", total) #=> ["n0=2", "n1=5", "n2=11"] (3rd run)
18| totals << total #=> [2, 5, 11] (3rd run)
19| end #=> 3
20|
21| flags = totals.map { |v| v > 5 } #=> [false, false, true]
22| stats = {
23| count: totals.length, #=> 3
24| max: totals.max, #=> 11
25| min: totals.min #=> 2
26| }
27|
28| buckets = Sample3.bucketize(totals) #=> {even: [2], odd: [5, 11]}
29| summary = "#{stats[:count]} items, max=#{stats[:max]}" #=> 3
30|
31| puts labels.join(", ") #=> nil
32| p flags #=> [false, false, true]
33| p stats #=> {count: 3, max: 11, min: 2}
34| p buckets #=> {even: [2], odd: [5, 11]}
35| p summary #=> 3 items, max=11
### sample/sample2.rb
1| module Sample2
2| FACTOR = 2
3|
4| def self.format(label, value)
5| "#{label}=#{value}" #=> 11 (3rd run)
6| end
7|
8| def self.scale(value)
9| value * FACTOR #=> 6 (3rd run)
10| end
11| end
### sample/sample3.rb
1| module Sample3
2| def self.bucketize(values)
3| values.group_by { |v| v % 2 == 0 ? :even : :odd } #=> {even: [2], odd: [5, 11]}
4| end
5|
6| def self.series(n)
7| (1..n).map { |i| i * i } #=> [1, 4] (3rd run)
8| end
9| end
結果をあとで見返したり共有したいときは、テキストと HTML をディスクに書き出すのが便利です。
同梱の sample を実行して、テキストと HTML を保存します:
lumitrace sample/sample.rb \
--text sample/lumitrace_results_01.txt \
--html sample/lumitrace_results_01.html
Lumitrace のテキストは sample/lumitrace_results_01.txt、HTML は sample/lumitrace_results_01.html に保存されます。
--html PATH を省略した場合の HTML 出力は lumitrace_recorded.html です。
HTML 出力を見る:
HTML について:
🔎、未実行の式は ∅ で表示されます。🧷 で表示されます。... が入ります。(実行行数/式のある行数) で表示されます。#file=...)に反映されるため、URL を共有するとそのファイル表示を開けます。#file=...&line=...)に更新され、同じファイル・行を開けます。Command: ... が表示されます。出力が多いときは、対象行を絞って読みやすくします。
範囲を指定して、別の出力として保存します:
lumitrace sample/sample.rb \
--text sample/lumitrace_results_02.txt \
--html sample/lumitrace_results_02.html \
--range sample/sample.rb:4-18,28-32
出力例(sample/lumitrace_results_02.txt):
HTML 出力を見る:
- [lumitrace_results_02.html](https://ko1.github.io/lumitrace/sample/lumitrace_results_02.html)
=== Lumitrace Results (text) ===
### sample/sample.rb (lines: 4-18, 28-32)
...
4| def score(n)
5| base = n + 1 #=> 3 (3rd run)
6| scaled = Sample2.scale(base) #=> 6 (3rd run)
7| squares = Sample3.series(n) #=> [1, 4] (3rd run)
8| squares.sum + scaled #=> 11 (3rd run)
9| end
10|
11| labels = []
12| totals = []
13|
14| 3.times do
15| n = it #=> 2 (3rd run)
16| total = score(n) #=> 11 (3rd run)
17| labels << Sample2.format("n#{n}", total) #=> ["n0=2", "n1=5", "n2=11"] (3rd run)
18| totals << total #=> [2, 5, 11] (3rd run)
...
28| buckets = Sample3.bucketize(totals) #=> {even: [2], odd: [5, 11]}
29| summary = "#{stats[:count]} items, max=#{stats[:max]}" #=> 3
30|
31| puts labels.join(", ") #=> nil
32| p flags #=> [false, false, true]
...
環境変数で HTML を有効化:
LUMITRACE_HTML=1 lumitrace path/to/entry.rb
LUMITRACE_HTML=/tmp/out.html lumitrace path/to/entry.rb
出力が長すぎたり読みづらいときに、1 行あたりの記録数を制限します。
LUMITRACE_MAX_SAMPLES=5 lumitrace path/to/entry.rb
特定の行だけを明示的に追いたいときの指定です。
lumitrace --range path/to/entry.rb:10-20,30-35 path/to/entry.rb
別コマンドをラップするときは、環境変数で range を渡せます(; 区切り):
LUMITRACE_RANGE="a.rb:1-3,5-6;b.rb" ruby your_script.rb
変更行だけを自動で追うと、レビュー時のノイズが減ります。
lumitrace -g path/to/entry.rb
lumitrace --git-diff=staged path/to/entry.rb
lumitrace --git-diff=base:HEAD~1 path/to/entry.rb
lumitrace --git-diff-context 5 path/to/entry.rb
lumitrace --git-cmd /usr/local/bin/git path/to/entry.rb
未追跡ファイルを除外:
lumitrace -g --git-diff-no-untracked path/to/entry.rb
レンジ計算や動作の理由を追いたいときに有効です。
lumitrace --verbose[=LEVEL] path/to/entry.rb
レベル: 1(基本ログ)、2(変換したファイル名)、3(変換後ソース)。
ツール連携や後処理のために JSON を出します。
lumitrace -j path/to/entry.rb
lumitrace_recorded.json が生成されます(HTML は --html を指定したときだけ出力されます)。
端末でさっと確認したいとき向けです。
lumitrace -t path/to/entry.rb
CI アーティファクトなどに残したいときに便利です。
lumitrace --text=/tmp/lumi.txt path/to/entry.rb
素早い確認と詳細閲覧を一回で得たいときに使います。
lumitrace -t -h path/to/entry.rb
テストなど別コマンドをラップして計測します。
lumitrace --html=sample/lumitrace_rake.html exec rake
HTML 出力:
CI で差分ログを出し、Pages で HTML を共有したいときの導線です。
GitHub Actions への追加手順(LUMITRACE_GIT_DIFF や Pages へのアップロード設定を含む)は sample/sample_project/README.md を参照してください。公開済み Pages はこちらです:
https://ko1.github.io/lumitrace_sample_project/
プロセスが増える構成のとき、結果がどう合流するかを押さえます。
fork/exec の結果はデフォルトでマージされます。親プロセスが最終出力を行い、子プロセスは LUMITRACE_RESULTS_DIR に断片 JSON を保存します。
AI に読ませる前提なら、次の順番にすると効率が良いです。
lumitrace --collect-mode types -j path/to/entry.rb
lumitrace --collect-mode last -j path/to/entry.rb
lumitrace --collect-mode history --max-samples 5 -j path/to/entry.rb
lumitrace --collect-mode last -j --range path/to/entry.rb:120-180 path/to/entry.rb
lumitrace --collect-mode last -j -g path/to/entry.rb
補助情報は lumitrace help --format json と lumitrace schema --format json で機械可読に取得できます。
CLI を使わずアプリに組み込みたい場合はここから始めます。
終了時にテキストを出力する設定:
require "lumitrace"
Lumitrace.enable!
1 行で有効化したい場合:
require "lumitrace/enable"
HTML も出力したい場合:
Lumitrace.enable!(html: true)
Lumitrace.enable!(html: "/tmp/lumi.html")
require だけで HTML を有効にする場合:
ENV["LUMITRACE_HTML"] = "1"
require "lumitrace/enable"
require だけで JSON を有効にする場合:
ENV["LUMITRACE_JSON"] = "1"
require "lumitrace/enable"
require だけでテキスト出力を制御する場合:
ENV["LUMITRACE_TEXT"] = "0" # テキストを無効化
require "lumitrace/enable"
環境変数でテキストをファイルに出力:
ENV["LUMITRACE_TEXT"] = "/tmp/lumi.txt"
require "lumitrace/enable"
require だけで有効化する場合:
ENV["LUMITRACE_ENABLE"] = "1"
require "lumitrace"
LUMITRACE_ENABLE に CLI 互換のオプションを渡すこともできます:
ENV["LUMITRACE_ENABLE"] = "-t --html=/tmp/lumi.html -j"
require "lumitrace"
exec 先でも読み込まれるように、Lumitrace は RUBYOPT=-rlumitrace を設定します。これにより fork/exec の結果をマージできます。
用途に合わせて HTML/JSON/テキストの保存先を変えられます。
LUMITRACE_HTML=/tmp/lumi.html ruby your_script.rb
JSON を終了時に出力したい場合:
Lumitrace.enable!(json: true)
Lumitrace.enable!(json: "/tmp/lumi.json")
ライブラリ側で git diff に連動させ、変更行だけを追う方法です。
現在のプログラムファイルに対する git diff の範囲だけを有効化します。
require "lumitrace/enable_git_diff"
デフォルトは作業ツリーの差分です。ステージ済み差分を使う場合:
LUMITRACE_GIT_DIFF=staged ruby your_script.rb
前後の文脈も含めたいときに範囲を広げます。
LUMITRACE_GIT_DIFF_CONTEXT=5 ruby your_script.rb
計測対象のディレクトリ範囲を明確にしたいときに使います。
デフォルトは現在のディレクトリ配下のみ計測します。 別のルートを指定したい場合:
LUMITRACE_ROOT=/path/to/project ruby your_script.rb
CLI を使う場合:
lumitrace --root /path/to/project your_script.rb
日常的に効く小さなコツをまとめます。
LUMITRACE_MAX_SAMPLES を下げると軽くなります。enable_git_diff が便利です。