여느 때처럼 즐겁게 코드를 작성하던 찰나, 진행하던 프로젝트의 PR에 대한 피드백 (코드 리뷰)을 받았습니다.
이미지에서 피드백해주신 코드는 옵셔널 바인딩 결과에 따라 에러를 debugPrint
해주는 부분이었는데요, 과연 링크를 남겨주신 부분이 무엇일까 클릭해보았더니 Zedd님께서 os_log를 주제로 작성하신 글이었습니다. 요지는 Unified logging System (통합 로깅 시스템)에 메시지를 로깅할 수 있는 방식이라는 것이네요. 제 나름대로 내용을 공부해 가볼게요.
OSLog (프레임워크)
과거의 데이터를 읽기 위한 통합 로깅 시스템.
OSLog 프레임워크는 사용자 (프로그래머)가 로그를 읽을 수 있게 해준다. 통합 로깅 시스템을 사용하면 Instrument 및 Console과 같은 Apple 툴과 함께 사용할 사용자 지정 디버깅 및 분석 툴을 구축할 수 있게 해준다.
오케이, 링크된 Logging을 살펴봅시다.
Logging
통합 로깅 시스템을 사용하여 디버깅 및 성능 분석을 위해 앱에서 원격 측정 (telemetry)을 캡처한다.
아직 통합 로깅 시스템에 대한 이해는 하지 못했지만 제가 기존에 에러가 일어나면 print
를 해서 콘솔창으로 확인하던 방식과 달리 로그를 남길 수 있는 방법인가 보네요. 계속 읽다보니 문서에 중요한 내용이 있었습니다.
통합 로깅 시스템은 시스템의 모든 수준에서 원격 측정을 캡처할 수 있는 포괄적이고 성능이 뛰어난 API를 제공합니다. 이 시스템은 데이터를 텍스트 기반 로그 파일에 쓰지 않고 메모리 및 디스크에 로그 데이터를 중앙 집중식으로 저장합니다. 콘솔 앱, 로그 명령줄 도구 또는 Xcode 디버그 콘솔을 사용하여 로그 메시지를 보거나 OSLog 프레임워크를 사용하여 로그 메시지에 프로그래밍 방식으로 액세스할 수도 있습니다.
그렇군요. 성능이 좋고 모든 수준에서 사용할 수 있다. 모든 수준에 대해 궁금하신 분은 이 문서를 읽어보세요. 아래와 같은 표를 찾으실 수 있으실 것입니다.
수준
에 대해 간단하게 보자면 아래와 같습니다.
또 한가지 중요한 점은 통합 로깅 시스템이 iOS 10, macOS 10.12, tvOS 10.0, watchOS 3.0 이후 버전부터 지원한다는 점입니다.
준비해둔 에러 상황에서 어떻게 작동하는지 확인해보겠습니다. mac에 기본 탑재된 console
앱으로 확인해볼게요.
os_log(_:)
import OSLog
os_log("artWork is nil.")
os_log(_:log:_:)
os_log(.error, log: .default, "artwork is Nil.")
os_log(.fault, log: .default, "artwork is Nil.")
물론 콘솔에서도 아래와 같이 로깅된 내용을 확인할 수 있습니다.
아래와 같이 OSLog
클래스의 인스턴스를 OSLog
프레임워크에 타입 프로퍼티로 만들어 확장해주시면 원하시는 subsystem
과 카테고리로 메시지를 로깅하실 수 있습니다.
import OSLog
extension OSLog {
private static var subsystem = Bundle.main.bundleIdentifier!
static let ui = OSLog(subsystem: subsystem, category: "UI")
static let data = OSLog(subsystem: subsystem, category: "Data")
}
// 메시지 로깅이 필요한 위치에서 아래 메서드를 호출
os_log(.fault, log: .data, OSLogMessage.artworkIsNil)
메시지 타입으로 StaticString
을 요구하여 문자열 보간법과 같은 방법을 직접적으로 적용할 수는 없지만 아래와 같은 방법으로 우회적으로 적용할 수 있습니다. 참고 자료
// 아래는 메시지가 `StaticString` 타입이 아니므로 에러가 발생합니다.
os_log(.info, log: .network, "New used logged in with name \(user.name)") // 에러 발생!
// 메시지를 미리 선언하여 아래와 같이 우회적으로 사용할 수 있습니다.
let message = "New used logged in with name \(user.name)"
os_log(.info, log: .network, "%@", message)
읽어주셔서 감사합니다!