چند سال پیش یک فروشگاه اینترنتی با شکایتِ عجیبی به من سپرده شد: مشتریان گاهی مبلغ پرداخت را از درگاه کسر می‌دیدند، ولی سفارش در پیشخوان ثبت نمی‌شد. در WooCommerce (ووکامرس) هیچ خطایی نمایش داده نمی‌شد، ایمیل‌های سیستم سالم به‌نظر می‌رسیدند، و پشتیبانی هاست با اطمینان می‌گفت سرور کاملاً سالم است. آن روز یک درس گران‌قیمت گرفتم: در ووکامرس بخش بزرگی از خطاها بی‌صدا اتفاق می‌افتند و تنها جایی که می‌شود ردشان را گرفت، فایل‌های log (لاگ) است. از آن پروژه به بعد، عادت کردم پیش از هر عیب‌یابیِ پیچیده، اول سراغ لاگ‌ها بروم — و در همین راهنما همان مسیری را می‌گویم که روی فروشگاه‌های واقعی اجرا کرده‌ام.

چرا خطاهای ووکامرس بی‌صدا اتفاق می‌افتند؟

ووکامرس یک افزونهٔ وردپرسی است که روی یک بستر بزرگ‌تر اجرا می‌شود؛ این یعنی هر خطا از سه لایهٔ مختلف می‌تواند بیاید: هستهٔ وردپرس، خودِ ووکامرس، یا هر افزونهٔ جانبی (درگاه پرداخت، افزونهٔ ارسال، افزونهٔ حسابداری). وقتی خطا در لایهٔ نمایش رخ نمی‌دهد — مثلاً یک خطای PHP در یک درخواست AJAX که با wp_ajax_ اجرا می‌شود — کاربر پیشخوان هیچ چیزی نمی‌بیند. به همین دلیل است که در عمل، پیام‌های خطای PHP که به‌طور پیش‌فرض در wp-config.php خاموش‌اند، در فایل‌های جداگانه‌ای ذخیره می‌شوند. اگر با لایهٔ افزونه‌ها آشنایی کافی ندارید، پیش از ادامه مقالهٔ افزونه وردپرس چیست و چگونه انتخاب کنیم را بخوانید؛ چون بخش بزرگی از عیب‌یابی ووکامرس، عیب‌یابی زنجیرهٔ افزونه‌هاست.

سکوت ووکامرس در برابر خطا، یک تصمیم طراحی است نه نقص فنی. یک فروشگاه در حال فروش، نباید با هر خطای جزئی، تجربهٔ خرید را خراب کند؛ پس توسعه‌دهندگان ووکامرس خطاهای بحرانی را در قالب پیام‌های عمومی نشان می‌دهند و جزئیات فنی را به لاگ می‌سپارند. این تفکیک، هم برای کاربر نهایی محترمانه است و هم برای توسعه‌دهنده حیاتی — به شرطی که بدانید کجا باید نگاه کنید.

در ووکامرس، پیشخوان پنل تبلیغات است؛ لاگ‌ها پروندهٔ واقعی سیستم.

سیستم لاگ ووکامرس از کجا می‌آید؟

ووکامرس از یک کلاس داخلی به نام WC_Logger استفاده می‌کند که یک رابط ساده برای ثبت رخدادها فراهم می‌کند. این کلاس به چند مقصد می‌تواند بنویسد: فایل، دیتابیس، ایمیل، و در نسخه‌های جدیدتر به سرویس‌های بیرونی از طریق API. اما حالت پیش‌فرض برای ۹۰٪ پروژه‌هایی که من دیده‌ام، ثبت در فایل است. توسعه‌دهنده‌ها و افزونه‌ها با استفاده از متد WC_Logger::log() می‌توانند پیام ثبت کنند و ووکامرس آن را در یک فایل متنی با پسوند .log ذخیره می‌کند.

این مکانیزم داخلی، از هوک‌های وردپرس هم بی‌بهره نیست. اگر با مفهوم هوک آشنایی ندارید، مقالهٔ هوک‌های وردپرس چیستند و چگونه کار می‌کنند نقطهٔ شروع خوبی است، چون بدون درک هوک‌ها نمی‌توانید بفهمید کدام افزونه در چه مرحله‌ای خطا تولید کرده. توسعه‌دهنده‌های حرفه‌ای اغلب از ترکیب WC_Logger و هوک‌های سفارشی مثل woocommerce_log_ برای رهگیری دقیق‌تر استفاده می‌کنند.

