Skip to content
This repository was archived by the owner on Feb 24, 2025. It is now read-only.

Commit 53e02ea

Browse files
Improve VPN logging logic (#2939)
Task/Issue URL: https://app.asana.com/0/1206580121312550/1207223772590802/f iOS PR: duckduckgo/iOS#3032 BSK PR: duckduckgo/BrowserServicesKit#877 ## Description Improves the logging logic for the VPN.
1 parent e581911 commit 53e02ea

File tree

10 files changed

+145
-12
lines changed

10 files changed

+145
-12
lines changed

DuckDuckGo.xcodeproj/project.pbxproj

+7-3
Original file line numberDiff line numberDiff line change
@@ -1148,7 +1148,6 @@
11481148
4B4BEC482A11B61F001D9AC5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4B4BEC342A11B509001D9AC5 /* Assets.xcassets */; };
11491149
4B4D603F2A0B290200BCD287 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B4D603E2A0B290200BCD287 /* NetworkExtension.framework */; };
11501150
4B4D60892A0B2A1C00BCD287 /* NetworkProtectionUNNotificationsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60762A0B29FA00BCD287 /* NetworkProtectionUNNotificationsPresenter.swift */; };
1151-
4B4D609F2A0B2C7300BCD287 /* Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85799C1725DEBB3F0007EC87 /* Logging.swift */; };
11521151
4B4D60A02A0B2D5B00BCD287 /* Bundle+VPN.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605E2A0B29FA00BCD287 /* Bundle+VPN.swift */; };
11531152
4B4D60A12A0B2D6100BCD287 /* NetworkProtectionOptionKeyExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605F2A0B29FA00BCD287 /* NetworkProtectionOptionKeyExtension.swift */; };
11541153
4B4D60A52A0B2EC000BCD287 /* UserText+NetworkProtectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D607C2A0B29FA00BCD287 /* UserText+NetworkProtectionExtensions.swift */; };
@@ -1511,6 +1510,8 @@
15111510
7B00997D2B6508B700FE7C31 /* NetworkProtectionProxy in Frameworks */ = {isa = PBXBuildFile; productRef = 7B00997C2B6508B700FE7C31 /* NetworkProtectionProxy */; };
15121511
7B00997F2B6508C200FE7C31 /* NetworkProtectionProxy in Frameworks */ = {isa = PBXBuildFile; productRef = 7B00997E2B6508C200FE7C31 /* NetworkProtectionProxy */; };
15131512
7B0099822B65C6B300FE7C31 /* MacTransparentProxyProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B0099802B65C6B300FE7C31 /* MacTransparentProxyProvider.swift */; };
1513+
7B01AC6E2C36BB7E004FADC7 /* VPNLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B01AC6D2C36BB7E004FADC7 /* VPNLogger.swift */; };
1514+
7B01AC6F2C36BB7E004FADC7 /* VPNLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B01AC6D2C36BB7E004FADC7 /* VPNLogger.swift */; };
15141515
7B0694982B6E980F00FA4DBA /* VPNProxyLauncher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B0694972B6E980F00FA4DBA /* VPNProxyLauncher.swift */; };
15151516
7B09CBA92BA4BE8100CF245B /* NetworkProtectionPixelEventTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B09CBA72BA4BE7000CF245B /* NetworkProtectionPixelEventTests.swift */; };
15161517
7B09CBAA2BA4BE8200CF245B /* NetworkProtectionPixelEventTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B09CBA72BA4BE7000CF245B /* NetworkProtectionPixelEventTests.swift */; };
@@ -3428,6 +3429,7 @@
34283429
56D145F029E6F06D00E3488A /* MockBookmarkManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockBookmarkManager.swift; sourceTree = "<group>"; };
34293430
56D6A3D529DB2BAB0055215A /* ContinueSetUpView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContinueSetUpView.swift; sourceTree = "<group>"; };
34303431
7B0099802B65C6B300FE7C31 /* MacTransparentProxyProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MacTransparentProxyProvider.swift; sourceTree = "<group>"; };
3432+
7B01AC6D2C36BB7E004FADC7 /* VPNLogger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VPNLogger.swift; sourceTree = "<group>"; };
34313433
7B05829D2A812AC000AC3F7C /* NetworkProtectionOnboardingMenu.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkProtectionOnboardingMenu.swift; sourceTree = "<group>"; };
34323434
7B0694972B6E980F00FA4DBA /* VPNProxyLauncher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNProxyLauncher.swift; sourceTree = "<group>"; };
34333435
7B09CBA72BA4BE7000CF245B /* NetworkProtectionPixelEventTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionPixelEventTests.swift; sourceTree = "<group>"; };
@@ -5311,6 +5313,7 @@
53115313
EEF12E6D2A2111880023E6BF /* MacPacketTunnelProvider.swift */,
53125314
7B0099802B65C6B300FE7C31 /* MacTransparentProxyProvider.swift */,
53135315
EE66418B2B9B1981005BCD17 /* NetworkProtectionTokenStore+SubscriptionTokenKeychainStorage.swift */,
5316+
7B01AC6D2C36BB7E004FADC7 /* VPNLogger.swift */,
53145317
);
53155318
path = NetworkExtensionTargets;
53165319
sourceTree = "<group>";
@@ -10868,6 +10871,7 @@
1086810871
4B2D06322A11C1D300DE1F49 /* NSApplicationExtension.swift in Sources */,
1086910872
F1FDC93B2BF51F41006B1435 /* VPNSettings+Environment.swift in Sources */,
1087010873
4BF0E50B2AD2552200FFEC9E /* NetworkProtectionPixelEvent.swift in Sources */,
10874+
7B01AC6F2C36BB7E004FADC7 /* VPNLogger.swift in Sources */,
1087110875
4B41EDA12B15437A001EEDF4 /* NetworkProtectionNotificationsPresenterFactory.swift in Sources */,
1087210876
7B0099822B65C6B300FE7C31 /* MacTransparentProxyProvider.swift in Sources */,
1087310877
B65DA5F32A77D3C700CBEE8D /* UserDefaultsWrapper.swift in Sources */,
@@ -10982,7 +10986,6 @@
1098210986
buildActionMask = 2147483647;
1098310987
files = (
1098410988
4B41EDA02B15437A001EEDF4 /* NetworkProtectionNotificationsPresenterFactory.swift in Sources */,
10985-
4B4D609F2A0B2C7300BCD287 /* Logging.swift in Sources */,
1098610989
EE66418C2B9B1981005BCD17 /* NetworkProtectionTokenStore+SubscriptionTokenKeychainStorage.swift in Sources */,
1098710990
7B7DFB202B7E736B009EA1A3 /* MacPacketTunnelProvider.swift in Sources */,
1098810991
F1DA51962BF6083700CF29FA /* PrivacyProPixel.swift in Sources */,
@@ -10996,6 +10999,7 @@
1099610999
4B4D60A02A0B2D5B00BCD287 /* Bundle+VPN.swift in Sources */,
1099711000
4B4D60AD2A0C807300BCD287 /* NSApplicationExtension.swift in Sources */,
1099811001
F1DA51922BF6081C00CF29FA /* AttributionPixelHandler.swift in Sources */,
11002+
7B01AC6E2C36BB7E004FADC7 /* VPNLogger.swift in Sources */,
1099911003
4B4D60A52A0B2EC000BCD287 /* UserText+NetworkProtectionExtensions.swift in Sources */,
1100011004
4BF0E50C2AD2552300FFEC9E /* NetworkProtectionPixelEvent.swift in Sources */,
1100111005
B65DA5F22A77D3C600CBEE8D /* UserDefaultsWrapper.swift in Sources */,
@@ -13178,7 +13182,7 @@
1317813182
repositoryURL = "https://github.com/duckduckgo/BrowserServicesKit";
1317913183
requirement = {
1318013184
kind = exactVersion;
13181-
version = 165.0.0;
13185+
version = 165.0.1;
1318213186
};
1318313187
};
1318413188
9FF521422BAA8FF300B9819B /* XCRemoteSwiftPackageReference "lottie-spm" */ = {

DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@
3232
"kind" : "remoteSourceControl",
3333
"location" : "https://github.com/duckduckgo/BrowserServicesKit",
3434
"state" : {
35-
"revision" : "777e5ae1ab890d9ec22e069bc5dc0f0ada4b35af",
36-
"version" : "165.0.0"
35+
"revision" : "2df7f9d9063c9f8f8f07ccb80c95d7e35738d1ea",
36+
"version" : "165.0.1"
3737
}
3838
},
3939
{

DuckDuckGo/Common/Logging/Logging.swift

-2
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ extension OSLog {
4242
case duckPlayer = "Duck Player"
4343
case tabSnapshots = "Tab Snapshots"
4444
case sync = "Sync"
45-
case networkProtection = "VPN"
4645
case dbp = "dbp"
4746
}
4847

@@ -70,7 +69,6 @@ extension OSLog {
7069
@OSLogWrapper(AppCategories.duckPlayer) static var duckPlayer
7170
@OSLogWrapper(AppCategories.tabSnapshots) static var tabSnapshots
7271
@OSLogWrapper(AppCategories.sync) static var sync
73-
@OSLogWrapper(AppCategories.networkProtection) static var networkProtection
7472
@OSLogWrapper(AppCategories.dbp) static var dbp
7573

7674
// Debug->Logging categories will only be enabled for one day

DuckDuckGo/NetworkProtection/NetworkExtensionTargets/NetworkExtensionTargets/MacPacketTunnelProvider.swift

+24
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ final class MacPacketTunnelProvider: PacketTunnelProvider {
138138

139139
// MARK: - PacketTunnelProvider.Event reporting
140140

141+
private static var vpnLogger = VPNLogger()
142+
141143
private static var packetTunnelProviderEvents: EventMapping<PacketTunnelProvider.Event> = .init { event, _, _, _ in
142144

143145
#if NETP_SYSTEM_EXTENSION
@@ -153,6 +155,8 @@ final class MacPacketTunnelProvider: PacketTunnelProvider {
153155
withAdditionalParameters: [PixelKit.Parameters.vpnCohort: PixelKit.cohort(from: defaults.vpnFirstEnabled)],
154156
includeAppVersionParameter: true)
155157
case .reportConnectionAttempt(attempt: let attempt):
158+
vpnLogger.log(attempt)
159+
156160
switch attempt {
157161
case .connecting:
158162
PixelKit.fire(
@@ -171,6 +175,8 @@ final class MacPacketTunnelProvider: PacketTunnelProvider {
171175
includeAppVersionParameter: true)
172176
}
173177
case .reportTunnelFailure(result: let result):
178+
vpnLogger.log(result)
179+
174180
switch result {
175181
case .failureDetected:
176182
PixelKit.fire(
@@ -186,6 +192,8 @@ final class MacPacketTunnelProvider: PacketTunnelProvider {
186192
break
187193
}
188194
case .reportLatency(let result):
195+
vpnLogger.log(result)
196+
189197
switch result {
190198
case .error:
191199
PixelKit.fire(
@@ -200,6 +208,8 @@ final class MacPacketTunnelProvider: PacketTunnelProvider {
200208
includeAppVersionParameter: true)
201209
}
202210
case .rekeyAttempt(let step):
211+
vpnLogger.log(step, named: "Rekey")
212+
203213
switch step {
204214
case .begin:
205215
PixelKit.fire(
@@ -218,6 +228,8 @@ final class MacPacketTunnelProvider: PacketTunnelProvider {
218228
includeAppVersionParameter: true)
219229
}
220230
case .tunnelStartAttempt(let step):
231+
vpnLogger.log(step, named: "Tunnel Start")
232+
221233
switch step {
222234
case .begin:
223235
PixelKit.fire(
@@ -236,6 +248,8 @@ final class MacPacketTunnelProvider: PacketTunnelProvider {
236248
includeAppVersionParameter: true)
237249
}
238250
case .tunnelStopAttempt(let step):
251+
vpnLogger.log(step, named: "Tunnel Stop")
252+
239253
switch step {
240254
case .begin:
241255
PixelKit.fire(
@@ -254,6 +268,8 @@ final class MacPacketTunnelProvider: PacketTunnelProvider {
254268
includeAppVersionParameter: true)
255269
}
256270
case .tunnelUpdateAttempt(let step):
271+
vpnLogger.log(step, named: "Tunnel Update")
272+
257273
switch step {
258274
case .begin:
259275
PixelKit.fire(
@@ -272,6 +288,8 @@ final class MacPacketTunnelProvider: PacketTunnelProvider {
272288
includeAppVersionParameter: true)
273289
}
274290
case .tunnelWakeAttempt(let step):
291+
vpnLogger.log(step, named: "Tunnel Wake")
292+
275293
switch step {
276294
case .begin:
277295
PixelKit.fire(
@@ -290,6 +308,8 @@ final class MacPacketTunnelProvider: PacketTunnelProvider {
290308
includeAppVersionParameter: true)
291309
}
292310
case .failureRecoveryAttempt(let step):
311+
vpnLogger.log(step)
312+
293313
switch step {
294314
case .started:
295315
PixelKit.fire(
@@ -317,6 +337,8 @@ final class MacPacketTunnelProvider: PacketTunnelProvider {
317337
)
318338
}
319339
case .serverMigrationAttempt(let step):
340+
vpnLogger.log(step, named: "Server Migration")
341+
320342
switch step {
321343
case .begin:
322344
PixelKit.fire(
@@ -335,6 +357,8 @@ final class MacPacketTunnelProvider: PacketTunnelProvider {
335357
includeAppVersionParameter: true)
336358
}
337359
case .tunnelStartOnDemandWithoutAccessToken:
360+
vpnLogger.logStartingWithoutAuthToken()
361+
338362
PixelKit.fire(
339363
NetworkProtectionPixelEvent.networkProtectionTunnelStartAttemptOnDemandWithoutAccessToken,
340364
frequency: .dailyAndCount,

DuckDuckGo/NetworkProtection/NetworkExtensionTargets/NetworkExtensionTargets/NetworkProtectionTokenStore+SubscriptionTokenKeychainStorage.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ extension NetworkProtectionKeychainTokenStore: SubscriptionTokenStoring {
3232
if token.hasPrefix("ddg:") {
3333
token = token.replacingOccurrences(of: "ddg:", with: "")
3434
}
35-
os_log("🔵 Wrapper successfully fetched token %{token}@", log: .networkProtection, type: .info, token)
35+
os_log("🟢 Wrapper successfully fetched token %{token}@", log: .networkProtection, token)
3636
return token
3737
}
3838

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
//
2+
// VPNLogger.swift
3+
//
4+
// Copyright © 2024 DuckDuckGo. All rights reserved.
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
19+
import Foundation
20+
import NetworkProtection
21+
// swiftlint:disable:next enforce_os_log_wrapper
22+
import OSLog
23+
24+
/// Logger for the VPN
25+
///
26+
/// Since we'll want to ensure this adheres to our privacy standards, grouping the logging logic to be mostly
27+
/// handled by a single class sounds like a good approach to be able to review what's being logged..
28+
///
29+
public final class VPNLogger {
30+
public typealias AttemptStep = PacketTunnelProvider.AttemptStep
31+
public typealias ConnectionAttempt = PacketTunnelProvider.ConnectionAttempt
32+
public typealias LogCallback = (OSLogType, OSLogMessage) -> Void
33+
34+
public init() {}
35+
36+
public func logStartingWithoutAuthToken() {
37+
os_log("🔴 Starting tunnel without an auth token", log: .networkProtection, type: .error)
38+
}
39+
40+
public func log(_ step: AttemptStep, named name: String) {
41+
let log = OSLog.networkProtection
42+
43+
switch step {
44+
case .begin:
45+
os_log("🔵 %{public}@ attempt begins", log: log, name)
46+
case .failure(let error):
47+
os_log("🔴 %{public}@ attempt failed with error: %{public}@", log: log, type: .error, name, error.localizedDescription)
48+
case .success:
49+
os_log("🟢 %{public}@ attempt succeeded", log: log, name)
50+
}
51+
}
52+
53+
public func log(_ step: ConnectionAttempt) {
54+
let log = OSLog.networkProtection
55+
56+
switch step {
57+
case .connecting:
58+
os_log("🔵 Connection attempt detected", log: log)
59+
case .failure:
60+
os_log("🔴 Connection attempt failed", log: log, type: .error)
61+
case .success:
62+
os_log("🟢 Connection attempt successful", log: log)
63+
}
64+
}
65+
66+
public func log(_ step: FailureRecoveryStep) {
67+
let log = OSLog.networkProtectionTunnelFailureMonitorLog
68+
69+
switch step {
70+
case .started:
71+
os_log("🔵 Failure Recovery attempt started", log: log)
72+
case .failed(let error):
73+
os_log("🔴 Failure Recovery attempt failed with error: %{public}@", log: log, type: .error, error.localizedDescription)
74+
case .completed(let health):
75+
switch health {
76+
case .healthy:
77+
os_log("🟢 Failure Recovery attempt completed", log: log)
78+
case .unhealthy:
79+
os_log("🔴 Failure Recovery attempt ended as unhealthy", log: log, type: .error)
80+
}
81+
}
82+
}
83+
84+
public func log(_ step: NetworkProtectionTunnelFailureMonitor.Result) {
85+
let log = OSLog.networkProtectionTunnelFailureMonitorLog
86+
87+
switch step {
88+
case .failureDetected:
89+
os_log("🔴 Tunnel failure detected", log: log, type: .error)
90+
case .failureRecovered:
91+
os_log("🟢 Tunnel failure recovered", log: log)
92+
case .networkPathChanged:
93+
os_log("🔵 Tunnel recovery detected path change", log: log)
94+
}
95+
}
96+
97+
public func log(_ result: NetworkProtectionLatencyMonitor.Result) {
98+
let log = OSLog.networkProtectionLatencyMonitorLog
99+
100+
switch result {
101+
case .error:
102+
os_log("🔴 There was an error logging the latency", log: log, type: .error)
103+
case .quality(let quality):
104+
os_log("Connection quality is: %{public}@", log: log, quality.rawValue)
105+
}
106+
}
107+
}

DuckDuckGoVPN/DuckDuckGoVPNAppDelegate.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ final class DuckDuckGoVPNAppDelegate: NSObject, NSApplicationDelegate {
360360
func applicationDidFinishLaunching(_ aNotification: Notification) {
361361

362362
APIRequest.Headers.setUserAgent(UserAgent.duckDuckGoUserAgent())
363-
os_log("DuckDuckGoVPN started", log: .networkProtectionLoginItemLog, type: .info)
363+
os_log("DuckDuckGoVPN started", log: .networkProtectionLoginItemLog)
364364

365365
setupMenuVisibility()
366366

LocalPackages/DataBrokerProtection/Package.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ let package = Package(
2929
targets: ["DataBrokerProtection"])
3030
],
3131
dependencies: [
32-
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "165.0.0"),
32+
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "165.0.1"),
3333
.package(path: "../SwiftUIExtensions"),
3434
.package(path: "../XPCHelper"),
3535
],

LocalPackages/NetworkProtectionMac/Package.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ let package = Package(
3232
.library(name: "VPNAppLauncher", targets: ["VPNAppLauncher"]),
3333
],
3434
dependencies: [
35-
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "165.0.0"),
35+
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "165.0.1"),
3636
.package(url: "https://github.com/airbnb/lottie-spm", exact: "4.4.3"),
3737
.package(path: "../AppLauncher"),
3838
.package(path: "../UDSHelper"),

LocalPackages/SubscriptionUI/Package.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ let package = Package(
1212
targets: ["SubscriptionUI"]),
1313
],
1414
dependencies: [
15-
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "165.0.0"),
15+
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "165.0.1"),
1616
.package(path: "../SwiftUIExtensions")
1717
],
1818
targets: [

0 commit comments

Comments
 (0)