Created
November 15, 2019 13:49
-
-
Save khorbushko/a51731d9f556de94ea40bcc1f35a687d to your computer and use it in GitHub Desktop.
print listener
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
import CocoaLumberjack | |
typealias FilePath = String | |
final class AppLogger { | |
private static let listener = ConsoleEavesdropper() | |
// MARK: - Logger | |
class var logFilesPaths: [FilePath] { | |
get { | |
let logers = DDLog.sharedInstance.allLoggers | |
var logFiles: [FilePath] = [] | |
for logger in logers { | |
if let currentLogger = logger as? DDFileLogger { | |
let files = currentLogger.logFileManager.unsortedLogFileInfos.compactMap({ $0.filePath }) | |
logFiles.append(contentsOf: files) | |
} | |
} | |
return logFiles | |
} | |
} | |
class var content: String { | |
var returnString: String = String.empty | |
logFilesPaths.forEach({ (filePath) in | |
if let data = try? Data(contentsOf: URL(fileURLWithPath: filePath)), | |
let contentString = String(data: data, encoding: .utf8) { | |
returnString += contentString | |
} | |
}) | |
return returnString | |
} | |
// MARK: - Configuration | |
class func configure() { | |
#if !PRODUCTIONMODE | |
let fileLogger: DDFileLogger = DDFileLogger() | |
fileLogger.rollingFrequency = TimeInterval(60 * 60 * 24) | |
fileLogger.logFileManager.maximumNumberOfLogFiles = 1 | |
fileLogger.logFormatter = LogFormatter() | |
DDLog.add(fileLogger, with: .all) | |
DDLogVerbose(String.empty) | |
DDLogVerbose(String.newLine) | |
DDLogVerbose("starting app") | |
let device = String(format: "Version: %@, Device: %@, %@, %@, UDID -> %@", | |
UIApplication.appVersion ?? "unknown", | |
UIDevice.current.modelName, | |
UIDevice.current.systemName, | |
UIDevice.current.systemVersion, | |
UIDevice.current.identifierForVendor?.uuidString ?? "nil") | |
DDLogVerbose(device) | |
listener.openConsolePipe() | |
listener.onWishperDetection = { whishper -> Bool in | |
DDLogVerbose(whishper) | |
return true | |
} | |
#endif | |
} | |
class func clear() { | |
logFilesPaths.forEach({ (filePath) in | |
try? FileManager.default.removeItem(atPath: filePath) | |
}) | |
} | |
class func onAppTerminate() { | |
#if !PRODUCTIONMODE | |
DDLogVerbose("terminated app") | |
#endif | |
} | |
class func onBackground() { | |
#if !PRODUCTIONMODE | |
DDLogVerbose("background app") | |
#endif | |
} | |
class func onForeground() { | |
#if !PRODUCTIONMODE | |
DDLogVerbose("foreground app") | |
#endif | |
} | |
} | |
// MARK: - LogFormatter | |
fileprivate class LogFormatter: NSObject, DDLogFormatter { //swiftlint:disable:this private_over_fileprivate | |
private let dateFormatter: DateFormatter | |
override init() { | |
dateFormatter = DateFormatter() | |
dateFormatter.formatterBehavior = .behavior10_4 | |
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss:SSS" | |
super.init() | |
} | |
func format(message logMessage: DDLogMessage) -> String? { | |
let dateAndTime = dateFormatter.string(from: logMessage.timestamp) | |
return "\(dateAndTime) [\(logMessage.fileName):\(logMessage.line)]: \(logMessage.message)" | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
final class ConsoleEavesdropper { | |
private var inputPipe: Pipe? | |
private var outputPipe: Pipe? | |
var onWishperDetection: ((String) -> Bool)? | |
func openConsolePipe() { | |
inputPipe = Pipe() | |
outputPipe = Pipe() | |
guard let inputPipe = inputPipe, | |
let outputPipe = outputPipe else { | |
return | |
} | |
#if !os(iOS) | |
return | |
#endif | |
let pipeReadHandle = inputPipe.fileHandleForReading | |
dup2(STDOUT_FILENO, outputPipe.fileHandleForWriting.fileDescriptor) | |
dup2(inputPipe.fileHandleForWriting.fileDescriptor, STDOUT_FILENO) | |
dup2(inputPipe.fileHandleForWriting.fileDescriptor, STDERR_FILENO) | |
NotificationCenter.default.addObserver(self, selector: #selector(self.handlePipeNotification), name: FileHandle.readCompletionNotification, object: pipeReadHandle) | |
pipeReadHandle.readInBackgroundAndNotify() | |
} | |
@objc func handlePipeNotification(notification: Notification) { | |
inputPipe?.fileHandleForReading.readInBackgroundAndNotify() | |
if let data = notification.userInfo?[NSFileHandleNotificationDataItem] as? Data, | |
let printWishper = String(data: data, encoding: String.Encoding.ascii) { | |
if onWishperDetection?(printWishper) == false { | |
return | |
} | |
outputPipe?.fileHandleForWriting.write(data) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment