Log Rotation เป็นกลไกการจัดการไฟล์บันทึกอัตโนมัติที่ป้องกันการล้นของดิสก์ผ่านการจัดเก็บ การบีบอัด และการลบเรกคอร์ดเก่า ในแอปพลิเคชันมือถือ บันทึกจะสะสมบนอุปกรณ์ของผู้ใช้ และหากไม่มีการหมุนเวียน บันทึกเหล่านั้นอาจใช้หน่วยความจำเป็นกิกะไบต์ภายในไม่กี่สัปดาห์ของการใช้งาน ตาม เอกสาร Redis การกำหนดค่า log rotation ที่ถูกต้องช่วยลดความเสี่ยงของระบบล้มเหลวเนื่องจากดิสก์เต็มลง 99% เมื่อเทียบกับการเติบโตของบันทึกที่ไม่สามารถควบคุมได้ กลยุทธ์การหมุนเวียนหลักคือ: ตามขนาดไฟล์ ตามเวลา และตามจำนวนไฟล์ — แต่ละอย่างจะถูกเลือกขึ้นอยู่กับสถานการณ์การใช้งาน: logrotate ใน Linux, CocoaLumberjack บน iOS และ Timber บน Android รองรับทั้งสามแนวทาง
ประเด็นสำคัญ
Log Rotation คือกระบวนการเปลี่ยนไฟล์บันทึกที่ใช้งานอยู่เป็นระยะไปยังไฟล์ใหม่พร้อมกับการจัดเก็บ บีบอัด หรือลบไฟล์เก่า หากไม่มีการหมุนเวียน ไฟล์บันทึกเดียวจะเติบโตอย่างไม่มีที่สิ้นสุดจนกระทั่งเต็มพาร์ติชันดิสก์ทั้งหมด ทำให้แอปพลิเคชันล้มเหลวและสูญเสียข้อมูล
สถานการณ์ทั่วไป: แอปพลิเคชันเขียนบันทึกลงในไฟล์ app.log เมื่อ app.log ถึง 100 MB ระบบจะเปลี่ยนชื่อเป็น app.log.1 บีบอัดเป็น app.log.1.gz และสร้าง app.log ใหม่ที่ว่างเปล่า เมื่อเต็มครั้งต่อไป app.log.1 จะกลายเป็น app.log.2, app.log.1.gz จะกลายเป็น app.log.2.gz และ app.log.2.gz เก่าจะถูกลบ กลไกนี้เรียกว่า การหมุนเวียนแบบ keep count — จำนวนสำเนาที่เก็บไว้คงที่
ตาม Splunk (2023) การกำหนดค่าการหมุนเวียนที่ไม่ถูกต้องเป็นสาเหตุของ 40% ของเหตุการณ์ที่เกี่ยวข้องกับการเต็มของพื้นที่ดิสก์บนเซิร์ฟเวอร์แอปพลิเคชัน สำหรับอุปกรณ์มือถือ การหมุนเวียนยิ่งสำคัญมากขึ้นเพราะผู้ใช้ไม่สามารถและไม่ควรจัดการบันทึกด้วยตนเอง
Log Rotation รองรับสามกลยุทธ์พื้นฐานที่สามารถรวมกันได้ การเลือกกลยุทธ์ขึ้นอยู่กับประเภทของแอปพลิเคชัน: ระบบเซิร์ฟเวอร์มักใช้การหมุนเวียนตามเวลา มือถือใช้ตามขนาด ระบบฝังตัวใช้ตามจำนวนไฟล์
| กลยุทธ์ | ตัวกระตุ้น | เมื่อใดควรใช้ |
|---|---|---|
| ตามขนาด | ไฟล์ถึง N ไบต์ | ระบบที่มีโหลดสูงและปริมาณบันทึกที่ไม่สามารถคาดเดาได้ |
| ตามเวลา | ผ่านไป N ชั่วโมง/วัน | การดัมพ์รายวัน ข้อกำหนดการปฏิบัติตาม |
| ตามจำนวนไฟล์ | สร้างไฟล์แล้ว N ไฟล์ | อุปกรณ์มือถือที่มีพื้นที่ดิสก์จำกัด |
การหมุนเวียนตามขนาด รับประกันว่าไม่มีไฟล์บันทึกใดเกินขีดจำกัดที่กำหนด ขีดจำกัดถูกเลือกตามพื้นที่ดิสก์ที่มีและความถี่ในการบันทึก สำหรับเซิร์ฟเวอร์ ขีดจำกัดทั่วไปคือ 100–500 MB ต่อไฟล์ สำหรับอุปกรณ์มือถือ — 1–10 MB หากแอปพลิเคชันบันทึกมากเกินไป ควรลดขีดจำกัด มิฉะนั้นการหมุนเวียนจะเกิดขึ้นทุกไม่กี่นาที
การหมุนเวียนตามเวลา ไม่ขึ้นกับปริมาณบันทึก — ไฟล์จะถูกเปลี่ยนตามตารางเวลาที่กำหนด สะดวกสำหรับระบบที่ต้องเก็บบันทึกตามจำนวนวันที่固定: การหมุนเวียนรายวันด้วย keep count = 30 หมายถึงการเก็บ 30 วัน ข้อเสีย — ไฟล์เดียวสามารถเติบโตถึงกิกะไบต์ต่อวันภายใต้โหลดหนัก
logrotate เป็นยูทิลิตี้ Linux มาตรฐานสำหรับการหมุนเวียนบันทึกอัตโนมัติ มันทำงานผ่าน cron และประมวลผลไฟล์กำหนดค่าจาก /etc/logrotate.d/ แต่ละบริการ (nginx, postgresql, แอปพลิเคชัน) สร้างการกำหนดค่าของตัวเองโดยระบุเส้นทางบันทึก กลยุทธ์การหมุนเวียน และการดำเนินการหลังการหมุนเวียน
# /etc/logrotate.d/myapp — การหมุนเวียนบันทึกของแอปพลิเคชัน
/var/log/myapp/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 0640 www-data www-data
postrotate
kill -HUP $(cat /var/run/myapp.pid)
endscript
}
การกำหนดค่านี้หมุนเวียนบันทึกทุกวัน เก็บสำเนา 7 ชุด บีบอัดไฟล์เก่าด้วย gzip (ยกเว้นไฟล์สุดท้าย — delaycompress), ไม่แสดงข้อผิดพลาดหากไม่มีบันทึก (missingok), ไม่หมุนเวียนไฟล์ว่าง (notifempty) และสร้างไฟล์ใหม่ด้วยสิทธิ์ 0640 หลังจากการหมุนเวียน มันส่งสัญญาณ HUP ไปยังกระบวนการแอปพลิเคชันผ่านสคริปต์ postrotate
size — หมุนเวียนเมื่อถึงขนาด (size 100M) rotate — จำนวนสำเนาที่เก็บ (rotate 7) compress — การบีบอัด gzip dateext — เพิ่มวันที่ในชื่อไฟล์แทนหมายเลขลำดับ sharedscripts — รัน postrotate หนึ่งครั้งสำหรับทุกไฟล์ ไม่ใช่แยกแต่ละไฟล์ maxage — ลบที่เก็บถาวรที่เก่ากว่า N วัน
บนอุปกรณ์มือถือ Log Rotation มีความสำคัญเพราะผู้ใช้ไม่ได้จัดการระบบไฟล์และไม่คาดหวังว่าแอปพลิเคชันจะใช้พื้นที่กิกะไบต์กับบันทึก iOS และ Android มีกลไกในตัว: os_log บน iOS ใช้บัฟเฟอร์วงแหวนขนาดคงที่ (การหมุนเวียนโดยการเขียนทับ), Android Logcat มีบัฟเฟอร์จำกัดในเคอร์เนล
สำหรับบันทึกไฟล์แบบกำหนดเองบน iOS ใช้ CocoaLumberjack กับคลาส DDFileLogger ซึ่งรองรับการหมุนเวียนตามขนาดและตามเวลา บน Android — Logback หรือการimplement แบบกำหนดเองผ่าน RollingFileAppender ทั้งสองเครื่องมืออนุญาตให้กำหนดขนาดไฟล์สูงสุดและจำนวนที่เก็บถาวร
// CocoaLumberjack — การหมุนเวียนไฟล์บน iOS
import CocoaLumberjack
let fileLogger = DDFileLogger()
fileLogger.maximumFileSize = 1024 * 1024 // 1 MB
fileLogger.logFileManager.maximumNumberOfLogFiles = 5
DDLog.add(fileLogger)
iOS: os_log ไม่ต้องการการหมุนเวียน — ข้อความจะถูกเขียนทับในบัฟเฟอร์วงแหวน แต่ถ้าแอปพลิเคชันเขียนบันทึกไฟล์แบบกำหนดเอง (สำหรับการดีบักหรือส่งไปยังเซิร์ฟเวอร์) ต้องกำหนดค่าการหมุนเวียนด้วยตนเอง CocoaLumberjack เป็นตัวเลือกมาตรฐานสำหรับทีม iOS — มันบีบอัดที่เก็บถาวรเป็น .gz โดยอัตโนมัติและลบไฟล์เก่าเมื่อเกินขีดจำกัด
Android ไม่จำกัดแอปพลิเคชันในการเขียนบันทึกลงในไดเรกทอรีของตัวเอง หากนักพัฒนเขียนบันทึกดีบักลงในไฟล์โดยไม่มีการหมุนเวียน ภายในหนึ่งเดือนของการใช้งานที่Active พวกมันอาจใช้พื้นที่ 500 MB ถึง 1 GB ผู้ใช้จะพบปัญหาเมื่อระบบแสดงคำเตือนพื้นที่จัดเก็บไม่เพียงพอและจะลบแอปพลิเคชัน Logback กับ RollingFileAppender แก้ปัญหานี้: ขีดจำกัด 5 MB พร้อมที่เก็บถาวร 3 ชุดรับประกันว่าบันทึกจะไม่มีวันเกิน 20 MB
ด้านล่างเป็นตัวอย่างการกำหนดค่าการหมุนเวียนบันทึกบนทั้งสองแพลตฟอร์ม บน iOS ใช้ CocoaLumberjack, บน Android — Logback พร้อมการกำหนดค่า XML
// Logback บน Android — การกำหนดค่าการหมุนเวียนใน logback.xml
// ขนาดไฟล์ 5MB, สำเนาที่เก็บถาวร 3 ชุด
@file:Suppress("unused")
// ใน logback.xml:
// <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
// <file>${DATA_DIR}/logs/app.log</file>
// <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
// <fileNamePattern>app.%i.log.gz</fileNamePattern>
// <minIndex>1</minIndex>
// <maxIndex>3</maxIndex>
// </rollingPolicy>
// <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
// <maxFileSize>5MB</maxFileSize>
// </triggeringPolicy>
// </appender>
CocoaLumberjack บน iOS รองรับไม่เพียงการหมุนเวียนตามขนาด แต่ยังการลบบันทึกเก่าตามวันที่ด้วย logFileManager.maximumLogFiles หากตั้งค่า maximumLogFiles = 0 ขีดจำกัดจะถูกลบออก — บันทึกจะสะสมอย่างไม่มีที่สิ้นสุด ซึ่งอันตรายสำหรับ production
// การหมุนเวียนแบบกำหนดเองพร้อมตรวจสอบปริมาณรวม
class SizeAwareLogger {
let maxTotalSize: Int64 = 20 * 1024 * 1024
func enforceQuota(at logDirectory: URL) {
let files = (try? FileManager.default
.contentsOfDirectory(
at: logDirectory,
includingPropertiesForKeys: [.fileSize]
)) ?? []
let total = files.reduce(0) {
$0 + (try? $1.resourceValues(forKeys: [.fileSize])
.fileSize).map(Int64.init) ?? 0
}
if total > maxTotalSize {
// ลบไฟล์ที่เก่าที่สุด
files.sorted { $0.path < $1.path }.first.map {
try? FileManager.default.removeItem(at: $0)
}
}
}
}
Log Rotation ไม่ใช่แค่การเก็บถาวรอัตโนมัติ แต่ยังเป็นตัวบ่งชี้สุขภาพของระบบ หากบันทึกหมุนเวียนบ่อยเกินไป (ทุกไม่กี่นาที) นั่นเป็นสัญญาณของการบันทึกที่มากเกินไปหรือลูปบันทึกข้อผิดพลาด ตั้งค่าการแจ้งเตือนเกี่ยวกับความถี่ในการหมุนเวียน: มากกว่า 10 ครั้งต่อชั่วโมงเป็นเหตุผลที่ต้องตรวจสอบ
ระบบตรวจสอบ (Prometheus, Grafana, Datadog) สามารถติดตามเมตริกการหมุนเวียนผ่านตัวส่งออกระบบไฟล์ Prometheus node_exporter ให้เมตริกขนาดไฟล์และเวลาแก้ไข บนอุปกรณ์มือถือ การตรวจสอบการหมุนเวียนมักถูกรวมอยู่ใน SDK: CocoaLumberjack บันทึกเหตุการณ์การหมุนเวียนผ่าน DDLog และ Logback ส่งสถานะผ่าน appender
การแจ้งเตือน: หากมีที่เก็บถาวรมากกว่าที่คาดไว้ (จำนวนการหมุนเวียนเกินขีดจำกัด) หรือปริมาณบันทึกทั้งหมดเกินโควต้า — ระบบควรแจ้งให้ผู้ดูแลระบบทราบ สำหรับเซิร์ฟเวอร์ เกณฑ์มาตรฐานคือ 80% ของขนาดพาร์ติชัน; สำหรับอุปกรณ์มือถือ — การแจ้งเตือนเมื่อเกิน 50 MB ต่อแอปพลิเคชัน
คำถามที่พบบ่อย
สำหรับเซิร์ฟเวอร์ — 100–500 MB, สำหรับแอปพลิเคชันมือถือ — 1–10 MB ขีดจำกัดที่เล็กเกินไป (น้อยกว่า 1 MB) ทำให้หมุนเวียนบ่อยและการดำเนินการ I/O ที่ไม่จำเป็น ขีดจำกัดที่ใหญ่เกินไป (มากกว่า 500 MB) เพิ่มเวลาในการเปิดและค้นหาในไฟล์
สำหรับ production — อย่างน้อย 7 วัน (หมุนเวียนรายวัน) หรือ 3–5 ที่เก็บถาวร (หมุนเวียนตามขนาด) สำหรับข้อกำหนดการปฏิบัติตาม — 30–90 วัน แต่ให้ใช้พื้นที่จัดเก็บแยกต่างหากที่มีการบีบอัดและนโยบายการเก็บรักษา ไม่ใช่การหมุนเวียนบนพาร์ติชันเดียวกัน
logrotate เป็นยูทิลิตี้ Linux — ไม่สามารถใช้งานบน iOS หรือ Android ได้ บนอุปกรณ์มือถือ การหมุนเวียนถูกimplement โดยไลบรารี: CocoaLumberjack สำหรับ iOS และ Logback สำหรับ Android พวกมันไม่ต้องการสิทธิ์ root และทำงานในสภาพแวดล้อม sandbox ของแอปพลิเคชัน
ตรวจสอบว่ามี การบันทึกแบบวงกลม หรือไม่ — เมื่อการจัดการข้อผิดพลาดสร้างข้อผิดพลาดใหม่ด้วยตนเอง เพิ่มการป้องกัน: ตัวนับการบันทึกซ้ำประเภทเดียวกันพร้อมเกณฑ์ (ไม่เกิน 100 ข้อความที่เหมือนกันต่อนาที) และการล็อคชั่วคราวหลังจากเกิน
ไม่จำเป็นแต่แนะนำ gzip บีบอัดบันทึกข้อความ 10–20 เท่าโดยไม่สูญเสียข้อมูล บนอุปกรณ์มือถือ การบีบอัดลดพื้นที่จัดเก็บจาก 50 MB เหลือ 3–5 MB ข้อเสียอย่างเดียว — ไม่สามารถอ่านที่เก็บถาวรได้โดยไม่ต้องคลายการบีบอัด แต่สำหรับการวิเคราะห์มักต้องการเพียงไฟล์ปัจจุบันเท่านั้น
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม