Leert sich einer Ihrer Magento 2 Caches scheinbar immer von selbst? Um das Problem zu analysieren kann ein Call Stack weiterhelfen. Gerade bei individuellen Extensions lässt sich damit nachvollziehen, welcher Code eine Cache Bereinigung tatsächlich ausgelöst hat.
Für eine temporäre Analyse kann beispielsweise ein Plugin auf TypeList::cleanType() und Cache Manager::flush() gesetzt werden. Die Registrierung erfolgt in der etc/di.xml:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <type name="Magento\Framework\App\Cache\TypeList"> <plugin name="cache_trace_type_list" type="Vendor\Module\Plugin\CacheTrace"/> </type> <type name="Magento\Framework\App\Cache\Manager"> <plugin name="cache_trace_manager" type="Vendor\Module\Plugin\CacheTrace"/> </type> </config> |
Das Plugin protokolliert neben dem betroffenen Cache Typ auch den Aufrufpfad:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
<?php declare(strict_types=1); namespace Vendor\Module\Plugin; use Magento\Framework\App\Cache\Manager; use Magento\Framework\App\Cache\TypeList; use Magento\Framework\Filesystem\DirectoryList; class CacheTrace { public function __construct( private readonly DirectoryList $directoryList ) { } public function beforeCleanType( TypeList $subject, string $typeCode ): array { $this->writeTrace('CLEAN', [$typeCode]); return [$typeCode]; } public function beforeFlush( Manager $subject, array $types ): array { $this->writeTrace('FLUSH', $types); return [$types]; } private function writeTrace(string $action, array $types): void { $trace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS, 25 ); $lines = []; foreach ($trace as $entry) { $call = ($entry['class'] ?? '') . ($entry['type'] ?? '') . ($entry['function'] ?? ''); $location = isset($entry['file']) ? $entry['file'] . ':' . ($entry['line'] ?? '') : ''; $lines[] = $call . ' ' . $location; } $message = sprintf( "[%s] %s: %s\n%s\n\n", date('Y-m-d H:i:s'), $action, implode(', ', $types), implode("\n", $lines) ); file_put_contents( $this->directoryList->getPath(DirectoryList::LOG) . '/cache-trace.log', $message, FILE_APPEND | LOCK_EX ); } } |
Wird nun beispielsweise der full_page oder layout Cache geleert, landet der zugehörige Call Stack in var/log/cache-trace.log. Dort lässt sich häufig direkt erkennen, ob der Aufruf aus dem Magento Core, einem Cronjob oder einer bestimmten Extension stammt.
Interessant ist die Unterscheidung zwischen CLEAN und FLUSH. Beim Clean werden gezielt Magento Cache Typen bereinigt, während ein Flush den dahinterliegenden Cache Speicher betrifft.
Solch ein Trace sollte nur zur Fehlersuche eingesetzt und anschließend wieder entfernt werden. Gerade wenn ein Shop scheinbar grundlos regelmäßig z.B. seinen Full Page Cache verliert, kann er aber ziemlich schnell zeigen, wer den Cache tatsächlich leert.