2026-06-19 03:38:22 +08:00
|
|
|
import Foundation
|
|
|
|
|
|
|
|
|
|
/// 日志队列 - 内存队列 + 定时上传
|
|
|
|
|
final class LogQueue {
|
|
|
|
|
|
|
|
|
|
private let appKey: String
|
|
|
|
|
private let sdkName: String
|
|
|
|
|
private let sdkVersion: String
|
|
|
|
|
private let uploader: LogUploader
|
|
|
|
|
|
|
|
|
|
private var queue: [Any] = []
|
|
|
|
|
private let queueLock = NSLock()
|
|
|
|
|
private var timer: Timer?
|
|
|
|
|
private let flushInterval: TimeInterval = 30
|
|
|
|
|
private let maxQueueSize = 50
|
|
|
|
|
|
|
|
|
|
init(appKey: String, sdkName: String, sdkVersion: String) {
|
|
|
|
|
self.appKey = appKey
|
|
|
|
|
self.sdkName = sdkName
|
|
|
|
|
self.sdkVersion = sdkVersion
|
|
|
|
|
self.uploader = LogUploader(appKey: appKey)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// 启动定时上传
|
|
|
|
|
func start() {
|
|
|
|
|
// 上传待处理的崩溃
|
|
|
|
|
uploadPendingCrashes()
|
|
|
|
|
|
|
|
|
|
// 启动定时器
|
|
|
|
|
timer = Timer.scheduledTimer(withTimeInterval: flushInterval, repeats: true) { [weak self] _ in
|
|
|
|
|
self?.flush()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// 停止队列
|
|
|
|
|
func stop() {
|
|
|
|
|
timer?.invalidate()
|
|
|
|
|
timer = nil
|
|
|
|
|
flush()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// 推送事件
|
|
|
|
|
func push(_ event: Any) {
|
|
|
|
|
queueLock.lock()
|
|
|
|
|
queue.append(event)
|
|
|
|
|
let count = queue.count
|
|
|
|
|
queueLock.unlock()
|
|
|
|
|
|
|
|
|
|
// 达到阈值时自动上传
|
|
|
|
|
if count >= maxQueueSize {
|
|
|
|
|
flush()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// 刷新队列
|
|
|
|
|
private func flush() {
|
|
|
|
|
queueLock.lock()
|
|
|
|
|
let events = queue
|
|
|
|
|
queue = []
|
|
|
|
|
queueLock.unlock()
|
|
|
|
|
|
|
|
|
|
guard !events.isEmpty else { return }
|
|
|
|
|
|
|
|
|
|
// 分离 issues 和 events
|
|
|
|
|
var issues: [IssueEvent] = []
|
|
|
|
|
var logEvents: [LogEvent] = []
|
|
|
|
|
|
|
|
|
|
for event in events {
|
|
|
|
|
if let issue = event as? IssueEvent {
|
|
|
|
|
issues.append(issue)
|
|
|
|
|
} else if let logEvent = event as? LogEvent {
|
|
|
|
|
logEvents.append(logEvent)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 上传 issues
|
|
|
|
|
if !issues.isEmpty {
|
|
|
|
|
uploader.uploadIssues(issues)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 上传 events
|
|
|
|
|
if !logEvents.isEmpty {
|
|
|
|
|
uploader.uploadEvents(logEvents)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// 上传待处理的崩溃
|
|
|
|
|
private func uploadPendingCrashes() {
|
2026-06-29 11:28:18 +08:00
|
|
|
let crashes = LogStorage.loadPendingCrashes()
|
2026-06-19 03:38:22 +08:00
|
|
|
guard !crashes.isEmpty else { return }
|
|
|
|
|
|
2026-06-29 11:28:18 +08:00
|
|
|
uploader.uploadIssues(crashes) { success in
|
2026-06-19 03:38:22 +08:00
|
|
|
if success {
|
2026-06-29 11:28:18 +08:00
|
|
|
LogStorage.clearPendingCrashes()
|
2026-06-19 03:38:22 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|