فعال‌سازی حالت دیباگ و لاگ‌گیری

در حالت پیش‌فرض، ووکامرس خطاهای خودش را ثبت نمی‌کند مگر آنکه حالت دیباگ فعال شود. برای فعال‌سازی، سه گزینه در وردپرس وجود دارد که هم‌زمان باید کنترل شوند. اول، ثابتِ WP_DEBUG در فایل wp-config.php؛ دوم، گزینهٔ «Debug log» در تنظیمات ووکامرس؛ سوم، سطح لاگ (Log level threshold) که با آن مشخص می‌کنید فقط خطاهای بحرانی ثبت شوند یا تمام پیام‌های اطلاعاتی.

یک الگوی امن برای فعال‌سازی موقت در سایت زنده:

// wp-config.php
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );

نکتهٔ حیاتی: WP_DEBUG_DISPLAY باید false بماند، چون در غیر این صورت خطاها به بازدیدکننده نشان داده می‌شوند و هم تجربهٔ خرید خراب می‌شود و هم مسیرهای فایل به‌صورت عمومی افشا می‌شوند. اگر سایت شما درآمدزا است، این سه خط را فقط در یک بازهٔ محدود فعال کنید و بعد از اتمام عیب‌یابی، فوراً به حالت پیش‌فرض برگردانید.

مسیر فیزیکی فایل‌های لاگ

دو دستهٔ لاگ در ووکامرس تولید می‌شود که هر کدام مسیر متفاوتی دارند. دستهٔ اول، لاگ خودِ ووکامرس است که در مسیر زیر قرار می‌گیرد:

wp-content/uploads/wc-logs/

این پوشه به‌طور پیش‌فرض توسط ووکامرس ساخته می‌شود و فایل‌های داخل آن معمولاً با الگوی <source>-<hash>-<date>-<hash>.log نام‌گذاری می‌شوند. مثلاً فایلی به نام payment-gateway-1a2b3c-2024-09-15-4d5e6f.log یعنی رخدادهای مربوط به درگاه پرداخت در بازه‌ای خاص.

دستهٔ دوم، لاگ خودِ PHP است که اگر WP_DEBUG_LOG فعال باشد در مسیر wp-content/debug.log نوشته می‌شود. اینجا همهٔ Notice، Warning و Fatal Error وردپرس و افزونه‌ها ثبت می‌شوند. اگر خطای ووکامرس در پیشخوان به‌شکل صفحهٔ سفید خود را نشان می‌دهد، احتمالاً مقصر اصلی در همین فایل قابل رهگیری است — روش‌های دقیق‌تر را در رفع خطای سفید صفحه در وردپرس و خطای ۵۰۰ وردپرس چیست و چگونه رفع می‌شود توضیح داده‌ام.

خواندن لاگ: چه چیزی را باید دید؟

یک فایل لاگ خام، ترسناک به نظر می‌رسد: ده‌ها یا صدها خط با timestamp و سطح‌بندی و پیام. اگر بخواهید تمامش را بخوانید، معمولاً ساعت‌ها وقت می‌برد. اما در عمل، الگوی عیب‌یابی من این است که اول دنبال سطح‌های FATAL و ERROR می‌گردم، سپس WARNING را نگاه می‌کنم و در نهایت اگر موضوع کیفی بود، سراغ INFO و DEBUG می‌روم. یک خط لاگ استاندارد ووکامرس معمولاً چنین است:

2026-09-15T10:23:45+00:00 INFO payment-gateway: Order #1024 processed successfully
2026-09-15T10:24:12+00:00 ERROR payment-gateway: Timeout while connecting to bank API for order #1025
2026-09-15T10:24:12+00:00 CRITICAL payment-gateway: Transaction rolled back for order #1025

خط اول سالم است، خط دوم یک مشکل ارتباطی را نشان می‌دهد، و خط سوم سطح بحرانی است. همین سه خط به شما می‌گوید مقصر اصلی، اتصال به API (Application Programming Interface — واسط برنامه‌نویسی) بانک است، نه خود ووکامرس. بدون این ترتیب، پیامِ «مشتری از پرداخت شکایت دارد» را نمی‌شد به یک ریشهٔ فنی تبدیل کرد.

