250x250
반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- basic
- Swift
- ToDoRim
- algorithm
- toyproject
- Equatable
- Extentsion
- pubspec
- swiftlint
- designPattern
- Leetcode
- it
- dart
- flutter
- github
- OSLog
- reetcode
- GIT
- UIAccessibility
- enumerations
- COMMIT
- SwiftGen
- Widget
- tip
- IOS
- pubspec.yaml
- listview
- protocol
- xcode
- keyWindow
Archives
- Today
- Total
수니의 개발새발
[iOS/Swift] OSLog (with. extension) 본문
728x90
반응형
항상 새 프로젝트를 시작할 때 로깅 라이브러리를 적용하고 있는데,
Lumberjack을 사용하다가 김종권님 블로그에서 OSLog라는 로깅 프레임워크를 알게 되었어요.
📌 이번 글은
OSLog 개념과 적용부터 extension으로 사용하는 방법입니다.
OSLog
- 과거의 데이터를 읽기 위한 통합 로깅 시스템
- OSLog 프레임워크는 사용자(프로그래머)가 로그를 읽을 수 있게 해준다.
Logging
- 통합 로깅 시스템을 사용하여 디버깅 및 성능 분석을 위해 앱에서 원격 측정 (telemetry)을 캡쳐한다.
통합 로깅 시스템
- 통합 : 로그 데이터 저장을 level에 따라 메모리와 디스크의 데이터 저장소에 모으는 것(iOS 10+)
- 장점 : 모든 level의 시스템에서 로깅 표출이 가능하다.
- xcode를 실행하지 않아도 console앱에서 로깅이 가능하다.
- os_log를 사용하면 mac의 콘솔 앱에서 로그를 쉽게 확인(필터 기능)하고 저장 기능을 활용할 수 있다.
level
level | disk 저장 여부 | 내용 |
Notice (Defualt) | O | 문제 해결에 필수적인 정보. Failure를 초래할 수 있는 정보 |
Info | log tool로 수집된 정보만 O | 문제 해결시 활용할 수 있는, 도움이 되지만 필수적이지 않은 정보 |
Debug | X | 개발 중 코드 디버깅 시 사용할 수 있는 유용한 정보 |
Error | O | 코드 실행 중 나타난 에러 |
Fault | O | 코드 속의 Faults 및 버그 관련 정보 |
OSLog 적용방법
1. Target > Build Phases > Link Binary With Libraries > +
2. OSLog 검색 > OSLog.framework 선택 > Add
3. 추가된 OSLog.framework > Status > Optional로 변경
OSLog+Extension 생성
- Extension을 생성하여 간편히 사용합니다.
- 코드를 보면 #if DEBUG 키워드를 사용하였는데, Debug 모드에서만 컴파일하도록 분기한 것입니다.
#if DEBUG 참고 포스팅
import Foundation
import os.log
extension OSLog {
static let subsystem = Bundle.main.bundleIdentifier!
static let network = OSLog(subsystem: subsystem, category: "Network")
static let debug = OSLog(subsystem: subsystem, category: "Debug")
static let info = OSLog(subsystem: subsystem, category: "Info")
static let error = OSLog(subsystem: subsystem, category: "Error")
}
struct Log {
/**
# (e) Level
- Authors : suni
- debug : 디버깅 로그
- info : 문제 해결 정보
- network : 네트워크 정보
- error : 오류
- custom(category: String) : 커스텀 디버깅 로그
*/
enum Level {
/// 디버깅 로그
case debug
/// 문제 해결 정보
case info
/// 네트워크 로그
case network
/// 오류 로그
case error
case custom(category: String)
fileprivate var category: String {
switch self {
case .debug:
return "🟡 DEBUG"
case .info:
return "🟠 INFO"
case .network:
return "🔵 NETWORK"
case .error:
return "🔴 ERROR"
case .custom(let category):
return "🟢 \(category)"
}
}
fileprivate var osLog: OSLog {
switch self {
case .debug:
return OSLog.debug
case .info:
return OSLog.info
case .network:
return OSLog.network
case .error:
return OSLog.error
case .custom:
return OSLog.debug
}
}
fileprivate var osLogType: OSLogType {
switch self {
case .debug:
return .debug
case .info:
return .info
case .network:
return .default
case .error:
return .error
case .custom:
return .debug
}
}
}
static private func log(_ message: Any, _ arguments: [Any], level: Level) {
#if DEBUG
if #available(iOS 14.0, *) {
let extraMessage: String = arguments.map({ String(describing: $0) }).joined(separator: " ")
let logger = Logger(subsystem: OSLog.subsystem, category: level.category)
let logMessage = "\(message) \(extraMessage)"
switch level {
case .debug,
.custom:
logger.debug("\(logMessage, privacy: .public)")
case .info:
logger.info("\(logMessage, privacy: .public)")
case .network:
logger.log("\(logMessage, privacy: .public)")
case .error:
logger.error("\(logMessage, privacy: .public)")
}
} else {
let extraMessage: String = arguments.map({ String(describing: $0) }).joined(separator: " ")
os_log("%{public}@", log: level.osLog, type: level.osLogType, "\(message) \(extraMessage)")
}
#endif
}
}
// MARK: - utils
extension Log {
/**
# debug
- Authors : suni
- Note : 개발 중 코드 디버깅 시 사용할 수 있는 유용한 정보
*/
static func debug(_ message: Any, _ arguments: Any...) {
log(message, arguments, level: .debug)
}
/**
# info
- Authors : suni
- Note : 문제 해결시 활용할 수 있는, 도움이 되지만 필수적이지 않은 정보
*/
static func info(_ message: Any, _ arguments: Any...) {
log(message, arguments, level: .info)
}
/**
# network
- Authors : suni
- Note : 네트워크 문제 해결에 필수적인 정보
*/
static func network(_ message: Any, _ arguments: Any...) {
log(message, arguments, level: .network)
}
/**
# error
- Authors : suni
- Note : 코드 실행 중 나타난 에러
*/
static func error(_ message: Any, _ arguments: Any...) {
log(message, arguments, level: .error)
}
/**
# custom
- Authors : suni
- Note : 커스텀 디버깅 로그
*/
static func custom(category: String, _ message: Any, _ arguments: Any...) {
log(message, arguments, level: .custom(category: category))
}
}
👩🏻💻 사용 예제
1. 필요한 소스 코드에 로그 찍기
Log.debug("Debug Log Sample")
Log.error("Error Log Sample")
Log.info("Info Log Sample 입니다. Info Log Sample 입니다. Info Log Sample 입니다. Info Log Sample 입니다.")
2. xcode console 로깅 확인
3. mac 콘솔 앱 로깅 확인
- '콘솔' 앱 > 기기 선택 > Bundle ID 검색 > 하위 시스템 선택
🙋🏻♀️ 참고
[Swift] 통합 로깅 시스템으로 로깅 해보자!: OSLog
[iOS - swift] os_log, Logger, 통합 로깅 시스템 (unified logging system)
728x90
반응형
'iOS - Swift' 카테고리의 다른 글
[iOS/Swift] Keychain으로 안전하게 데이터 저장/반환/삭제하기 (pod 'SwiftKeychainWrapper') (0) | 2022.06.10 |
---|---|
[iOS/Swift] UserDefaults 반환/저장하기 (feat. 자동 로그인 여부 저장) (0) | 2022.06.09 |
[Xcode/Swift] 전처리기, 전처리문(#if DEBUG) (with. Active Compilation Conditions) (0) | 2022.04.01 |
[iOS/Swift] SwiftLint 규칙 정리 (0) | 2022.03.27 |
[iOS/Swift] Storyboard, ViewController 접근 코드를 Protocol로 정의 (StoryboardInstantiable) (0) | 2022.02.09 |
Comments