To find a line inside a file, run grep "search term" filename. To search every file in a directory and its subdirectories, add -r: grep -r "search term" /path/to/directory. That single command is usually the fastest way to find the exact line in a log file that explains why something broke.
Basic searches
grep scans text and prints any line that matches what you're looking for. The simplest form is:
grep "Fatal error" error_log
That prints every line in error_log containing the phrase Fatal error. A few flags make this more useful day to day:
-iignores case, soerroralso matchesErrorandERROR.-nshows the line number next to each match, which helps when you need to open the file and look at the surrounding context.-cprints a count of matching lines instead of the lines themselves. Handy for checking whether an error is a one-off or happening constantly.-vinverts the match, showing every line that does not contain the search term. Useful for filtering out noise.
Combine flags as needed: grep -in "warning" error_log finds warnings regardless of case and shows line numbers.
Searching recursively across a directory
Most real debugging involves more than one file. If you're not sure which log or which site under public_html/ threw the error, search the whole directory tree:
grep -rn "PHP Fatal error" ~/public_html/
The -r flag recurses into every subdirectory, and -l (lowercase L) is worth knowing too: it prints only the filenames that contain a match, not the matching lines themselves. That's a fast way to answer which of these files mentions this string before digging into any one of them:
grep -rl "undefined function" ~/public_html/
If you're deploying code and tracking down where a build artifact went wrong, this is also useful after a git deployment lands the wrong files somewhere: grep the deploy path for a string you know should (or shouldn't) be there.
Watching a log as it happens
grep works on a snapshot of a file. If you want to watch new lines appear in real time and filter them as they come in, pipe tail -f into grep:
tail -f error_log | grep --line-buffered "500"
The --line-buffered flag keeps output flowing line by line instead of waiting for a buffer to fill, which matters when you're piping to another command. This combination is a standard way to reproduce a bug live: open the tail, trigger the request in your browser, and watch the matching line appear.
Patterns, not just plain text
grep supports regular expressions, which let you search for a shape of text instead of an exact phrase. A few examples:
grep -E "error|warning|critical" error_logmatches any of three words. The-Eflag enables extended regex so|works as "or".grep -E "[0-9]{3} " access_logmatches any three-digit number followed by a space, useful for pulling out HTTP status codes like 404 or 500 from an access log.grep "^\[" error_logmatches lines that start with a bracket, which is how PHP formats its timestamp prefix, so this isolates the start of each log entry.
If you only need to know the error exists somewhere but don't care which line, -q makes grep run silently and only sets an exit code, which is mostly useful inside a script rather than at an interactive prompt.
Where the logs actually are
On a VPS, you have root SSH access, so log locations depend on what you installed and whatever path your application's framework writes to (a Laravel app logs to storage/logs/laravel.log, for example). If you manage the server yourself, you're also responsible for log rotation, since these files grow without bound otherwise. On shared hosting, if you can't locate the right log file, open a ticket and a human can point you to it.
When to open a ticket
If you've grepped the logs and the error message doesn't point to anything in your own code or configuration, or if you suspect the issue is on the server side rather than in your application, open a ticket from the portal. If the error looks like a 403 error or another server response code, mention that in the ticket along with the exact log line, since that's usually enough for a human to pinpoint the cause.