Monitoring and Logging PHP Applications: How Not to Miss a Bug

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Your Application is Silent — That's a Bad Sign

\n\n

Have you ever found out about a bug in production from an angry user? If yes — you know how painful it is. If no — you're lucky (for now).

\n\n

PHP is a language that powers 78% of all websites in the world. But it has one peculiarity: it's too "quiet". By default, PHP will simply swallow an error, show a white screen, or, even worse, continue working with incorrect data. Without a monitoring and logging system, you are blind.

\n\n

In this article, we'll break down how to turn your PHP application from a "black box" into a transparent system where every error, every slow request, and every suspicious action is recorded. Let's go!

\n\n

Why "echo $error" is Not Logging?

\n\n

Many beginner developers write:

\n\n
try {\n    // some code\n} catch (Exception $e) {\n    echo $e->getMessage();\n}\n
\n\n

This is not logging. This is shouting into the void. Outputting to the browser is not saved, not structured, and gives you no analytics. Real logging is when you can:

\n\n
    \n
  • See an error 5 minutes after it occurs
  • \n
  • Understand which server and environment it happened on
  • \n
  • Filter through thousands of records and find the exact one
  • \n
  • Get a notification in Telegram/Slack if something breaks
  • \n
\n\n

Let's move on to the tools that can do this.

\n\n

Monolog — The De Facto Standard for PHP

\n\n

If you write in PHP and don't use Monolog, you are most likely reinventing the wheel. This library has become the standard for logging in PHP (yes, Laravel and Symfony use it under the hood).

\n\n

Installation and a Simple Example

\n\n
composer require monolog/monolog\n
\n\n
<?php\nuse Monolog\\Logger;\nuse Monolog\\Handler\\StreamHandler;\n\n// Create a log channel\n$log = new Logger('my_app');\n// Write to file /var/log/my_app.log\n$log->pushHandler(new StreamHandler('/var/log/my_app.log', Logger::WARNING));\n\n// Use it\n$log->warning('This is a warning');\n$log->error('Critical error: database unavailable');\n
\n\n

That's better. But Monolog can do much more. You can send logs to different places simultaneously:

\n\n
    \n
  • To a file — for local debugging
  • \n
  • To Elasticsearch — for full-fledged search
  • \n
  • To Telegram/Slack — for urgent notifications
  • \n
  • To Syslog — for system administration
  • \n
\n\n

Advanced Example with Multiple Handlers

\n\n
<?php\nuse Monolog\\Logger;\nuse Monolog\\Handler\\StreamHandler;\nuse Monolog\\Handler\\TelegramBotHandler;\nuse Monolog\\Handler\\ElasticsearchHandler;\nuse Monolog\\Formatter\\LineFormatter;\n\n$log = new Logger('production');\n\n// Write all errors to a file\n$fileHandler = new StreamHandler('/var/log/app.log', Logger::DEBUG);\n$log->pushHandler($fileHandler);\n\n// Critical errors — straight to Telegram\n$telegramHandler = new TelegramBotHandler(\n    'YOUR_BOT_TOKEN', \n    'YOUR_CHAT_ID', \n    Logger::CRITICAL\n);\n$telegramHandler->setFormatter(new LineFormatter(\n    "[%datetime%] %channel%.%level_name%: %message% %context%\\n"\n));\n$log->pushHandler($telegramHandler);\n\n// Log\n$log->critical('Database is down', ['server' => gethostname()]);\n
\n\n

Now, if the database goes down at night, you'll find out via a notification on your phone. Not in the morning from a client.

\n\n

Sentry — Error Monitoring with Context

\n\n

Monolog is great for writing logs, but when there are many errors, just reading files is a nightmare. This is where Sentry comes to the rescue — an error collection system with a web interface.

\n\n

Sentry automatically collects:

\n
    \n
  • Stack trace
  • \n
  • Request data (URL, headers, body)
  • \n
  • User information (if provided)
  • \n
  • Variable state

Blogs

Book Recommendations