lumitrace 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/AGENTS.md +37 -0
- data/README.md +30 -3
- data/Rakefile +21 -0
- data/bench/bench_sample.rb +71 -0
- data/docs/ai-help.md +44 -0
- data/docs/ai-schema.md +36 -0
- data/docs/spec.md +81 -14
- data/docs/supported_syntax.md +5 -0
- data/docs/tutorial.ja.md +16 -3
- data/docs/tutorial.md +16 -3
- data/exe/lumitrace +41 -2
- data/lib/lumitrace/ai_docs.rb +107 -0
- data/lib/lumitrace/env.rb +4 -2
- data/lib/lumitrace/generate_resulted_html.rb +209 -43
- data/lib/lumitrace/help_manifest.rb +72 -0
- data/lib/lumitrace/record_instrument.rb +500 -47
- data/lib/lumitrace/record_require.rb +2 -2
- data/lib/lumitrace/schema_manifest.rb +62 -0
- data/lib/lumitrace/version.rb +1 -1
- data/lib/lumitrace.rb +152 -17
- data/runv/README.md +15 -8
- data/runv/index.html +1531 -86
- data/runv/sync_inline.rb +29 -0
- data/sample/lumitrace_rake.html +22 -18
- data/sample/lumitrace_recorded.html +25 -34
- data/test/test_lumitrace.rb +232 -13
- metadata +9 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4be2a97656c1b025f8ae4c8eacf1f1d00969f0759de4b838fdb0681610689e76
|
|
4
|
+
data.tar.gz: a2142bb03fec41ed02668ae63c27437dfe885f874bbb758cb1b5649fde2df635
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 42b5a8463939fe9820d9cce36bc56f2b3bb5eb2759096f975f517460d371969353a0fe322181fb7ab153eb94f388888f4118b8c9e5eebcd1b744046c778874e3
|
|
7
|
+
data.tar.gz: f076ae99fdfd6f0f28d77f29957c504e254609b1812a265b3353c368173007bbd21570c683064b9704bf8e81c49132bef2e03f573987047c27e09229e272082b
|
data/AGENTS.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# AGENTS
|
|
2
|
+
|
|
3
|
+
This file describes how agents should work in this repository.
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
- Keep changes focused on Lumitrace and its docs/tests.
|
|
7
|
+
- Prefer minimal, reviewable edits over wide refactors.
|
|
8
|
+
|
|
9
|
+
## Where To Look First
|
|
10
|
+
- Overview and usage: `README.md`
|
|
11
|
+
- Detailed behavior/spec: `docs/spec.md`
|
|
12
|
+
- Syntax coverage: `docs/supported_syntax.md`
|
|
13
|
+
- Tutorials: `docs/tutorial.md`, `docs/tutorial.ja.md`
|
|
14
|
+
|
|
15
|
+
## Repository Layout
|
|
16
|
+
- Source code: `lib/`, `exe/`, `bin/`
|
|
17
|
+
- Docs: `docs/`
|
|
18
|
+
- Tests: `test/`
|
|
19
|
+
- Samples: `sample/`
|
|
20
|
+
|
|
21
|
+
## Coding And Style
|
|
22
|
+
- Follow existing Ruby style and structure in nearby files.
|
|
23
|
+
- Keep changes small and localized when possible.
|
|
24
|
+
- Add comments only when logic is non-obvious.
|
|
25
|
+
|
|
26
|
+
## Tests
|
|
27
|
+
- Prefer running the smallest relevant test set.
|
|
28
|
+
- When source code changes, run tests by default (at least `rake test`).
|
|
29
|
+
- If you cannot run tests, say so and explain why.
|
|
30
|
+
|
|
31
|
+
## Safety
|
|
32
|
+
- Do not delete or rewrite large sections without a clear reason.
|
|
33
|
+
- Do not use destructive git commands unless asked.
|
|
34
|
+
|
|
35
|
+
## Communication
|
|
36
|
+
- Summarize what you changed and why.
|
|
37
|
+
- Call out any assumptions or follow-ups needed.
|
data/README.md
CHANGED
|
@@ -8,6 +8,8 @@ Lumitrace instruments Ruby source code at load time, records expression results,
|
|
|
8
8
|
- [Tutorial](https://ko1.github.io/lumitrace/docs/tutorial.html)
|
|
9
9
|
- [Tutorial in Japanese](https://ko1.github.io/lumitrace/docs/tutorial.ja.html)
|
|
10
10
|
- [Spec](https://ko1.github.io/lumitrace/docs/spec.html)
|
|
11
|
+
- [AI Help](https://ko1.github.io/lumitrace/docs/ai-help.html)
|
|
12
|
+
- [AI Schema](https://ko1.github.io/lumitrace/docs/ai-schema.html)
|
|
11
13
|
- [Supported Syntax](https://ko1.github.io/lumitrace/docs/supported_syntax.html)
|
|
12
14
|
- [GitHub repository](https://github.com/ko1/lumitrace)
|
|
13
15
|
|
|
@@ -41,7 +43,7 @@ lumitrace -h path/to/entry.rb
|
|
|
41
43
|
Limit the number of recorded values per expression (defaults to 3):
|
|
42
44
|
|
|
43
45
|
```bash
|
|
44
|
-
|
|
46
|
+
LUMITRACE_MAX_SAMPLES=5 lumitrace path/to/entry.rb
|
|
45
47
|
```
|
|
46
48
|
|
|
47
49
|
Write JSON output explicitly:
|
|
@@ -57,6 +59,14 @@ Restrict to specific line ranges:
|
|
|
57
59
|
lumitrace --range path/to/entry.rb:10-20,30-35 path/to/entry.rb
|
|
58
60
|
```
|
|
59
61
|
|
|
62
|
+
Show AI/human help:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
lumitrace help
|
|
66
|
+
lumitrace help --format json
|
|
67
|
+
lumitrace schema --format json
|
|
68
|
+
```
|
|
69
|
+
|
|
60
70
|
### Library
|
|
61
71
|
|
|
62
72
|
Enable instrumentation and HTML output at exit:
|
|
@@ -83,11 +93,28 @@ require "lumitrace/enable"
|
|
|
83
93
|
- Text: printed by default; use `--text=PATH` to write to a file.
|
|
84
94
|
- HTML: `lumitrace_recorded.html` by default, or `--html=PATH`.
|
|
85
95
|
- JSON: written only when `--json` (CLI) or `LUMITRACE_JSON` (library/CLI) is provided. Default filename is `lumitrace_recorded.json`.
|
|
96
|
+
- JSON collection mode: `--collect-mode=last|types|history` (default `last`).
|
|
86
97
|
- Fork/exec: merged by default. Child processes write fragments under `LUMITRACE_RESULTS_DIR`.
|
|
87
98
|
|
|
99
|
+
JSON event entries always include `types` (type-name => count).
|
|
100
|
+
|
|
101
|
+
```json
|
|
102
|
+
{
|
|
103
|
+
"file": "/abs/path/app.rb",
|
|
104
|
+
"start_line": 10,
|
|
105
|
+
"start_col": 2,
|
|
106
|
+
"end_line": 10,
|
|
107
|
+
"end_col": 9,
|
|
108
|
+
"kind": "expr",
|
|
109
|
+
"types": { "Integer": 3, "NilClass": 1 },
|
|
110
|
+
"total": 4
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
88
114
|
## Environment Variables
|
|
89
115
|
|
|
90
|
-
- `
|
|
116
|
+
- `LUMITRACE_MAX_SAMPLES`: default max samples per expression (default 3 if unset).
|
|
117
|
+
- `LUMITRACE_COLLECT_MODE`: value collection mode (`last`, `types`, `history`; default `last`).
|
|
91
118
|
- `LUMITRACE_ROOT`: root directory used to decide which files are instrumented.
|
|
92
119
|
- `LUMITRACE_TEXT`: control text output. `1` forces text on, `0`/`false` disables. Any other value is treated as the text output path.
|
|
93
120
|
- `LUMITRACE_HTML`: enable HTML output; `1` uses the default path, otherwise treats the value as the HTML output path. `0`/`false` disables.
|
|
@@ -105,7 +132,7 @@ require "lumitrace/enable"
|
|
|
105
132
|
## Notes And Limitations
|
|
106
133
|
|
|
107
134
|
- Requires `RubyVM::InstructionSequence.translate` support.
|
|
108
|
-
- Very large projects or hot loops can still generate large HTML; use `
|
|
135
|
+
- Very large projects or hot loops can still generate large HTML; use `LUMITRACE_MAX_SAMPLES`.
|
|
109
136
|
- Instrumentation changes evaluation order for debugging, not for production.
|
|
110
137
|
|
|
111
138
|
## Development
|
data/Rakefile
CHANGED
|
@@ -13,6 +13,27 @@ task default: :test
|
|
|
13
13
|
|
|
14
14
|
require "benchmark"
|
|
15
15
|
|
|
16
|
+
desc "Sync embedded Lumitrace code in runv/index.html"
|
|
17
|
+
task :runv do
|
|
18
|
+
ruby "runv/sync_inline.rb"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
namespace :docs do
|
|
22
|
+
desc "Generate AI help/schema docs from manifests"
|
|
23
|
+
task :ai do
|
|
24
|
+
require_relative "lib/lumitrace"
|
|
25
|
+
|
|
26
|
+
help_path = File.expand_path("docs/ai-help.md", __dir__)
|
|
27
|
+
schema_path = File.expand_path("docs/ai-schema.md", __dir__)
|
|
28
|
+
|
|
29
|
+
File.write(help_path, Lumitrace.render_ai_help_markdown)
|
|
30
|
+
File.write(schema_path, Lumitrace.render_ai_schema_markdown)
|
|
31
|
+
|
|
32
|
+
puts "updated #{help_path}"
|
|
33
|
+
puts "updated #{schema_path}"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
16
37
|
desc "Run simple runtime comparison for lumitrace vs ruby"
|
|
17
38
|
task :bench do
|
|
18
39
|
sample = File.expand_path("bench/bench_sample.rb", __dir__)
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Small-ish workload for lumitrace timing.
|
|
4
|
+
# Run:
|
|
5
|
+
# time lumitrace bench_sample.rb
|
|
6
|
+
|
|
7
|
+
WORDS = %w[alpha beta gamma delta epsilon zeta eta theta iota kappa lambda mu nu xi omicron pi rho sigma tau upsilon phi chi psi omega].freeze
|
|
8
|
+
|
|
9
|
+
class MiniReport
|
|
10
|
+
def initialize(size)
|
|
11
|
+
@size = size
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def run
|
|
15
|
+
data = build_data
|
|
16
|
+
counts = count_words(data)
|
|
17
|
+
stats = summarize(counts)
|
|
18
|
+
format_output(stats)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def build_data
|
|
24
|
+
out = []
|
|
25
|
+
@size.times do |i|
|
|
26
|
+
base = WORDS[i % WORDS.length]
|
|
27
|
+
out << "#{base}-#{i}"
|
|
28
|
+
if i % 7 == 0
|
|
29
|
+
out << base.upcase
|
|
30
|
+
elsif i % 5 == 0
|
|
31
|
+
out << base.reverse
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
out
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def count_words(data)
|
|
38
|
+
counts = Hash.new(0)
|
|
39
|
+
data.each do |w|
|
|
40
|
+
key = w.downcase
|
|
41
|
+
counts[key] += 1
|
|
42
|
+
end
|
|
43
|
+
counts
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def summarize(counts)
|
|
47
|
+
top = counts.sort_by { |_, v| -v }.first(5)
|
|
48
|
+
total = counts.values.sum
|
|
49
|
+
{
|
|
50
|
+
total: total,
|
|
51
|
+
unique: counts.length,
|
|
52
|
+
top: top
|
|
53
|
+
}
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def format_output(stats)
|
|
57
|
+
lines = []
|
|
58
|
+
lines << "total=#{stats[:total]} unique=#{stats[:unique]}"
|
|
59
|
+
stats[:top].each_with_index do |(k, v), idx|
|
|
60
|
+
lines << "#{idx + 1}. #{k}=#{v}"
|
|
61
|
+
end
|
|
62
|
+
lines.join("\n")
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
n = (ENV["N"] || 1000).to_i
|
|
67
|
+
report = MiniReport.new(n)
|
|
68
|
+
result = report.run
|
|
69
|
+
|
|
70
|
+
# Keep output minimal but non-empty
|
|
71
|
+
puts result if ENV["PRINT"] == "1"
|
data/docs/ai-help.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<!-- generated file: do not edit. run `rake docs:ai` -->
|
|
2
|
+
|
|
3
|
+
# Lumitrace Help
|
|
4
|
+
|
|
5
|
+
- Version: 0.4.0
|
|
6
|
+
- Help version: 1
|
|
7
|
+
- Primary JSON entrypoint: `lumitrace help --format json`
|
|
8
|
+
- Schema JSON entrypoint: `lumitrace schema --format json`
|
|
9
|
+
|
|
10
|
+
## Recommended Flow
|
|
11
|
+
- Read `lumitrace help --format json`.
|
|
12
|
+
- Read `lumitrace schema --format json` to understand output structure.
|
|
13
|
+
- Run lumitrace with `--collect-mode` and optional `--max-samples`.
|
|
14
|
+
- Inspect JSON/HTML/text outputs depending on your task.
|
|
15
|
+
|
|
16
|
+
## Commands
|
|
17
|
+
- `lumitrace [options] script.rb [ruby_opt]`
|
|
18
|
+
- Run a Ruby script with Lumitrace enabled.
|
|
19
|
+
- `lumitrace [options] exec CMD [args...]`
|
|
20
|
+
- Run an arbitrary command with Lumitrace env injected.
|
|
21
|
+
- `lumitrace help [--format text|json]`
|
|
22
|
+
- Show AI/human help.
|
|
23
|
+
- `lumitrace schema [--format text|json]`
|
|
24
|
+
- Show output schema for each collect mode.
|
|
25
|
+
|
|
26
|
+
## Collect Modes
|
|
27
|
+
- `last`: Keep only the last observed value and type counts.
|
|
28
|
+
- `types`: Keep only type counts and total hit count.
|
|
29
|
+
- `history`: Keep last N sampled values and type counts.
|
|
30
|
+
|
|
31
|
+
## Key Options
|
|
32
|
+
- `--collect-mode` (default="last"; values=last,types,history)
|
|
33
|
+
- `--max-samples` (default=3; Used by history mode.)
|
|
34
|
+
- `--json[=PATH]` (Emit JSON output.)
|
|
35
|
+
- `--html[=PATH]` (Emit HTML output.)
|
|
36
|
+
- `--text[=PATH]` (Emit text output.)
|
|
37
|
+
- `--range SPEC` (repeatable=true; Restrict instrumentation to file ranges.)
|
|
38
|
+
- `--git-diff[=MODE]` (Restrict instrumentation to diff hunks.)
|
|
39
|
+
|
|
40
|
+
## Examples
|
|
41
|
+
- `lumitrace --collect-mode history --max-samples 5 -j app.rb`
|
|
42
|
+
- `lumitrace --collect-mode types -h -j app.rb`
|
|
43
|
+
- `lumitrace help --format json`
|
|
44
|
+
- `lumitrace schema --format json`
|
data/docs/ai-schema.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<!-- generated file: do not edit. run `rake docs:ai` -->
|
|
2
|
+
|
|
3
|
+
# Lumitrace JSON Schema
|
|
4
|
+
|
|
5
|
+
- Version: 0.4.0
|
|
6
|
+
- Schema version: 1
|
|
7
|
+
- Top level: array of event
|
|
8
|
+
|
|
9
|
+
## Common Event Fields
|
|
10
|
+
- `file` (string, required) - Absolute source path.
|
|
11
|
+
- `start_line` (integer, required)
|
|
12
|
+
- `start_col` (integer, required)
|
|
13
|
+
- `end_line` (integer, required)
|
|
14
|
+
- `end_col` (integer, required)
|
|
15
|
+
- `kind` (string, required)
|
|
16
|
+
- `name` (string|null, optional) - Present for kind=arg.
|
|
17
|
+
- `total` (integer, required) - Execution count.
|
|
18
|
+
- `types` (object, required) - Ruby class name => observed count.
|
|
19
|
+
|
|
20
|
+
## Value Summary Fields
|
|
21
|
+
- `type` (string, required) - Ruby class name.
|
|
22
|
+
- `preview` (string, required) - Value preview string (inspect-based).
|
|
23
|
+
- `length` (integer, optional) - Original preview length when preview was truncated.
|
|
24
|
+
|
|
25
|
+
## Collect Modes
|
|
26
|
+
- `last`
|
|
27
|
+
- required fields: file, start_line, start_col, end_line, end_col, kind, total, types, last_value
|
|
28
|
+
- optional fields: name
|
|
29
|
+
- `last_value`: value_summary
|
|
30
|
+
- `types`
|
|
31
|
+
- required fields: file, start_line, start_col, end_line, end_col, kind, total, types
|
|
32
|
+
- optional fields: name
|
|
33
|
+
- `history`
|
|
34
|
+
- required fields: file, start_line, start_col, end_line, end_col, kind, total, types, sampled_values
|
|
35
|
+
- optional fields: name
|
|
36
|
+
- `sampled_values`: array (items: value_summary)
|
data/docs/spec.md
CHANGED
|
@@ -7,6 +7,12 @@
|
|
|
7
7
|
|
|
8
8
|
Lumitrace instruments Ruby source code at load time (via `RubyVM::InstructionSequence.translate` when available), records expression results, and renders text or HTML output that overlays recorded values on your code. It is designed for local “what happened here?” inspection.
|
|
9
9
|
|
|
10
|
+
## AI-Oriented Docs
|
|
11
|
+
|
|
12
|
+
- AI help reference: `docs/ai-help.md`
|
|
13
|
+
- AI schema reference: `docs/ai-schema.md`
|
|
14
|
+
- Regenerate both files with: `rake docs:ai`
|
|
15
|
+
|
|
10
16
|
## Goals
|
|
11
17
|
|
|
12
18
|
- Record expression results with minimal friction.
|
|
@@ -35,10 +41,10 @@ Lumitrace instruments Ruby source code at load time (via `RubyVM::InstructionSeq
|
|
|
35
41
|
- `LUMITRACE_ENABLE=1` + `require "lumitrace"` (auto-`enable!`)
|
|
36
42
|
- `LUMITRACE_ENABLE="-t -h -j ..."` + `require "lumitrace"` (CLI-style options parsed and passed to `enable!`)
|
|
37
43
|
|
|
38
|
-
### `Lumitrace.enable!(
|
|
44
|
+
### `Lumitrace.enable!(max_samples: nil, ranges_by_file: nil, root: nil, text: nil, html: nil, json: nil, verbose: nil, at_exit: true)`
|
|
39
45
|
|
|
40
46
|
- Arguments:
|
|
41
|
-
- `
|
|
47
|
+
- `max_samples`: integer, string, or nil.
|
|
42
48
|
- `ranges_by_file`: hash or nil. `{ "/path/to/file.rb" => [1..5, 10..12] }`.
|
|
43
49
|
- `text`: boolean or string or nil. When nil, determined from environment variables. When string, uses it as the text output path.
|
|
44
50
|
- `html`: boolean or string or nil. When nil, determined from environment variables.
|
|
@@ -52,7 +58,8 @@ Lumitrace instruments Ruby source code at load time (via `RubyVM::InstructionSeq
|
|
|
52
58
|
- Fixes the HTML output directory to the `Dir.pwd` at call time.
|
|
53
59
|
- Root scope for instrumentation uses `root` if provided, otherwise `ENV["LUMITRACE_ROOT"]` if set, otherwise `Dir.pwd`.
|
|
54
60
|
- Environment variables (resolved by `Lumitrace.enable!`):
|
|
55
|
-
- `
|
|
61
|
+
- `LUMITRACE_MAX_SAMPLES`: default max samples per expression when `max_samples` is nil (default 3 if unset).
|
|
62
|
+
- `LUMITRACE_COLLECT_MODE`: value collection mode (`last`, `types`, `history`; default `last`).
|
|
56
63
|
- `LUMITRACE_ROOT`: root directory used to decide which files are instrumented.
|
|
57
64
|
- `LUMITRACE_HTML`: enable HTML output; `1` uses the default path, otherwise treats the value as the HTML output path. `0`/`false` disables.
|
|
58
65
|
- `LUMITRACE_TEXT`: control text output. `1` forces text on, `0`/`false` disables. If unset, text is enabled only when both HTML and JSON are disabled. Any other value is treated as the text output path.
|
|
@@ -129,6 +136,7 @@ Lumitrace instruments Ruby source code at load time (via `RubyVM::InstructionSeq
|
|
|
129
136
|
### Wrap Targets
|
|
130
137
|
|
|
131
138
|
- `CallNode` (except those with block bodies)
|
|
139
|
+
- `YieldNode`
|
|
132
140
|
- Variable reads:
|
|
133
141
|
- `LocalVariableReadNode`
|
|
134
142
|
- `ConstantReadNode`
|
|
@@ -136,15 +144,18 @@ Lumitrace instruments Ruby source code at load time (via `RubyVM::InstructionSeq
|
|
|
136
144
|
- `ClassVariableReadNode`
|
|
137
145
|
- `GlobalVariableReadNode`
|
|
138
146
|
- Literal nodes are excluded (e.g. integer, string, true/false, nil, etc.)
|
|
147
|
+
- Method and block arguments are recorded by inserting `Lumitrace::R` at the start of the body.
|
|
139
148
|
|
|
140
149
|
## Recording
|
|
141
150
|
|
|
142
151
|
- Results are stored per expression key:
|
|
143
152
|
- `id` (an integer assigned at instrumentation time) with a separate `id -> location` table.
|
|
144
|
-
-
|
|
153
|
+
- Collection mode is selected by `collect_mode` (`last`, `types`, `history`; default `last`).
|
|
154
|
+
- In `history` mode, keep only the last N values (`max_samples_per_expr`, default 3).
|
|
145
155
|
- Track `total` count for how many times the expression executed.
|
|
146
|
-
-
|
|
147
|
-
-
|
|
156
|
+
- In `collect_mode=last`, `last_value.preview` is always the `inspect` result string.
|
|
157
|
+
- `last_value.length` is included only when `preview` is truncated.
|
|
158
|
+
- Argument records are stored alongside expression records with `kind: "arg"` and `name` (argument name).
|
|
148
159
|
|
|
149
160
|
## Fork/Exec Merge
|
|
150
161
|
|
|
@@ -156,7 +167,42 @@ Lumitrace instruments Ruby source code at load time (via `RubyVM::InstructionSeq
|
|
|
156
167
|
|
|
157
168
|
### Output JSON
|
|
158
169
|
|
|
159
|
-
`lumitrace_recorded.json` contains an array of entries
|
|
170
|
+
`lumitrace_recorded.json` contains an array of entries.
|
|
171
|
+
|
|
172
|
+
`collect_mode=last` (default):
|
|
173
|
+
|
|
174
|
+
```json
|
|
175
|
+
{
|
|
176
|
+
"file": "/path/to/file.rb",
|
|
177
|
+
"start_line": 10,
|
|
178
|
+
"start_col": 4,
|
|
179
|
+
"end_line": 10,
|
|
180
|
+
"end_col": 20,
|
|
181
|
+
"kind": "expr",
|
|
182
|
+
"name": null,
|
|
183
|
+
"last_value": { "type": "String", "preview": "\"ok\"" },
|
|
184
|
+
"types": { "Integer": 10, "NilClass": 2, "String": 111 },
|
|
185
|
+
"total": 123
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
`collect_mode=types`:
|
|
190
|
+
|
|
191
|
+
```json
|
|
192
|
+
{
|
|
193
|
+
"file": "/path/to/file.rb",
|
|
194
|
+
"start_line": 10,
|
|
195
|
+
"start_col": 4,
|
|
196
|
+
"end_line": 10,
|
|
197
|
+
"end_col": 20,
|
|
198
|
+
"kind": "expr",
|
|
199
|
+
"name": null,
|
|
200
|
+
"types": { "Integer": 10, "NilClass": 2, "String": 111 },
|
|
201
|
+
"total": 123
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
`collect_mode=history`:
|
|
160
206
|
|
|
161
207
|
```json
|
|
162
208
|
{
|
|
@@ -165,11 +211,22 @@ Lumitrace instruments Ruby source code at load time (via `RubyVM::InstructionSeq
|
|
|
165
211
|
"start_col": 4,
|
|
166
212
|
"end_line": 10,
|
|
167
213
|
"end_col": 20,
|
|
168
|
-
"
|
|
214
|
+
"kind": "expr",
|
|
215
|
+
"name": null,
|
|
216
|
+
"sampled_values": [
|
|
217
|
+
{ "type": "Integer", "preview": "42" },
|
|
218
|
+
{ "type": "NilClass", "preview": "nil" },
|
|
219
|
+
{ "type": "String", "preview": "\"ok\"" }
|
|
220
|
+
],
|
|
221
|
+
"types": { "Integer": 10, "NilClass": 2, "String": 111 },
|
|
169
222
|
"total": 123
|
|
170
223
|
}
|
|
171
224
|
```
|
|
172
225
|
|
|
226
|
+
- `last_value`: summary of the last observed value: `{ type, preview }` (+ `length` only when truncated).
|
|
227
|
+
- `types`: observed Ruby class counts (class name => count).
|
|
228
|
+
- `sampled_values`: retained sample (last N values) of summary objects (`{ type, preview }` + optional `length`) in `history` mode.
|
|
229
|
+
|
|
173
230
|
## CLI
|
|
174
231
|
|
|
175
232
|
### `lumitrace`
|
|
@@ -184,14 +241,15 @@ lumitrace [options] exec CMD [args...]
|
|
|
184
241
|
- `-h` enables HTML output (default path). `--html=PATH` writes to a file.
|
|
185
242
|
- `-j` enables JSON output (default path). `--json=PATH` writes to a file.
|
|
186
243
|
- `-g` enables git diff with `working` mode. `--git-diff=MODE` selects `staged|base:REV|range:SPEC`.
|
|
187
|
-
- `--max` sets max
|
|
244
|
+
- `--max-samples` sets max samples per expression in `collect_mode=history`.
|
|
245
|
+
- `--collect-mode` sets value collection mode (`last|types|history`).
|
|
188
246
|
- `--range` restricts instrumentation per file (`FILE` or `FILE:1-5,10-12`). Can be repeated.
|
|
189
247
|
- `--git-diff=MODE` restricts instrumentation to diff hunks (`staged|base:REV|range:SPEC`).
|
|
190
248
|
- `--git-diff-context` expands hunks by +/-N lines.
|
|
191
249
|
- `--git-cmd` overrides the git executable.
|
|
192
250
|
- `--git-diff-no-untracked` excludes untracked files (untracked files are included by default).
|
|
193
251
|
- `--verbose[=LEVEL]` prints verbose logs to stderr (level 1-3).
|
|
194
|
-
- `
|
|
252
|
+
- `LUMITRACE_MAX_SAMPLES` sets the default max samples per expression.
|
|
195
253
|
- The CLI launches a child process (Ruby or `exec` target) with `RUBYOPT=-rlumitrace` and `LUMITRACE_*` env vars.
|
|
196
254
|
|
|
197
255
|
### Text Output (CLI)
|
|
@@ -199,19 +257,28 @@ lumitrace [options] exec CMD [args...]
|
|
|
199
257
|
- Text output starts with a header line: `=== Lumitrace Results (text) ===`.
|
|
200
258
|
- Each file is printed with a header: `### path/to/file.rb`.
|
|
201
259
|
- Each line is prefixed with a line number like ` 12| `.
|
|
260
|
+
- Lines where all instrumentable expressions are unexecuted are prefixed with `!`.
|
|
202
261
|
- Skipped ranges are represented by a line containing `...`.
|
|
203
|
-
- Only the last value is shown per expression
|
|
204
|
-
- When `--text` is used
|
|
262
|
+
- Only the last value is shown per expression as `value (Type)`; if an expression ran multiple times, the last value is annotated with the ordinal run (e.g., `#=> 2 (Integer) (3rd run)`).
|
|
263
|
+
- When `collect_mode=history` and `--text` is used with no `--max-samples`, `max_samples` defaults to `1`.
|
|
205
264
|
- When `ranges_by_file` is provided, only files present in the hash are shown in text output.
|
|
265
|
+
- When writing to stdout (`tty: true`), long comments are truncated to the terminal width (using `COLUMNS` or `IO.console.winsize`). File output is not truncated.
|
|
206
266
|
|
|
207
267
|
## HTML Rendering
|
|
208
268
|
|
|
209
269
|
- `GenerateResultedHtml.render_all` renders all files in one page.
|
|
270
|
+
- The page header shows the active collect mode:
|
|
271
|
+
- `Mode: last (last value)`
|
|
272
|
+
- `Mode: types (type counts)`
|
|
273
|
+
- `Mode: history (last N sample[s])`
|
|
274
|
+
- In `history`, `N` uses configured `max_samples` when available; otherwise it is inferred from the loaded events.
|
|
210
275
|
- Each file is shown in its own section.
|
|
211
|
-
- Expressions are marked with an inline icon.
|
|
276
|
+
- Expressions are marked with an inline icon (`🔎` for executed, `∅` for not hit).
|
|
212
277
|
- Hovering the icon shows recorded values.
|
|
213
|
-
- Only the last 3 values are shown in the tooltip
|
|
278
|
+
- Only the last 3 values are shown in the tooltip as `value (Type)`; additional values are summarized as `... (+N more)`.
|
|
214
279
|
- Tooltip is scrollable horizontally for long values.
|
|
280
|
+
- When ranges are used, skipped sections are shown as `...` in the line-number column.
|
|
281
|
+
- Lines where all instrumentable expressions are unexecuted are highlighted in a light red. If a line mixes executed and unexecuted expressions, only the unexecuted expressions are highlighted.
|
|
215
282
|
|
|
216
283
|
### Copy/Paste Behavior
|
|
217
284
|
|
data/docs/supported_syntax.md
CHANGED
data/docs/tutorial.ja.md
CHANGED
|
@@ -26,11 +26,13 @@ lumitrace sample/sample.rb
|
|
|
26
26
|
```
|
|
27
27
|
12|
|
|
28
28
|
```
|
|
29
|
+
- 記録対象の式がすべて未実行の行は `!` が付きます。
|
|
29
30
|
- 範囲が飛ぶ場合は次の行が入ります:
|
|
30
31
|
```
|
|
31
32
|
...
|
|
32
33
|
```
|
|
33
34
|
- 最終値は `#=> ...` で表示され、複数回実行された場合は `(3rd run)` が付きます。
|
|
35
|
+
- TTY に出力する場合、長いコメントは端末幅(`COLUMNS` または `IO.console.winsize`)に合わせて省略されます。
|
|
34
36
|
|
|
35
37
|
出力例(stdout):
|
|
36
38
|
|
|
@@ -123,6 +125,12 @@ Lumitrace のテキストは `sample/lumitrace_results_01.txt`、HTML は `sampl
|
|
|
123
125
|
HTML 出力を見る:
|
|
124
126
|
- [lumitrace_results_01.html](https://ko1.github.io/lumitrace/sample/lumitrace_results_01.html)
|
|
125
127
|
|
|
128
|
+
HTML について:
|
|
129
|
+
- 実行済みの式は `🔎`、未実行の式は `∅` で表示されます。
|
|
130
|
+
- 引数の値は HTML では `🧷` で表示されます。
|
|
131
|
+
- 記録対象の式がすべて未実行の行は薄い赤で表示され、混在行では未実行の式のみ薄赤になります。
|
|
132
|
+
- 範囲指定時の省略は行番号欄に `...` が入ります。
|
|
133
|
+
|
|
126
134
|
### 範囲指定の例
|
|
127
135
|
|
|
128
136
|
出力が多いときは、対象行を絞って読みやすくします。
|
|
@@ -145,6 +153,7 @@ HTML 出力を見る:
|
|
|
145
153
|
=== Lumitrace Results (text) ===
|
|
146
154
|
|
|
147
155
|
### sample/sample.rb (lines: 4-18, 28-32)
|
|
156
|
+
...
|
|
148
157
|
4| def score(n)
|
|
149
158
|
5| base = n + 1 #=> 3 (3rd run)
|
|
150
159
|
6| scaled = Sample2.scale(base) #=> 6 (3rd run)
|
|
@@ -166,6 +175,7 @@ HTML 出力を見る:
|
|
|
166
175
|
30|
|
|
167
176
|
31| puts labels.join(", ") #=> nil
|
|
168
177
|
32| p flags #=> [false, false, true]
|
|
178
|
+
...
|
|
169
179
|
```
|
|
170
180
|
|
|
171
181
|
環境変数で HTML を有効化:
|
|
@@ -180,7 +190,7 @@ LUMITRACE_HTML=/tmp/out.html lumitrace path/to/entry.rb
|
|
|
180
190
|
出力が長すぎたり読みづらいときに、1 行あたりの記録数を制限します。
|
|
181
191
|
|
|
182
192
|
```bash
|
|
183
|
-
|
|
193
|
+
LUMITRACE_MAX_SAMPLES=5 lumitrace path/to/entry.rb
|
|
184
194
|
```
|
|
185
195
|
|
|
186
196
|
### 行範囲を限定する
|
|
@@ -220,9 +230,11 @@ lumitrace -g --git-diff-no-untracked path/to/entry.rb
|
|
|
220
230
|
レンジ計算や動作の理由を追いたいときに有効です。
|
|
221
231
|
|
|
222
232
|
```bash
|
|
223
|
-
lumitrace --verbose path/to/entry.rb
|
|
233
|
+
lumitrace --verbose[=LEVEL] path/to/entry.rb
|
|
224
234
|
```
|
|
225
235
|
|
|
236
|
+
レベル: `1`(基本ログ)、`2`(変換したファイル名)、`3`(変換後ソース)。
|
|
237
|
+
|
|
226
238
|
### JSON も出力する
|
|
227
239
|
|
|
228
240
|
ツール連携や後処理のために JSON を出します。
|
|
@@ -249,6 +261,7 @@ CI アーティファクトなどに残したいときに便利です。
|
|
|
249
261
|
lumitrace --text=/tmp/lumi.txt path/to/entry.rb
|
|
250
262
|
```
|
|
251
263
|
|
|
264
|
+
|
|
252
265
|
### テキストと HTML を両方出力
|
|
253
266
|
|
|
254
267
|
素早い確認と詳細閲覧を一回で得たいときに使います。
|
|
@@ -409,5 +422,5 @@ lumitrace --root /path/to/project your_script.rb
|
|
|
409
422
|
|
|
410
423
|
日常的に効く小さなコツをまとめます。
|
|
411
424
|
|
|
412
|
-
- 出力が大きい場合は `
|
|
425
|
+
- 出力が大きい場合は `LUMITRACE_MAX_SAMPLES` を下げると軽くなります。
|
|
413
426
|
- 1 ファイルだけの確認は `enable_git_diff` が便利です。
|
data/docs/tutorial.md
CHANGED
|
@@ -26,11 +26,13 @@ Text output format:
|
|
|
26
26
|
```
|
|
27
27
|
12|
|
|
28
28
|
```
|
|
29
|
+
- Lines where all instrumentable expressions are unexecuted are prefixed with `!`.
|
|
29
30
|
- Skipped ranges are shown as:
|
|
30
31
|
```
|
|
31
32
|
...
|
|
32
33
|
```
|
|
33
34
|
- The last value is shown as `#=> ...` (with `(3rd run)` when run multiple times).
|
|
35
|
+
- When printing to a TTY, long comments are truncated to the terminal width (from `COLUMNS` or `IO.console.winsize`).
|
|
34
36
|
|
|
35
37
|
Example output (stdout):
|
|
36
38
|
|
|
@@ -123,6 +125,12 @@ If you run without `--html PATH`, the HTML output defaults to `lumitrace_recorde
|
|
|
123
125
|
View the HTML output:
|
|
124
126
|
- [lumitrace_results_01.html](https://ko1.github.io/lumitrace/sample/lumitrace_results_01.html)
|
|
125
127
|
|
|
128
|
+
HTML notes:
|
|
129
|
+
- Executed expressions show `🔎`; unexecuted expressions show `∅`.
|
|
130
|
+
- Argument values show `🧷` in HTML.
|
|
131
|
+
- Lines where all instrumentable expressions are unexecuted are shaded light red; mixed lines only shade the unexecuted expressions.
|
|
132
|
+
- When ranges are used, skipped sections are shown as `...` in the line-number column.
|
|
133
|
+
|
|
126
134
|
### Range example
|
|
127
135
|
|
|
128
136
|
When a full run is too noisy, narrow the scope to specific line ranges so you can focus on the slice you care about.
|
|
@@ -145,6 +153,7 @@ View the HTML output:
|
|
|
145
153
|
=== Lumitrace Results (text) ===
|
|
146
154
|
|
|
147
155
|
### sample/sample.rb (lines: 4-18, 28-32)
|
|
156
|
+
...
|
|
148
157
|
4| def score(n)
|
|
149
158
|
5| base = n + 1 #=> 3 (3rd run)
|
|
150
159
|
6| scaled = Sample2.scale(base) #=> 6 (3rd run)
|
|
@@ -166,6 +175,7 @@ View the HTML output:
|
|
|
166
175
|
30|
|
|
167
176
|
31| puts labels.join(", ") #=> nil
|
|
168
177
|
32| p flags #=> [false, false, true]
|
|
178
|
+
...
|
|
169
179
|
```
|
|
170
180
|
|
|
171
181
|
Enable HTML output via env:
|
|
@@ -180,7 +190,7 @@ LUMITRACE_HTML=/tmp/out.html lumitrace path/to/entry.rb
|
|
|
180
190
|
If the output is too long or slow to scan, cap how many values per line are recorded.
|
|
181
191
|
|
|
182
192
|
```bash
|
|
183
|
-
|
|
193
|
+
LUMITRACE_MAX_SAMPLES=5 lumitrace path/to/entry.rb
|
|
184
194
|
```
|
|
185
195
|
|
|
186
196
|
### Limit to specific lines
|
|
@@ -220,9 +230,11 @@ lumitrace -g --git-diff-no-untracked path/to/entry.rb
|
|
|
220
230
|
Turn this on when you need to understand how ranges were computed or why a line was (not) recorded.
|
|
221
231
|
|
|
222
232
|
```bash
|
|
223
|
-
lumitrace --verbose path/to/entry.rb
|
|
233
|
+
lumitrace --verbose[=LEVEL] path/to/entry.rb
|
|
224
234
|
```
|
|
225
235
|
|
|
236
|
+
Levels: `1` (basic), `2` (instrumented file names), `3` (instrumented source).
|
|
237
|
+
|
|
226
238
|
### Write JSON too
|
|
227
239
|
|
|
228
240
|
Use JSON output when you want to post-process results with scripts or other tools.
|
|
@@ -249,6 +261,7 @@ Send text output to a file when you want to archive results or attach them to CI
|
|
|
249
261
|
lumitrace --text=/tmp/lumi.txt path/to/entry.rb
|
|
250
262
|
```
|
|
251
263
|
|
|
264
|
+
|
|
252
265
|
### Text plus HTML
|
|
253
266
|
|
|
254
267
|
Get both the fast terminal view and the richer HTML report in one run.
|
|
@@ -408,5 +421,5 @@ lumitrace --root /path/to/project your_script.rb
|
|
|
408
421
|
|
|
409
422
|
Small knobs that keep outputs readable and noise low in day-to-day use.
|
|
410
423
|
|
|
411
|
-
- If your output is large, lower `
|
|
424
|
+
- If your output is large, lower `LUMITRACE_MAX_SAMPLES`.
|
|
412
425
|
- For quick checks on a single file, `enable_git_diff` keeps noise down.
|