Live monitoring catches bugs that only appear at runtime — not during a test run. Instead of scanning a finished test report, IssueLoop watches a process or log file continuously: whenever error-matching lines appear in the output, they are buffered, debounced into a single entry, and written to the same JSONL log that the batch test runner uses. From that point on,Documentation Index
Fetch the complete documentation index at: https://mintlify.com/onenot8/issueLoop/llms.txt
Use this file to discover all available pages before exploring further.
issueloop tickets picks them up with no extra steps. Use live monitoring alongside the batch workflow for long-running servers, daemons, or any process whose failures surface in production-style logs rather than a test suite.
Mode A — watch a process
In this mode IssueLoop spawns and owns the process. When the process writes matching lines to its output, the watcher captures them.The repo identifier — must match a
name entry in test_manifest.json so that tickets can be associated with the right project.The shell command to spawn. Executed with
shell=True. Both stdout and stderr are merged into a single stream for pattern matching.Working directory for the spawned process. Defaults to the current directory.
How many seconds of quiet output to wait before flushing the buffered error block as a single ticket entry. Default is
3.0.A list of compiled
re pattern objects to match against incoming lines. Any line matching at least one pattern starts or extends the error buffer. Defaults to the DEFAULT_ERROR_PATTERNS list — see the Error detection patterns section. Override this to narrow or expand what counts as an error for your process.An optional callback invoked each time the debounce timer fires and a buffered error block is written to disk. The callback receives the flushed entry dict as its only argument. Use this to trigger real-time notifications or forward errors to an external system without polling the JSONL log.
Mode B — tail a log file
In this mode the target process is already running and writing to a file. IssueLoop seeks to the end of the file and reads new lines as they arrive — it never re-reads historical content.The repo identifier — must match a
name entry in test_manifest.json.Absolute or relative path to the log file to tail. IssueLoop seeks to the end of the file on open and only reads lines written after the watcher started.
A human-readable label stored on each flushed entry as the
command field. Defaults to "tail:<log_path>". Set this to something descriptive if you have multiple watchers on the same repo so you can tell their ticket entries apart.How many seconds of quiet output to wait before flushing. Default is
3.0.Override the compiled regex patterns used to detect errors. Defaults to
DEFAULT_ERROR_PATTERNS.Optional callback invoked with the flushed entry dict each time the debounce timer fires and a block is written to disk.
Error detection patterns
IssueLoop matches each incoming line against a set of compiled regular expressions. A line that matches any pattern starts (or extends) the current error buffer. The default patterns are:| Pattern | Notes |
|---|---|
Traceback (most recent call last) | Python exception header |
\w*exception\w* (case-insensitive) | Any word containing “exception” |
\w*error\w* (case-insensitive) | Any word containing “error” |
^FAILED\b | pytest-style failure line at start of line |
\bfatal\b (case-insensitive) | Fatal messages |
panic: | Go-style panics |
\bpanicked at\b | Rust-style panics |
re.search, so they match anywhere in the line, not just at the start (except ^FAILED, which is anchored). Once the first matching line arrives, every subsequent line is added to the buffer regardless of whether it matches — this ensures the full traceback or stack trace is captured, not just the first error line.
Debouncing
Errors rarely arrive as a single line. A Python traceback spans many lines; a Go panic dumps a goroutine stack. Without debouncing, each line would become its own ticket entry, flooding the queue with fragments of the same event. The debounce mechanism works like this:- The first matching line starts the buffer and arms a timer set to
debounce_seconds(default3.0). - Each subsequent line resets the timer.
- When the timer fires — meaning no new lines arrived for
debounce_seconds— the entire buffer is flushed as a single JSONL entry and the buffer is cleared.
debounce_seconds lower for interactive workflows where you want faster feedback, or higher for noisy logs where related errors arrive in slow waves.
Stopping a watcher
stop_watch accepts the integer handle returned by watch_process or watch_log_file. It cancels the debounce timer, flushes any remaining buffered lines immediately, and terminates the spawned process (if running in process-watch mode).
Output format
Each flushed error block is written todata/logs/run_<repo>.jsonl as a JSON object with the same shape as a batch test runner result:
issueloop tickets myrepo (or issueloop.create_tickets("myrepo")) reads live monitoring entries and batch test entries from the same file and triages them all in one pass. No extra configuration is required.