PHPackages                             soloterm/vtail - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Logging &amp; Monitoring](/categories/logging)
4. /
5. soloterm/vtail

ActiveLibrary[Logging &amp; Monitoring](/categories/logging)

soloterm/vtail
==============

Vendor-aware tail for Laravel logs with stack trace formatting and vendor frame collapsing

v0.1.0(5mo ago)32MITPHPPHP ^8.1CI passing

Since Dec 16Pushed 5mo agoCompare

[ Source](https://github.com/soloterm/vtail)[ Packagist](https://packagist.org/packages/soloterm/vtail)[ RSS](/packages/soloterm-vtail/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (4)Versions (2)Used By (0)

vtail
=====

[](#vtail)

[![Latest Version on Packagist](https://camo.githubusercontent.com/08fde0d1d873442126a259b802260064123759ae47e58453ccd4e8f708e7605f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f736f6c6f7465726d2f767461696c2e737667)](https://packagist.org/packages/soloterm/vtail)[![Total Downloads](https://camo.githubusercontent.com/e16724b98d78922b2ef0ae761e940401a3ed950b7d23313b2ea3c1d7108a1a6a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f736f6c6f7465726d2f767461696c2e737667)](https://packagist.org/packages/soloterm/vtail)[![License](https://camo.githubusercontent.com/074b89bca64d3edc93a1db6c7e3b1636b874540ba91d66367c0e5e354c56d0ea/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e737667)](LICENSE)

Vendor-aware tail for Laravel logs with stack trace formatting and vendor frame collapsing.

vtail is an interactive TUI for real-time log monitoring that intelligently collapses vendor frames in stack traces, making it easier to focus on your application code.

[![vtail screenshot](art/screenshot.png)](art/screenshot.png)

Features
--------

[](#features)

- **Vendor Frame Collapsing** - Hide vendor frames in stack traces with a single keypress, collapsing them into a count like `#… (5 vendor frames)`
- **Smart Stack Trace Formatting** - Stack traces are visually grouped with borders and dimmed decorations
- **Line Wrapping Toggle** - Switch between wrapped and truncated long lines
- **Follow Mode** - Auto-scroll to new log entries as they arrive
- **Keyboard Navigation** - Vim-style navigation (j/k/g/G) plus page up/down
- **ANSI &amp; Unicode Aware** - Proper handling of colored output and wide characters (CJK, emoji)

Vendor Frame Collapsing
-----------------------

[](#vendor-frame-collapsing)

Press `v` to toggle vendor frame visibility. Consecutive vendor frames collapse into a single line showing the count:

### Vendor frames shown (default)

[](#vendor-frames-shown-default)

```
[2024-01-15 10:23:45] production.ERROR: User not found
 {"exception":"[object] (App\\Exceptions\\UserNotFoundException(code: 0):
 User not found at /app/Services/UserService.php:128)
 ╭─Trace────────────────────────────────────────────────────────────────────╮
 │ #00 /app/Http/Controllers/UserController.php(42): store()                │
 │ #01 /vendor/laravel/framework/src/Illuminate/Routing/Router.php(693)     │
 │ #02 /vendor/laravel/framework/src/Illuminate/Routing/Router.php(670)     │
 │ #03 /vendor/laravel/framework/src/Illuminate/Routing/Router.php(636)     │
 │ #04 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183)  │
 │ #05 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(119)  │
 │ #06 /app/Services/UserService.php(128): createUser()                     │
 ╰══════════════════════════════════════════════════════════════════════════╯

```

### Vendor frames hidden (press `v`)

[](#vendor-frames-hidden-press-v)

```
[2024-01-15 10:23:45] production.ERROR: User not found
 {"exception":"[object] (App\\Exceptions\\UserNotFoundException(code: 0):
 User not found at /app/Services/UserService.php:128)
 ╭─Trace────────────────────────────────────────────────────────────────────╮
 │ #00 /app/Http/Controllers/UserController.php(42): store()                │
 │ #… (5 vendor frames)                                                     │
 │ #06 /app/Services/UserService.php(128): createUser()                     │
 ╰══════════════════════════════════════════════════════════════════════════╯

```

Your application code stands out while framework internals are summarized.

Installation
------------

[](#installation)

```
composer global require soloterm/vtail
```

Or install locally in your project:

```
composer require --dev soloterm/vtail
```

Usage
-----

[](#usage)

```
vtail [options]

Options:
  -h, --help       Show help message
  -n        Initial tail count (default: 100)
  --no-vendor      Start with vendor frames hidden
  --no-wrap        Start with line wrapping disabled

Examples:
  vtail storage/logs/laravel.log
  vtail --no-vendor laravel.log
  vtail -n 50 /var/log/app.log
```

Hotkeys
-------

[](#hotkeys)

KeyAction`v`Toggle vendor frame visibility`w`Toggle line wrapping`t`Truncate (clear) the log file`f` / `Space`Toggle follow mode`j` / `Down`Scroll down one line`k` / `Up`Scroll up one line`g`Jump to top`G`Jump to bottom (enables follow)`PgUp`Page up`PgDn`Page down`q` / `Ctrl-C`QuitArchitecture
------------

[](#architecture)

```
                              vtail Data Flow
    ============================================================

    ┌─────────────────┐
    │   laravel.log   │
    │   (Log File)    │
    └────────┬────────┘
             │
             │ tail -f -n
             ▼
    ┌─────────────────┐
    │  Tail Process   │  Subprocess via proc_open()
    │  (Non-blocking) │  with async pipe reading
    └────────┬────────┘
             │
             │ Raw log lines (strings)
             ▼
    ┌─────────────────────────────────────────────────────────┐
    │                    LogFormatter                         │
    │  ┌───────────────────────────────────────────────────┐  │
    │  │  • Detect stack frames (#N pattern)               │  │
    │  │  • Detect exception headers                       │  │
    │  │  • Identify vendor frames (/vendor/ path)         │  │
    │  │  • Group consecutive vendor frames                │  │
    │  │  • Apply ANSI styling (borders, dim text)         │  │
    │  │  • Wrap/truncate to terminal width                │  │
    │  └───────────────────────────────────────────────────┘  │
    └────────┬────────────────────────────────────────────────┘
             │
             │ Line objects with metadata
             ▼
    ┌─────────────────────────────────────────────────────────┐
    │                   LineCollection                        │
    │  ┌───────────────────────────────────────────────────┐  │
    │  │  • Store formatted Line objects                   │  │
    │  │  • Apply hideVendor filter                        │  │
    │  │  • Collapse vendor groups → "#... (N frames)"     │  │
    │  │  • Calculate scroll position adjustments          │  │
    │  └───────────────────────────────────────────────────┘  │
    └────────┬────────────────────────────────────────────────┘
             │
             │ Display-ready strings
             ▼
    ┌─────────────────────────────────────────────────────────┐
    │                    Application                          │
    │  ┌───────────────────────────────────────────────────┐  │
    │  │  Event Loop (25ms / 40 FPS)                       │  │
    │  │  ┌─────────────────────────────────────────────┐  │  │
    │  │  │ 1. Collect output from tail subprocess      │  │  │
    │  │  │ 2. Process lines if new data or dirty flag  │  │  │
    │  │  │ 3. Render viewport to terminal              │  │  │
    │  │  │ 4. Wait for user input (25ms timeout)       │  │  │
    │  │  │ 5. Handle hotkey → update state → repeat    │  │  │
    │  │  └─────────────────────────────────────────────┘  │  │
    │  └───────────────────────────────────────────────────┘  │
    └────────┬────────────────────────────────────────────────┘
             │
             │ ANSI escape sequences
             ▼
    ┌─────────────────────────────────────────────────────────┐
    │                      Terminal                           │
    │  ┌───────────────────────────────────────────────────┐  │
    │  │  ┌─────────────────────────────────────────────┐  │  │
    │  │  │ STATUS BAR                                  │  │  │
    │  │  │ laravel.log | Lines: 247 | VENDOR: hidden   │  │  │
    │  │  ├─────────────────────────────────────────────┤  │  │
    │  │  │ CONTENT AREA                                │  │  │
    │  │  │ ╭─Trace──────────────────────────────────╮  │  │  │
    │  │  │ │ #01 /app/Http/Controllers/Api.php(42)  │  │  │  │
    │  │  │ │ #… (5 vendor frames)                   │  │  │  │
    │  │  │ │ #07 /app/Models/User.php(128)          │  │  │  │
    │  │  │ ╰────────────────────────────────────────╯  │  │  │
    │  │  ├─────────────────────────────────────────────┤  │  │
    │  │  │ HOTKEY BAR                                  │  │  │
    │  │  │ v vendor  w wrap  t truncate  f follow      │  │  │
    │  │  └─────────────────────────────────────────────┘  │  │
    │  └───────────────────────────────────────────────────┘  │
    └─────────────────────────────────────────────────────────┘

                           ▲
                           │ Keyboard input
                           │
                    ┌──────┴──────┐
                    │    User     │
                    └─────────────┘

```

### Component Overview

[](#component-overview)

ComponentFileResponsibility**Application**`src/Application.php`Event loop, state management, rendering**LogFormatter**`src/Formatting/LogFormatter.php`Parse logs, detect vendors, apply styling**LineCollection**`src/Formatting/LineCollection.php`Filter lines, collapse vendor groups**Line**`src/Formatting/Line.php`Data class for formatted lines**AnsiAware**`src/Formatting/AnsiAware.php`ANSI-safe string operations**Terminal**`src/Terminal/Terminal.php`TTY control, raw mode, cursor**KeyPressListener**`src/Input/KeyPressListener.php`Hotkey bindings### Vendor Detection

[](#vendor-detection)

A stack frame is considered "vendor" if:

1. The path contains `/vendor/` (except when `BoundMethod.php` is calling app code)
2. The frame is `{main}` (root of execution)

Consecutive vendor frames are grouped and can be collapsed into a single line showing the count.

Requirements
------------

[](#requirements)

- PHP 8.1+
- Extensions: `pcntl`, `posix`, `mbstring`
- Unix-like OS (Linux, macOS)

License
-------

[](#license)

MIT

Related Projects
----------------

[](#related-projects)

vtail is part of the [SoloTerm](https://github.com/soloterm) project:

- [Solo](https://github.com/soloterm/solo) - All-in-one Laravel command for local development
- [Screen](https://github.com/soloterm/screen) - Pure PHP terminal renderer
- [Dumps](https://github.com/soloterm/dumps) - Laravel command to intercept dumps
- [Grapheme](https://github.com/soloterm/grapheme) - Unicode grapheme width calculator
- [Notify](https://github.com/soloterm/notify) - PHP package for desktop notifications via OSC escape sequences
- [Notify Laravel](https://github.com/soloterm/notify-laravel) - Laravel integration for soloterm/notify
- [TNotify](https://github.com/soloterm/tnotify) - Standalone, cross-platform CLI for desktop notifications

###  Health Score

31

—

LowBetter than 68% of packages

Maintenance73

Regular maintenance activity

Popularity7

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity33

Early-stage or recently created project

 Bus Factor1

Top contributor holds 92.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

153d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/033238953a59b9223a1bde703b5e4254e63c7412195da1cb9de5af44bf53fc0a?d=identicon)[aarondfrancis](/maintainers/aarondfrancis)

---

Top Contributors

[![aarondfrancis](https://avatars.githubusercontent.com/u/881931?v=4)](https://github.com/aarondfrancis "aarondfrancis (12 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (1 commits)")

---

Tags

logcliterminallaraveltail

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/soloterm-vtail/health.svg)

```
[![Health](https://phpackages.com/badges/soloterm-vtail/health.svg)](https://phpackages.com/packages/soloterm-vtail)
```

###  Alternatives

[spatie/laravel-tail

Easily tail application logs

7592.5M4](/packages/spatie-laravel-tail)[shalvah/clara

🔊 Simple, pretty, testable console output for CLI apps.

2811.8M6](/packages/shalvah-clara)[ytake/laravel-fluent-logger

fluent logger for laravel and lumen

63541.6k1](/packages/ytake-laravel-fluent-logger)[trash-panda/progress-bar-log

Component to display a progress bar and last X logs at the same time

4119.2k](/packages/trash-panda-progress-bar-log)[kitloong/laravel-app-logger

Laravel log for your application

101.2M8](/packages/kitloong-laravel-app-logger)[moesif/moesif-laravel

Moesif Collection/Data Ingestion Middleware for Laravel

1065.8k](/packages/moesif-moesif-laravel)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
