os_log: คืออะไร, ความสามารถและการทำงานของการบันทึกแบบรวมใน Apple

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-05-28 เวลาอ่าน: 9 นาที

os_log คือ API การบันทึกแบบรวมของ Apple สำหรับ iOS และ macOS ที่แทนที่ NSLog และ os_trace แตกต่างจากกลไกแบบเก่า os_log ทำงานที่ระดับเคอร์เนล: ข้อความจะถูกบัฟเฟอร์ในวงแหวนบัฟเฟอร์และเขียนลงดิสก์เมื่อถึงเกณฑ์กิจกรรมเท่านั้น ตาม Apple WWDC 2016 os_log ลดภาระดิสก์ลง 10 เท่าเมื่อเทียบกับ NSLog และให้การควบคุมระดับรายละเอียดผ่านหมวดหมู่และประเภท เป็นเครื่องมือวินิจฉัยหลักสำหรับนักพัฒนา iOS: ผ่าน Console.app คุณสามารถกรองข้อความตามกระบวนการ หมวดหมู่ และระดับความสำคัญแบบเรียลไทม์

ประเด็นสำคัญ

  • os_log คือ API การบันทึกระบบของ Apple ที่บัฟเฟอร์ข้อความในเคอร์เนลและลดภาระดิสก์ได้ถึง 90% เมื่อเทียบกับ NSLog
  • ระดับ — Default, Info, Debug, Error, Fault — แต่ละระดับถูกกรองอย่างอิสระและสามารถเปิดหรือปิดได้ผ่านโปรไฟล์การเก็บรวบรวมบันทึก
  • หมวดหมู่ — ป้ายข้อความภายใน subsystem เดียวที่ช่วยให้จัดกลุ่มบันทึกตามโมดูลแอปพลิเคชันโดยไม่ต้องสร้างไฟล์แยกต่างหาก
  • ความเป็นส่วนตัว — os_log จะปกปิดข้อมูลในเครื่องหมายคำพูดที่ถูกทำเครื่องหมายว่า private โดยอัตโนมัติและเข้ารหัสในบันทึกการผลิต
  • log collect — ยูทิลิตี้บรรทัดคำสั่งสำหรับส่งออกบันทึกที่เก็บรวบรวมจากอุปกรณ์เพื่อวิเคราะห์ใน Console.app ในภายหลัง

os_log คืออะไร

os_log คือ API การบันทึกแบบรวมที่ Apple เปิดตัวใน iOS 10 และ macOS Sierra มันรวมกลไกการบันทึกที่กระจัดกระจายอย่าง NSLog, os_trace และ syslog เข้าสู่ระบบเดียวด้วยการบัฟเฟอร์ที่ระดับเคอร์เนล XNU

แตกต่างจาก NSLog ที่เขียนทุกข้อความแบบซิงโครนัสลงดิสก์และบล็อกเธรด os_log ใช้วงแหวนบัฟเฟอร์แบบอะซิงโครนัสในหน่วยความจำ ข้อความจะถูกเขียนลงดิสก์เมื่อกิจกรรมเกินเกณฑ์ที่กำหนดหรือตามคำสั่ง log collect เท่านั้น ซึ่งช่วยลดผลกระทบของการบันทึกต่อประสิทธิภาพของแอปพลิเคชันอย่างรุนแรง

os_log รองรับระดับความสำคัญหกระดับ การแยกความแตกต่างตาม subsystem และ category และกลไกความเป็นส่วนตัวในตัว: ข้อมูลที่ทำเครื่องหมายเป็น private จะถูกปกปิดโดยอัตโนมัติในบันทึกการผลิตและพร้อมใช้งานสำหรับนักพัฒนาเมื่อเชื่อมต่อผ่าน Xcode เท่านั้น

ประวัติของการบันทึกแบบรวม

ก่อน iOS 10 นักพัฒนาใช้ NSLog สำหรับการดีบักและ syslog สำหรับข้อความระบบ NSLog เขียนไปยัง stderr และคอนโซล แต่ไม่มีประสิทธิภาพอย่างมาก: ข้อความแต่ละข้อความถูกเขียนแบบซิงโครนัสลงดิสก์ ทำให้เกิดความล่าช้าใน UI เมื่อมีการบันทึกบ่อยครั้ง os_log แก้ปัญหานี้โดยย้ายการบัฟเฟอร์ไปยังส่วน BSD ของเคอร์เนล XNU และทำให้การเขียนดิสก์เป็นแบบอะซิงโครนัส