لاگ را نخوانید تا متن را بفهمید؛ لاگ را بخوانید تا زمان و سطح خطا را به یک رخداد واقعی فروشگاه گره بزنید.

الگوهای رایج خطا در لاگ ووکامرس

در بیش از صد پروژه فروشگاهی که عیب‌یابی کرده‌ام، پنج الگو را بارها دیده‌ام. هر الگو، امضای فنی مشخصی دارد و مقصر متفاوتی را نشان می‌دهد:

  • Connection Timeout: پیام‌هایی مثل cURL error 28 یا Gateway timeout در لاگ درگاه پرداخت. مقصر معمولاً سرور درگاه یا فایروال است، نه ووکامرس.
  • Fatal error در حین ثبت سفارش: یک خط Fatal error: Call to undefined function ... در debug.log. مقصر، افزونه‌ای است که به تابعی از نسخه‌ای قدیمی وابسته بوده — روش پیدا کردنش در چگونه افزونهٔ مشکل‌ساز وردپرس را پیدا کنیم آمده.
  • Memory Exhausted: پیام‌های Allowed memory size exhausted وسط محاسبهٔ سبد خرید. اینجا باید هم WP_MEMORY_LIMIT و هم مصرف افزونه‌ها را بررسی کنید؛ مقالهٔ افزونه‌های وردپرس چطور روی سرعت سایت اثر می‌گذارند برای این الگو مرجع خوبی است.
  • خطای Cron: پیام‌های wp-cron.php که به‌صورت ناموفق اجرا شده‌اند و سفارش‌های در حال انتظار را به وضعیت نهایی نمی‌برند. راهنمای کامل در عیب‌یابی مشکلات کرون در وردپرس.
  • خطای هم‌زمانی افزونه‌ها: دو افزونه که هم‌زمان یک هوک را تغییر می‌دهند و ترتیب اجرا بهم می‌ریزد. اینجا باید از مقالهٔ بررسی سازگاری افزونه‌های وردپرس استفاده کنید.

جدول تشخیص سریع بر اساس نشانه

