libSession attachment upload/download improvements, logging tweaks

pull/1018/head
Morgan Pretty 7 months ago
parent bce7a093cf
commit a87a547886

@ -1 +1 @@
Subproject commit c3aa3b99e05d7e7568cdd1dc2e0f1200e3ec01f1
Subproject commit 1d20f5e392ba55847a30431f196d638834a4feb0

@ -8,10 +8,14 @@ import GRDB
import SessionSnodeKit
import SessionUtilitiesKit
private extension Log.Category {
static var ip2Country: Log.Category = "IP2Country"
// MARK: - Log.Level
public extension Log.Category {
static let ip2Country: Log.Category = .create("IP2Country", defaultLevel: .info)
}
// MARK: - IP2Country
public enum IP2Country {
public static var isInitialized: Atomic<Bool> = Atomic(false)
private static var countryNamesCache: Atomic<[String: String]> = Atomic([:])

@ -25,19 +25,42 @@ public enum Log {
case error
case critical
case off
case `default`
}
public struct Category: ExpressibleByStringLiteral, ExpressibleByExtendedGraphemeClusterLiteral, ExpressibleByUnicodeScalarLiteral {
public typealias StringLiteralType = String
public struct Category: Hashable {
public let rawValue: String
fileprivate let customPrefix: String
public let defaultLevel: Log.Level
fileprivate static let identifierPrefix: String = "logLevel-"
fileprivate var identifier: String { "\(Category.identifierPrefix)\(rawValue)" }
private init(rawValue: String, customPrefix: String, defaultLevel: Log.Level) {
self.rawValue = rawValue
self.customPrefix = customPrefix
self.defaultLevel = defaultLevel
AllLoggingCategories.register(category: self)
}
fileprivate let rawValue: String
fileprivate init?(identifier: String) {
guard identifier.hasPrefix(Category.identifierPrefix) else { return nil }
self.init(
rawValue: identifier.substring(from: Category.identifierPrefix.count),
customPrefix: "",
defaultLevel: .default
)
}
public init(stringLiteral value: String) {
self.rawValue = value
public init(rawValue: String, customPrefix: String = "") {
self.init(rawValue: rawValue, customPrefix: customPrefix, defaultLevel: .default)
}
public init(unicodeScalarLiteral value: Character) {
self.rawValue = String(value)
@discardableResult public static func create(_ rawValue: String, customPrefix: String = "", defaultLevel: Log.Level) -> Log.Category {
return Log.Category(rawValue: rawValue, customPrefix: customPrefix, defaultLevel: defaultLevel)
}
}
@ -501,7 +524,7 @@ public class Logger {
(DispatchQueue.isDBWriteQueue ? "DBWrite" : nil)
]
.compactMap { $0 }
.appending(contentsOf: categories.map { $0.rawValue })
.appending(contentsOf: categories.map { "\($0.customPrefix)\($0.rawValue)" })
.joined(separator: ", ")
return "[\(prefixes)] "
@ -516,7 +539,7 @@ public class Logger {
.trimmingCharacters(in: .whitespacesAndNewlines)
switch level {
case .off: return
case .off, .default: return
case .verbose: DDLogVerbose("💙 \(logMessage)", file: file, function: function, line: line)
case .debug: DDLogDebug("💚 \(logMessage)", file: file, function: function, line: line)
case .info: DDLogInfo("💛 \(logMessage)", file: file, function: function, line: line)
@ -525,7 +548,7 @@ public class Logger {
case .critical: DDLogError("🔥 \(logMessage)", file: file, function: function, line: line)
}
let mainCategory: String = (categories.first?.rawValue ?? "[General]")
let mainCategory: String = (categories.first?.rawValue ?? "General")
var systemLogger: SystemLoggerType? = systemLoggers.wrappedValue[mainCategory]
if systemLogger == nil {
@ -577,7 +600,7 @@ private class SystemLogger: SystemLoggerType {
public func log(_ level: Log.Level, _ log: String) {
switch level {
case .off: return
case .off, .default: return
case .verbose: logger.trace("\(log)")
case .debug: logger.debug("\(log)")
case .info: logger.info("\(log)")
@ -623,3 +646,34 @@ private extension DispatchQueue {
public func SNLog(_ message: String, forceNSLog: Bool = false) {
Log.info(message)
}
// MARK: - AllLoggingCategories
public struct AllLoggingCategories {
public static var defaultLevels: [Log.Category: Log.Level] {
return AllLoggingCategories.registeredCategoryDefaults.wrappedValue
.reduce(into: [:]) { result, cat in result[cat] = cat.defaultLevel }
}
private static let registeredCategoryDefaults: Atomic<Set<Log.Category>> = Atomic([])
// MARK: - Initialization
public let rawValue: Int
public init(rawValue: Int) {
self.rawValue = -1 // `0` is a protected value so can't use it
}
fileprivate static func register(category: Log.Category) {
guard
!registeredCategoryDefaults.wrappedValue.contains(where: { cat in
/// **Note:** We only want to use the `rawValue` to distinguish between logging categories
/// as the `defaultLevel` can change via the dev settings and any additional metadata could
/// be file/class specific
category.rawValue != cat.rawValue
})
else { return }
registeredCategoryDefaults.mutate { $0.insert(category) }
}
}

@ -8,12 +8,6 @@ import SessionUtil
// MARK: - LibSession
public enum LibSession {
private static let logLevels: [LogCategory: LOG_LEVEL] = [
.config: LOG_LEVEL_INFO,
.network: LOG_LEVEL_INFO,
.manual: LOG_LEVEL_INFO,
]
public static var version: String { String(cString: LIBSESSION_UTIL_VERSION_STR) }
}
@ -21,19 +15,29 @@ public enum LibSession {
extension LibSession {
public static func addLogger() {
/// Setup any custom category defaul log levels for libSession
Log.Category.create("config", defaultLevel: .info)
Log.Category.create("network", defaultLevel: .info)
/// Set the default log level first (unless specified we only care about semi-dangerous logs)
session_logger_set_level_default(LOG_LEVEL_WARN)
/// Then set any explicit category log levels we have
logLevels.forEach { cat, level in
guard let cCat: [CChar] = cat.rawValue.cString(using: .utf8) else { return }
AllLoggingCategories.defaultLevels.forEach { category, level in
guard
let cCat: [CChar] = category.rawValue.cString(using: .utf8),
let cLogLevel: LOG_LEVEL = level.libSession
else { return }
session_logger_set_level(cCat, level)
session_logger_set_level(cCat, cLogLevel)
}
/// Finally register the actual logger callback
session_add_logger_full({ msgPtr, msgLen, catPtr, catLen, lvl in
guard let msg: String = String(pointer: msgPtr, length: msgLen, encoding: .utf8) else { return }
guard
let msg: String = String(pointer: msgPtr, length: msgLen, encoding: .utf8),
let cat: String = String(pointer: catPtr, length: catLen, encoding: .utf8)
else { return }
/// Logs from libSession come through in the format:
/// `[yyyy-MM-dd hh:mm:ss] [+{lifetime}s] [{cat}:{lvl}|log.hpp:{line}] {message}`
@ -48,45 +52,35 @@ extension LibSession {
return "\(logParts[1])] \(message)"
}()
Log.custom(Log.Level(lvl), [LogCategory(catPtr, catLen).logCat], processedMessage)
Log.custom(
Log.Level(lvl),
[Log.Category(rawValue: cat, customPrefix: "libSession:")],
processedMessage
)
})
}
public static func clearLoggers() {
session_clear_loggers()
}
// MARK: - Internal
fileprivate enum LogCategory: String {
case libSession
case config
case network
case quic
case manual
var logCat: Log.Category {
switch self {
case .libSession: return "libSession"
case .config: return "libSession:config"
case .network: return "libSession:network"
case .quic: return "libSession:quic"
case .manual: return "libSession:manual"
}
}
init(_ catPtr: UnsafePointer<CChar>?, _ catLen: Int) {
switch String(pointer: catPtr, length: catLen, encoding: .utf8).map({ LogCategory(rawValue: $0) }) {
case .some(let cat): self = cat
case .none: self = .libSession
}
}
}
}
// MARK: - Convenience
fileprivate extension Log.Level {
var libSession: LOG_LEVEL? {
switch self {
case .verbose: return LOG_LEVEL_TRACE
case .debug: return LOG_LEVEL_DEBUG
case .info: return LOG_LEVEL_INFO
case .warn: return LOG_LEVEL_WARN
case .error: return LOG_LEVEL_ERROR
case .critical: return LOG_LEVEL_CRITICAL
case .off: return LOG_LEVEL_OFF
case .default: return nil // It'll use the default value by default so just return nil
}
}
init(_ level: LOG_LEVEL) {
switch level {
case LOG_LEVEL_TRACE: self = .verbose

Loading…
Cancel
Save