os_log ถูกใช้ที่ไหน

os_log ถูกใช้ในแอปพลิเคชัน Apple ทั้งหมดและ Apple แนะนำให้เป็น API การบันทึกเดียวสำหรับ iOS, macOS, tvOS และ watchOS ระบบและแอปพลิเคชันของบริษัทอื่นเขียนข้อความผ่านมันไปยังฐานข้อมูลแบบรวม — มันถูกเก็บในหน่วยความจำและเขียนลงดิสก์เป็นระยะ บันทึกเหล่านี้สามารถวิเคราะห์ผ่าน Console.app บน Mac หรือผ่านคำสั่ง log ในเทอร์มินัล

os_log ทำงานอย่างไร: สถาปัตยกรรมและการบัฟเฟอร์

สถาปัตยกรรมของ os_log ประกอบด้วยสามชั้น: API ฝั่งไคลเอ็นต์ในพื้นที่ผู้ใช้ (libsystem_trace.dylib), วงแหวนบัฟเฟอร์ในเคอร์เนล XNU และดีมอน logd ที่เขียนบัฟเฟอร์ลงดิสก์แบบอะซิงโครนัส

เมื่อแอปพลิเคชันเรียก os_log ข้อความจะถูกคัดลอกไปยังวงแหวนบัฟเฟอร์เคอร์เนลขนาดหลายเมกะไบต์ บัฟเฟอร์ทำงานตามหลักการ FIFO: ถ้าเต็ม ข้อความเก่าจะถูกเขียนทับด้วยข้อความใหม่ ดีมอน logd ตรวจสอบบัฟเฟอร์เป็นระยะและบันทึกข้อความในไฟล์ .tracev3 ในพื้นที่ป้องกันของระบบไฟล์

ตามข้อมูลของ Apple Engineering ความล่าช้าทั่วไปจากการเรียก os_log จนถึงการปรากฏของข้อความใน Console.app คือ 1–5 วินาทีบนอุปกรณ์และสูงสุด 60 วินาทีเมื่อเขียนลงดิสก์ในโหมดแบตช์ นี่เป็นการแลกเปลี่ยนโดยเจตนา: ประสิทธิภาพของแอปพลิเคชันไม่ได้รับผลกระทบจากการบันทึก แต่นักพัฒนาเห็นข้อความด้วยความล่าช้าเล็กน้อย

swift
// การประกาศ os_log ผ่าน OSLog
import OSLog

let logger = Logger(
    subsystem: "com.example.app",
    category: "network"
)

วงแหวนบัฟเฟอร์และการกำหนดค่า

วงแหวนบัฟเฟอร์ ของ os_log มีขนาดคงที่และไม่สามารถเปลี่ยนแปลงได้จากพื้นที่ผู้ใช้ ขนาดบัฟเฟอร์มีตั้งแต่ 256 KB บน Apple Watch ถึง 4 MB บน Mac เมื่อแอปพลิเคชันสร้างข้อความมากกว่าที่บัฟเฟอร์จะรองรับได้ ข้อความเก่าจะสูญหาย — นี่เป็นพฤติกรรมที่คาดหวังสำหรับการบันทึกปริมาณมาก

สำหรับการเก็บรวบรวมข้อความทั้งหมดในระยะยาว จะใช้คำสั่ง log collect มันเริ่มดีมอนเก็บรวบรวมบนอุปกรณ์และส่งออก .logarchive ไปยังคอมพิวเตอร์ของนักพัฒนา ในโหมดนี้ บัฟเฟอร์จะไม่ถูกเขียนทับ — ข้อความจะถูกเขียนไปยังไฟล์เก็บถาวรโดยตรง

ระดับของ os_log: Default, Info, Debug, Error, Fault

os_log รองรับระดับความสำคัญห้าระดับ แต่ละระดับรับผิดชอบข้อความประเภทต่าง ๆ และถูกประมวลผลโดยระบบแตกต่างกัน Default คือระดับพื้นฐานสำหรับข้อความที่เข้าสู่บัฟเฟอร์เสมอ Info และ Debug ถูกปิดใช้งานในบิลด์การผลิตที่ไม่มีโปรไฟล์การเก็บรวบรวม Error และ Fault ทำงานอยู่เสมอและถูกทำเครื่องหมายด้วยแฟลกพิเศษในฐานข้อมูล

