iOS2022. 7. 29. 10:38

iOS에서 mac과 xcode가 없이도 로그를 확인할 수 있도록 작성한 로거앱을 소개하겠다.

이 앱은 안드로이드와 달리 별도의 앱을 폰에 설치하여 로그를 확인할 수 있는 방법이 iOS에서는 제공되지 않는것인지 내가 못찾는것인지 찾을수가 없어서 그냥 내가 필요해서 만든 앱이다.

 

https://github.com/samse/SwiftSocketLogger

 

GitHub - samse/SwiftSocketLogger: Swift socket logger

Swift socket logger. Contribute to samse/SwiftSocketLogger development by creating an account on GitHub.

github.com

github에서 소스를 다운받아서 빌드하여 앱을 설치해야 한다. 스토어에서 설치 가능하도록 스토어게시를 시도해볼 생각이다.

위 소스로 앱을 설치하고 실행하면 아래 처럼 로그를 확인할 수 있다.

 

 

소켓으로 로그를 수신받아 로깅을 하는 방식이며 백그라운드에서 로그를 수집할 수 있어야 하기 때문에 백그라운드앱으로 작성되었다. 백그라운드 동작 방식은 무음 mp3를 재생하는 단순하고 쉬운 방식으로 작성하였다. 이겄 때문에 스토어게시가 안될수도 있겠단 생각이 들긴 한데 리젝되면 다른 방식으로 수정해볼 예정이다.

 

이제 로거 서버에 해당하는 로거앱을 설치하였으니 로그를 발생시키기 위해서 필요한 클라이언트앱에서는 어떻게 해야 하는지 설명하겠다.

github 페이지에서도 설명하였지만 일단 로거앱의 소스중에 swiftsocket 폴더의 소스를 클라이언트 앱으로 모두 가져와야 한다.

그리고 다음의 클라이언트용 로거 클래스를 추가한다.

 

class SocketLogger : NSObject {
    enum LoggerStatus: Int { case disconnected=0, connecting, connected }
    var status: LoggerStatus = .disconnected

    func sendLogs(_ logStr: String, completion: (() -> ())?) {
        if status == .connected {
            return
        }
        status = .connecting
        print("Logger sendLogs : \(logStr)")
        let client = TCPClient(address: "127.0.0.1", port: 2532)
        switch client.connect(timeout: 10) {
          case .success:
            status = .connected
            let data = logStr.data(using: .utf8)
            let _ = client.send(data: data!)
            DispatchQueue.global().asyncAfter(deadline: .now() + 0.2) {
                self.status = .disconnected
                if let completion = completion { completion() }
            }
          case .failure(let error):
            print("failure: \(error)")
            status = .disconnected
        }
    }
}

 

그리고 소켓 로거클래스를 사용하는 로거도 추가한다.

 

class Logger {
    static func debug(_ message: String?) {
        printLog(level: "🐛 DEBUG", message: message)
    }
    
    /// 경고 로그
    static func warning(_ message: String?) {
        printLog(level: "⚠️ WARNING", message: message)
    }
    
    /// 오류 로그
    static func error(_ message: String?) {
        printLog(level: "🚫 ERROR", message: message)
    }
    
    /// 정보 로그
    static func info(_ message: String?) {
        printLog(level: "ℹ️ INFO", message: message)
    }

    func printLog(level: String, message: String) {
        let logStr = "[\(level)] \(message ?? "")"
        self.appendLog(logStr)
    }
    
    static var logQueue = [String]()
    static let lock = NSLock()
    private static func appendLog(_ logStr: String) {
        print("\(logStr)")
        lock.lock(); defer { lock.unlock() }
        logQueue.append(logStr)
        triggerLogging()
    }
    private static func getLog() -> String? {
        if logQueue.count > 0 {
            return logQueue.first
        }
        return nil
    }
    private static func removeLog() {
        if logQueue.count > 0 {
            logQueue.removeFirst()
        }
    }
    
    static var socketLogger: SocketLogger = SocketLogger()
    private static func triggerLogging() {
        if let logStr = getLog() {
            socketLogger.sendLogs(logStr) {
                removeLog()
                triggerLogging()
            }
        }
    }
}

 

이제 앱코드내에서 다음과 같이 로거를 호출하면 SwiftSocketLogger앱에 해당 로그가 나오게 된다.

Logger.debug("my log" )
Logger.info("my info log")

아래 그림에 보는것과 같이 우상단의 디버그레벨 문구를 누르면 디버그레벨을 변경이 가능하며 좌측의 텍스트필드에 값을 입력하면 해당 값으로 로그를 필터링해서 볼수 있다.

 

 

단말만으로 디버깅을 해야 하는 상황에서 유용하게 사용할 만한 방법이라고 생각되며 잘 사용하고 있는 앱이다 다른 개발자들도 일부 불편함을 해소하는데 사용되었으면 좋겠다.

 

Posted by 삼스