มาเลิกใช้ print กันเถอะ

Jassadakorn.ket
te<h @TDG
Published in
3 min readAug 20, 2024

ทุกคนคงจะรู้จัก function print ใน swift กันเป็นอย่างดีอยู่แล้ว ซึ่งมันเป็นหนึ่งในเครื่องมือที่เราใช้ debug ดูค่าตัวแปรต่างๆที่เขียนไว้ในโปรเจคว่ามันถูกต้องมั้ย ซึ่งผมคิดว่ามันก็โอเคแหล่ะในโปรเจคเล็กๆมีคนทำงานร่วมกันไม่เยอะ คุณอยากจะ ใส่ print มันทั้งโปรเจคก็ไม่มีใครว่าอะไร หรือจะห้าม push code มาเลยก็ได้เหมือนกัน หรือบางที่จะใส่สี ใส่ emoji มาให้อ่านง่าย

แต่ละที่แต่ละบริษัทก็มีวิธีจัดการต่างกัน

ซึ่งผมพยายาม ลด ละ เลิกใช้มัน เพราะมันมีปัญหาต่างๆมากมายที่ผมเจอก็มีประมาณนี้

  1. print มันใช้ง่ายไม่ต้อง setup อะไรก็จริงแต่มันไม่มี meta data ว่าข้อความนี้มันมาจากไหน class ไหน และไม่รู้ว่ามันมาจากส่วนไหนของโปรเจค
  2. Print ไม่มีบอกระดับหรือ log level ว่า ข้อความมันเป็นแค่การ debug มันคือ info หรือมันคือ error และเราจะแยก message ธรรมดากับ error ยังไงล่ะ ?
  3. Print เมื่อเรา stop run บน xcode แล้วมันไม่สามารถดูข้อความได้ บางทีเราส่ง appให้ QA แล้วอยากดู Log แต่ทำไม่ได้

ซึ่งบางที่ก็แก้ปัญหาโดยวิธีใส่ชื่อ class ลงไปใน print หรือบางที่ก็ใส่ Emoji เพื่อไป filter ส่วน log QA อาจจะใช้ NewRelic ซึ่งโคตรช้าและแพง และนั่นก็ไม่ได้เป็นการแก้ปัญหาระยะยาว

ผมขอแนะนำสิ่งที่ดีกว่านั่นก็คือ Logger ที่อยู่ใน OSLog ที่มีมาตั่งแต่ iOS 14

import OSLog
let logger = Logger(subsystem: "com.company.project", category: "feature")

ซึ่งในการ initial Logger จะ require parameters 2 ตัว

  1. subsystem: String
  2. category: String

subsystem ส่วนใหญ่แล้วผมจะใช้เป็น bundle id ของ module นั้นๆ

category สามารถใส่ใช้ได้ทั้งชื่อของ class หรือชื่อของ feature อยู่ที่ว่าจะแบ่งละเอียดแค่ไหน

import SwiftUI
import OSLog

@main
struct LoggerProjectApp: App {

let logger = Logger(subsystem: "com.company.project", category: "feature")

var body: some Scene {
WindowGroup {
ContentView()
.onAppear {
logger.notice("notice")
logger.info("info")
logger.debug("debug")
logger.error("error")
logger.fault("fault")
}
}
}
}

เมื่อรันจะได้ result ดังนี้

สังเกตุได้ว่านอกจาก message แล้วจะมีข้อมูลอย่างอื่นขึ้นมาด้วย เช่น Icon, Timestamp, Subsystem, Feature และสีของ background

สามารถเปิด ปิดได้ที่ปุ่มนี้

เราสามารถกด filter เพื่อดูแต่ type ที่เราต้องการได้

รวมถึงสามารถ filter by subsystem และ category ได้อีกด้วย

และอีกหนึ่ง feature ลับของ Logger คือ click to go log

เวลาเอาเมาส์เข้าไปใกล้มันจะขึ้นมาแบบนี้ให้ลองกดไปที่ลูกศร มันจะพาไปยังไฟล์และบรรทัดที่ log ให้ทันทีซึ่ง print ทำไม่ได้แน่นอน

อีกหนึ่ง feature ที่ผมชอบมากๆเลยก็คือการดู log จาก application Console ในเครื่อง Mac โดยที่ไม่จำเป็นต้องเชื่อมต่อ Xcode เลย

เปิด app Console ขึ้นมาจากนั้นเลือกไปยังเครื่องที่เราต้องการจะเป็นเครื่อง iPhone จริง หรือ simulator ก็ได้ แล้วกด start streaming

ลองทดสอบ app เพื่อดูว่ามี message ที่เรา log ไว้ขึ้นบน app Console หรือไม่ ( ไม่จำเป็นต้อง build Xcode ) ถ้าหา message ไม่เจอ ตรงมุมขวาบนจะมี filter subsystem และ category

จะสังเกตุได้ว่า เรา log ไป 5 Type

Notice, Info, Debug, Error, Fault

ทำไมขึ้นแค่ Notice, Error, Fault จากที่ผมไป reseach มา Apple มีคำอธิบายดังนี้

debug และ info จะ log แค่ใน memory ส่วนที่เหลือจะ write ลงไฟล์ ซึ่ง app Console บน Mac ก็จะคอยอ่านไฟล์ log ตัวนี้นั่นเอง

เท่านี้ app บน environment ที่เรา test กัน internal ก็สามารถดู log ได้สบาย สามารถ reproduce bug ได้ง่ายขึ้น

แต่ผมมีข้อควรระวังไว้นิดนึงว่า log เหล่านี้ไม่ควรหลุดไปที่ Production เด็ดขาดมันอันตราย แต่ apple ก็ provide สิ่งที่เรียกว่า privacy เอาไว้ด้วย

ก่อนที่จะยาวไปกว่านี้ซึ่งจริงๆ OSLog ยังมี feature ที่น่าสนใจอีกมากมาย อยากให้ทุกคนลองไปศึกษากันดู และลองเลิกใช้ print แบบผม

ถ้ามีคำแนะนำอะไร แนะนำได้เลยครับผม หากผิดพลาดประการใดขออภัย

--

--