نشانه در فروشگاهاحتمال سطح لاگفایل هدفاقدام اول
مشتری پول داده، سفارش ثبت نشدهCRITICAL در درگاهwc-logs/payment-*.logبررسی پاسخ خام API بانک و timeout
سبد خرید خالی می‌شودWARNING سشنdebug.logبررسی تداخل افزونهٔ کش و سشن
ایمیل سفارش نمی‌آیدERROR در SMTPwc-logs/<mailer>.logتست SMTP و بررسی هدرهای رد شده
صفحهٔ محصول ۵۰۰ می‌دهدFATALdebug.logغیرفعال‌سازی افزونهٔ آخر و قالب پیش‌فرض
موجودی اشتباه نمایش داده می‌شودINFO/WARNINGwc-logs/*-stock-*.logبررسی cron و افزونهٔ همگام‌سازی انبار

ابزارهای تحلیل و پایش لاگ

وقتی فایل لاگ از چند مگابایت رد می‌شود، باز کردنش در ویرایشگر پیشخوان بی‌فایده است. من در عمل سه ابزار را ترکیب می‌کنم: اول، دانلود فایل از طریق FTP (File Transfer Protocol — پروتکل انتقال فایل) و باز کردن با VS Code یا Sublime Text که جستجوی regex دارند؛ دوم، استفاده از ابزارهای خط فرمان مثل grep و awk که می‌توانند صدها هزار خط را در چند ثانیه فیلتر کنند؛ سوم، در سایت‌های پرترافیک، نصب افزونه‌ای مثل Query Monitor که به‌جای خواندن فایل، خطاها را در لحظه نمایش می‌دهد.

یک دستور ساده که در پروژه‌های لینوکسی زیاد استفاده می‌کنم:

grep -i "error\|fatal\|critical" wp-content/debug.log | tail -n 100

این دستور صد خط آخر مربوط به خطاها را نشان می‌دهد و تقریباً همیشه نقطهٔ شروع خوبی است. اگر با خط فرمان راحت نیستید، فایل را دانلود کنید و از جستجوی معمولی ویرایشگر خودتان استفاده کنید — تفاوت فاحشی در نتیجه نخواهد بود.

اشتباهات رایج در خواندن لاگ

چهار اشتباه را در پروژه‌های واقعی بارها دیده‌ام و هر کدام هزینهٔ زمانی جدی داشته‌اند:

  • خاموش‌کردن دیباگ بعد از هر بررسی: بعضی توسعه‌دهنده‌ها دیباگ را در سایت زنده روشن می‌گذارند و ماه بعد یک فایل debug.log چند گیگابایتی پیدا می‌کنند که هم فضای هاست را خورده و هم به‌خاطر افشای مسیرها، امنیت سایت را تهدید کرده. توصیهٔ من در امنیت فروشگاه ووکامرس را چگونه افزایش دهیم همین است: دیباگ، حالت موقت است نه دائمی.
  • نادیده‌گرفتن timestamp: اگر خطا ساعت ۱۴:۳۲ ثبت شده و مشتری ساعت ۱۴:۳۴ سفارش داده، هیچ ربطی بین آن‌ها نیست. هر خط لاگ باید با یک رخداد واقعی گره بخورد وگرنه فقط حدس است.
  • فقط خواندن خط آخر: در خطاهای آبشاری، اولین خط مهم‌تر از خط آخر است؛ چون خط آخر معمولاً نتیجه است نه علت.
  • حذف لاگ قبل از بکاپ: هرگز فایل لاگ را پاک نکنید تا زمانی که یک نسخه پشتیبان گرفته‌اید. لاگ، سند تاریخی فروشگاه شماست — روش درست بکاپ در چگونه از سایت وردپرسی بکاپ بگیریم آمده است.

لایه‌های پنهان لاگ‌گیری در ووکامرس

برای توسعه‌دهنده‌های ارشد، لاگ ووکامرس یک API است، نه فقط یک فایل. کلاس WC_Logger از طریق فیلترهای woocommerce_log_handle و woocommerce_log_threshold قابل توسعه است؛ می‌توانید یک handler سفارشی بنویسید که به‌جای فایل، به Elasticsearch یا Sentry بنویسد. این معماری، برای فروشگاه‌هایی که روی چند سرور اجرا می‌شوند (مثلاً load balancer + چند node) حیاتی است، چون فایل‌های محلی دیگر هم‌افزایی ندارند.

نکتهٔ دوم، تفکیک source است. در ووکامرس، هر منبع (مثل درگاه پرداخت، افزونهٔ ارسال، افزونهٔ اشتراک) یک شناسه دارد و لاگ‌ها به تفکیک آن ذخیره می‌شوند. اگر می‌خواهید سیستم لاگ خودتان را با همین الگو بنویسید، نمونهٔ کامل در ساختار هسته وردپرس چگونه کار می‌کند و ساختار فایل‌های یک افزونه استاندارد قابل مطالعه است. قاعده‌ای که سال‌ها روی آن پافشاری می‌کنم: اگر افزونه‌ای می‌نویسید که روزی با داده فروشگاهی سر و کار دارد، از همان روز اول یک منبع لاگ اختصاصی برایش بسازید؛ عیب‌یابی آینده‌تان را نجات می‌دهد. در پروژه‌ای که سه افزونهٔ سفارشی برای یک فروشگاه صنعتی نوشتیم، همین تفکیک باعث شد روزی که یک خطای نادر همگام‌سازی انبار پیش آمد، در پنج دقیقه مقصر پیدا شود؛ چیزی که در نسخهٔ قبلی بدون لاگ‌گیری اختصاصی، سه روز وقت برده بود. برای پروژه‌های پیچیده، فهرست کامل چک‌های عیب‌یابی را در چک‌لیست عیب‌یابی حرفه‌ای خطاهای وردپرس جمع کرده‌ام و از آن به‌عنوان نسخهٔ ساده‌شده در جلسه‌های تیم استفاده می‌کنم.

اگر روی پروژه‌ای خطای ووکامرسی داشته‌اید که بعد از ساعت‌ها فقط با یک نگاه به لاگ حل شده، خوشحال می‌شوم الگویش را در دیدگاه بنویسید — همان‌قدر که برای من در پروژه‌های بعدی ارزش داشت، می‌تواند برای توسعه‌دهندهٔ بعدی هم باشد. 🔍