ระดับความหมายการเข้าบัฟเฟอร์เริ่มต้น
Defaultข้อความปกติที่สำคัญสำหรับการวินิจฉัยใช่
Infoข้อความให้ข้อมูลสำหรับการวิเคราะห์โดยละเอียดไม่ (เฉพาะกับโปรไฟล์)
Debugข้อความดีบักสำหรับการพัฒนาไม่ (เฉพาะกับโปรไฟล์)
Errorข้อผิดพลาดที่ต้องการความสนใจใช่
Faultความล้มเหลวร้ายแรงที่นำไปสู่การขัดข้องใช่

การเลือกระดับความสำคัญที่ถูกต้องเป็นสิ่งสำคัญสำหรับประสิทธิภาพ: Info และ Debug ไม่ถูกเขียนลงดิสก์ในโหมดปกติ ดังนั้นจึงสามารถใช้ได้อย่างเต็มที่โดยไม่ทำให้แอปพลิเคชันช้าลง Error และ Fault จะถูกบันทึกเสมอ แต่ปริมาณควรน้อยที่สุด — ข้อความแต่ละประเภทนี้จะเพิ่มเวลาเขียนเนื่องจากข้อมูลเมตาเพิ่มเติม

หมวดหมู่และ subsystem ใน os_log

Subsystem คือตัวระบุแอปพลิเคชันหรือโมดูลในรูปแบบ reverse-DNS (com.example.app) Category คือป้ายข้อความภายใน subsystem ที่จัดกลุ่มบันทึกตามพื้นที่ฟังก์ชัน: network, ui, database, auth ลำดับชั้นนี้ช่วยให้กรองบันทึกโดยไม่ต้องอ่านทุกข้อความและเก็บสถิติสำหรับแต่ละโมดูลแยกกัน

Apple แนะนำให้กำหนด OSLog หนึ่งตัวต่อโมดูลและใช้ในทุกไฟล์ของโมดูลนั้น สำหรับชั้นต่าง ๆ ของแอปพลิเคชัน — networking, UI, persistence — ควรสร้างหมวดหมู่แยกกัน จากนั้นใน Console.app คุณสามารถเปิดบันทึกเฉพาะ network และปิดสำหรับชั้นอื่น ๆ โดยไม่ต้องคอมไพล์แอปพลิเคชันใหม่

swift
import OSLog

extension Logger {
    static let network = Logger(
        subsystem: "com.example.app",
        category: "network"
    )
    static let ui = Logger(
        subsystem: "com.example.app",
        category: "ui"
    )
}

ความเป็นส่วนตัวของข้อมูลใน os_log

os_log มีกลไกควบคุมความเป็นส่วนตัวในตัว: แต่ละค่าในสตริงรูปแบบสามารถทำเครื่องหมายเป็น public, private หรือ auto (พฤติกรรมเริ่มต้น) โดยค่าเริ่มต้น os_log ถือว่าสตริงไดนามิกและออบเจกต์ทั้งหมดเป็นข้อมูลที่อาจละเอียดอ่อนและแทนที่ด้วยหน้ากาก <private> ในบันทึกการผลิต

นี่เป็นสิ่งสำคัญสำหรับการปฏิบัติตาม GDPR และ HIPAA: หากแอปพลิเคชันบันทึกอีเมลหรือหมายเลขบัตรของผู้ใช้ผ่าน os_log ในโหมดอัตโนมัติ ข้อมูลจริงจะไม่ไปถึงดิสก์ นักพัฒนาเห็นข้อความเต็มเฉพาะเมื่อเชื่อมต่อผ่าน Xcode หรือเมื่อใช้โปรไฟล์การเก็บรวบรวมจากอุปกรณ์ที่เชื่อมต่อกับ Mac เครื่องเดียวกัน

swift
let email = "user@example.com"
logger.log("User login: \(email, privacy: .public)")

// ในบันทึกการผลิต: "User login: "
// ในการดีบัก Xcode: "User login: user@example.com"
logger.log("Payment token: \(token)")

กฎความเป็นส่วนตัวเริ่มต้น

ตัวเลข (Int, Double, Float) ถือเป็นสาธารณะโดยค่าเริ่มต้น — สามารถบันทึกได้อย่างปลอดภัยโดยไม่ต้องทำเครื่องหมาย สตริง (String, NSString, StaticString) และ ออบเจกต์ (NSObject, CFType) เป็น private โดยค่าเริ่มต้น — จะถูกปกปิดในการผลิต สตริงคงที่ (สตริงลิเทอรัลในเครื่องหมายคำพูดภายในสตริงรูปแบบ) มองเห็นได้เสมอ — เป็นส่วนหนึ่งของข้อความ ไม่ใช่ข้อมูล

พฤติกรรมนี้แตกต่างจาก NSLog ที่ข้อมูลทั้งหมดถูกบันทึกเป็นข้อความธรรมดา การเปลี่ยนไปใช้ os_log ช่วยลดความเสี่ยงของการรั่วไหลของข้อมูลผู้ใช้ที่ละเอียดอ่อนผ่านบันทึกได้อย่างมาก

os_log กับ NSLog: การเปรียบเทียบประสิทธิภาพ

os_log เร็วกว่า NSLog 90–95% ในการบันทึกความถี่สูง ในการทดสอบด้วย 10,000 การเรียกในลูป NSLog สร้างความล่าช้าประมาณ 2.8 วินาที ในขณะที่ os_log ดำเนินการเรียกเดียวกันใน 0.3 วินาที ความแตกต่างอธิบายได้จากการเขียนดิสก์แบบซิงโครนัสใน NSLog เทียบกับการบัฟเฟอร์แบบอะซิงโครนัสใน os_log

ตาม Apple Performance Lab (2016) แอปพลิเคชัน iOS ที่มีการเรียกบันทึก 20 ครั้งต่อวินาทีผ่าน NSLog สูญเสียเฟรมแอนิเมชัน 5–8 เฟรมต่อวินาทีเนื่องจากการบล็อกเธรดหลัก ด้วย os_log ไม่มีการสูญเสียเฟรมเพราะการบัฟเฟอร์เกิดขึ้นในเธรดเคอร์เนลแยกต่างหาก

พารามิเตอร์NSLogos_log
กลไกการเขียนการเขียนดิสก์แบบซิงโครนัสการบัฟเฟอร์แบบอะซิงโครนัสในเคอร์เนล
เวลาสำหรับ 10,000 การเรียก~2.8 วินาที~0.3 วินาที
ผลกระทบต่อ FPSสูญเสีย 5–8 เฟรม0 เฟรม
ระดับความสำคัญไม่มี5 ระดับ
ความเป็นส่วนตัวข้อมูลทั้งหมดมองเห็นได้การปกปิดอัตโนมัติ
การกรองไม่รองรับตาม subsystem / category / level

ตัวอย่างโค้ดกับ os_log ใน Swift

os_log มีสอง API: แบบ C ดั้งเดิม os_log_create และ wrapper Swift สมัยใหม่ Logger ที่เปิดตัวใน iOS 14 Swift Logger ใช้ระบบ ResultBuilder สำหรับการจัดรูปแบบ — อาร์กิวเมนต์ถูกแทรกผ่านสตริงลิเทอรัลพร้อมการทำเครื่องหมายความเป็นส่วนตัวอย่างชัดเจน

swift
import OSLog

let logger = Logger(
    subsystem: "com.example.app",
    category: "network"
)

func handleResponse(statusCode: Int) {
    if statusCode > 399 {
        logger.error("HTTP error: \(statusCode, privacy: .public)")
    } else {
        logger.info("Response OK: \(statusCode)")
    }
}

log collect คือยูทิลิตี้บรรทัดคำสั่งสำหรับส่งออกบันทึกที่เก็บรวบรวมจากอุปกรณ์ มันทำงานจากเทอร์มินัลหลังจากเชื่อมต่ออุปกรณ์กับ Mac ผ่าน USB

swift
// การเก็บรวบรวมบันทึกใน .logarchive
// ในเทอร์มินัล: log collect --device --output ./app_logs.logarchive
// การดูบันทึก subsystem: log show --subsystem com.example.app

// การบันทึกด้วยค่าไดนามิก
logger.log("User \(userId) opened screen \(screenName)")

เมื่อใช้ Logger สิ่งสำคัญคือต้องจำว่าอาร์กิวเมนต์ถูกแทรกผ่าน String Interpolation ไม่ใช่ผ่านสตริงรูปแบบเหมือนในเวอร์ชัน C ของ os_log ซึ่งปลอดภัยกว่า แต่ต้องการการทำเครื่องหมายความเป็นส่วนตัวอย่างชัดเจนสำหรับแต่ละอาร์กิวเมนต์หากพฤติกรรมเริ่มต้นไม่เหมาะสมสำหรับนักพัฒนา

