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.4 KiB

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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 "debug".localized
case .info: return "info".localized
case .warning: return "warning".localized
case .error: return "error".localized
case .success: return "success".localized
}
}
}
///
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))
}
}