summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2021-09-14 12:15:25 +0200
committerAndrej Mihajlov <and@mullvad.net>2021-09-14 12:15:25 +0200
commit9dd0730bdc9ec141f6fdbb73cd69988a12f04e0f (patch)
tree984a26abaefa328d675a76f3f23ada242cdcff80
parentb8930db15b76d1866ab18cd58cdf9936dbe0ffa2 (diff)
downloadmullvadvpn-9dd0730bdc9ec141f6fdbb73cd69988a12f04e0f.tar.xz
mullvadvpn-9dd0730bdc9ec141f6fdbb73cd69988a12f04e0f.zip
Remove log forwarder
There is no benefit in forwarding logs now when we have OSLog and problem report controller that offers viewing on-device logs.
-rw-r--r--ios/MullvadVPN.xcodeproj/project.pbxproj22
-rw-r--r--ios/MullvadVPN/LogStreamerViewController.swift189
-rw-r--r--ios/MullvadVPN/Logging/LogEntryParser.swift98
-rw-r--r--ios/MullvadVPN/Logging/LogStreamer.swift141
-rw-r--r--ios/MullvadVPN/Logging/StringStreamIterator.swift58
-rw-r--r--ios/MullvadVPN/Logging/TextFileStream.swift77
-rw-r--r--ios/MullvadVPN/SettingsViewController.swift17
7 files changed, 1 insertions, 601 deletions
diff --git a/ios/MullvadVPN.xcodeproj/project.pbxproj b/ios/MullvadVPN.xcodeproj/project.pbxproj
index d159f98b47..5f81d89189 100644
--- a/ios/MullvadVPN.xcodeproj/project.pbxproj
+++ b/ios/MullvadVPN.xcodeproj/project.pbxproj
@@ -39,7 +39,6 @@
580EE22824B3289300F9D8A1 /* AssociatedValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 580EE22724B3289300F9D8A1 /* AssociatedValue.swift */; };
580EE22924B3289300F9D8A1 /* AssociatedValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 580EE22724B3289300F9D8A1 /* AssociatedValue.swift */; };
5811DE50239014550011EB53 /* NEVPNStatus+Debug.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5811DE4F239014550011EB53 /* NEVPNStatus+Debug.swift */; };
- 58141EC924DAC0ED0013F79C /* TextFileStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58141EC824DAC0ED0013F79C /* TextFileStream.swift */; };
5815039724D6ECAE00C9C50E /* CustomFormatLogHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5815039624D6ECAE00C9C50E /* CustomFormatLogHandler.swift */; };
5815039824D6ECAE00C9C50E /* CustomFormatLogHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5815039624D6ECAE00C9C50E /* CustomFormatLogHandler.swift */; };
5815039D24D6ECE600C9C50E /* TextFileOutputStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5815039C24D6ECE600C9C50E /* TextFileOutputStream.swift */; };
@@ -112,7 +111,6 @@
585834FC24D2BC9500A8AF56 /* Logging in Frameworks */ = {isa = PBXBuildFile; productRef = 585834FB24D2BC9500A8AF56 /* Logging */; };
585CA70F25F8C44600B47C62 /* UIMetrics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 585CA70E25F8C44600B47C62 /* UIMetrics.swift */; };
585DA8AF26B9492500B8C587 /* Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = 585DA8AE26B9492500B8C587 /* Promise.swift */; };
- 585FE2F124E1365400439C50 /* LogStreamer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 585FE2F024E1365400439C50 /* LogStreamer.swift */; };
5860392726D91B8400554C79 /* PromiseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58A94AE526D23C3D001CB97C /* PromiseTests.swift */; };
5860392926DCE7AB00554C79 /* PromiseCompletion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5860392826DCE7AB00554C79 /* PromiseCompletion.swift */; };
5860392A26DCE7AB00554C79 /* PromiseCompletion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5860392826DCE7AB00554C79 /* PromiseCompletion.swift */; };
@@ -201,9 +199,6 @@
58BFA5CD22A7CE1F00A6173D /* ApplicationConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58BFA5CB22A7CE1F00A6173D /* ApplicationConfiguration.swift */; };
58C3478B26C1094F0060838B /* Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = 585DA8AE26B9492500B8C587 /* Promise.swift */; };
58C3A4B222456F1B00340BDB /* AccountInputGroupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58C3A4B122456F1A00340BDB /* AccountInputGroupView.swift */; };
- 58C3B06724EA768100C0348E /* LogStreamerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58C3B06624EA768100C0348E /* LogStreamerViewController.swift */; };
- 58C3B06924EAA25000C0348E /* StringStreamIterator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58C3B06824EAA25000C0348E /* StringStreamIterator.swift */; };
- 58C4CB0124EBE5A700A22D49 /* LogEntryParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58C4CB0024EBE5A700A22D49 /* LogEntryParser.swift */; };
58CAF4EA26025927007C5886 /* PacketTunnelIpc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5845F841236CBACD00B2D93C /* PacketTunnelIpc.swift */; };
58CAF4EF26025954007C5886 /* SimulatorTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58BA693023EADA6A009DC256 /* SimulatorTunnelProvider.swift */; };
58CB0EE024B86751001EF0D8 /* MullvadRest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58CB0EDF24B86751001EF0D8 /* MullvadRest.swift */; };
@@ -356,7 +351,6 @@
580EE22324B3243100F9D8A1 /* AsyncBlockOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncBlockOperation.swift; sourceTree = "<group>"; };
580EE22724B3289300F9D8A1 /* AssociatedValue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssociatedValue.swift; sourceTree = "<group>"; };
5811DE4F239014550011EB53 /* NEVPNStatus+Debug.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NEVPNStatus+Debug.swift"; sourceTree = "<group>"; };
- 58141EC824DAC0ED0013F79C /* TextFileStream.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFileStream.swift; sourceTree = "<group>"; };
5815039324D6EB7200C9C50E /* LogRotation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogRotation.swift; sourceTree = "<group>"; };
5815039624D6ECAE00C9C50E /* CustomFormatLogHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomFormatLogHandler.swift; sourceTree = "<group>"; };
5815039C24D6ECE600C9C50E /* TextFileOutputStream.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFileOutputStream.swift; sourceTree = "<group>"; };
@@ -394,7 +388,6 @@
5857F24624C882D700CF6F47 /* SelectLocationNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectLocationNavigationController.swift; sourceTree = "<group>"; };
585CA70E25F8C44600B47C62 /* UIMetrics.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIMetrics.swift; sourceTree = "<group>"; };
585DA8AE26B9492500B8C587 /* Promise.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Promise.swift; sourceTree = "<group>"; };
- 585FE2F024E1365400439C50 /* LogStreamer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogStreamer.swift; sourceTree = "<group>"; };
5860392826DCE7AB00554C79 /* PromiseCompletion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PromiseCompletion.swift; sourceTree = "<group>"; };
5862805322428EF100F5A6E1 /* TranslucentButtonBlurView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TranslucentButtonBlurView.swift; sourceTree = "<group>"; };
5866F39B2243B82D00168AE5 /* MullvadVPN.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MullvadVPN.entitlements; sourceTree = "<group>"; };
@@ -454,9 +447,6 @@
58BFA5C522A7C97F00A6173D /* RelayCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayCache.swift; sourceTree = "<group>"; };
58BFA5CB22A7CE1F00A6173D /* ApplicationConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationConfiguration.swift; sourceTree = "<group>"; };
58C3A4B122456F1A00340BDB /* AccountInputGroupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountInputGroupView.swift; sourceTree = "<group>"; };
- 58C3B06624EA768100C0348E /* LogStreamerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogStreamerViewController.swift; sourceTree = "<group>"; };
- 58C3B06824EAA25000C0348E /* StringStreamIterator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringStreamIterator.swift; sourceTree = "<group>"; };
- 58C4CB0024EBE5A700A22D49 /* LogEntryParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogEntryParser.swift; sourceTree = "<group>"; };
58C6B35322BB87C4003C19AD /* PrivateKeyWithMetadata.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivateKeyWithMetadata.swift; sourceTree = "<group>"; };
58CB0EDF24B86751001EF0D8 /* MullvadRest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MullvadRest.swift; sourceTree = "<group>"; };
58CC40EE24A601900019D96E /* ObserverList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObserverList.swift; sourceTree = "<group>"; };
@@ -600,14 +590,10 @@
children = (
581503A224D6F1EC00C9C50E /* ChainedError+Logger.swift */,
5815039624D6ECAE00C9C50E /* CustomFormatLogHandler.swift */,
- 58C4CB0024EBE5A700A22D49 /* LogEntryParser.swift */,
581503A524D6F4AE00C9C50E /* Logging.swift */,
5815039324D6EB7200C9C50E /* LogRotation.swift */,
- 585FE2F024E1365400439C50 /* LogStreamer.swift */,
- 58C3B06824EAA25000C0348E /* StringStreamIterator.swift */,
- 5815039C24D6ECE600C9C50E /* TextFileOutputStream.swift */,
- 58141EC824DAC0ED0013F79C /* TextFileStream.swift */,
5823FA4F26CA690600283BF8 /* OSLogHandler.swift */,
+ 5815039C24D6ECE600C9C50E /* TextFileOutputStream.swift */,
);
path = Logging;
sourceTree = "<group>";
@@ -759,7 +745,6 @@
5815039F24D6ECF200C9C50E /* Logging */,
58B993B02608A34500BA7811 /* LoginContentView.swift */,
58CE5E65224146200008646E /* LoginViewController.swift */,
- 58C3B06624EA768100C0348E /* LogStreamerViewController.swift */,
5840250322B11AB700E4CFEC /* MullvadEndpoint.swift */,
58CB0EDF24B86751001EF0D8 /* MullvadRest.swift */,
5866F39B2243B82D00168AE5 /* MullvadVPN.entitlements */,
@@ -1241,7 +1226,6 @@
5873884D239E6D7E00E96C4E /* EmbeddedViewContainerView.swift in Sources */,
583BC70724FE4DC500C9DE04 /* Optional+DispatchQueue.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 */,
@@ -1264,7 +1248,6 @@
58ACF64F26567A7100ACE4B7 /* CustomSwitchContainer.swift in Sources */,
5857F24324C8662600CF6F47 /* SelectLocationHeaderView.swift in Sources */,
58AEEF652344A36000C9BBD5 /* KeychainError.swift in Sources */,
- 58C3B06924EAA25000C0348E /* StringStreamIterator.swift in Sources */,
580EE22824B3289300F9D8A1 /* AssociatedValue.swift in Sources */,
581503A624D6F4AE00C9C50E /* Logging.swift in Sources */,
58CCA01222424D11004F3011 /* SettingsViewController.swift in Sources */,
@@ -1288,15 +1271,12 @@
587AD7C623421D7000E93A53 /* TunnelSettings.swift in Sources */,
581503A324D6F1EC00C9C50E /* ChainedError+Logger.swift in Sources */,
58FD5BF024238EB300112C88 /* SKProduct+Formatting.swift in Sources */,
- 58C3B06724EA768100C0348E /* LogStreamerViewController.swift in Sources */,
58B43C1925F77DB60002C8C3 /* ConnectMainContentView.swift in Sources */,
58561C99239A5D1500BD6B5E /* IPEndpoint.swift in Sources */,
58FD5BF22424F7D700112C88 /* UserInterfaceInteractionRestriction.swift in Sources */,
5823FA5026CA690600283BF8 /* OSLogHandler.swift in Sources */,
5811DE50239014550011EB53 /* NEVPNStatus+Debug.swift in Sources */,
- 58141EC924DAC0ED0013F79C /* TextFileStream.swift in Sources */,
58C3A4B222456F1B00340BDB /* AccountInputGroupView.swift in Sources */,
- 58C4CB0124EBE5A700A22D49 /* LogEntryParser.swift in Sources */,
58F840B22464491D0044E708 /* ChainedError.swift in Sources */,
58E1338126D2BF5C00CC316B /* Promise+Result.swift in Sources */,
58FAEDFF24533A7000CB0F5B /* KeychainReturn.swift in Sources */,
diff --git a/ios/MullvadVPN/LogStreamerViewController.swift b/ios/MullvadVPN/LogStreamerViewController.swift
deleted file mode 100644
index 7774fdf810..0000000000
--- a/ios/MullvadVPN/LogStreamerViewController.swift
+++ /dev/null
@@ -1,189 +0,0 @@
-//
-// LogStreamerViewController.swift
-// MullvadVPN
-//
-// Created by pronebird on 17/08/2020.
-// Copyright © 2020 Mullvad VPN AB. All rights reserved.
-//
-
-#if DEBUG
-
-import Foundation
-import UIKit
-import Logging
-
-class LogStreamerViewController: UIViewController, UITextViewDelegate {
-
- private let textView = UITextView()
- private let streamer: LogStreamer<UTF8>
- private let logEntryParser = LogEntryParser()
- private var currentTextColor: UIColor?
- private let timestampFormatter: DateFormatter = {
- let formatter = DateFormatter()
- formatter.dateFormat = "HH:mm:ss.SSS"
- return formatter
- }()
-
- private var autoScrollButtonItem: UIBarButtonItem {
- return UIBarButtonItem(barButtonSystemItem: autoScroll ? .pause : .play, target: self, action: #selector(handleToggleAutoscroll(_:)))
- }
-
- private var dismissButtonItem: UIBarButtonItem {
- return UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(handleDismissButton(_:)))
- }
-
- var autoScroll: Bool = true {
- didSet {
- updateAutoScrollBarItem()
- handleAutoScroll()
- }
- }
-
- init(fileURLs: [URL]) {
- streamer = LogStreamer(fileURLs: fileURLs)
- super.init(nibName: nil, bundle: nil)
- }
-
- required init?(coder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
-
- // MARK: - View lifecycle
-
- override func viewDidLoad() {
- super.viewDidLoad()
-
- navigationItem.title = "App logs"
- navigationItem.leftBarButtonItem = autoScrollButtonItem
- navigationItem.rightBarButtonItem = dismissButtonItem
-
- addSubviews()
- startStreamer()
- }
-
- // MARK: - UITextViewDelegate
-
- func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
- let translation = scrollView.panGestureRecognizer.translation(in: scrollView.superview)
-
- // Disable autoscroll if user scrolled up
- if translation.y > 0 {
- autoScroll = false
- } else if translation.y < 0 {
- // Enable autoscroll if user scrolled to the bottom of the view
- let maxScrollY = scrollView.contentSize.height - scrollView.frame.height
-
- if targetContentOffset.pointee.y >= maxScrollY {
- autoScroll = true
- }
- }
- }
-
- func scrollViewShouldScrollToTop(_ scrollView: UIScrollView) -> Bool {
- // Disable autoscroll when user requested scroll to top
- autoScroll = false
- return true
- }
-
- // MARK: - Private
-
- private func addSubviews() {
- textView.translatesAutoresizingMaskIntoConstraints = false
- textView.isEditable = false
- if #available(iOS 13.0, *) {
- textView.font = UIFont.monospacedSystemFont(ofSize: UIFont.systemFontSize, weight: .regular)
- } else {
- textView.font = UIFont(name: "Courier", size: UIFont.systemFontSize)
- }
- textView.delegate = self
-
- view.addSubview(textView)
-
- NSLayoutConstraint.activate([
- textView.topAnchor.constraint(equalTo: view.topAnchor),
- textView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
- textView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
- textView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
- ])
- }
-
- private func startStreamer() {
- self.streamer.start { [weak self] (str) in
- guard let self = self else { return }
-
- DispatchQueue.main.async {
- // Try parsing the entry
- let entry = self.logEntryParser.parse(str)
-
- // Since the log streamer sends the log file line-by-line, it's possible that only a
- // part of a multiline message is captured at first.
- let message = entry.map { (entry) -> String in
- // Reformat the log entry date
- let timestamp = self.timestampFormatter.string(from: entry.timestamp)
-
- return "\(timestamp) \(entry.module) \(entry.message)\n"
- } ?? "\(str)\n"
-
-
- // Compute the range for replacing the text color
- let start = self.textView.text.utf16.count
- let end = start + message.utf16.count
- let textRange = NSRange(start..<end)
-
- self.textView.insertText(message)
- self.handleAutoScroll()
-
- // Update the current log entry color
- if let logLevel = entry?.level {
- self.currentTextColor = self.textColor(for: logLevel)
- }
-
- // Apply the color attribute to the inserted text
- if let textColor = self.currentTextColor {
- self.textView.textStorage.addAttributes([.foregroundColor: textColor], range: textRange)
- }
- }
- }
- }
-
- private func handleAutoScroll() {
- if autoScroll && !textView.isTracking && (!textView.isDragging || textView.isDecelerating) {
- scrollToBottom()
- }
- }
-
- private func scrollToBottom() {
- let textRange = NSRange(..<textView.text.endIndex, in: textView.text)
-
- textView.scrollRangeToVisible(textRange)
- }
-
- private func updateAutoScrollBarItem() {
- navigationItem.leftBarButtonItem = autoScrollButtonItem
- }
-
- private func textColor(for logLevel: Logger.Level) -> UIColor {
- switch logLevel {
- case .debug, .trace:
- return .lightGray
- case .error, .critical:
- return .red
- case .info, .notice:
- return .blue
- case .warning:
- return .orange
- }
- }
-
- // MARK: - Actions
-
- @objc func handleDismissButton(_ sender: Any) {
- dismiss(animated: true)
- }
-
- @objc func handleToggleAutoscroll(_ sender: Any) {
- autoScroll = !autoScroll
- }
-}
-
-#endif
diff --git a/ios/MullvadVPN/Logging/LogEntryParser.swift b/ios/MullvadVPN/Logging/LogEntryParser.swift
deleted file mode 100644
index c7b3a68db7..0000000000
--- a/ios/MullvadVPN/Logging/LogEntryParser.swift
+++ /dev/null
@@ -1,98 +0,0 @@
-//
-// LogEntryParser.swift
-// MullvadVPN
-//
-// Created by pronebird on 18/08/2020.
-// Copyright © 2020 Mullvad VPN AB. All rights reserved.
-//
-
-#if DEBUG
-
-import Foundation
-import Logging
-
-struct ParsedLogEntry {
- let timestamp: Date
- let level: Logger.Level
- let module: String
- let message: String
-}
-
-class LogEntryParser {
- /// Date formatter used for decoding the timestamp
- private let dateFormatter = CustomFormatLogHandler.makeDateFormatter()
-
- /// Parse a log entry in the following format:
- /// [<DATE>][<MODULE>][<LOG_LEVEL>] <MESSAGE>
- func parse(_ str: String) -> ParsedLogEntry? {
- let ranges = Self.stringRangesWithinSquareBrackets(string: str, maxResults: 3)
- guard ranges.count == 3 else {
- return nil
- }
-
- let strings = ranges.map { String(str[$0]) }
-
- guard let timestamp = dateFormatter.date(from: strings[0]),
- let logLevel = Logger.Level(rawValue: strings[2]) else {
- return nil
- }
-
- // Extract the log message following the log level
- let startIndex = str.index(ranges.last!.upperBound, offsetBy: 1, limitedBy: str.endIndex)
- let message = startIndex.map({ (startIndex) -> String in
- return str[startIndex..<str.endIndex].trimmingCharacters(in: .whitespaces)
- }) ?? ""
-
- return ParsedLogEntry(
- timestamp: timestamp,
- level: logLevel,
- module: strings[1],
- message: message
- )
- }
-
- /// Find consecutive ranges of strings within square brackets.
- private static func stringRangesWithinSquareBrackets(string: String, maxResults: Int) -> [Range<String.Index>] {
- var results = [Range<String.Index>]()
- var maybeStartIndex: String.Index?
-
- guard maxResults > 0 else { return results }
-
- loop: for (offset, char) in string.enumerated() {
- switch char {
- case "[":
- if maybeStartIndex == nil {
- maybeStartIndex = string.index(string.startIndex, offsetBy: offset + 1, limitedBy: string.endIndex)
- } else {
- // out of order
- break loop
- }
-
- case "]":
- if let startIndex = maybeStartIndex {
- maybeStartIndex = nil
-
- let endIndex = string.index(string.startIndex, offsetBy: offset)
-
- results.append((startIndex..<endIndex))
-
- if results.count >= maxResults {
- // done
- break loop
- }
- } else {
- // out of order
- break loop
- }
-
- default:
- continue
- }
- }
-
- return results
- }
-
-}
-
-#endif
diff --git a/ios/MullvadVPN/Logging/LogStreamer.swift b/ios/MullvadVPN/Logging/LogStreamer.swift
deleted file mode 100644
index 23da9fae31..0000000000
--- a/ios/MullvadVPN/Logging/LogStreamer.swift
+++ /dev/null
@@ -1,141 +0,0 @@
-//
-// LogStreamer.swift
-// MullvadVPN
-//
-// Created by pronebird on 10/08/2020.
-// Copyright © 2020 Mullvad VPN AB. All rights reserved.
-//
-
-#if DEBUG
-
-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 pendingFileURLs: [URL]
- private var streams = [TextFileStream<Codec>]()
- private var eventSources = [DispatchSourceFileSystemObject]()
- private let queue = DispatchQueue(label: "net.mullvad.MullvadVPN.LogStreamer<\(Codec.self)>")
- private var retry: DispatchWorkItem?
- private var handlerBlock: ((String) -> Void)?
- private var isStarted = false
-
- init(fileURLs: [URL]) {
- self.fileURLs = fileURLs
- self.pendingFileURLs = fileURLs
- }
-
- deinit {
- cancelAndRemoveAllEventSources()
- }
-
- func start(handler: @escaping (String) -> Void) {
- queue.async {
- guard !self.isStarted else { return }
-
- self.isStarted = true
- self.handlerBlock = handler
- self.poll()
- }
- }
-
- func stop() {
- queue.async {
- guard self.isStarted else { return }
-
- self.isStarted = false
-
- self.retry?.cancel()
- self.handlerBlock = nil
-
- self.cancelAndRemoveAllEventSources()
- self.streams.removeAll()
- self.pendingFileURLs = self.fileURLs
- }
- }
-
- private func openRemainingStreams() -> Bool {
- var failedURLs = [URL]()
- for fileURL in pendingFileURLs {
- if let stream = TextFileStream<Codec>(fileURL: fileURL, separator: "\n") {
- streams.append(stream)
-
- stream.read { [weak self] (s) in
- guard let self = self else { return }
-
- self.queue.async {
- self.handlerBlock?(s)
- }
- }
-
- addFileWatch(fileURL: fileURL, stream: stream)
- } else {
- failedURLs.append(fileURL)
- }
- }
-
- pendingFileURLs = failedURLs
-
- return failedURLs.isEmpty
- }
-
- private func poll() {
- if !self.openRemainingStreams() {
- self.scheduleRetry()
- }
- }
-
- private func scheduleRetry() {
- let workItem = DispatchWorkItem(block: { [weak self] in
- guard let self = self, self.isStarted else { return }
-
- self.poll()
- })
- queue.asyncAfter(wallDeadline: .now() + .seconds(kLogPollIntervalSeconds), execute: workItem)
- retry = workItem
- }
-
- /// Watch file renames and re-add the stream once that happens
- private func addFileWatch(fileURL: URL, stream: TextFileStream<Codec>) {
- let source = DispatchSource.makeFileSystemObjectSource(
- fileDescriptor: stream.fileDescriptor,
- eventMask: .rename,
- queue: queue
- )
-
- source.setEventHandler { [weak self, weak source] in
- guard let self = self, let source = source, self.isStarted else { return }
-
- // Cancel current event source
- source.cancel()
-
- // Release the stream
- self.streams.removeAll { (s) -> Bool in
- return stream === s
- }
-
- // Release the current event source
- self.eventSources.removeAll { (s) -> Bool in
- return source === s
- }
-
- // Add the file URL to backlog & start polling
- self.pendingFileURLs.append(fileURL)
- self.poll()
- }
-
- source.activate()
-
- eventSources.append(source)
- }
-
- private func cancelAndRemoveAllEventSources() {
- eventSources.forEach { $0.cancel() }
- eventSources.removeAll()
- }
-}
-
-#endif
diff --git a/ios/MullvadVPN/Logging/StringStreamIterator.swift b/ios/MullvadVPN/Logging/StringStreamIterator.swift
deleted file mode 100644
index c13b921c33..0000000000
--- a/ios/MullvadVPN/Logging/StringStreamIterator.swift
+++ /dev/null
@@ -1,58 +0,0 @@
-//
-// StringStreamIterator.swift
-// MullvadVPN
-//
-// Created by pronebird on 17/08/2020.
-// Copyright © 2020 Mullvad VPN AB. All rights reserved.
-//
-
-#if DEBUG
-
-import Foundation
-
-class StringStreamIterator<Codec>: IteratorProtocol where Codec: UnicodeCodec {
- let separator: Character
-
- private var string = ""
- private var data = [Codec.CodeUnit]()
- private var parser = Codec.ForwardParser()
-
- init(separator: Character) {
- self.separator = separator
- }
-
- func append<S>(bytes: S) where S: Sequence, S.Element == Codec.CodeUnit {
- data.append(contentsOf: bytes)
- }
-
- func next() -> String? {
- var dataIterator = data.makeIterator()
- var bytesRead = 0
-
- defer {
- if bytesRead > 0 {
- data.removeSubrange(..<bytesRead)
- }
- }
-
- while case .valid(let encodedScalar) = parser.parseScalar(from: &dataIterator) {
- let unicodeScalar = Codec.decode(encodedScalar)
- let character = Character(unicodeScalar)
-
- bytesRead += encodedScalar.count
-
- if character == separator {
- let returnString = string
- string = ""
-
- return returnString
- } else {
- string.append(character)
- }
- }
-
- return nil
- }
-}
-
-#endif
diff --git a/ios/MullvadVPN/Logging/TextFileStream.swift b/ios/MullvadVPN/Logging/TextFileStream.swift
deleted file mode 100644
index de1aad6d91..0000000000
--- a/ios/MullvadVPN/Logging/TextFileStream.swift
+++ /dev/null
@@ -1,77 +0,0 @@
-//
-// TextFileStream.swift
-// MullvadVPN
-//
-// Created by pronebird on 05/08/2020.
-// Copyright © 2020 Mullvad VPN AB. All rights reserved.
-//
-
-#if DEBUG
-
-import Foundation
-import Darwin
-
-class TextFileStream<Codec> where Codec: UnicodeCodec {
- let fileDescriptor: Int32
-
- private let readSource: DispatchSourceRead
- private let queue = DispatchQueue(label: "net.mullvad.MullvadVPN.TextFileStream<\(Codec.self)>")
- private let stringStream: StringStreamIterator<Codec>
-
- init?(fileURL: URL, separator: Character) {
- let filePath = fileURL.path.utf8CString.map { $0 }
-
- let fileDescriptor = open(filePath, O_RDONLY)
- if (fileDescriptor == -1) {
- return nil
- }
-
- // Avoid blocking the read operation
- _ = fcntl(fileDescriptor, F_SETFL, O_NONBLOCK);
-
- let readSource = DispatchSource.makeReadSource(fileDescriptor: fileDescriptor, queue: queue)
- readSource.setCancelHandler {
- close(fileDescriptor)
- }
-
- stringStream = StringStreamIterator(separator: separator)
-
- self.readSource = readSource
- self.fileDescriptor = fileDescriptor
- }
-
- deinit {
- readSource.cancel()
- }
-
- func read(_ handler: @escaping (String) -> Void) {
- readSource.setEventHandler { [weak self] in
- guard let self = self else { return }
-
- let estimated = Int(self.readSource.data + 1)
- var buffer = [Codec.CodeUnit](repeating: 0, count: estimated)
- let actual = Darwin.read(self.fileDescriptor, &buffer, estimated)
-
- if actual == -1 {
- print("TextFileStream<\(Codec.self)>: read error: \(errno)")
- }
-
- if actual > 0 {
- let bytes = buffer[..<actual]
- self.stringStream.append(bytes: bytes)
-
- while let s = self.stringStream.next() {
- handler(s)
- }
- }
- }
- readSource.activate()
- }
-
- func cancel() {
- readSource.cancel()
- }
-
-}
-
-#endif
diff --git a/ios/MullvadVPN/SettingsViewController.swift b/ios/MullvadVPN/SettingsViewController.swift
index 769181dfc8..a2a7f91208 100644
--- a/ios/MullvadVPN/SettingsViewController.swift
+++ b/ios/MullvadVPN/SettingsViewController.swift
@@ -143,23 +143,6 @@ class SettingsViewController: UITableViewController, AccountObserver {
middleSection.addRows([versionRow])
staticDataSource.addSections([middleSection])
- #if DEBUG
- let logStreamerRow = StaticTableViewRow(reuseIdentifier: CellIdentifier.basicCell.rawValue) { (_, cell) in
- let cell = cell as! SettingsCell
-
- cell.titleLabel.text = "App logs"
- }
- logStreamerRow.actionBlock = { [weak self] (indexPath) in
- let logController = LogStreamerViewController(fileURLs: ApplicationConfiguration.logFileURLs)
- let navController = UINavigationController(rootViewController: logController)
-
- navController.modalPresentationStyle = .fullScreen
-
- self?.present(navController, animated: true)
- }
- middleSection.addRows([logStreamerRow])
- #endif
-
let bottomSection = StaticTableViewSection()
let problemReportRow = StaticTableViewRow(reuseIdentifier: CellIdentifier.basicCell.rawValue) { (indexPath, cell) in