Skip to content

Commit 49a01e9

Browse files
committed
Adding OSLog and Loggly support
1 parent 2c0e48e commit 49a01e9

18 files changed

+375
-72
lines changed

Loop.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@
3232
432E73CB1D24B3D6009AD15D /* RemoteDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 432E73CA1D24B3D6009AD15D /* RemoteDataManager.swift */; };
3333
433EA4C21D9F39C900CD78FB /* PumpIDTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 433EA4C11D9F39C900CD78FB /* PumpIDTableViewController.swift */; };
3434
433EA4C41D9F71C800CD78FB /* CommandResponseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 433EA4C31D9F71C800CD78FB /* CommandResponseViewController.swift */; };
35+
4341F4EB1EDB92AC001C936B /* LogglyService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4341F4EA1EDB92AC001C936B /* LogglyService.swift */; };
3536
43441A9C1EDB34810087958C /* StatusExtensionContext+LoopKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43441A9B1EDB34810087958C /* StatusExtensionContext+LoopKit.swift */; };
37+
43441AA01EDB4D390087958C /* OSLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43441A9F1EDB4D390087958C /* OSLog.swift */; };
3638
4346D1E71C77F5FE00ABAFE3 /* ChartTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4346D1E61C77F5FE00ABAFE3 /* ChartTableViewCell.swift */; };
3739
4346D1F61C78501000ABAFE3 /* ChartPoint+Loop.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4346D1F51C78501000ABAFE3 /* ChartPoint+Loop.swift */; };
3840
434F54571D287FDB002A9274 /* NibLoadable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 434F54561D287FDB002A9274 /* NibLoadable.swift */; };
@@ -378,7 +380,9 @@
378380
4337615E1D52F487004A3647 /* GlucoseHUDView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GlucoseHUDView.swift; sourceTree = "<group>"; };
379381
433EA4C11D9F39C900CD78FB /* PumpIDTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PumpIDTableViewController.swift; sourceTree = "<group>"; };
380382
433EA4C31D9F71C800CD78FB /* CommandResponseViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CommandResponseViewController.swift; sourceTree = "<group>"; };
383+
4341F4EA1EDB92AC001C936B /* LogglyService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LogglyService.swift; sourceTree = "<group>"; };
381384
43441A9B1EDB34810087958C /* StatusExtensionContext+LoopKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "StatusExtensionContext+LoopKit.swift"; sourceTree = "<group>"; };
385+
43441A9F1EDB4D390087958C /* OSLog.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OSLog.swift; sourceTree = "<group>"; };
382386
4346D1E61C77F5FE00ABAFE3 /* ChartTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChartTableViewCell.swift; sourceTree = "<group>"; };
383387
4346D1EF1C781BEA00ABAFE3 /* SwiftCharts.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftCharts.framework; path = Carthage/Build/iOS/SwiftCharts.framework; sourceTree = "<group>"; };
384388
4346D1F51C78501000ABAFE3 /* ChartPoint+Loop.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ChartPoint+Loop.swift"; sourceTree = "<group>"; };
@@ -739,6 +743,7 @@
739743
isa = PBXGroup;
740744
children = (
741745
438849EB1D29EC34003B3F23 /* AmplitudeService.swift */,
746+
4341F4EA1EDB92AC001C936B /* LogglyService.swift */,
742747
438849ED1D2A1EBB003B3F23 /* MLabService.swift */,
743748
438849E91D297CB6003B3F23 /* NightscoutService.swift */,
744749
437CCADF1D285C7B0075D2C3 /* ServiceAuthentication.swift */,
@@ -842,6 +847,7 @@
842847
43CEE6E51E56AFD400CB9116 /* NightscoutUploader.swift */,
843848
4398973A1CD2FC2000223065 /* NSDateFormatter.swift */,
844849
43E344A31B9E1B1C00C85C07 /* NSUserDefaults.swift */,
850+
43441A9F1EDB4D390087958C /* OSLog.swift */,
845851
43BFF0CA1E466C0900FF19A9 /* StateColorPalette.swift */,
846852
43F41C361D3BF32400C11ED6 /* UIAlertController.swift */,
847853
43BFF0BB1E45C80600FF19A9 /* UIColor+Loop.swift */,
@@ -1442,6 +1448,7 @@
14421448
43776F901B8022E90074EA36 /* AppDelegate.swift in Sources */,
14431449
437CCADA1D284ADF0075D2C3 /* AuthenticationTableViewCell.swift in Sources */,
14441450
439BED2E1E760BC600B0AED5 /* EnliteCGMManager.swift in Sources */,
1451+
4341F4EB1EDB92AC001C936B /* LogglyService.swift in Sources */,
14451452
43CE7CDE1CA8B63E003CC1B0 /* Data.swift in Sources */,
14461453
43BFF0CB1E466C0900FF19A9 /* StateColorPalette.swift in Sources */,
14471454
438991691E91B571000EEF90 /* ChartPoint.swift in Sources */,
@@ -1500,6 +1507,7 @@
15001507
43F41C371D3BF32400C11ED6 /* UIAlertController.swift in Sources */,
15011508
433EA4C41D9F71C800CD78FB /* CommandResponseViewController.swift in Sources */,
15021509
434F545F1D288345002A9274 /* ShareService.swift in Sources */,
1510+
43441AA01EDB4D390087958C /* OSLog.swift in Sources */,
15031511
43CEE6E61E56AFD400CB9116 /* NightscoutUploader.swift in Sources */,
15041512
4328E0331CFC091100E199AA /* WatchContext+LoopKit.swift in Sources */,
15051513
4F526D611DF8D9A900A04910 /* NetBasal.swift in Sources */,

