Linux task wait diagnosis, file contention timelines and replayable incident reports in MoonBit
./moonlocklens diagnose 1234
./moonlocklens watch 1234 --samples 10 --interval 500 --output incident.json
./moonlocklens report incident.json --markdown > incident.md.\output\cli\moonlocklens-0.4.0\moonlocklens.cmd report fixtures/task-session.json.\output\cli\moonlocklens-0.4.0\moonlocklens.cmd inspect fixtures/contention.locks --pid 300chmod +x moonlocklens
./moonlocklens live --file /path/to/cache.lock --waiting
./moonlocklens capture incident.locks
./moonlocklens inspect incident.locks --json > report.jsonPID 300 的请求 [源行 3]
→ 等待 PID 200 的请求 [源行 2]
→ 等待 PID 100 的根锁 [源行 1]moon test --target wasm-gc --deny-warn
moon test --target js --deny-warn
moon run examples/demo --target wasm-gc
moon run cmd/main --target js -- inspect fixtures/contention.locks
moon run cmd/main --target js -- chain fixtures/contention.locks 3
moon run cmd/main --target js -- range fixtures/contention.locks 08:01:42 99 99
moon run cmd/main --target js -- live./scripts/verify.ps1 -MoonHome ./release-local/toolchainmoon add length-super/moonlocklens@0.4.0let snapshot = @locks.parse(text)
let chain = snapshot.wait_chain(3) // 请求本身 → 直接 blocker → 根记录
let impact = snapshot.bottlenecks() // 根记录按所有后代等待数排序
let matching = snapshot.matching(pid=300, waiting_only=true)
let context = snapshot.with_blockers(matching.map(e => e.line))
let children = snapshot.children(1) // 只返回直接等待项
let hits = snapshot.query_range(
@locks.file_key("08:01:42"),
@locks.byte_range("0", "99"),
include_waiters=false,
)pub struct FileCapture {
// private fields
}pub(all) struct FileReport {
file : FileKey
sample_count : Int
observed_span_ms : Int64
peak_waiting_records : Int
max_consecutive_wait_samples : Int
frames : Array[FileFrameReport]
} derive(ToJson)pub struct TaskCapture {
// private fields
}pub(all) struct TaskChange {
pid : Int
start_ticks : String
change : String
before : String
after : String
} derive(ToJson)pub(all) struct TaskComparison {
root_pid : Int
root_start_ticks : String
evidence_complete : Bool
before_waiters : Int
after_waiters : Int
resolved_lock_waits : Int
new_lock_waits : Int
changes : Array[TaskChange]
issues : Array[String]
} derive(ToJson)pub(all) struct TaskFrameReport {
elapsed_ms : Int64
root_state : String
processes : Array[TaskProcess]
blocker_processes : Array[ProcessInfo]
issues : Array[String]
} derive(ToJson, Debug)pub(all) struct TaskReport {
root_pid : Int
root_start_ticks : String
started_at : String
sample_count : Int
observed_span_ms : Int64
max_consecutive_wait_samples : Int
max_sampled_wait_span_ms : Int64
frames : Array[TaskFrameReport]
transitions : Array[TaskTransition]
next_steps : Array[String]
} derive(ToJson, Debug)pub(all) struct WaitAssessment {
status : String
threshold_samples : Int
sample_count : Int
observed_streak : Int
evidence_gaps : Int
reason : String
} derive(ToJson)fn parse_process(stat : String, wchan? : String, wchan_error? : String) -> ProcessInfo raise LockErrorInstall
Download zipLinux task wait diagnosis, file contention timelines and replayable incident reports in MoonBit