diff options
| author | Andrej Mihajlov <and@mullvad.net> | 2023-02-01 16:28:50 +0100 |
|---|---|---|
| committer | Andrej Mihajlov <and@mullvad.net> | 2023-02-03 10:58:39 +0100 |
| commit | d9060599a20a595b6ef44926d3ca32f94f9fad90 (patch) | |
| tree | 29d4a7923c2fb12d1e87d19ae93fc2bea691db4a | |
| parent | 2240e29f72b20ea8da5d1e437543069fb5b29aa7 (diff) | |
| download | mullvadvpn-d9060599a20a595b6ef44926d3ca32f94f9fad90.tar.xz mullvadvpn-d9060599a20a595b6ef44926d3ca32f94f9fad90.zip | |
Rework logging configurator into builder
| -rw-r--r-- | ios/MullvadLogging/Logging.swift | 123 | ||||
| -rw-r--r-- | ios/MullvadVPN/AppDelegate.swift | 21 | ||||
| -rw-r--r-- | ios/PacketTunnel/PacketTunnelProvider.swift | 19 |
3 files changed, 102 insertions, 61 deletions
diff --git a/ios/MullvadLogging/Logging.swift b/ios/MullvadLogging/Logging.swift index 9120dcb886..b13328999a 100644 --- a/ios/MullvadLogging/Logging.swift +++ b/ios/MullvadLogging/Logging.swift @@ -9,71 +9,92 @@ import Foundation @_exported import Logging -public func initLoggingSystem( - bundleIdentifier: String, - applicationGroupIdentifier: String, - metadata: Logger.Metadata? = nil -) { - let containerURL = FileManager.default.containerURL( - forSecurityApplicationGroupIdentifier: applicationGroupIdentifier - )! - let logsDirectoryURL = containerURL.appendingPathComponent("Logs", isDirectory: true) - let logFileName = "\(bundleIdentifier).log" - let logFileURL = logsDirectoryURL.appendingPathComponent(logFileName) +private enum LoggerOutput { + case fileOutput(_ fileOutput: TextOutputStream) + case osLogOutput(_ subsystem: String) +} - // Create Logs folder within container if it doesn't exist - try? FileManager.default.createDirectory( - at: logsDirectoryURL, - withIntermediateDirectories: false, - attributes: nil - ) +public struct MissingSharedContainerError: LocalizedError { + public var errorDescription: String? { + return "Cannot obtain shared container URL." + } +} - // Rotate log - var logRotationError: Error? - do { - try LogRotation.rotateLog( - logsDirectory: logsDirectoryURL, - logFileName: logFileName - ) - } catch { - logRotationError = error +public struct OpenFileStreamError: LocalizedError { + public var errorDescription: String? { + return "Failed to open file stream." } +} - // Create an array of log output streams - var streams: [TextOutputStream] = [] +public struct LoggerBuilder { + private(set) var logRotationErrors: [Error] = [] + private var outputs: [LoggerOutput] = [] - // Create output stream to file - if let fileLogStream = TextFileOutputStream(fileURL: logFileURL, createFile: true) { - streams.append(fileLogStream) - } + public var metadata: Logger.Metadata = [:] - // Configure Logging system - LoggingSystem.bootstrap { label -> LogHandler in - var logHandlers: [LogHandler] = [] + public init() {} - #if DEBUG - logHandlers.append(OSLogHandler(subsystem: bundleIdentifier, category: label)) - #endif + public mutating func addFileOutput(securityGroupIdentifier: String, basename: String) throws { + guard let containerURL = FileManager.default.containerURL( + forSecurityApplicationGroupIdentifier: securityGroupIdentifier + ) else { + throw MissingSharedContainerError() + } + + let logsDirectoryURL = containerURL.appendingPathComponent("Logs", isDirectory: true) + let logFileName = "\(basename).log" + let logFileURL = logsDirectoryURL.appendingPathComponent(logFileName, isDirectory: false) + + try? FileManager.default.createDirectory( + at: logsDirectoryURL, + withIntermediateDirectories: false, + attributes: nil + ) - if !streams.isEmpty { - logHandlers.append(CustomFormatLogHandler(label: label, streams: streams)) + do { + try LogRotation.rotateLog(logsDirectory: logsDirectoryURL, logFileName: logFileName) + } catch { + logRotationErrors.append(error) } - if logHandlers.isEmpty { - return SwiftLogNoOpLogHandler() + if let outputStream = TextFileOutputStream(fileURL: logFileURL, createFile: true) { + outputs.append(.fileOutput(outputStream)) } else { - var multiplex = MultiplexLogHandler(logHandlers) - if let metadata = metadata { + throw OpenFileStreamError() + } + } + + public mutating func addOSLogOutput(subsystem: String) { + outputs.append(.osLogOutput(subsystem)) + } + + public func install() { + LoggingSystem.bootstrap { label -> LogHandler in + let logHandlers: [LogHandler] = outputs.map { output in + switch output { + case let .fileOutput(stream): + return CustomFormatLogHandler(label: label, streams: [stream]) + + case let .osLogOutput(subsystem): + return OSLogHandler(subsystem: subsystem, category: label) + } + } + + if logHandlers.isEmpty { + return SwiftLogNoOpLogHandler() + } else { + var multiplex = MultiplexLogHandler(logHandlers) multiplex.metadata = metadata + return multiplex } - return multiplex } - } - if let logRotationError = logRotationError { - Logger(label: "LogRotation").error( - error: logRotationError, - message: "Failed to rotate log" - ) + if !logRotationErrors.isEmpty { + let rotationLogger = Logger(label: "LogRotation") + + for error in logRotationErrors { + rotationLogger.error(error: error, message: "Failed to rotate log") + } + } } } diff --git a/ios/MullvadVPN/AppDelegate.swift b/ios/MullvadVPN/AppDelegate.swift index 945d45d3eb..89b9b505f2 100644 --- a/ios/MullvadVPN/AppDelegate.swift +++ b/ios/MullvadVPN/AppDelegate.swift @@ -47,10 +47,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { - initLoggingSystem( - bundleIdentifier: Bundle.main.bundleIdentifier!, - applicationGroupIdentifier: ApplicationConfiguration.securityGroupIdentifier - ) + configureLogging() logger = Logger(label: "AppDelegate") @@ -302,6 +299,22 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD // MARK: - Private + private func configureLogging() { + var loggerBuilder = LoggerBuilder() + let bundleIdentifier = Bundle.main.bundleIdentifier! + + try? loggerBuilder.addFileOutput( + securityGroupIdentifier: ApplicationConfiguration.securityGroupIdentifier, + basename: bundleIdentifier + ) + + #if DEBUG + loggerBuilder.addOSLogOutput(subsystem: bundleIdentifier) + #endif + + loggerBuilder.install() + } + private func addApplicationNotifications(application: UIApplication) { let notificationCenter = NotificationCenter.default diff --git a/ios/PacketTunnel/PacketTunnelProvider.swift b/ios/PacketTunnel/PacketTunnelProvider.swift index 50de296161..b73d95116d 100644 --- a/ios/PacketTunnel/PacketTunnelProvider.swift +++ b/ios/PacketTunnel/PacketTunnelProvider.swift @@ -103,17 +103,24 @@ class PacketTunnelProvider: NEPacketTunnelProvider, TunnelMonitorDelegate { } override init() { + var loggerBuilder = LoggerBuilder() + let pid = ProcessInfo.processInfo.processIdentifier + loggerBuilder.metadata["pid"] = .string("\(pid)") - var metadata = Logger.Metadata() - metadata["pid"] = .string("\(pid)") + let bundleIdentifier = Bundle.main.bundleIdentifier! - initLoggingSystem( - bundleIdentifier: Bundle.main.bundleIdentifier!, - applicationGroupIdentifier: ApplicationConfiguration.securityGroupIdentifier, - metadata: metadata + try? loggerBuilder.addFileOutput( + securityGroupIdentifier: ApplicationConfiguration.securityGroupIdentifier, + basename: bundleIdentifier ) + #if DEBUG + loggerBuilder.addOSLogOutput(subsystem: bundleIdentifier) + #endif + + loggerBuilder.install() + providerLogger = Logger(label: "PacketTunnelProvider") tunnelLogger = Logger(label: "WireGuard") |
