You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

152 lines
5.3 KiB

import Foundation
import SwiftUI
import os.log
import Combine
///
enum LogLevel: String, CaseIterable {
case debug = "🔍"
case info = ""
case warning = "⚠️"
case error = ""
case success = ""
var localizedName: String {
switch self {
case .debug: return "调试"
case .info: return "信息"
case .warning: return "警告"
case .error: return "错误"
case .success: return "成功"
}
}
}
///
class Logger: ObservableObject {
static let shared = Logger()
@Published var isEnabled = true
@Published var minimumLevel: LogLevel = .debug
private let dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "HH:mm:ss"
return formatter
}()
private init() {}
///
/// - Parameters:
/// - level:
/// - message:
/// - file:
/// - function:
/// - line:
/// - className:
func log(
_ level: LogLevel,
_ message: String,
file: String = #file,
function: String = #function,
line: Int = #line,
className: String? = nil
) {
guard isEnabled && shouldLog(level) else { return }
let timestamp = dateFormatter.string(from: Date())
let fileName = URL(fileURLWithPath: file).lastPathComponent
let functionName = function
let lineNumber = line
let classDisplayName = className ?? "Unknown"
let logMessage = "[\(timestamp)] \(level.rawValue) [\(classDisplayName)] [\(fileName):\(lineNumber)] \(functionName): \(message)"
//
print(logMessage)
//
#if DEBUG
// os_log("%{public}@", log: .default, type: .debug, logMessage)
#endif
}
///
private func shouldLog(_ level: LogLevel) -> Bool {
let levelOrder: [LogLevel] = [.debug, .info, .warning, .error, .success]
guard let currentIndex = levelOrder.firstIndex(of: minimumLevel),
let messageIndex = levelOrder.firstIndex(of: level) else {
return false
}
return messageIndex >= currentIndex
}
// MARK: - 便
func debug(_ message: String, file: String = #file, function: String = #function, line: Int = #line, className: String? = nil) {
log(.debug, message, file: file, function: function, line: line, className: className)
}
func info(_ message: String, file: String = #file, function: String = #function, line: Int = #line, className: String? = nil) {
log(.info, message, file: file, function: function, line: line, className: className)
}
func warning(_ message: String, file: String = #file, function: String = #function, line: Int = #line, className: String? = nil) {
log(.warning, message, file: file, function: function, line: line, className: className)
}
func error(_ message: String, file: String = #file, function: String = #function, line: Int = #line, className: String? = nil) {
log(.error, message, file: file, function: function, line: line, className: className)
}
func success(_ message: String, file: String = #file, function: String = #function, line: Int = #line, className: String? = nil) {
log(.success, message, file: file, function: function, line: line, className: className)
}
}
// MARK: -
///
func logDebug(_ message: String, file: String = #file, function: String = #function, line: Int = #line, className: String? = nil) {
Logger.shared.debug(message, file: file, function: function, line: line, className: className)
}
///
func logInfo(_ message: String, file: String = #file, function: String = #function, line: Int = #line, className: String? = nil) {
Logger.shared.info(message, file: file, function: function, line: line, className: className)
}
///
func logWarning(_ message: String, file: String = #file, function: String = #function, line: Int = #line, className: String? = nil) {
Logger.shared.warning(message, file: file, function: function, line: line, className: className)
}
///
func logError(_ message: String, file: String = #file, function: String = #function, line: Int = #line, className: String? = nil) {
Logger.shared.error(message, file: file, function: function, line: line, className: className)
}
///
func logSuccess(_ message: String, file: String = #file, function: String = #function, line: Int = #line, className: String? = nil) {
Logger.shared.success(message, file: file, function: function, line: line, className: className)
}
// MARK: -
extension NSObject {
var className: String {
return String(describing: type(of: self))
}
static var className: String {
return String(describing: self)
}
}
extension View {
var className: String {
return String(describing: type(of: self))
}
}