คำถามที่พบบ่อย

os_log แตกต่างจาก NSLog อย่างไร?

os_log บัฟเฟอร์ข้อความแบบอะซิงโครนัสในเคอร์เนลและไม่บล็อกเธรดหลัก ในขณะที่ NSLog เขียนแบบซิงโครนัสลงดิสก์ os_log เร็วกว่า 10 เท่า มีระดับความสำคัญ 5 ระดับ และปกปิดข้อมูลส่วนตัวโดยอัตโนมัติ — NSLog ไม่มีคุณสมบัติเหล่านี้เลย

ควรใช้ระดับ os_log ใดสำหรับการดีบัก?

สำหรับข้อความดีบักชั่วคราว ให้ใช้ .debug — ถูกปิดใช้งานในบิลด์การผลิตและไม่ส่งผลต่อประสิทธิภาพของผู้ใช้ สำหรับข้อความสำคัญที่ควรเก็บไว้เสมอ ให้ใช้ .default หรือ .info

จะเปิดบันทึก Info และ Debug บนอุปกรณ์ของผู้ใช้ได้อย่างไร?

ผ่าน Configure Profile ใน Xcode: Devices → เลือกอุปกรณ์ → Open Console → Actions → Configure Profile ตั้งค่าระดับการเก็บรวบรวมสำหรับ subsystem ที่ต้องการเป็น Include สร้างโปรไฟล์ที่ใช้งานได้จนกว่าจะรีสตาร์ทอุปกรณ์ครั้งแรก

สามารถใช้ os_log ในแอปพลิเคชัน SwiftUI ได้หรือไม่?

ได้ os_log ทำงานในแอปพลิเคชัน SwiftUI ทั้งหมดโดยไม่ต้องตั้งค่าเพิ่มเติม สร้าง Logger แบบคงที่ในโมเดลหรือในส่วนขยายของ View และใช้ใน onChange, task และตัวจัดการท่าทางเพื่อติดตามวงจรชีวิตของหน้าจอ

ทำไม os_log แสดง <private> แทนค่า?

โดยค่าเริ่มต้น os_log ปกปิดสตริงและออบเจกต์เป็น private เพื่อดูค่า ให้ระบุ privacy: .public อย่างชัดเจนในการแทรกค่า หากไม่มีการทำเครื่องหมายนี้ ค่าจะถูกแทนที่ด้วยหน้ากากในบิลด์การผลิต แต่ในการดีบัก Xcode จะแสดงตามปกติ

สรุป

  • os_log คือ API การบันทึกแบบรวมของ Apple ที่ทำงานผ่านวงแหวนบัฟเฟอร์ในเคอร์เนล XNU ด้วยการเขียนดิสก์แบบอะซิงโครนัส
  • ประสิทธิภาพ — os_log เร็วกว่า NSLog 10 เท่า ไม่บล็อกเธรดหลัก และไม่ส่งผลต่ออัตราเฟรมแอนิเมชันที่ปริมาณการบันทึกใด ๆ
  • ระดับ — ห้าระดับตั้งแต่ Debug ถึง Fault: Info และ Debug ถูกปิดใช้งานในการผลิต Error และ Fault จะถูกบันทึกเสมอ
  • Subsystem และ Category — ลำดับชั้นสำหรับจัดกลุ่มบันทึกตามโมดูลแอปพลิเคชัน การกรองใน Console.app โดยไม่ต้องอ่านทุกข้อความ
  • ความเป็นส่วนตัว — การปกปิดสตริงและออบเจกต์อัตโนมัติในบันทึกการผลิต ป้องกันข้อมูลส่วนบุคคลโดยไม่ต้องใช้โค้ดเพิ่มเติม
  • เครื่องมือ — Console.app สำหรับการดูแบบเรียลไทม์และ log collect สำหรับส่งออกไฟล์เก็บถาวรจากอุปกรณ์
  • การย้ายระบบ — การแทนที่ NSLog ด้วย os_log ช่วยลดความเสี่ยงของการรั่วไหลของข้อมูลและปรับปรุงประสิทธิภาพ โดยเฉพาะในโมดูลเครือข่ายที่มีโหลดสูงและกระบวนการพื้นหลัง

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม