diff options
| author | Andrej Mihajlov <and@mullvad.net> | 2020-08-10 17:53:28 +0300 |
|---|---|---|
| committer | Andrej Mihajlov <and@mullvad.net> | 2020-08-18 17:18:20 +0200 |
| commit | f32cf04ca018e9572c032e9989d95a577008a7b6 (patch) | |
| tree | a4da1146dda6333924e984c9b99706b8db5a70ff /ios | |
| parent | 2e9143040fbd7f9e26b397ba6051e2f91b0f732d (diff) | |
| download | mullvadvpn-f32cf04ca018e9572c032e9989d95a577008a7b6.tar.xz mullvadvpn-f32cf04ca018e9572c032e9989d95a577008a7b6.zip | |
Add consolidated log streamer
Diffstat (limited to 'ios')
| -rw-r--r-- | ios/MullvadVPN.xcodeproj/project.pbxproj | 4 | ||||
| -rw-r--r-- | ios/MullvadVPN/Logging/LogStreamer.swift | 84 | ||||
| -rw-r--r-- | ios/MullvadVPN/Logging/TextFileStream.swift | 4 |
3 files changed, 90 insertions, 2 deletions
diff --git a/ios/MullvadVPN.xcodeproj/project.pbxproj b/ios/MullvadVPN.xcodeproj/project.pbxproj index 6ce6bcc2c7..1052ad7602 100644 --- a/ios/MullvadVPN.xcodeproj/project.pbxproj +++ b/ios/MullvadVPN.xcodeproj/project.pbxproj @@ -90,6 +90,7 @@ 5857F24724C882D700CF6F47 /* SelectLocationNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5857F24624C882D700CF6F47 /* SelectLocationNavigationController.swift */; }; 585834F824D2BC1F00A8AF56 /* Logging in Frameworks */ = {isa = PBXBuildFile; productRef = 585834F724D2BC1F00A8AF56 /* Logging */; }; 585834FC24D2BC9500A8AF56 /* Logging in Frameworks */ = {isa = PBXBuildFile; productRef = 585834FB24D2BC9500A8AF56 /* Logging */; }; + 585FE2F124E1365400439C50 /* LogStreamer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 585FE2F024E1365400439C50 /* LogStreamer.swift */; }; 5860F1C223A785C600CEA666 /* WireguardDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5860F1C123A785C600CEA666 /* WireguardDevice.swift */; }; 5860F1C423A8D25F00CEA666 /* WireguardConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5860F1C323A8D25F00CEA666 /* WireguardConfiguration.swift */; }; 5862805422428EF100F5A6E1 /* TranslucentButtonBlurView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5862805322428EF100F5A6E1 /* TranslucentButtonBlurView.swift */; }; @@ -292,6 +293,7 @@ 58561C98239A5D1500BD6B5E /* IPEndpoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IPEndpoint.swift; sourceTree = "<group>"; }; 5857F24224C8662600CF6F47 /* SelectLocationHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectLocationHeaderView.swift; sourceTree = "<group>"; }; 5857F24624C882D700CF6F47 /* SelectLocationNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectLocationNavigationController.swift; sourceTree = "<group>"; }; + 585FE2F024E1365400439C50 /* LogStreamer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogStreamer.swift; sourceTree = "<group>"; }; 5860F1C123A785C600CEA666 /* WireguardDevice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WireguardDevice.swift; sourceTree = "<group>"; }; 5860F1C323A8D25F00CEA666 /* WireguardConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WireguardConfiguration.swift; sourceTree = "<group>"; }; 5862805322428EF100F5A6E1 /* TranslucentButtonBlurView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TranslucentButtonBlurView.swift; sourceTree = "<group>"; }; @@ -468,6 +470,7 @@ 581503A524D6F4AE00C9C50E /* Logging.swift */, 5815039324D6EB7200C9C50E /* LogRotation.swift */, 58141EC824DAC0ED0013F79C /* TextFileStream.swift */, + 585FE2F024E1365400439C50 /* LogStreamer.swift */, ); path = Logging; sourceTree = "<group>"; @@ -995,6 +998,7 @@ 582BB1AF229566420055B6EF /* SettingsCell.swift in Sources */, 5873884D239E6D7E00E96C4E /* EmbeddedViewContainerView.swift in Sources */, 58F3C0A4249CB069003E76BE /* HeaderBarView.swift in Sources */, + 585FE2F124E1365400439C50 /* LogStreamer.swift in Sources */, 58B9EB132488ED2100095626 /* AlertPresenter.swift in Sources */, 587A01FC23F1F0BE00B68763 /* SimulatorTunnelProviderHost.swift in Sources */, 5862805422428EF100F5A6E1 /* TranslucentButtonBlurView.swift in Sources */, diff --git a/ios/MullvadVPN/Logging/LogStreamer.swift b/ios/MullvadVPN/Logging/LogStreamer.swift new file mode 100644 index 0000000000..5c5e34ea40 --- /dev/null +++ b/ios/MullvadVPN/Logging/LogStreamer.swift @@ -0,0 +1,84 @@ +// +// LogStreamer.swift +// MullvadVPN +// +// Created by pronebird on 10/08/2020. +// Copyright © 2020 Mullvad VPN AB. All rights reserved. +// + +import Foundation + +private let kLogPollIntervalSeconds = 2 + +/// A class that consolidates multiple log streams into one +class LogStreamer<Codec> where Codec: UnicodeCodec { + private let fileURLs: [URL] + private var remainingFileURLs: [URL] + private var streams = [TextFileStream<Codec>]() + private let queue = DispatchQueue(label: "net.mullvad.MullvadVPN.LogStreamer<\(Codec.self)>") + private var retry: DispatchWorkItem? + private var handlerBlock: ((String) -> Void)? + + init(fileURLs: [URL]) { + self.fileURLs = fileURLs + self.remainingFileURLs = fileURLs + } + + func start(handler: @escaping (String) -> Void) { + queue.async { + self.handlerBlock = handler + self.poll() + } + } + + func stop() { + queue.async { + self.retry?.cancel() + self.handlerBlock = nil + + self.streams.removeAll() + self.remainingFileURLs = self.fileURLs + } + } + + private func openRemainingStreams() -> Bool { + var failedURLs = [URL]() + for fileURL in remainingFileURLs { + if let stream = TextFileStream<Codec>(fileURL: fileURL, separator: "\n") { + streams.append(stream) + + didAddStream(stream) + } else { + failedURLs.append(fileURL) + } + } + + remainingFileURLs = failedURLs + + return failedURLs.isEmpty + } + + private func poll() { + if !self.openRemainingStreams() { + self.scheduleRetry() + } + } + + private func scheduleRetry() { + let workItem = DispatchWorkItem(block: { [weak self] in + self?.poll() + }) + queue.asyncAfter(wallDeadline: .now() + .seconds(kLogPollIntervalSeconds), execute: workItem) + retry = workItem + } + + private func didAddStream(_ stream: TextFileStream<Codec>) { + stream.read { [weak self] (s) in + guard let self = self else { return } + + self.queue.async { + self.handlerBlock?(s) + } + } + } +} diff --git a/ios/MullvadVPN/Logging/TextFileStream.swift b/ios/MullvadVPN/Logging/TextFileStream.swift index 2ae9b3e82f..f37ae0b522 100644 --- a/ios/MullvadVPN/Logging/TextFileStream.swift +++ b/ios/MullvadVPN/Logging/TextFileStream.swift @@ -15,7 +15,7 @@ class TextFileStream<Codec> where Codec: UnicodeCodec { private let queue = DispatchQueue(label: "net.mullvad.MullvadVPN.TextFileStream<\(Codec.self)>") private let stringStream: StringStreamIterator<Codec> - init?(fileURL: URL, separator: Character, encoding: String.Encoding = .utf8) { + init?(fileURL: URL, separator: Character) { let filePath = fileURL.path.utf8CString.map { $0 } let fileDescriptor = open(filePath, O_RDONLY) @@ -50,7 +50,7 @@ class TextFileStream<Codec> where Codec: UnicodeCodec { let actual = Darwin.read(self.fileDescriptor, &buffer, estimated) if actual == -1 { - print("TextFileInputStream: read error: \(errno)") + print("TextFileStream<\(Codec.self)>: read error: \(errno)") } if actual > 0 { |
