feat(ios): add cross-instance log center
This commit is contained in:
@@ -0,0 +1,200 @@
|
||||
import Foundation
|
||||
|
||||
public enum RuntimeLogSource: String, Codable, Equatable, Sendable, CaseIterable {
|
||||
case delivery
|
||||
|
||||
public var label: String {
|
||||
switch self {
|
||||
case .delivery: return "通知投递"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum RuntimeLogLevel: String, Codable, Equatable, Sendable, CaseIterable {
|
||||
case info
|
||||
case warning
|
||||
case error
|
||||
|
||||
public var label: String {
|
||||
switch self {
|
||||
case .info: return "信息"
|
||||
case .warning: return "警告"
|
||||
case .error: return "错误"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum ConnectionOutcome: String, Codable, Equatable, Sendable, CaseIterable {
|
||||
case success
|
||||
case stale
|
||||
case failed
|
||||
case unsupported
|
||||
|
||||
public var label: String {
|
||||
switch self {
|
||||
case .success: return "成功"
|
||||
case .stale: return "需登录"
|
||||
case .failed: return "失败"
|
||||
case .unsupported: return "不支持"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public struct RuntimeLogEntry: Codable, Equatable, Identifiable, Sendable {
|
||||
public let id: String
|
||||
public let source: RuntimeLogSource
|
||||
public let level: RuntimeLogLevel
|
||||
public let message: String
|
||||
public let eventType: String?
|
||||
public let instanceID: UUID?
|
||||
public let instanceName: String?
|
||||
public let occurredAt: Date
|
||||
public let code: String?
|
||||
public let durationMs: Int?
|
||||
|
||||
public init(
|
||||
id: String,
|
||||
source: RuntimeLogSource,
|
||||
level: RuntimeLogLevel,
|
||||
message: String,
|
||||
eventType: String? = nil,
|
||||
instanceID: UUID? = nil,
|
||||
instanceName: String? = nil,
|
||||
occurredAt: Date,
|
||||
code: String? = nil,
|
||||
durationMs: Int? = nil
|
||||
) {
|
||||
self.id = id
|
||||
self.source = source
|
||||
self.level = level
|
||||
self.message = message
|
||||
self.eventType = eventType
|
||||
self.instanceID = instanceID
|
||||
self.instanceName = instanceName
|
||||
self.occurredAt = occurredAt
|
||||
self.code = code
|
||||
self.durationMs = durationMs
|
||||
}
|
||||
}
|
||||
|
||||
public struct ConnectionLogEntry: Codable, Equatable, Identifiable, Sendable {
|
||||
public let id: String
|
||||
public let instanceID: UUID
|
||||
public let instanceName: String
|
||||
public let outcome: ConnectionOutcome
|
||||
public let state: String
|
||||
public let errorCode: String?
|
||||
public let httpStatus: Int?
|
||||
public let durationMs: Int
|
||||
public let observedAt: Date
|
||||
|
||||
public init(
|
||||
id: String,
|
||||
instanceID: UUID,
|
||||
instanceName: String,
|
||||
outcome: ConnectionOutcome,
|
||||
state: String,
|
||||
errorCode: String? = nil,
|
||||
httpStatus: Int? = nil,
|
||||
durationMs: Int,
|
||||
observedAt: Date
|
||||
) {
|
||||
self.id = id
|
||||
self.instanceID = instanceID
|
||||
self.instanceName = instanceName
|
||||
self.outcome = outcome
|
||||
self.state = state
|
||||
self.errorCode = errorCode
|
||||
self.httpStatus = httpStatus
|
||||
self.durationMs = durationMs
|
||||
self.observedAt = observedAt
|
||||
}
|
||||
}
|
||||
|
||||
public struct LogCapabilitySummary: Equatable, Sendable {
|
||||
public let total: Int
|
||||
public let supported: Int
|
||||
public let unsupported: Int
|
||||
public let authRequired: Int
|
||||
public let degraded: Int
|
||||
public let unknown: Int
|
||||
|
||||
public init(
|
||||
total: Int,
|
||||
supported: Int,
|
||||
unsupported: Int,
|
||||
authRequired: Int,
|
||||
degraded: Int,
|
||||
unknown: Int
|
||||
) {
|
||||
self.total = total
|
||||
self.supported = supported
|
||||
self.unsupported = unsupported
|
||||
self.authRequired = authRequired
|
||||
self.degraded = degraded
|
||||
self.unknown = unknown
|
||||
}
|
||||
}
|
||||
|
||||
public struct ConnectionSummary: Equatable, Sendable {
|
||||
public let total: Int
|
||||
public let success: Int
|
||||
public let failed: Int
|
||||
public let averageDurationMs: Int
|
||||
public let availabilityPercent: Int
|
||||
}
|
||||
|
||||
public struct InstanceDiagnostic: Equatable, Identifiable, Sendable {
|
||||
public let id: UUID
|
||||
public let name: String
|
||||
public let origin: String
|
||||
public let tags: [String]
|
||||
public let state: ConnectionStatus
|
||||
public let healthStatus: String?
|
||||
public let version: String?
|
||||
public let platform: String?
|
||||
public let observedAt: Date
|
||||
public let capabilities: LogCapabilitySummary
|
||||
public let connection: ConnectionSummary?
|
||||
|
||||
public init(
|
||||
id: UUID,
|
||||
name: String,
|
||||
origin: String,
|
||||
tags: [String],
|
||||
state: ConnectionStatus,
|
||||
healthStatus: String?,
|
||||
version: String?,
|
||||
platform: String?,
|
||||
observedAt: Date,
|
||||
capabilities: LogCapabilitySummary,
|
||||
connection: ConnectionSummary?
|
||||
) {
|
||||
self.id = id
|
||||
self.name = name
|
||||
self.origin = origin
|
||||
self.tags = tags
|
||||
self.state = state
|
||||
self.healthStatus = healthStatus
|
||||
self.version = version
|
||||
self.platform = platform
|
||||
self.observedAt = observedAt
|
||||
self.capabilities = capabilities
|
||||
self.connection = connection
|
||||
}
|
||||
}
|
||||
|
||||
public struct LogSnapshot: Equatable, Sendable {
|
||||
public let observedAt: Date
|
||||
public let runtime: [RuntimeLogEntry]
|
||||
public let counts: [RuntimeLogSource: Int]
|
||||
public let connections: [ConnectionLogEntry]
|
||||
public let diagnostics: [InstanceDiagnostic]
|
||||
}
|
||||
|
||||
public protocol LogStore: Sendable {
|
||||
func runtimeLogs() async throws -> [RuntimeLogEntry]
|
||||
func connectionLogs() async throws -> [ConnectionLogEntry]
|
||||
func append(runtime: [RuntimeLogEntry], connections: [ConnectionLogEntry]) async throws
|
||||
func pruneConnections(before: Date) async throws -> Int
|
||||
}
|
||||
Reference in New Issue
Block a user