Files
multi-simadmin/apps/ios/Sources/MultiSimAdmin/Features/Logs/LogCenterModels.swift
T
chick e01a105645 feat(ios): simplify navigation and ship 0.2.0
Move diagnostics into settings, remove the app-local notification module, unify the global theme switcher, refine privacy copy and the instance detail experience, and rebuild the app icon.
2026-09-12 17:10:02 +08:00

219 lines
5.8 KiB
Swift

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 featureStatus: [FeatureStatus]
public let connection: ConnectionSummary?
public init(
id: UUID,
name: String,
origin: String,
tags: [String],
state: ConnectionStatus,
healthStatus: String?,
version: String?,
platform: String?,
observedAt: Date,
featureStatus: [FeatureStatus],
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.featureStatus = featureStatus
self.connection = connection
}
}
public struct FeatureStatus: Equatable, Identifiable, Sendable {
public enum State: Equatable, Sendable {
case ready
case requiresLogin
case unavailable
}
public var id: String { name }
public let name: String
public let state: State
public init(name: String, state: State) {
self.name = name
self.state = state
}
}
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
func clearRuntimeLogs() async throws -> Int
}