// _____ _ // |_ _| |_ _ _ ___ ___ _ __ __ _ // | | | ' \| '_/ -_) -_) ' \/ _` |_ // |_| |_||_|_| \___\___|_|_|_\__,_(_) // // Threema iOS Client // Copyright (c) 2019-2020 Threema GmbH // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License, version 3, // as published by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . import Foundation import CocoaLumberjackSwift /// Note: Add Log level for Swift in Build Settings - Preprocessor Macros for AdHoc and AppStore: /// DD_LOG_LEVEL=0b0100011 (Error, Warning and Notice) /// Swift method for logging Notice Log level @inlinable public func DDLogNotice(_ message: @autoclosure () -> String, level: DDLogLevel = DDDefaultLogLevel, context: Int = 0, file: StaticString = #file, function: StaticString = #function, line: UInt = #line, tag: Any? = nil, asynchronous async: Bool = asyncLoggingEnabled, ddlog: DDLog = .sharedInstance) { _DDLogMessage(message(), level: level, flag: DDLogFlag(rawValue: DDLogFlag.RawValue(DDLogFlagNotice)) , context: context, file: file, function: function, line: line, tag: tag, asynchronous: async, ddlog: ddlog) } @objc public class LogManager: NSObject { private static var isDebug: Bool = false @objc public static let debugLogFile: URL? = FileUtility.appDataDirectory?.appendingPathComponent("validation_log.txt") /// Log levels definition for Swift. Includes new Notice Log level at the end, to not break the standard Log levels like in public enum DDLogLevelCustom: UInt { case err = 0b0000001 case warn = 0b0000010 case info = 0b0000100 case verbose = 0b0001000 case debug = 0b0010000 case notice = 0b0100000 } @objc public static func initializeGlobalLogger(debug: Bool) { isDebug = debug if isDebug { DDTTYLogger.sharedInstance?.logFormatter = LogFormatterCustom() DDLog.add(DDTTYLogger.sharedInstance as! DDLogger, with: LogManager.logLevel()) } // Add Debug Logger is enabled by user if let validationLogging = UserSettings.shared()?.validationLogging, validationLogging { addFileLogger(debugLogFile) } else { removeFileLogger(debugLogFile) } } @objc public static func addFileLogger(_ logFile: URL?) { guard let logFile = logFile else { return } if let existingLogger = findFileLogger(logFile), existingLogger.count == 0 { let fileLogger: FileLoggerCustom = FileLoggerCustom(logFile: logFile) DDLog.add(fileLogger, with: logLevel()) } } @objc public static func removeFileLogger(_ logFile: URL?) { guard let logFile = logFile else { return } if let existingLoggers = findFileLogger(logFile), existingLoggers.count > 0 { for logger in existingLoggers { DDLog.remove(logger) } } } @objc public static func deleteLogFile(_ logFile: URL?) { FileUtility.delete(fileUrl: logFile) } @objc public static func logFileSize(_ logFile: URL?) -> Int64 { guard let logFile = logFile else { return 0 } return FileUtility.fileSizeInBytes(fileUrl: logFile) ?? 0 } /** Get Log Level depence on debug environment or not. - Returns: Log Level */ private static func logLevel() -> DDLogLevel { // Default log level is Error, Warning and Notice var ddLogLevel: DDLogLevel = DDLogLevel(rawValue: DDLogLevelCustom.err.rawValue | DDLogLevelCustom.warn.rawValue | DDLogLevelCustom.notice.rawValue)! if isDebug { ddLogLevel = .all } return ddLogLevel } /** Looking for existing file logger (FileLoggerCustom). - Parameters: - logFile: Log file path - Returns: Array of file loggers */ private static func findFileLogger(_ logFile: URL?) -> [DDLogger]? { guard let logFile = logFile else { return nil } var fileLoggers: [DDLogger] = [] for logger in DDLog.allLoggers { if let fileLogger = logger as? FileLoggerCustom, fileLogger.logFile == logFile { fileLoggers.append(logger) } } return fileLoggers } }