ตำแหน่งไฟล์ debug log ของ WordPress: debug.log อยู่ที่ไหน และย้ายอย่างไร
หา debug.log ใน wp-content ย้ายออกไปนอก web root ไม่ให้ผู้เข้าชมโหลดไปได้ และแก้การตั้งค่า WP_DEBUG ที่ทำให้ไฟล์ว่างเปล่า
เผยแพร่แล้ว
WordPress เขียน debug log ไว้ที่ wp-content/debug.log เป็นค่าเริ่มต้น ซึ่งบนดิสก์คือพาธเต็มแบบ /path/to/your/site/wp-content/debug.log ไฟล์นี้จะยังไม่มีอยู่จนกว่าจะมีอะไรถูกบันทึกจริง และจะถูกเขียนก็ต่อเมื่อ WP_DEBUG เป็น true และเปิด WP_DEBUG_LOG ไว้ใน wp-config.php เท่านั้น ตำแหน่งเริ่มต้นนี้ยังเป็นปัญหาความปลอดภัยของจริงด้วย เพราะบนโฮสต์ส่วนใหญ่ ใครก็ตามสามารถเรียกไฟล์นี้จากเบราว์เซอร์ได้
ค่าคงที่สามตัว และหน้าที่ของแต่ละตัว
ทั้งสามตัวต้องอยู่ใน wp-config.php เหนือบรรทัดที่เขียนว่า /* That's all, stop editing! Happy blogging. */ อะไรก็ตามที่เพิ่มไว้ใต้บรรทัดนั้นจะทำงานหลังจาก WordPress บูตเสร็จแล้ว จึงถูกเมินไปเฉย ๆ
| ค่าคงที่ | ค่าเริ่มต้น | หน้าที่ |
|---|---|---|
WP_DEBUG | false | สวิตช์หลัก ยกระดับการรายงานข้อผิดพลาดของ PHP ให้แสดง notice, warning และ deprecation ไม่มีอะไรในรายการนี้ทำงานได้ถ้าไม่มีมัน |
WP_DEBUG_LOG | false | ส่งข้อผิดพลาดลงไฟล์ ค่า true หมายถึง wp-content/debug.log ส่วนค่าที่เป็นสตริงจะถือเป็นพาธไฟล์ที่ต้องการเขียนลงไป |
WP_DEBUG_DISPLAY | true | พิมพ์ข้อผิดพลาดลงใน HTML ของหน้าเว็บ ซึ่งผู้เข้าชมทุกคนมองเห็น |
ส่วนที่คนเข้าใจผิดคือความสัมพันธ์ระหว่างกัน WP_DEBUG_LOG ถูกอ่านอยู่ภายในเงื่อนไข WP_DEBUG ของโค้ดตอนเริ่มระบบของ WordPress ถ้า WP_DEBUG เป็น false การตั้ง WP_DEBUG_LOG เป็น true จะไม่เกิดผลใด ๆ เลย ไม่มีไฟล์ ไม่มีข้อผิดพลาด ไม่มีคำเตือน ถ้าคุณเพิ่ม WP_DEBUG_LOG แล้วไม่มี log โผล่มา ให้ตรวจ WP_DEBUG ก่อน
การตั้งค่าที่ใช้ได้จริงบนเว็บที่เปิดใช้งานอยู่:
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
@ini_set( 'display_errors', 0 );
ถ้า WP_DEBUG ถูกประกาศไว้แล้วด้านบนของไฟล์ ซึ่งมักเป็นแบบนั้น และตั้งเป็น false ให้แก้บรรทัดเดิมนั้น อย่าเพิ่ม define() ตัวที่สอง เพราะการประกาศค่าคงที่ซ้ำจะทำให้ PHP โยนคำเตือนออกมา ซึ่งบนเว็บที่เปิดการแสดงผลไว้จะไปโผล่ตรงหัวหน้าเว็บพอดี
ทำไม WP_DEBUG_DISPLAY ต้องเป็น false บนเว็บจริง
เมื่อเปิดการแสดงผล ข้อผิดพลาดของ PHP จะถูกพ่นลงในคำตอบ HTML แค่ notice เรื่องฟังก์ชันที่เลิกใช้จากธีมตัวเดียว ก็พิมพ์พาธเต็มบนระบบไฟล์ของเซิร์ฟเวอร์ให้ผู้เข้าชมทุกคนเห็น ข้อผิดพลาดของฐานข้อมูลก็พิมพ์ชื่อตารางและเศษคิวรีออกมา แย่กว่านั้น ผลลัพธ์ที่ถูกพิมพ์ออกก่อนส่ง header จะทำให้การเปลี่ยนเส้นทางพัง ทำให้คำตอบของ REST และ AJAX ที่ต้องการ JSON สะอาดพัง และอาจทำให้เกิดหน้าจอขาวที่คนมักไปโทษปลั๊กอิน
มีรายละเอียดหนึ่งที่ควรรู้ การตั้ง WP_DEBUG_DISPLAY เป็น null ไม่เหมือนกับ false ค่า null บอก WordPress ให้ปล่อยค่า display_errors ของ PHP ไว้ตามเดิม แล้วรับค่าที่เซิร์ฟเวอร์ตั้งไว้มาใช้ ส่วน false คือการบังคับปิดจริงจัง บนเว็บที่ใช้งานจริงให้ใช้ false และเพิ่มบรรทัด ini_set ข้างต้นเป็นการกันไว้อีกชั้น เพราะปลั๊กอินอาจสลับ display_errors กลับมาเปิดได้ในภายหลังของคำขอเดียวกัน
ตำแหน่งเริ่มต้นถูกเรียกดูได้จากภายนอก
wp-content/debug.log อยู่ภายใน web root และไม่มีอะไรใน WordPress ที่ติดตั้งมาตรฐานคอยบล็อกคำขอตรงไปที่ไฟล์นี้ บน Apache หรือ nginx ทั่วไป การเรียก https://yoursite.com/wp-content/debug.log จะคืนไฟล์กลับมาเป็นข้อความธรรมดา debug log มีทั้งพาธเต็มบนเซิร์ฟเวอร์ รายละเอียดภายในของปลั๊กอินและธีม ข้อผิดพลาดฐานข้อมูลพร้อมข้อความคิวรีจริง และบางครั้งมีค่าที่ส่งผ่านฟังก์ชันที่ทำงานล้มเหลวด้วย นั่นคือข้อมูลสอดแนมฟรี ๆ ให้กับใครก็ตามที่เดา URL ถูก และมันเป็นหนึ่งใน URL แรก ๆ ที่สแกนเนอร์อัตโนมัติลองยิง
มีสองวิธีจัดการ วิธีที่ดีกว่าคือย้ายไฟล์ log
ย้าย log ด้วยการระบุพาธ
ตั้งแต่ WordPress 5.1 เป็นต้นมา WP_DEBUG_LOG รับค่าเป็นสตริงพาธไฟล์แทนค่าบูลีนได้ ให้ชี้ไปนอก document root:
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', '/home/youruser/logs/wp-errors.log' );
define( 'WP_DEBUG_DISPLAY', false );
มีกฎสามข้อสำหรับพาธนั้น ใช้พาธ แบบสัมบูรณ์ เพราะพาธสัมพัทธ์จะถูกอ้างอิงกับไดเรกทอรีทำงานของ PHP ซึ่งเปลี่ยนไปตามคำขอและตามเซิร์ฟเวอร์ คุณจะตามหาไฟล์ไม่เจอ ต่อมา ไดเรกทอรีต้องมีอยู่แล้ว เพราะ PHP จะไม่สร้างให้ และถ้าเปิดไฟล์ไม่ได้ มันจะล้มเหลวแบบเงียบ ๆ สุดท้าย ไดเรกทอรีนั้นต้อง เขียนได้โดยผู้ใช้ที่ PHP รันอยู่ ซึ่งบนโฮสต์แบบแชร์ไม่ใช่บัญชีเดียวกับที่คุณล็อกอินผ่าน SFTP
ถ้าโฮสติ้งของคุณจำกัดให้อยู่แต่ใน web root และไม่มีที่ให้เขียนเหนือขึ้นไป ให้ใช้พาธเริ่มต้นต่อไป แล้วบล็อกการเข้าถึงที่ระดับเซิร์ฟเวอร์แทน สำหรับ Apache:
<Files "debug.log">
Require all denied
</Files>
โค้ดนี้ต้องอยู่ในไฟล์ .htaccess ภายใน wp-content ไม่ใช่ไฟล์ที่โฟลเดอร์ราก เพราะ WordPress เขียนทับ .htaccess ที่รากเมื่อคุณบันทึกค่าลิงก์ถาวร และอาจลบสิ่งที่คุณเพิ่มไว้ทิ้ง ส่วนบน nginx ไฟล์ .htaccess ไม่มีผลใด ๆ เลย คุณต้องใช้ location block ในการตั้งค่าเซิร์ฟเวอร์ ซึ่งบนโฮสต์แบบ managed มักแปลว่าต้องแจ้งฝ่ายซัพพอร์ต
พูดกันตรง ๆ ว่าการบล็อกให้อะไรคุณบ้าง ไฟล์ยังอยู่บนดิสก์ในไดเรกทอรีที่เว็บเซิร์ฟเวอร์ให้บริการอยู่ ช่องโหว่แบบ path traversal ในปลั๊กอินตัวใดตัวหนึ่งก็ยังอ่านมันได้ การย้ายออกไปนอก web root จึงเป็นการแก้ที่หนักแน่นกว่า
วิธีอ่านและเฝ้าดูไฟล์แบบสด
ถ้าเข้าผ่าน SSH ได้ ให้เฝ้าดูมันสด ๆ ขณะที่คุณทำให้บั๊กเกิดซ้ำ:
tail -f wp-content/debug.log
ทำให้ข้อผิดพลาดเกิดซ้ำในอีกแท็บหนึ่ง แล้วบรรทัดใหม่จะปรากฏขึ้นทันทีที่ถูกเขียน ถ้าอยากดูเฉพาะสิ่งที่เพิ่งเกิด หรือกรองให้เหลือปลั๊กอินตัวเดียว:
tail -n 100 wp-content/debug.log
grep -i 'plugin-slug' wp-content/debug.log | tail -n 50
PHP ต่อข้อความไว้ท้ายไฟล์ ดังนั้น ให้อ่านจากล่างขึ้นบน แต่ละรายการมีเวลากำกับเป็น UTC ซึ่งจะไม่ตรงกับการตั้งค่าเขตเวลาใน WordPress ของคุณ อย่าให้เรื่องนี้ทำให้คุณเข้าใจผิดว่ากำลังดูรายการเก่า
ถ้าใช้ WP-CLI คุณสลับค่าคงที่เหล่านี้ได้โดยไม่ต้องแก้ไฟล์ด้วยมือ:
wp config set WP_DEBUG true --raw
wp config set WP_DEBUG_LOG true --raw
wp config set WP_DEBUG_DISPLAY false --raw
แฟล็ก --raw สำคัญมาก เพราะถ้าไม่ใส่ ค่าจะถูกเขียนเป็นสตริง "true" แทนที่จะเป็นบูลีน ส่วนกรณีที่ระบุเป็นพาธ ให้ตัด --raw ออก เพื่อให้ค่าถูกเขียนเป็นสตริงในเครื่องหมายคำพูด
ไม่มี SSH ใช่ไหม ดาวน์โหลดไฟล์ผ่าน SFTP หรือเปิดใน file manager ของโฮสต์ และควรเลี่ยงปลั๊กอินที่เอา log มาแสดงใน wp-admin เว้นแต่คุณจะไว้ใจมันเต็มร้อย เพราะนั่นคือการยื่นสิทธิ์อ่านไฟล์ที่เต็มไปด้วยรายละเอียดภายในของเซิร์ฟเวอร์ให้ปลั๊กอิน
ถ้าอยากได้บล็อกโค้ด wp-config ที่ตรงกับระบบของคุณเป๊ะ ๆ รวมถึงพาธนอก web root ที่ปลอดภัยและกฎเซิร์ฟเวอร์ที่เข้าคู่กัน ตัวสร้างค่า debug log ของ WordPress จะสร้างให้คุณได้
ปิดมันเมื่อทำเสร็จ
ไม่มีอะไรในแกนหลักของ WordPress ที่หมุนเวียนหรือตัดขนาด debug.log ให้ บนเว็บที่โยน notice ทุกครั้งที่โหลดหน้า ไฟล์จะโตไม่มีที่สิ้นสุดและทำให้ดิสก์เต็ม ซึ่งทำให้เว็บล่มหนักกว่าบั๊กที่คุณกำลังตามหาเสียอีก เปิดการบันทึก ทำให้ปัญหาเกิดซ้ำ อ่าน log แล้วตั้ง WP_DEBUG กลับเป็น false
วิธีล้างไฟล์โดยไม่ต้องลบทิ้ง:
: > wp-content/debug.log
เมื่อ log ยังว่างเปล่า
ไล่ตรวจตามลำดับนี้ WP_DEBUG เป็น false ซึ่งเป็นสาเหตุที่พบบ่อยที่สุดตัวเดียว และมันปิดทุกอย่างที่เหลือแบบเงียบ ๆ ค่าคงที่อยู่ใต้บรรทัด “stop editing” ใน wp-config.php สิทธิ์ของไฟล์ คือ PHP เขียนลง wp-content ไม่ได้ หรือเขียนลงไดเรกทอรีที่คุณระบุเองไม่ได้ เกิด fatal error ก่อนที่ wp-config จะโหลดจบ เช่น ไวยากรณ์ผิดในไฟล์ config เอง ซึ่งเกิดเร็วเกินกว่าที่ระบบบันทึกของ WordPress จะจับได้ กรณีนี้จะไปโผล่ใน PHP error log ของเซิร์ฟเวอร์แทน โฮสต์เขียนทับค่าของคุณ บางแพลตฟอร์มแบบ managed ล็อกค่า error_log ของ PHP ไว้ หรือส่งการบันทึกเข้าแดชบอร์ดของตัวเอง ในกรณีนั้นค่าคงที่ของคุณถูกต้องแล้ว แต่ผลลัพธ์ไปอยู่ที่อื่น ตรวจตัวดู log ของโฮสต์ก่อนจะสรุปว่าการตั้งค่าของคุณพัง
FAQ
คำถาม
ไฟล์ debug log ของ WordPress อยู่ที่ไหน
ค่าเริ่มต้นคือ wp-content/debug.log อยู่ในโฟลเดอร์ wp-content ตรง ๆ WordPress จะสร้างไฟล์นี้ก็ต่อเมื่อมีข้อผิดพลาดถูกบันทึกจริง ดังนั้นการที่โฟลเดอร์ wp-content ว่างเปล่าไม่ได้แปลว่าการบันทึก log พัง ถ้าคุณกำหนด WP_DEBUG_LOG เป็นพาธไฟล์แทนค่า true log จะถูกเขียนไปที่พาธนั้นแทน
ทำไมไม่มีไฟล์ debug.log ใน wp-content
มีสาเหตุที่พบบ่อยสามอย่าง หนึ่ง WP_DEBUG เป็น false WordPress จึงไม่เปิดการบันทึกไม่ว่าจะตั้ง WP_DEBUG_LOG ไว้อย่างไร สอง ยังไม่มีข้อผิดพลาดเกิดขึ้น ไฟล์จึงยังไม่ถูกสร้าง สาม PHP เขียนลง wp-content ไม่ได้เพราะสิทธิ์ไฟล์ ตรวจค่าคงที่ก่อน แล้วค่อยตรวจสิทธิ์
คนอื่นดาวน์โหลดไฟล์ debug.log ของเราได้ไหม
โดยทั่วไปได้ เพราะ wp-content/debug.log อยู่ใน web root โดยไม่มีกฎควบคุมการเข้าถึงคุ้มครองอยู่ การเรียก URL นั้นจากเบราว์เซอร์จึงมักได้ไฟล์กลับมา และ debug log มักมีพาธเต็มบนเซิร์ฟเวอร์ ข้อผิดพลาดของฐานข้อมูล และเศษคิวรีอยู่ด้วย ให้ย้าย log ออกไปนอก web root หรือบล็อกมันในการตั้งค่าเซิร์ฟเวอร์
WP_DEBUG_LOG กับ WP_DEBUG_DISPLAY ต่างกันอย่างไร
WP_DEBUG_LOG เขียนข้อผิดพลาดลงไฟล์ ส่วน WP_DEBUG_DISPLAY พิมพ์ข้อผิดพลาดลงใน HTML ของหน้าเว็บซึ่งผู้เข้าชมอ่านได้ บนเว็บที่ใช้งานจริงคุณต้องการเปิดการบันทึกและปิดการแสดงผล และทั้งสองค่าจะถูกเมินโดยสิ้นเชิงถ้าไม่ได้ตั้ง WP_DEBUG เป็น true ซึ่งเป็นขั้นตอนที่คนพลาดมากที่สุด
อ่าน debug log ของ WordPress อย่างไร
ถ้าเข้าผ่าน SSH ได้ ให้รัน tail -f ที่พาธของ log เพื่อดูรายการใหม่ปรากฏสด ๆ ขณะที่คุณทำให้ปัญหาเกิดซ้ำ ถ้าไม่มี SSH ให้ดาวน์โหลดไฟล์ผ่าน SFTP หรือเปิดใน file manager ของโฮสต์ อ่านจากล่างขึ้นบน เพราะ PHP ต่อรายการใหม่ไว้ท้ายไฟล์
การเปิด WP_DEBUG ทำให้เว็บจริงช้าลงไหม
ช้าลงเล็กน้อย แต่ความเสี่ยงที่ใหญ่กว่าคือพื้นที่ดิสก์ การบันทึกแบบละเอียดบนเว็บที่มีคนเข้าเยอะทำให้ debug.log โตถึงระดับกิกะไบต์และทำให้ดิสก์เต็ม ซึ่งทำให้เว็บล่ม ให้เปิดใช้ ทำให้บั๊กเกิดซ้ำ อ่าน log แล้วปิดกลับ ไม่มีอะไรในแกนหลักของ WordPress ที่หมุนเวียนหรือตัดขนาดไฟล์นั้นให้คุณ