summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2023-02-01 16:28:50 +0100
committerAndrej Mihajlov <and@mullvad.net>2023-02-03 10:58:39 +0100
commitd9060599a20a595b6ef44926d3ca32f94f9fad90 (patch)
tree29d4a7923c2fb12d1e87d19ae93fc2bea691db4a
parent2240e29f72b20ea8da5d1e437543069fb5b29aa7 (diff)
downloadmullvadvpn-d9060599a20a595b6ef44926d3ca32f94f9fad90.tar.xz
mullvadvpn-d9060599a20a595b6ef44926d3ca32f94f9fad90.zip
Rework logging configurator into builder
-rw-r--r--ios/MullvadLogging/Logging.swift123
-rw-r--r--ios/MullvadVPN/AppDelegate.swift21
-rw-r--r--ios/PacketTunnel/PacketTunnelProvider.swift19
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")