Skip to content

Commit

Permalink
(ios) swift-log integration
Browse files Browse the repository at this point in the history
  • Loading branch information
robbiehanson authored and dpad85 committed Feb 13, 2024
1 parent 9ef8fb4 commit 8b68d1c
Show file tree
Hide file tree
Showing 132 changed files with 1,941 additions and 792 deletions.
85 changes: 85 additions & 0 deletions phoenix-ios/phoenix-ios.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,15 @@
"version" : "2.1.1"
}
},
{
"identity" : "swift-log",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-log.git",
"state" : {
"revision" : "e97a6fcb1ab07462881ac165fdbb37f067e205d5",
"version" : "1.5.4"
}
},
{
"identity" : "swift-protobuf",
"kind" : "remoteSourceControl",
Expand Down
9 changes: 3 additions & 6 deletions phoenix-ios/phoenix-ios/AppDelegate.swift
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import UIKit
import PhoenixShared
import os.log
import Firebase
import Combine
import BackgroundTasks

fileprivate let filename = "AppDelegate"
#if DEBUG && true
fileprivate var log = Logger(
subsystem: Bundle.main.bundleIdentifier!,
category: "AppDelegate"
)
fileprivate var log = LoggerFactory.shared.logger(filename, .trace)
#else
fileprivate var log = Logger(OSLog.disabled)
fileprivate var log = LoggerFactory.shared.logger(filename, .warning)
#endif


Expand Down
10 changes: 3 additions & 7 deletions phoenix-ios/phoenix-ios/MVI/MVI.swift
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
import SwiftUI
import PhoenixShared
import Combine
import os.log

fileprivate let filename = "MVI"
#if DEBUG && false
fileprivate var log = Logger(
subsystem: Bundle.main.bundleIdentifier!,
category: "MVI"
)
fileprivate var log = LoggerFactory.shared.logger(filename, .trace)
#else
fileprivate var log = Logger(OSLog.disabled)
fileprivate var log = LoggerFactory.shared.logger(filename, .warning)
#endif


class MVIState<Model: MVI.Model, Intent: MVI.Intent>: ObservableObject {

private var _initialModel: Model? = nil
Expand Down
10 changes: 4 additions & 6 deletions phoenix-ios/phoenix-ios/SceneDelegate.swift
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import UIKit
import SwiftUI
import Combine
import os.log


fileprivate let filename = "SceneDelegate"
#if DEBUG && true
fileprivate var log = Logger(
subsystem: Bundle.main.bundleIdentifier!,
category: "SceneDelegate"
)
fileprivate let log = LoggerFactory.shared.logger(filename, .trace)
#else
fileprivate var log = Logger(OSLog.disabled)
fileprivate var log = LoggerFactory.shared.logger(filename, .warning)
#endif

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
Expand Down
9 changes: 3 additions & 6 deletions phoenix-ios/phoenix-ios/kotlin/KotlinFutures.swift
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import Foundation
import Combine
import PhoenixShared
import os.log

fileprivate let filename = "KotlinFutures"
#if DEBUG && true
fileprivate var log = Logger(
subsystem: Bundle.main.bundleIdentifier!,
category: "KotlinFutures"
)
fileprivate var log = LoggerFactory.shared.logger(filename, .trace)
#else
fileprivate var log = Logger(OSLog.disabled)
fileprivate var log = LoggerFactory.shared.logger(filename, .warning)
#endif

extension DatabaseManager {
Expand Down
31 changes: 23 additions & 8 deletions phoenix-ios/phoenix-ios/kotlin/KotlinLogger.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Foundation
import PhoenixShared
import os.log
import Logging


class KotlinLogger {

Expand All @@ -16,15 +17,29 @@ class KotlinLogger {

private func splitTag(_ tag: String) -> (String, String) {

// The tag is something like: "PhoenixShared.PhoenixBusiness.BalanceManager"
// We want to split that into ("PhoenixShared.PhoenixBusiness", "BalanceManager")
// The tag is something like:
// - "fr.acinq.lightning.blockchain.electrum.ElectrumWatcher"
// - "fr.acinq.phoenix.managers.CurrencyManager"
//
// We want to split this into something like:
// - ("lightning-kmp", "ElectrumWatcher")
// - ("phoenix-kmp", "CurrencyManager")
//
// So there's a clear: (module, filename)

if let idx = tag.lastIndex(of: ".") {
let idxPlusOne = tag.index(after: idx)
if idxPlusOne != tag.endIndex {
let subsystem = String(tag.prefix(upTo: idx))
let category = String(tag.suffix(from: idxPlusOne))
return (subsystem, category)
let subsystem = tag.prefix(upTo: idx)
let filename = String(tag.suffix(from: idxPlusOne))

if subsystem.hasPrefix("fr.acinq.lightning") {
return ("lightning-kmp", filename)
} else if subsystem.hasPrefix("fr.acinq.phoenix") {
return ("phoenix-kmp", filename)
} else {
return (String(subsystem), filename)
}
}
}

Expand All @@ -37,8 +52,8 @@ class KotlinLogger {
return cachedLogger
}

let (subsystem, category) = splitTag(tag)
let newLogger = Logger(subsystem: subsystem, category: category)
let (module, filename) = self.splitTag(tag)
let newLogger = LoggerFactory.shared.logger(module: module, filename: filename, level: .trace)
loggers[tag] = newLogger

return newLogger
Expand Down
10 changes: 3 additions & 7 deletions phoenix-ios/phoenix-ios/kotlin/KotlinObservables.swift
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
import Foundation
import Combine
import PhoenixShared
import os.log

fileprivate let filename = "KotlinObservables"
#if DEBUG && true
fileprivate var log = Logger(
subsystem: Bundle.main.bundleIdentifier!,
category: "KotlinObservables"
)
fileprivate var log = LoggerFactory.shared.logger(filename, .trace)
#else
fileprivate var log = Logger(OSLog.disabled)
fileprivate var log = LoggerFactory.shared.logger(filename, .warning)
#endif


class ObservableConnectionsMonitor: ObservableObject {

@Published var connections: Connections
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import Foundation
import Combine
import PhoenixShared
import os.log

fileprivate let filename = "KotlinPublishers+Lightning"
#if DEBUG && true
fileprivate var log = Logger(
subsystem: Bundle.main.bundleIdentifier!,
category: "KotlinPublishers+Lightning"
)
fileprivate var log = LoggerFactory.shared.logger(filename, .trace)
#else
fileprivate var log = Logger(OSLog.disabled)
fileprivate var log = LoggerFactory.shared.logger(filename, .warning)
#endif

extension Lightning_kmpPeer {
Expand Down
9 changes: 3 additions & 6 deletions phoenix-ios/phoenix-ios/kotlin/KotlinPublishers+Phoenix.swift
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import Foundation
import Combine
import PhoenixShared
import os.log

fileprivate let filename = "KotlinPublishers+Phoenix"
#if DEBUG && true
fileprivate var log = Logger(
subsystem: Bundle.main.bundleIdentifier!,
category: "KotlinPublishers+Phoenix"
)
fileprivate var log = LoggerFactory.shared.logger(filename, .trace)
#else
fileprivate var log = Logger(OSLog.disabled)
fileprivate var log = LoggerFactory.shared.logger(filename, .warning)
#endif

extension PeerManager {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Foundation

/// This file is **ONLY** for the Notify-Service-Extension (background process)
///
extension LoggerFactory {
class var friendlyProcessName: String {
return friendlyProcessName_background
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Foundation

/// This file is **ONLY** for the main Phoenix app
///
extension LoggerFactory {
class var friendlyProcessName: String {
return friendlyProcessName_foreground
}
}
146 changes: 146 additions & 0 deletions phoenix-ios/phoenix-ios/logging/LoggerFactory.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import Foundation
import Logging

class LoggerFactory {

static let shared = LoggerFactory()

private let logFileManager: LogFileManager

private init() { // must use shared instance

let logsDir = try! LoggerFactory.logsDirectory()
let formatter = LoggerFactory.formatter()

logFileManager = LogFileManager(
logsDirectory: logsDir,
logFilePrefix: LoggerFactory.logFilePrefix,
rollingConfig: LogFileManager.RollingConfiguration(
maximumFileSize: 1024 * 1024 * 2, // 2 MiB,
rollingFrequency: 60 * 60 * 24, // 24 hours,
rollOnAppLaunch: false // allow log files to span app launches
),
cleanupConfig: LogFileManager.CleanupConfiguration(
maximumNumberOfLogFiles: 8, // 8 archived log files (+ current log file)
logFilesDiskQuota: 1024 * 1024 * 20 // 20 MiB
),
formatter: formatter
)

logFileManager.prepare()
}

class var friendlyProcessName_foreground: String {
return "Phoenix"
}

class var friendlyProcessName_background: String {
return "NotifySrvExt"
}

class var logFilePrefix: String {
return "\(self.friendlyProcessName)-"
}

class func logsDirectory() throws -> URL {

let sharedDir = FileManager.default.containerURL(
forSecurityApplicationGroupIdentifier: "group.co.acinq.phoenix"
)!

let logsDir: URL
if #available(iOS 16.0, *) {
logsDir = sharedDir.appending(path: "logs", directoryHint: .isDirectory)
} else {
logsDir = sharedDir.appendingPathComponent("logs", isDirectory: true)
}

try FileManager.default.createDirectory(at: logsDir, withIntermediateDirectories: true)
return logsDir
}

class func formatter() -> LogFormatter {

let pi = ProcessInfo.processInfo
let pid = pi.processIdentifier
let df = ISO8601DateFormatter()

let formatter = {(
level: Logging.Logger.Level,
message: String,
module: String,
filename: String
) -> String in

let ts = df.string(from: Date.now)
let lvl = level.logFileAbbreviation
let tid = Thread.currentThreadID

return "[\(ts)] [\(pid):\(tid)] [\(module)/\(filename)] [\(lvl)] \(message)"
}

return formatter
}

func handler(module: String, filename: String) -> LogHandler {

let osLogHandler = OSLogHandler(module: module, filename: filename)
let fileHandler = LogFileHandler(module: module, filename: filename, logFileManager: logFileManager)

return MultiplexLogHandler([osLogHandler, fileHandler])
}

func logger(module: String, filename: String, level: Logger.Level) -> Logger {

// the Logger's label works similarly to a DispatchQueue label
let label = "\(module)/\(filename)"

var logger = Logger(label: label) { _ in
handler(module: module, filename: filename)
}
logger.logLevel = level
return logger
}

func logger(_ filename: String, _ level: Logger.Level) -> Logger {
return logger(module: "swift", filename: filename, level: level)
}
}

extension Logging.Logger.Level {
var logFileAbbreviation: String {
switch self {
case .trace : return "T"
case .debug : return "D"
case .info : return "I"
case .notice : return "N"
case .warning : return "W"
case .error : return "E"
case .critical : return "C"
}
}

static func fromLogFileAbbreviation(_ str: String) -> Logging.Logger.Level? {
switch str {
case "T" : return .trace
case "D" : return .debug
case "I" : return .info
case "N" : return .notice
case "W" : return .warning
case "E" : return .error
case "C" : return .critical
default : return nil
}
}
}

extension Thread {
class var currentThreadID: String {
var tid: __uint64_t = 0
if (pthread_threadid_np(nil, &tid) == 0) {
return "\(tid)"
} else {
return "?"
}
}
}
Loading

0 comments on commit 8b68d1c

Please sign in to comment.