178 lines
7.2 KiB
Swift
178 lines
7.2 KiB
Swift
//
|
|
// Copyright 2021 The Matrix.org Foundation C.I.C
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
//
|
|
|
|
import Foundation
|
|
import SwiftyBeaver
|
|
|
|
/// Various MXLog configuration options. Used in conjunction with `MXLog.configure()`
|
|
public class MXLogConfiguration: NSObject {
|
|
/// the desired log level. `.verbose` by default.
|
|
public var logLevel = MXLogLevel.verbose
|
|
|
|
/// whether logs should be written directly to files. `false` by default.
|
|
public var redirectLogsToFiles = false
|
|
|
|
/// the maximum total space to use for log files in bytes. `100MB` by default.
|
|
public var logFilesSizeLimit: UInt = 100 * 1024 * 1024 // 100MB
|
|
|
|
/// the maximum number of log files to use before rolling. `50` by default.
|
|
public var maxLogFilesCount: UInt = 50
|
|
|
|
/// the subname for log files. Files will be named as 'console-[subLogName].log'. `nil` by default
|
|
public var subLogName: String?
|
|
}
|
|
|
|
/// MXLog logging levels. Use .none to disable logging entirely.
|
|
public enum MXLogLevel: UInt {
|
|
case none
|
|
case verbose
|
|
case debug
|
|
case info
|
|
case warning
|
|
case error
|
|
}
|
|
|
|
private var logger: SwiftyBeaver.Type = {
|
|
let logger = SwiftyBeaver.self
|
|
MXLog.configureLogger(logger, withConfiguration: MXLogConfiguration())
|
|
return logger
|
|
}()
|
|
|
|
/**
|
|
Logging utility that provies multiple logging levels as well as file output and rolling.
|
|
Its purpose is to provide a common entry for customizing logging and should be used throughout the code.
|
|
Please see `MXLog.h` for Objective-C options.
|
|
*/
|
|
public class MXLog: NSObject {
|
|
/// Method used to customize MXLog's behavior.
|
|
/// Called automatically when first accessing the logger with the default values.
|
|
/// Please see `MXLogConfiguration` for all available options.
|
|
/// - Parameters:
|
|
/// - configuration: the `MXLogConfiguration` instance to use
|
|
public static func configure(_ configuration: MXLogConfiguration) {
|
|
configureLogger(logger, withConfiguration: configuration)
|
|
}
|
|
|
|
public static func verbose(_ message: @autoclosure () -> Any,
|
|
file: String = #file,
|
|
function: String = #function,
|
|
line: Int = #line,
|
|
context: Any? = nil) {
|
|
logger.verbose(message(), file: file, function: function, line: line, context: context)
|
|
}
|
|
|
|
public static func debug(_ message: @autoclosure () -> Any,
|
|
file: String = #file,
|
|
function: String = #function,
|
|
line: Int = #line,
|
|
context: Any? = nil) {
|
|
logger.debug(message(), file: file, function: function, line: line, context: context)
|
|
}
|
|
|
|
public static func info(_ message: @autoclosure () -> Any,
|
|
file: String = #file,
|
|
function: String = #function,
|
|
line: Int = #line,
|
|
context: Any? = nil) {
|
|
logger.info(message(), file: file, function: function, line: line, context: context)
|
|
}
|
|
|
|
public static func warning(_ message: @autoclosure () -> Any,
|
|
file: String = #file,
|
|
function: String = #function,
|
|
line: Int = #line,
|
|
context: Any? = nil) {
|
|
logger.warning(message(), file: file, function: function, line: line, context: context)
|
|
}
|
|
|
|
/// Log error with additional details
|
|
///
|
|
/// - Parameters:
|
|
/// - message: Description of the error without any variables (this is to improve error aggregations by type)
|
|
/// - context: Additional context-dependent details about the issue
|
|
public static func error(_ message: @autoclosure () -> Any,
|
|
file: String = #file,
|
|
function: String = #function,
|
|
line: Int = #line,
|
|
context: Any? = nil) {
|
|
logger.error(message(), file: file, function: function, line: line, context: context)
|
|
}
|
|
|
|
/// Log failure with additional details
|
|
///
|
|
/// A failure is any type of programming error which should never occur in production. In `DEBUG` configuration
|
|
/// any failure will raise `assertionFailure`
|
|
///
|
|
/// - Parameters:
|
|
/// - message: Description of the error without any variables (this is to improve error aggregations by type)
|
|
/// - context: Additional context-dependent details about the issue
|
|
public static func failure(_ message: String,
|
|
file: String = #file,
|
|
function: String = #function,
|
|
line: Int = #line,
|
|
context: Any? = nil) {
|
|
logger.error(message, file: file, function: function, line: line, context: context)
|
|
#if DEBUG
|
|
assertionFailure("\(message)")
|
|
#endif
|
|
}
|
|
|
|
// MARK: - Private
|
|
|
|
fileprivate static func configureLogger(_ logger: SwiftyBeaver.Type, withConfiguration configuration: MXLogConfiguration) {
|
|
if let subLogName = configuration.subLogName {
|
|
MXLogger.setSubLogName(subLogName)
|
|
}
|
|
|
|
MXLogger.redirectNSLog(toFiles: configuration.redirectLogsToFiles,
|
|
numberOfFiles: configuration.maxLogFilesCount,
|
|
sizeLimit: configuration.logFilesSizeLimit)
|
|
|
|
guard configuration.logLevel != .none else {
|
|
logger.removeAllDestinations()
|
|
return
|
|
}
|
|
|
|
logger.removeAllDestinations()
|
|
|
|
let consoleDestination = ConsoleDestination()
|
|
consoleDestination.useNSLog = true
|
|
consoleDestination.asynchronously = false
|
|
consoleDestination.format = "$C$N.$F:$l $M $X$c" // See https://docs.swiftybeaver.com/article/20-custom-format
|
|
consoleDestination.levelColor.verbose = ""
|
|
consoleDestination.levelColor.debug = ""
|
|
consoleDestination.levelColor.info = ""
|
|
consoleDestination.levelColor.warning = "⚠️ "
|
|
consoleDestination.levelColor.error = "🚨 "
|
|
|
|
switch configuration.logLevel {
|
|
case .verbose:
|
|
consoleDestination.minLevel = .verbose
|
|
case .debug:
|
|
consoleDestination.minLevel = .debug
|
|
case .info:
|
|
consoleDestination.minLevel = .info
|
|
case .warning:
|
|
consoleDestination.minLevel = .warning
|
|
case .error:
|
|
consoleDestination.minLevel = .error
|
|
case .none:
|
|
break
|
|
}
|
|
logger.addDestination(consoleDestination)
|
|
}
|
|
}
|