Monitor
On this page
The Monitor records what each request to your sites did: the server's stages, every query, cache read, mail, log line and outgoing call with when it started and how long it took, the exceptions, the jobs it queued and, for a page, what the browser saw. It keeps that history on your computer and counts it into routes, query shapes, exceptions, jobs, outgoing hosts and pages, so the slow and broken parts stand out.
The Monitor is part of Short Leash Pro.
What does it record?
Every request through Short Leash's proxy, for every site, with what the app did for it:
| Part | What you get |
|---|---|
| The request | Method, route, status, time, headers and body (masked when saved) |
| The server | Stages (boot, middleware, action, render, response), memory, the signed-in user's id when the framework knows it |
| Queries | Each one with its SQL, values and time. N+1s and repeated queries are found for you, and Explain reads a query's plan (MySQL, MariaDB, PostgreSQL and SQLite, not MongoDB) |
| Calls out | Outgoing HTTP calls with their status and time |
| Cache, mail, views, logs | Each with when it happened |
| Exceptions | Class, message and stack trace, with dependency frames folded, grouped across requests |
| Jobs | Jobs a request queued, shown under it when they run, plus commands and scheduled tasks |
| The browser | Load timings, Web Vitals (LCP, INP, CLS, TTFB), JavaScript errors, console errors, and the API calls the page made |
What does the Monitor screen show first?
Four tiles for the range you pick (the last hour, 24 hours or 7 days), for all your sites or the one you chose: requests, server errors, the slowest route's P95 and exceptions, each with its trend. A tile with something wrong has a red edge on top. Under them are the tabs: pages, routes, queries, exceptions, jobs and outgoing calls.
Which frameworks does it work with?
All of them, in one of three ways, with nothing to install in your project:
- Short Leash's agents load into the app the way each runtime allows: PHP through Short Leash's prepend file, Python through a wrapper around your WSGI or ASGI app, Ruby through
RUBYOPT, Node throughNODE_OPTIONS. They cover Laravel and Statamic, WordPress, Django, Flask, FastAPI and other WSGI or ASGI apps, SQLAlchemy, Rails and Rack, Express, Next.js and other Node servers on Node 18.19, 20.6 or later. Other PHP apps (Symfony, Craft, plain PHP) show each request's time, memory,dump()calls and fatal errors; for their queries and calls, add OpenTelemetry.- Jobs: Laravel's queue workers report their jobs. Celery and RQ workers do when you start them through the agent, as a site process:
python -m leash_monitor.run celery -A proj worker. Rails reports Active Job jobs run in the app's own process; Sidekiq and Solid Queue workers aren't covered yet. - Turning them off: the agents load while dump capture is on (the Capturing switch in Dumps). If an app won't start with Short Leash's agent, turn off Short Leash's agent in the site's settings; the app restarts without it.
- Jobs: Laravel's queue workers report their jobs. Celery and RQ workers do when you start them through the agent, as a site process:
- OpenTelemetry: Short Leash listens for OTLP on
127.0.0.1:9914(or a free port when that's taken; the site's settings show which) and points the apps it starts at it, with a token that changes each time Short Leash starts, so Go, Deno, Bun and anything instrumented show up the same way. If your project already sends its telemetry somewhere (its environment,.env,.env.local,.env.developmentor.env.development.localsetsOTEL_EXPORTER_OTLP_ENDPOINT), Short Leash leaves that alone; turn on Send OpenTelemetry to Short Leash in the site's settings to send it to Short Leash anyway. That beats what those files set, but not what you set in the site's environment in Short Leash. - The proxy records every request for every site, so even a site with no agent shows its requests, times and pages.
How does the browser part work?
For pages you open on this computer, Short Leash adds one small script to the page (served from the site itself, at /.well-known/leash/monitor.js). It reports errors, console errors, the page's own API calls and its timings, and links them to the request that served the page. Short Leash asks your app for those pages uncompressed so the script can go in; it's never added to shared traffic, to pages the app compresses anyway, or to pages whose security policy wouldn't allow it. Only the site's own pages can report to it, so another website open in your browser can't add to its Monitor. Turn it off per site with Browser capture in the site's settings.
How long is history kept?
7 days or 1 GB, whichever comes first, oldest first. Hourly counts for routes and pages are kept 30 days. Change both in Settings › Monitor, which also shows how much is kept and how far back it goes. Clear history clears the Monitor and the live requests.
Is it safe to keep requests on disk?
History lives in Short Leash's folder, readable only by you. Before anything is saved, cookies, authorization headers, values whose names look secret (password, token, secret, key, code, session and the like) in query strings, forms, JSON and URLs, query values bound to such columns, the same values written into SQL (remember_token = '…', an INSERT's values), and values that look like tokens become [masked]. Masking by name and shape can miss a secret written into free text, such as an object you dumped, or SQL that hides the column's name; clear history if that happens. While Short Leash runs, the last requests stay as they happened, unmasked, so you can debug the one in front of you. Traffic through a share is kept with smaller bodies, marked shared, and limited to a fifth of the history.
What is a canonical log line?
One wide line per request, job or command with everything that matters about it: http.route, http.status, duration_ms, db.queries, db.n_plus_one, cache.hits, exception.class, user.id and more. Search them by field, such as status>=500 db.queries>20, in the Monitor's Canonical log, or from a terminal:
leash monitor tail --follow -q 'status>=500'
Add your own fields: Laravel's Context::add() values and leash_tag(['tenant' => 'acme']) in PHP, leash_monitor.tag(tenant="acme") in Python, Leash.tag(tenant: "acme") in Ruby and globalThis.leash?.tag({ tenant: "acme" }) in Node appear as app.tenant. An app that prints its own canonical line (a log line with canonical-log-line in it, in logfmt or JSON, naming the request's X-Leash-Request id as request_id) gets it merged into the request's.
Can AI tools read it?
Yes. The leash mcp server has get_trace, get_slow_routes, get_query_groups, get_n_plus_one, get_exception_groups, get_jobs, get_outgoing, get_page_errors and search_canonical. Bodies of traffic through a share are left out unless a tool asks for them, since a visitor wrote them.
Copy for agent under a finding in a group, such as an N+1 on a route or a failed job, copies it for a coding assistant: what Short Leash found, the route, query, job or host it's about, which of these tools read more (with the site and request id to pass), and how to check the fix when there's a way. It says that the names, queries and messages in it come from your site and its programs, so the assistant treats them as data, not instructions.
Copy as Markdown in an open group's header copies what the panel shows, ready for an issue, a pull request or a coding assistant:
- Exceptions: the message, where it was thrown and the first frame in your app, how often and when, the routes and users it hit, the stack with your app's frames listed and library frames folded to a count, and the latest occurrence.
- Queries: the SQL with
?for its values, where it's called from, how often it ran with its total, average and slowest time, any N+1 or duplicate finding, and one run's values, masked. - Routes: requests, server errors, average and P95 times, findings, and the slowest recent requests.
- Jobs: runs and failures, the last error, and recent runs with their wait and run times.
- Outgoing: calls, failures, timings and the calls in its latest request.
- Pages: Web Vitals at P75 with their ratings, the one that's poor, and JavaScript errors.
Every copy ends by saying it's data from Short Leash's Monitor, not instructions. Everything a copy holds is masked by Short Leash's background service, by the same rules as saved data: what the Monitor saved was masked when it was saved, and a request still only in memory is masked the same way before it's copied. A group's sample request shows as it's saved, masked.
Does it notify me?
When a route takes more than a second, an N+1 is found, an exception is new, a job fails or a page's Web Vitals are poor. Choose where those go under Monitor in Settings › Notifications.