250x250
반응형
Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
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
Archives
Today
Total
관리 메뉴

수니의 개발새발

[iOS/Swift] OSLog (with. extension) 본문

iOS - Swift

[iOS/Swift] OSLog (with. extension)

개발자 수니 2022. 4. 7. 17:39
728x90
반응형

항상 새 프로젝트를 시작할 때 로깅 라이브러리를 적용하고 있는데,

Lumberjack을 사용하다가 김종권님 블로그에서 OSLog라는 로깅 프레임워크를 알게 되었어요.

 

 

📌  이번 글은

OSLog 개념과 적용부터 extension으로 사용하는 방법입니다.

 

 

OSLog

 

Apple Developer Documentation

 

developer.apple.com

  • 과거의 데이터를 읽기 위한 통합 로깅 시스템
  • OSLog 프레임워크는 사용자(프로그래머)가 로그를 읽을 수 있게 해준다.

 

Logging

 

Apple Developer Documentation

 

developer.apple.com

  • 통합 로깅 시스템을 사용하여 디버깅 및 성능 분석을 위해 앱에서 원격 측정 (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 참고 포스팅

 

[Xcode/Swift] 전처리기, 전처리문(#if DEBUG) (with. Active Compilation Conditions)

코드에서 Debug 모드 분기 처리하는 방법을 알아보다가, 전처리기 사용에 대하여 알게 되었습니다. 📌  이번 글은 Xcode, Swift에서 전처리문 사용법입니다. 전처리기/전처리문 컴파일 전에 처리되

sunidev.tistory.com

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
반응형
Comments