diff --git a/Sources/Clickstream/Core/Data/Utilities/Reachability+Extension.swift b/Sources/Clickstream/Core/Data/Utilities/Reachability+Extension.swift index 0ad60b8..990d0aa 100644 --- a/Sources/Clickstream/Core/Data/Utilities/Reachability+Extension.swift +++ b/Sources/Clickstream/Core/Data/Utilities/Reachability+Extension.swift @@ -17,6 +17,7 @@ enum NetworkType: Equatable { case wwan2g case wwan3g case wwan4g + case wwan5g case unknownTechnology(name: String) var trackingId: String { @@ -27,6 +28,7 @@ enum NetworkType: Equatable { case .wwan2g: return "2G" case .wwan3g: return "3G" case .wwan4g: return "4G" + case .wwan5g: return "5G" case .unknownTechnology(let name): return "Unknown Technology: \"\(name)\"" } } @@ -51,7 +53,18 @@ extension Reachability { } internal static func getWWANNetworkType() -> NetworkType { - guard let currentRadioAccessTechnology = CTTelephonyNetworkInfo().currentRadioAccessTechnology else { return .unknown } + var _currentRadioAccessTechnology: String? = nil + if let accessTechnology = CTTelephonyNetworkInfo().serviceCurrentRadioAccessTechnology?.values.first{ + _currentRadioAccessTechnology = accessTechnology + } + + guard let currentRadioAccessTechnology = _currentRadioAccessTechnology else { return .unknown } + + if #available(iOS 14.1, *) { + if currentRadioAccessTechnology == CTRadioAccessTechnologyNRNSA || currentRadioAccessTechnology == CTRadioAccessTechnologyNR{ + return .wwan5g + } + } switch currentRadioAccessTechnology { case CTRadioAccessTechnologyGPRS, CTRadioAccessTechnologyEdge, @@ -70,5 +83,5 @@ extension Reachability { default: return .unknownTechnology(name: currentRadioAccessTechnology) } - } + } } diff --git a/Sources/Clickstream/EventScheduler/Core/EventWarehouser.swift b/Sources/Clickstream/EventScheduler/Core/EventWarehouser.swift index 682c8ce..9667a5a 100644 --- a/Sources/Clickstream/EventScheduler/Core/EventWarehouser.swift +++ b/Sources/Clickstream/EventScheduler/Core/EventWarehouser.swift @@ -63,7 +63,8 @@ extension DefaultEventWarehouser { #endif #if TRACKER_ENABLED let healthEvent = HealthAnalysisEvent(eventName: .ClickstreamEventCached, - eventGUID: event.guid) + eventGUID: event.guid, + eventCount: 1) if event.type != Constants.EventType.instant.rawValue { Tracker.sharedInstance?.record(event: healthEvent) } diff --git a/Sources/Clickstream/NetworkManager/Core/NetworkBuilder.swift b/Sources/Clickstream/NetworkManager/Core/NetworkBuilder.swift index 9086706..cabad51 100644 --- a/Sources/Clickstream/NetworkManager/Core/NetworkBuilder.swift +++ b/Sources/Clickstream/NetworkManager/Core/NetworkBuilder.swift @@ -71,7 +71,7 @@ extension DefaultNetworkBuilder { checkedSelf.trackHealthEvents(eventBatch: eventBatch, eventBatchData: data) } - + eventRequest.eventCount = eventBatch.events.count checkedSelf.retryMech.trackBatch(with: eventRequest) #if EVENT_VISUALIZER_ENABLED /// Update status of the event batch to sent to network @@ -114,7 +114,8 @@ extension DefaultNetworkBuilder { let healthEvent = HealthAnalysisEvent(eventName: .ClickstreamBatchSent, events: eventGUIDsString, - eventBatchGUID: eventBatch.uuid) + eventBatchGUID: eventBatch.uuid, + eventCount: eventBatch.events.count) Tracker.sharedInstance?.record(event: healthEvent) #endif } diff --git a/Sources/Clickstream/NetworkManager/Core/RetryMechanism.swift b/Sources/Clickstream/NetworkManager/Core/RetryMechanism.swift index 2ef2fd0..4746d09 100644 --- a/Sources/Clickstream/NetworkManager/Core/RetryMechanism.swift +++ b/Sources/Clickstream/NetworkManager/Core/RetryMechanism.swift @@ -255,7 +255,8 @@ extension DefaultRetryMechanism { var healthEvent: HealthAnalysisEvent! healthEvent = HealthAnalysisEvent(eventName: .ClickstreamWriteToSocketFailed, eventBatchGUID: eventRequest.guid, - reason: FailureReason.ParsingException.rawValue) + reason: FailureReason.ParsingException.rawValue, + eventCount: eventRequest.eventCount) Tracker.sharedInstance?.record(event: healthEvent) #if ETE_TEST_SUITE_ENABLED Clickstream.ackEvent = AckEventDetails(guid: eventRequest.guid, status: "Bad Request") @@ -269,7 +270,8 @@ extension DefaultRetryMechanism { #if TRACKER_ENABLED let healthEvent = HealthAnalysisEvent(eventName: .ClickstreamEventBatchErrorResponse, eventBatchGUID: eventRequest.guid, // eventRequest.guid is the batch GUID - reason: error.localizedDescription) + reason: error.localizedDescription, + eventCount: eventRequest.eventCount) Tracker.sharedInstance?.record(event: healthEvent) #if ETE_TEST_SUITE_ENABLED Clickstream.ackEvent = AckEventDetails(guid: eventRequest.guid, status: "\(error)") @@ -381,8 +383,9 @@ extension DefaultRetryMechanism { persistence.deleteOne(eventRequest.guid) #if TRACKER_ENABLED if Tracker.debugMode { - let healthEvent = HealthAnalysisEvent(eventName: .ClickstreamEventBatchTimeout, - eventBatchGUID: fetchedEventRequest.guid) + let healthEvent = HealthAnalysisEvent(eventName: .ClickstreamEventBatchDropped, + eventBatchGUID: fetchedEventRequest.guid, + eventCount: eventRequest.eventCount) Tracker.sharedInstance?.record(event: healthEvent) } #endif @@ -457,21 +460,6 @@ extension DefaultRetryMechanism { } // MARK: - Track Clickstream health. -extension DefaultRetryMechanism { - func trackHealthEvents(eventRequest: EventRequest) { - #if TRACKER_ENABLED - if Tracker.debugMode { - guard eventRequest.eventType != Constants.EventType.instant else { return } - - let healthEvent = HealthAnalysisEvent(eventName: .ClickstreamEventBatchSuccessAck, - eventBatchGUID: eventRequest.guid) - Tracker.sharedInstance?.record(event: healthEvent) - - } - #endif - } -} - extension DefaultRetryMechanism { func trackHealthAndPerformanceEvents(eventRequest: EventRequest, startTime: Date) { @@ -480,7 +468,8 @@ extension DefaultRetryMechanism { guard eventRequest.eventType != Constants.EventType.instant else { return } let healthEvent = HealthAnalysisEvent(eventName: .ClickstreamEventBatchSuccessAck, - eventBatchGUID: eventRequest.guid) + eventBatchGUID: eventRequest.guid, + eventCount: eventRequest.eventCount) Tracker.sharedInstance?.record(event: healthEvent) } diff --git a/Sources/Clickstream/NetworkManager/Domain/Entities/EventRequest.swift b/Sources/Clickstream/NetworkManager/Domain/Entities/EventRequest.swift index 12be104..e90c5f3 100644 --- a/Sources/Clickstream/NetworkManager/Domain/Entities/EventRequest.swift +++ b/Sources/Clickstream/NetworkManager/Domain/Entities/EventRequest.swift @@ -19,6 +19,7 @@ struct EventRequest: Codable, Equatable { var createdTimestamp: Date? var eventType: Constants.EventType? var isInternal: Bool? + var eventCount: Int init(guid: String, data: Data? = nil) { @@ -29,6 +30,7 @@ struct EventRequest: Codable, Equatable { self.createdTimestamp = Date() self.isInternal = false self.eventType = .realTime + self.eventCount = 0 } static func == (lhs: Self, rhs: Self) -> Bool { @@ -62,6 +64,7 @@ extension EventRequest: DatabasePersistable { t.column("data", .blob) t.column("retriesMade", .text).notNull() t.column("createdTimestamp", .datetime).notNull() + t.column("eventCount", .integer).notNull() } } } @@ -86,6 +89,13 @@ extension EventRequest: DatabasePersistable { t.add(column: "eventType", .text) } - return [("addsIsInternalToEventRequest", addsIsInternal), ("addsEventTypeToEventRequest", addsEventType)] + let addsEventCount: (TableAlteration) -> Void = { t in + t.add(column: "eventCount", .integer).notNull().defaults(to: 0) + } + + return [("addsIsInternalToEventRequest", addsIsInternal), + ("addsEventTypeToEventRequest", addsEventType), + ("addsEventCountToEventRequest", addsEventCount) + ] } } diff --git a/Sources/Tracker/Health/HealthAnalysisEvent.swift b/Sources/Tracker/Health/HealthAnalysisEvent.swift index 09e79c9..d9a3e89 100644 --- a/Sources/Tracker/Health/HealthAnalysisEvent.swift +++ b/Sources/Tracker/Health/HealthAnalysisEvent.swift @@ -45,12 +45,15 @@ struct HealthAnalysisEvent: Codable, Equatable, AnalysisEvent { private(set) var timeToConnection: String? + private(set) var eventCount: Int + init?(eventName: HealthEvents, events: String? = nil, eventGUID: String? = nil, eventBatchGUID: String? = nil, reason: String? = nil, - timeToConnection: String? = nil) { + timeToConnection: String? = nil, + eventCount: Int = 0) { // Don't initialize if debugMode is off guard Tracker.debugMode else { @@ -68,12 +71,13 @@ struct HealthAnalysisEvent: Codable, Equatable, AnalysisEvent { self.guid = UUID().uuidString self.sessionID = Tracker.sharedInstance?.commonProperties?.session.sessionId self.timeToConnection = timeToConnection + self.eventCount = eventCount self.trackedVia = Tracker.healthTrackingConfigs.trackedVia.rawValue } private enum CodingKeys : String, CodingKey { - case guid,eventName,eventType,timestamp,reason,eventGUID,eventBatchGUID,events,sessionID,trackedVia, timeToConnection + case guid,eventName,eventType,timestamp,reason,eventGUID,eventBatchGUID,events,sessionID,trackedVia, timeToConnection, eventCount } static func == (lhs: HealthAnalysisEvent, rhs: HealthAnalysisEvent) -> Bool { @@ -110,6 +114,8 @@ extension HealthAnalysisEvent: Notifiable { properties[TrackerConstant.clickstream_error_reason] = reason } + properties[TrackerConstant.clickstream_event_count] = eventCount + let dict: [String : Any] = [TrackerConstant.eventName: eventName.rawValue, TrackerConstant.eventProperties: properties] NotificationCenter.default.post(name: TrackerConstant.DebugEventsNotification, object: dict) @@ -130,6 +136,7 @@ extension HealthAnalysisEvent: DatabasePersistable { t.column("eventBatchGUID", .text) t.column("events", .text) t.column("sessionID", .text) + t.column("eventCount", .integer) } } } @@ -153,6 +160,10 @@ extension HealthAnalysisEvent: DatabasePersistable { t.add(column: "timeToConnection", .text) } - return [("addsTrackedViaToHealthEvent", addsTrackedVia), ("addsTimeToConnectionToHealthEvent", addsTimeToConnection)] + let addsEventCount: (TableAlteration) -> Void = { t in + t.add(column: "eventCount", .integer).defaults(to: 0) + } + + return [("addsTrackedViaToHealthEvent", addsTrackedVia), ("addsTimeToConnectionToHealthEvent", addsTimeToConnection), ("addsEventCountToHealthEvent", addsEventCount)] } } diff --git a/Sources/Tracker/Tracker.swift b/Sources/Tracker/Tracker.swift index afb8bdb..eacec11 100644 --- a/Sources/Tracker/Tracker.swift +++ b/Sources/Tracker/Tracker.swift @@ -221,11 +221,20 @@ public final class Tracker { } } } - + var eventCount = 0 + for e in eventNameBasedAggregation { + if e.eventCount > 0 { + eventCount += e.eventCount + } else { + eventCount = 0 + break /// break the loop and reset event count. If any one of the event has eventCount -1, final eventCount in aggregated event will be wrong and will be of no use + } + } + let eventBatchGuids = eventNameBasedAggregation.compactMap { $0.eventBatchGUID } var healthEvent = Gojek_Clickstream_Internal_Health.with { - $0.numberOfEvents = Int64(eventGuids.count) + $0.numberOfEvents = eventCount > 0 ? Int64(eventCount) : Int64(eventGuids.count) $0.numberOfBatches = Int64(eventBatchGuids.count) $0.healthMeta = metaData $0.healthMeta.eventGuid = eventGuid diff --git a/Sources/Tracker/Utilities/TrackerConstants.swift b/Sources/Tracker/Utilities/TrackerConstants.swift index 61d3920..b59d4c7 100644 --- a/Sources/Tracker/Utilities/TrackerConstants.swift +++ b/Sources/Tracker/Utilities/TrackerConstants.swift @@ -26,7 +26,7 @@ enum HealthEvents: String, Codable, CaseIterable { case ClickstreamEventBatchTriggerFailed = "Clickstream Event Batch Trigger Failed" case ClickstreamWriteToSocketFailed = "Clickstream Write to Socket Failed" case ClickstreamEventBatchErrorResponse = "Clickstream Event Batch Error response" - case ClickstreamEventBatchTimeout = "Clickstream Event Batch Timeout" + case ClickstreamEventBatchDropped = "Clickstream Event Batch Dropped" case ClickstreamConnectionSuccess = "Clickstream Connection Success" case ClickstreamConnectionFailure = "Clickstream Connection Failure" @@ -88,5 +88,5 @@ public struct TrackerConstant { case aggregate = "aggregate" } - static let InstantEvents: [HealthEvents] = [.ClickstreamEventBatchTimeout, .ClickstreamConnectionSuccess, .ClickstreamConnectionFailure, .ClickstreamEventBatchErrorResponse, .ClickstreamWriteToSocketFailed, .ClickstreamEventBatchTriggerFailed] + static let InstantEvents: [HealthEvents] = [.ClickstreamEventBatchDropped, .ClickstreamConnectionSuccess, .ClickstreamConnectionFailure, .ClickstreamEventBatchErrorResponse, .ClickstreamWriteToSocketFailed, .ClickstreamEventBatchTriggerFailed] }