I reconsidered the author part because it's better to make the ownership obvious to get rid of problems according to the unclearness.
100 lines
3.2 KiB
Swift
100 lines
3.2 KiB
Swift
// Copyright 2018-Present Shin Yamamoto. All rights reserved. MIT license.
|
|
|
|
import Foundation
|
|
import os.log
|
|
|
|
var log = {
|
|
return Logger()
|
|
}()
|
|
|
|
struct Logger {
|
|
private let osLog: OSLog
|
|
private let s = DispatchSemaphore(value: 1)
|
|
|
|
enum Level: Int, Comparable {
|
|
case debug = 0
|
|
case info = 1
|
|
case warning = 2
|
|
case error = 3
|
|
|
|
var displayName: String {
|
|
switch self {
|
|
case .debug:
|
|
return "Debug:"
|
|
case .info:
|
|
return "Info:"
|
|
case .warning:
|
|
return "Warning:"
|
|
case .error:
|
|
return "Error:"
|
|
}
|
|
}
|
|
@available(iOS 10.0, *)
|
|
var osLogType: OSLogType {
|
|
switch self {
|
|
case .debug: return .debug
|
|
case .info: return .info
|
|
case .warning: return .default
|
|
case .error: return .error
|
|
}
|
|
}
|
|
|
|
static func < (lhs: Logger.Level, rhs: Logger.Level) -> Bool {
|
|
return lhs.rawValue < rhs.rawValue
|
|
}
|
|
}
|
|
|
|
typealias Hook = ((String, Level) -> Void)
|
|
var hook: Hook?
|
|
|
|
fileprivate init() {
|
|
osLog = OSLog(subsystem: "com.scenee.FloatingPanel", category: "FloatingPanel")
|
|
}
|
|
|
|
private func log(_ level: Level, _ message: Any, _ arguments: [Any], tag: String, function: String, line: UInt) {
|
|
_ = s.wait(timeout: .now() + 0.033)
|
|
defer { s.signal() }
|
|
|
|
let extraMessage: String = arguments.map({ String(describing: $0) }).joined(separator: " ")
|
|
let _tag = tag.isEmpty ? "" : "\(tag):"
|
|
let log: String = {
|
|
switch level {
|
|
case .debug:
|
|
return "\(level.displayName)\(_tag) \(message) \(extraMessage) (\(function):\(line))"
|
|
default:
|
|
return "\(level.displayName)\(_tag) \(message) \(extraMessage)"
|
|
}
|
|
}()
|
|
|
|
hook?(log, level)
|
|
|
|
os_log("%@", log: osLog, type: level.osLogType, log)
|
|
}
|
|
|
|
private func getPrettyFunction(_ function: String, _ file: String) -> String {
|
|
if let filename = file.split(separator: "/").last {
|
|
return filename + ":" + function
|
|
} else {
|
|
return file + ":" + function
|
|
}
|
|
}
|
|
|
|
func debug(_ log: Any, _ arguments: Any..., tag: String = "", function: String = #function, file: String = #file, line: UInt = #line) {
|
|
#if __FP_LOG
|
|
self.log(.debug, log, arguments, tag: tag, function: getPrettyFunction(function, file), line: line)
|
|
#endif
|
|
}
|
|
|
|
func info(_ log: Any, _ arguments: Any..., tag: String = "", function: String = #function, file: String = #file, line: UInt = #line) {
|
|
self.log(.info, log, arguments, tag: tag, function: getPrettyFunction(function, file), line: line)
|
|
}
|
|
|
|
func warning(_ log: Any, _ arguments: Any..., function: String = #function, file: String = #file, line: UInt = #line) {
|
|
self.log(.warning, log, arguments, tag: "", function: getPrettyFunction(function, file), line: line)
|
|
}
|
|
|
|
func error(_ log: Any, _ arguments: Any..., function: String = #function, file: String = #file, line: UInt = #line) {
|
|
self.log(.error, log, arguments, tag: "", function: getPrettyFunction(function, file), line: line)
|
|
}
|
|
}
|