DEV Community

Magevanta
Magevanta

Posted on • Originally published at magevanta.com

Magento 2 Logging Best Practices: Keep Your Logs Clean and Actionable

Logs are your first line of defense when something goes wrong in production. But in a default Magento 2 installation, the logging setup is often either too noisy — filled with warnings that don't matter — or too quiet, missing the errors that actually need attention. Getting logging right is a force multiplier for your whole operations workflow.

This guide covers how Magento 2 logging works under the hood, what you should configure, what to ignore, and how to build a lean, actionable logging setup.

How Magento 2 Logging Works

Magento uses Monolog as its logging library. Log channels are defined as virtual types in di.xml, and each module can register its own logger instance. By default, most logging goes to var/log/system.log and var/log/exception.log, but individual modules write to their own files:

  • var/log/system.log — general system messages
  • var/log/exception.log — PHP exceptions caught by Magento
  • var/log/debug.log — debug-level messages (should be disabled in production)
  • var/log/cron.log — cron job execution
  • var/log/payment.log — payment-related activity
  • var/log/shipping.log — shipping carrier requests and responses

Each of these can grow very large, very fast on a busy store.

Step 1: Disable Debug Logging in Production

This one is critical. Magento's debug mode logs an enormous amount of data — request parameters, SQL queries, observer calls — and it should never be enabled in production.

Check your current setting:

php bin/magento config:show dev/debug/debug_logging
Enter fullscreen mode Exit fullscreen mode

Disable it:

php bin/magento config:set dev/debug/debug_logging 0
php bin/magento cache:flush
Enter fullscreen mode Exit fullscreen mode

Also check var/log/debug.log — if it exists and is growing, that's your culprit. On a high-traffic store this file can reach several GB within hours.

Step 2: Implement Log Rotation

Magento does not rotate logs automatically. Without rotation, log files will grow indefinitely until your disk fills up — and that will take your store down.

Use logrotate on Linux. Create /etc/logrotate.d/magento:

/var/www/html/var/log/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 664 www-data www-data
    sharedscripts
    postrotate
        /usr/bin/find /var/www/html/var/log -name "*.log" -mtime +14 -delete
    endscript
}
Enter fullscreen mode Exit fullscreen mode

Adjust the path and user to match your setup. This keeps 14 days of compressed logs and removes anything older.

You can also clean old logs via Magento's built-in cron task. Check app/etc/crontab.xml — the log_clean job runs and cleans database logs (customer log, quote log), but not file-based logs in var/log/. That's still your responsibility.

Step 3: Fix Third-Party Module Log Spam

A very common problem: a third-party module logs aggressively at WARNING or INFO level for things that aren't actually problems. These entries flood your logs and make it hard to spot real issues.

To identify noisy modules, look at what's filling your system.log:

grep -oP 'main\.\w+' var/log/system.log | sort | uniq -c | sort -rn | head -20
Enter fullscreen mode Exit fullscreen mode

Or check by log level:

grep -c 'WARNING' var/log/system.log
grep -c 'ERROR' var/log/system.log
grep -c 'CRITICAL' var/log/system.log
Enter fullscreen mode Exit fullscreen mode

If WARNING vastly outnumbers ERROR and CRITICAL, you have log spam. Track it to the source:

grep 'WARNING' var/log/system.log | grep -oP 'in .*\.php' | sort | uniq -c | sort -rn | head -10
Enter fullscreen mode Exit fullscreen mode

Once identified, you have two options:

  1. Raise the minimum log level for that module's handler in di.xml
  2. Open a support ticket with the extension vendor — this is their bug, not yours

Step 4: Set Minimum Log Level Per Handler

You can configure the minimum severity level for Magento's default log handlers via di.xml. Add this to your module or app/etc/di.xml:

<type name="Magento\Framework\Logger\Handler\System">
    <arguments>
        <argument name="fileName" xsi:type="string">/var/log/system.log</argument>
        <argument name="loggerType" xsi:type="number">400</argument>
    </arguments>
</type>
Enter fullscreen mode Exit fullscreen mode

The loggerType corresponds to Monolog levels:

  • 100 = DEBUG
  • 200 = INFO
  • 250 = NOTICE
  • 300 = WARNING
  • 400 = ERROR
  • 500 = CRITICAL

Setting 400 (ERROR) means WARNING and below will be ignored. This is a reasonable production default for system.log.

Step 5: Write Better Custom Logs

If you're developing a custom module, follow these guidelines to write logs that are actually useful:

Use the right level:

$this->logger->debug('Processing item', ['id' => $itemId]);    // dev only
$this->logger->info('Order exported', ['order' => $orderId]);  // informational
$this->logger->warning('Fallback used', ['reason' => $msg]);   // worth noting
$this->logger->error('Export failed', ['exception' => $e]);    // needs attention
$this->logger->critical('Payment gateway down', [...]);         // wake someone up
Enter fullscreen mode Exit fullscreen mode

Always include context:

// Bad
$this->logger->error('Failed to process order');

// Good
$this->logger->error('Failed to process order', [
    'order_id'  => $order->getIncrementId(),
    'exception' => $e->getMessage(),
    'trace'     => $e->getTraceAsString(),
]);
Enter fullscreen mode Exit fullscreen mode

Context arrays are serialized to JSON in the log line, making them searchable and parseable by log aggregators.

Use a dedicated log channel for your module:

<!-- di.xml -->
<virtualType name="MyModule\Logger\Handler" type="Magento\Framework\Logger\Handler\Base">
    <arguments>
        <argument name="fileName" xsi:type="string">/var/log/mymodule.log</argument>
    </arguments>
</virtualType>
<virtualType name="MyModule\Logger\Logger" type="Magento\Framework\Logger\Monolog">
    <arguments>
        <argument name="name" xsi:type="string">mymodule</argument>
        <argument name="handlers" xsi:type="array">
            <item name="system" xsi:type="object">MyModule\Logger\Handler</item>
        </argument>
    </arguments>
</virtualType>
Enter fullscreen mode Exit fullscreen mode

This keeps your logs isolated from Magento core logs and makes debugging much faster.

Step 6: Monitor Critical Logs

Logging is only useful if someone reads the logs. In production, set up alerting:

  • Simple option: Use a cron job that runs grep -c CRITICAL var/log/system.log and sends an alert if the count increases
  • Better option: Ship logs to a centralized service like Papertrail, Logtail, Datadog, or Elasticsearch + Kibana
  • Best option: Use structured JSON logging so your log aggregator can parse fields properly

For JSON logging in Magento, you can replace the default formatter:

<type name="Magento\Framework\Logger\Handler\System">
    <arguments>
        <argument name="formatter" xsi:type="object">Monolog\Formatter\JsonFormatter</argument>
    </arguments>
</type>
Enter fullscreen mode Exit fullscreen mode

JSON logs are harder to read manually but much easier to query, filter, and alert on.

Step 7: Don't Log Sensitive Data

This sounds obvious but it happens — especially with payment modules. Never log:

  • Credit card numbers or CVV codes
  • Full customer passwords or tokens
  • API keys or secrets
  • Full HTTP request bodies from payment endpoints

If you need to log payment-related activity for debugging, log only order IDs, masked card data (last 4 digits), and response codes. Many PCI DSS compliance failures originate in log files.

Quick Wins Checklist

  • [ ] dev/debug/debug_logging = 0 in production
  • [ ] logrotate configured for var/log/*.log
  • [ ] var/log/debug.log doesn't exist or is empty
  • [ ] System log filtered to ERROR level minimum
  • [ ] Third-party log spam identified and addressed
  • [ ] Critical log monitoring / alerting in place
  • [ ] No sensitive data in any log file

Conclusion

Good logging discipline makes the difference between a 5-minute incident response and a 5-hour debugging session. On Magento 2, the defaults are not production-ready — you need to actively configure log levels, implement rotation, suppress noise, and make sure critical errors reach the right people.

Invest 30 minutes into your logging setup now and you'll save hours when something inevitably goes wrong.

Top comments (0)