Pull the application's log files off the server and read them in the browser — web server errors, access logs, PHP-FPM, systemd, or a container's output — with level filtering, text search and download.
Getting here: Servers → a server → Applications → an application → Logs
1. How the tab works
Nothing loads until you ask for it. You choose what to read and how much, press Fetch Logs, and the panel connects to the server over SSH, reads the tail of the file, and displays it.
Before the first fetch:
2. Log source
| Source | What it is | Where it comes from |
|---|---|---|
| Error Logs | The web server's error log for this application | /var/log/nginx/<name>_error.log or the Apache equivalent |
| Access Logs | Every request the web server served | …/<name>_access.log |
| PHP-FPM Logs | The PHP process manager's own log | /var/log/php<version>-fpm.log |
| Systemd Logs | The web server service's journal | journalctl -u nginx / -u apache2 |
The exact path being read is shown in small text under the controls, so you always know which file you are looking at.
Docker Image applications are different
An application deployed from a Docker image has no PHP-FPM or vhost logs of its own. For those, the source list collapses to a single option, selected automatically:
| Source | What it is |
|---|---|
| Container Logs | The container's own stdout and stderr — docker logs |
That is the right and only place to look for a container: whatever your image prints is what you get.
Which source answers which question
- The site returns 500, or a page is blank → Error Logs. PHP fatals, nginx upstream failures and permission problems land here.
- "Is anyone actually reaching the site?" → Access Logs. Every request with its status code — this is where you confirm traffic is arriving at all, and which status it gets.
- PHP crashes, worker exhaustion, memory limits → PHP-FPM Logs.
- The web server itself will not start, or restarted unexpectedly → Systemd Logs. When nginx or Apache is down there is no vhost error log entry to find, because the service never got far enough to write one. This is the source people forget.
- A container that exits, restarts, or never comes up → Container Logs.
3. Lines
50 / 100 / 200 / 500 / 1000, defaulting to 200.
This is the tail length — the last N lines of the file.
It also bounds everything below it. The filters and the search work on what was fetched, not on the file on disk. Searching 200 lines for an error that happened an hour ago finds nothing, and the honest fix is to fetch 1000 rather than to conclude the error isn't there.
Start at 200 for a quick look; go to 1000 when you are searching for something specific or the log is busy.
4. Fetching
Fetch Logs runs the read, showing Fetching… while it works. Afterwards:
- Refresh re-runs the same fetch with the same settings.
- Last fetched: shows the time of the most recent read, so you can tell a stale view from a fresh one.
If it fails:
That message is usually accurate — an unreachable server or a stopped service is the common cause, rather than a missing file. A missing file reports itself distinctly, as No error log found for ….
The panel finds the right file itself
Log files are not always named after the application, and the answer depends on how the vhost was created:
- A fresh install names them after the application.
- An application deployed from Git or a ZIP gets no vhost at deploy time — its only vhost comes later from Add Domain, which names log files after the domain.
- An application with several domains has several vhosts, each with its own log file.
The server's stored web server setting can also be stale for one particular application — for instance, if Apache was set up by hand for it alone.
So rather than assuming, the panel tests every combination of web server and candidate name against what is actually on disk and uses the first that exists. The detected values then correct the path shown in the tab. This is why the path hint can change after your first fetch: it stops being a guess and becomes what was really read.
5. Level filter badges
Once logs are loaded, four badges appear, each with a live count:
| Badge | Colour |
|---|---|
| All | grey — total lines fetched |
| Errors | red |
| Warnings | amber |
| Info | blue |
Clicking one filters the view to that level; the selected badge is ringed.
How lines get classified
By reading the text of each line — looking for error, [warn], [info], [debug] and similar markers. There is no structured log parsing behind it.
Two consequences worth knowing:
- A line can be classified by coincidence. An access-log entry for a URL containing the word "error" is counted as an error.
- Continuation lines are not classified. A stack trace's second and later lines carry no marker, so they show as plain output and are hidden when you filter to Errors — which can make an error look truncated. Switch back to All to read the whole trace.
Treat the counts as a fast triage signal, not an audit.
Debug lines are recognised and dimmed in the viewer, but have no badge of their own — they are visible under All.
6. Text search
Filter logs… narrows to lines containing what you type, case-insensitively, and combines with the level badge — Errors plus database shows only error-classified lines mentioning the database. ✕ clears it.
The viewer header tells you what you are looking at:
Useful things to search for: a status code (500, 404), an IP address, a specific URL path, a filename from a stack trace, or a timestamp such as 14:2 to narrow to a window.
7. The viewer
A dark terminal-style panel:
- Numbered lines, so you can refer to a position while filtered.
- Colour and a dot per level — red for errors, amber for warnings, blue for info, dimmed grey for debug, plain for everything else.
- Long lines wrap rather than scrolling sideways, so nothing is hidden off the edge.
- Scrolls within a fixed height; the page itself stays put.
When a filter matches nothing: No lines match your filter.
Download
The Download button in the viewer's title bar saves the log as a .log file named after the application, source and timestamp — for example myapp-error-1723545600000.log.
It downloads everything fetched, not the filtered view. That is usually what you want when you are attaching a log to a support request or a bug report: the surrounding context is what makes the error diagnosable.
8. Practical use
- Reproduce, then fetch. Trigger the problem, then read — the tail shows the most recent lines, so a fresh fetch puts your event at the bottom.
- Fetch more lines before concluding a log is empty. The default 200 covers only the last moments of a busy site.
- Cross-check error against access. An error with no matching access entry means the request never reached the application; an access entry with a 500 and no error line often means the failure happened upstream, in the web server itself.
- Go to Systemd when the site is entirely down. A web server that failed to start writes nothing to a vhost log.
- Read a stack trace under All, not under Errors.
- Download before you go asking for help. A screenshot of a filtered view omits precisely the context needed.
9. Common problems
| Problem | Cause |
|---|---|
| No error log found for … | No log file exists yet under any candidate name — often an application that has never served a request, or one whose vhost was never created |
| Failed to fetch logs | The server is unreachable or the service is not running |
| Logs look old | The view is a snapshot — press Refresh |
| The error you are looking for is missing | It is older than the tail you fetched; raise Lines |
| Nothing under Errors but the site is broken | The failure never reached the application — check Access Logs, then Systemd Logs |
| An error appears cut off | Its continuation lines are unclassified and hidden by the level filter — switch to All |
| An access line counted as an error | Classification is text-based; a URL containing "error" is enough |
| No PHP-FPM option | The application is a Docker image deployment — only Container Logs applies |
| Empty container logs | The container prints nothing, or never started — check the Services tab |
| Path hint changed after fetching | Expected: the panel replaced its guess with the file it actually found |
| Filter finds nothing you know is there | Search only covers the lines fetched, not the whole file |
10. How this relates to other places
| Where | Scope |
|---|---|
| Logs (this tab) | Web server, PHP-FPM, systemd and container logs for this application |
| Services tab | PM2 process logs — a Node process's own output, per process |
| Server logs | Server-wide services rather than one application's vhost |
| Settings tab | Uptime monitoring — tells you the site is unreachable; this tells you why |
The pairing worth remembering: Settings alerts you, Logs explains it.
Something here not matching what you see in the panel?
Tell us