Loop/AppDelegate.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@ final class AppDelegate: UIResponder, UIApplicationDelegate {
2323

2424
NotificationManager.authorize(delegate: self)
2525

26-
AnalyticsManager.sharedManager.application(application, didFinishLaunchingWithOptions: launchOptions)
26+
let bundle = Bundle(for: type(of: self))
27+
DiagnosticLogger.shared = DiagnosticLogger(subsystem: bundle.bundleIdentifier!, version: bundle.shortVersionString)
28+
DiagnosticLogger.shared?.forCategory("AppDelegate").info(#function)
29+
30+
AnalyticsManager.shared.application(application, didFinishLaunchingWithOptions: launchOptions)
2731

2832
if let navVC = window?.rootViewController as? UINavigationController,
2933
let statusVC = navVC.viewControllers.first as? StatusTableViewController {
@@ -75,7 +79,7 @@ extension AppDelegate: UNUserNotificationCenterDelegate {
7579
let startDate = response.notification.request.content.userInfo[NotificationManager.UserInfoKey.bolusStartDate.rawValue] as? Date,
7680
startDate.timeIntervalSinceNow >= TimeInterval(minutes: -5)
7781
{
78-
AnalyticsManager.sharedManager.didRetryBolus()
82+
AnalyticsManager.shared.didRetryBolus()
7983

8084
deviceManager.enactBolus(units: units, at: startDate) { (_) in
8185
completionHandler()

Loop/Extensions/OSLog.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//
2+
// OSLog.swift
3+
// Loop
4+
//
5+
// Copyright © 2017 LoopKit Authors. All rights reserved.
6+
//
7+
8+
import os.log
9+
10+
11+
extension OSLog {
12+
func debug(_ message: StaticString, _ args: CVarArg...) {
13+
log(message, type: .debug, args)
14+
}
15+
16+
func info(_ message: StaticString, _ args: CVarArg...) {
17+
log(message, type: .info, args)
18+
}
19+
20+
func error(_ message: StaticString, _ args: CVarArg...) {
21+
log(message, type: .error, args)
22+
}
23+
24+
private func log(_ message: StaticString, type: OSLogType, _ args: CVarArg...) {
25+
os_log(message, log: self, type: type, args)
26+
}
27+
}

Loop/Managers/AnalyticsManager.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ final class AnalyticsManager {
2626
}
2727
}
2828

29-
static let sharedManager = AnalyticsManager()
29+
static let shared = AnalyticsManager()
3030

3131
// MARK: - Helpers
3232

Loop/Managers/DeviceDataManager.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ final class DeviceDataManager {
2323

2424
// MARK: - Utilities
2525

26-
let logger = DiagnosticLogger()
26+
let logger = DiagnosticLogger.shared!
2727

2828
/// Remember the launch date of the app for diagnostic reporting
2929
fileprivate let launchDate = Date()
@@ -61,7 +61,7 @@ final class DeviceDataManager {
6161
}
6262

6363
if let oldVal = oldVal, newVal - oldVal >= 0.5 {
64-
AnalyticsManager.sharedManager.pumpBatteryWasReplaced()
64+
AnalyticsManager.shared.pumpBatteryWasReplaced()
6565
}
6666
}
6767
}
@@ -93,7 +93,7 @@ final class DeviceDataManager {
9393
case is MySentryAlertMessageBody, is MySentryAlertClearedMessageBody:
9494
break
9595
case let body:
96-
logger.addMessage(["messageType": Int(message.messageType.rawValue), "messageBody": body.txData.hexadecimalString], toCollection: "sentryOther")
96+
logger.forCategory("MySentry").info(["messageType": Int(message.messageType.rawValue), "messageBody": body.txData.hexadecimalString])
9797
}
9898
default:
9999
break
@@ -112,15 +112,15 @@ final class DeviceDataManager {
112112

113113
rileyLinkManager.connectDevice(device)
114114

115-
AnalyticsManager.sharedManager.didChangeRileyLinkConnectionState()
115+
AnalyticsManager.shared.didChangeRileyLinkConnectionState()
116116
}
117117

118118
func disconnectFromRileyLink(_ device: RileyLinkDevice) {
119119
connectedPeripheralIDs.remove(device.peripheral.identifier.uuidString)
120120

121121
rileyLinkManager.disconnectDevice(device)
122122

123-
AnalyticsManager.sharedManager.didChangeRileyLinkConnectionState()
123+
AnalyticsManager.shared.didChangeRileyLinkConnectionState()
124124

125125
if connectedPeripheralIDs.count == 0 {
126126
NotificationManager.clearPendingNotificationRequests()
@@ -246,7 +246,7 @@ final class DeviceDataManager {
246246
}
247247

248248
if newValue.unitVolume > previousVolume + 1 {
249-
AnalyticsManager.sharedManager.reservoirWasRewound()
249+
AnalyticsManager.shared.reservoirWasRewound()
250250
}
251251
}
252252
}

Loop/Managers/DiagnosticLogger+LoopKit.swift

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,14 @@ import LoopKit
1313

1414
extension DiagnosticLogger {
1515
func addError(_ message: String, fromSource source: String) {
16-
let info = [
17-
"source": source,
18-
"message": message,
19-
"reportedAt": DateFormatter.ISO8601StrictDateFormatter().string(from: Date())
16+
let message = [
17+
"message": message
2018
]
2119

22-
addMessage(info, toCollection: "errors")
20+
forCategory(source).error(message)
2321
}
2422

2523
func addError(_ message: Error, fromSource source: String) {
26-
addError(String(describing: message), fromSource: source)
24+
forCategory(source).error(message)
2725
}
2826
}

Loop/Managers/DiagnosticLogger.swift

Lines changed: 111 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,34 +7,135 @@
77
//
88

99
import Foundation
10+
import os.log
1011

1112

1213
final class DiagnosticLogger {
13-
private lazy var isSimulator: Bool = TARGET_OS_SIMULATOR != 0
14+
private let isSimulator: Bool = TARGET_OS_SIMULATOR != 0
15+
let subsystem: String
16+
let version: String
1417

1518
var mLabService: MLabService {
1619
didSet {
1720
try! KeychainManager().setMLabDatabaseName(mLabService.databaseName, APIKey: mLabService.APIKey)
1821
}
1922
}
2023

21-
init() {
24+
var logglyService: LogglyService {
25+
didSet {
26+
try! KeychainManager().setLogglyCustomerToken(logglyService.customerToken)
27+
}
28+
}
29+
30+
let remoteLogLevel: OSLogType
31+
32+
static var shared: DiagnosticLogger?
33+
34+
init(subsystem: String, version: String) {
35+
self.subsystem = subsystem
36+
self.version = version
37+
remoteLogLevel = isSimulator ? .fault : .info
38+
2239
if let (databaseName, APIKey) = KeychainManager().getMLabCredentials() {
2340
mLabService = MLabService(databaseName: databaseName, APIKey: APIKey)
2441
} else {
2542
mLabService = MLabService(databaseName: nil, APIKey: nil)
2643
}
44+
45+
let customerToken = KeychainManager().getLogglyCustomerToken()
46+
logglyService = LogglyService(customerToken: customerToken)
2747
}
2848

29-
func addMessage(_ message: [String: Any], toCollection collection: String) {
30-
if !isSimulator,
31-
let messageData = try? JSONSerialization.data(withJSONObject: message, options: []),
32-
let task = mLabService.uploadTaskWithData(messageData, inCollection: collection)
33-
{
34-
task.resume()
35-
} else {
36-
NSLog("%@: %@", collection, message)
49+
func forCategory(_ category: String) -> CategoryLogger {
50+
return CategoryLogger(logger: self, category: category)
51+
}
52+
}
53+
54+
55+
extension OSLogType {
56+
fileprivate var tagName: String {
57+
switch self {
58+
case let t where t == .info:
59+
return "info"
60+
case let t where t == .debug:
61+
return "debug"
62+
case let t where t == .error:
63+
return "error"
64+
case let t where t == .fault:
65+
return "fault"
66+
default:
67+
return "default"
68+
}
69+
}
70+
}
71+
72+
73+
final class CategoryLogger {
74+
private let logger: DiagnosticLogger
75+
let category: String
76+
77+
private let systemLog: OSLog
78+
79+
fileprivate init(logger: DiagnosticLogger, category: String) {
80+
self.logger = logger
81+
self.category = category
82+
83+
systemLog = OSLog(subsystem: logger.subsystem, category: category)
84+
}
85+
86+
private func remoteLog(_ type: OSLogType, message: String) {
87+
guard logger.remoteLogLevel.rawValue <= type.rawValue else {
88+
return
89+
}
90+
91+
logger.logglyService.client?.send(message, tags: [type.tagName, category])
92+
}
93+
94+
private func remoteLog(_ type: OSLogType, message: [String: Any]) {
95+
guard logger.remoteLogLevel.rawValue <= type.rawValue else {
96+
return
3797
}
98+
99+
logger.logglyService.client?.send(message, tags: [type.tagName, category])
100+
101+
// Legacy mLab logging. To be removed.
102+
if let messageData = try? JSONSerialization.data(withJSONObject: message, options: []) {
103+
logger.mLabService.uploadTaskWithData(messageData, inCollection: category)?.resume()
104+
}
105+
}
106+
107+
func debug(_ message: [String: Any]) {
108+
systemLog.debug("%{public}@", String(describing: message))
109+
remoteLog(.debug, message: message)
110+
}
111+
112+
func debug(_ message: String) {
113+
systemLog.error("%{public}@", message)
114+
remoteLog(.debug, message: message)
115+
}
116+
117+
func info(_ message: [String: Any]) {
118+
systemLog.info("%{public}@", String(describing: message))
119+
remoteLog(.info, message: message)
120+
}
121+
122+
func info(_ message: String) {
123+
systemLog.error("%{public}@", message)
124+
remoteLog(.info, message: message)
125+
}
126+
127+
func error(_ message: [String: Any]) {
128+
systemLog.error("%{public}@", String(reflecting: message))
129+
remoteLog(.error, message: message)
130+
}
131+
132+
func error(_ message: String) {
133+
systemLog.error("%{public}@", message)
134+
remoteLog(.error, message: message)
135+
}
136+
137+
func error(_ error: Error) {
138+
self.error(String(reflecting: error))
38139
}
39140
}
40141

Loop/Managers/KeychainManager+Loop.swift

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,11 @@
99
import Foundation
1010

1111

12-
private let AmplitudeAPIKeyService = "AmplitudeAPIKey"
1312
private let DexcomShareURL = URL(string: "https://share1.dexcom.com")!
1413
private let NightscoutAccount = "NightscoutAPI"
1514

1615

1716
extension KeychainManager {
18-
func setAmplitudeAPIKey(_ key: String?) throws {
19-
try replaceGenericPassword(key, forService: AmplitudeAPIKeyService)
20-
}
21-
22-
func getAmplitudeAPIKey() -> String? {
23-
return try? getGenericPasswordForService(AmplitudeAPIKeyService)
24-
}
25-
2617
func setDexcomShareUsername(_ username: String?, password: String?) throws {
2718
let credentials: InternetCredentials?
2819

0 commit comments

Comments
 (0)