Ios log 4 (#569)

iOS logging refactoring
This commit is contained in:
isamnezia 2024-02-10 19:44:55 +03:00 committed by GitHub
parent f2d13148a3
commit 158c11a0ec
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 252 additions and 93 deletions

View file

@ -0,0 +1,82 @@
import Foundation
import os.log
struct Log {
private static let IsLoggingEnabledKey = "IsLoggingEnabled"
static var isLoggingEnabled: Bool {
get {
sharedUserDefaults.bool(forKey: IsLoggingEnabledKey)
}
set {
sharedUserDefaults.setValue(newValue, forKey: IsLoggingEnabledKey)
}
}
private static let appGroupID = "group.org.amnezia.AmneziaVPN"
static let neLogURL = {
let sharedContainerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupID)!
return sharedContainerURL.appendingPathComponent("ne.log", isDirectory: false)
}()
private static var sharedUserDefaults = {
UserDefaults(suiteName: appGroupID)!
}()
static let dateFormatter: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
return dateFormatter
}()
var records: [Record]
init() {
self.records = []
}
init(_ str: String) {
self.records = str.split(whereSeparator: \.isNewline)
.compactMap {
Record(String($0))!
}
}
init?(at url: URL) {
if !FileManager.default.fileExists(atPath: url.path) {
guard let _ = try? "".data(using: .utf8)?.write(to: url) else { return nil }
}
guard let fileHandle = try? FileHandle(forUpdating: url) else { return nil }
defer { fileHandle.closeFile() }
guard
let data = try? fileHandle.readToEnd(),
let str = String(data: data, encoding: .utf8) else {
return nil
}
self.init(str)
}
static func clear(at url: URL) {
if FileManager.default.fileExists(atPath: url.path) {
guard let fileHandle = try? FileHandle(forUpdating: url) else { return }
defer { fileHandle.closeFile() }
try? fileHandle.truncate(atOffset: 0)
}
}
}
extension Log: CustomStringConvertible {
var description: String {
records
.map {
$0.description
}
.joined(separator: "\n")
}
}

View file

@ -0,0 +1,26 @@
import Foundation
public func swiftUpdateLogData(_ qtString: std.string) -> std.string {
let qtLog = Log(String(describing: qtString))
var log = qtLog
if let neLog = Log(at: Log.neLogURL) {
neLog.records.forEach {
log.records.append($0)
}
log.records.sort {
$0.date < $1.date
}
}
return std.string(log.description)
}
public func swiftDeleteLog() {
Log.clear(at: Log.neLogURL)
}
public func toggleLogging(_ isEnabled: Bool) {
Log.isLoggingEnabled = isEnabled
}

View file

@ -0,0 +1,82 @@
import Foundation
import os.log
extension Log {
struct Record {
let date: Date
let level: Level
let message: String
init?(_ str: String) {
let dateStr = String(str.prefix(19))
guard let date = Log.dateFormatter.date(from: dateStr) else { return nil }
let str = str.dropFirst(20)
guard let endIndex = str.firstIndex(of: " ") else { return nil }
let levelStr = String(str[str.startIndex..<endIndex])
guard let level = Level(rawValue: levelStr) else { return nil }
let messageStartIndex = str.index(after: endIndex)
let message = String(str[messageStartIndex..<str.endIndex])
self.init(date: date, level: level, message: message)
}
init(date: Date, level: Level, message: String) {
self.date = date
self.level = level
self.message = message
}
func save(at url: URL) {
guard let data = "\n\(description)".data(using: .utf8) else { return }
if !FileManager.default.fileExists(atPath: url.path) {
guard let _ = try? "".data(using: .utf8)?.write(to: url) else { return }
}
guard let fileHandle = try? FileHandle(forUpdating: url) else { return }
defer { fileHandle.closeFile() }
guard let _ = try? fileHandle.seekToEnd() else { return }
try? fileHandle.write(contentsOf: data)
}
}
}
extension Log.Record: CustomStringConvertible {
var description: String {
"\(Log.dateFormatter.string(from: date)) \(level.rawValue) \(message)"
}
}
extension Log.Record {
enum Level: String {
case debug
case warning
case error
case critical
case fatal
case info
case system // critical
init(from osLogType: OSLogType) {
switch osLogType {
case OSLogType.default:
self = .info
case OSLogType.info:
self = .info
case OSLogType.debug:
self = .debug
case OSLogType.error:
self = .error
case OSLogType.fault:
self = .fatal
default:
self = .info
}
}
}
}

View file

@ -0,0 +1,20 @@
import Foundation
import os.log
public func wg_log(_ type: OSLogType, staticMessage: StaticString) {
guard Log.isLoggingEnabled else { return }
Log.Record(date: Date(), level: Log.Record.Level(from: type), message: "\(staticMessage)").save(at: Log.neLogURL)
}
public func wg_log(_ type: OSLogType, message: String) {
guard Log.isLoggingEnabled else { return }
Log.Record(date: Date(), level: Log.Record.Level(from: type), message: message).save(at: Log.neLogURL)
}
public func log(_ type: OSLogType, message: String) {
guard Log.isLoggingEnabled else { return }
Log.Record(date: Date(), level: Log.Record.Level(from: type), message: message).save(at: Log.neLogURL)
}

View file

@ -10,12 +10,6 @@
#include "../protocols/vpnprotocol.h"
#import "ios_controller_wrapper.h"
#import <NetworkExtension/NetworkExtension.h>
#import <NetworkExtension/NETunnelProviderManager.h>
#import <NetworkExtension/NEVPNManager.h>
#import <NetworkExtension/NETunnelProviderSession.h>
const char* Action::start = "start";
const char* Action::restart = "restart";
const char* Action::stop = "stop";

View file

@ -1,57 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import Foundation
import os.log
public class Logger {
static var global: Logger?
var tag: String
init(tagged tag: String) {
self.tag = tag
}
deinit {}
func log(message: String) {
// let suiteName = "group.org.amnezia.AmneziaVPN"
// let logKey = "logMessages"
// let sharedDefaults = UserDefaults(suiteName: suiteName)
// var logs = sharedDefaults?.array(forKey: logKey) as? [String] ?? []
// logs.append(message)
// sharedDefaults?.set(logs, forKey: logKey)
}
private func writeLog(to targetFile: String) -> Bool {
return true;
}
static func configureGlobal(tagged tag: String, withFilePath filePath: String?) {
// if Logger.global != nil {
// return
// }
//
// Logger.global = Logger(tagged: tag)
//
// var appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "Unknown version"
//
// if let appBuild = Bundle.main.infoDictionary?["CFBundleVersion"] as? String {
// appVersion += " (\(appBuild))"
// }
//
// Logger.global?.log(message: "App version: \(appVersion)")
}
}
func wg_log(_ type: OSLogType, staticMessage msg: StaticString) {
// os_log(msg, log: OSLog.default, type: type)
// Logger.global?.log(message: "\(msg)")
}
func wg_log(_ type: OSLogType, message msg: String) {
// os_log("%{AMNEZIA}s", log: OSLog.default, type: type, msg)
// Logger.global?.log(message: msg)
}

View file

@ -33,8 +33,7 @@ struct Constants {
static let kMessageKeySplitTunnelSites = "SplitTunnelSites"
}
class PacketTunnelProvider: NEPacketTunnelProvider {
class PacketTunnelProvider: NEPacketTunnelProvider {
private lazy var wgAdapter: WireGuardAdapter = {
return WireGuardAdapter(with: self) { logLevel, message in
wg_log(logLevel.osLogLevel, message: message)
@ -61,8 +60,6 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
var protoType: TunnelProtoType = .none
override init() {
Logger.configureGlobal(tagged: Constants.loggerTag, withFilePath: FileManager.logFileURL?.path)
Logger.global?.log(message: "Init NEPacketTunnelProvider")
super.init()
}
@ -71,17 +68,17 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
let tmpStr = String(data: messageData, encoding: .utf8)!
wg_log(.error, message: tmpStr)
guard let message = try? JSONSerialization.jsonObject(with: messageData, options: []) as? [String: Any] else {
Logger.global?.log(message: "Failed to serialize message from app")
log(.error, message: "Failed to serialize message from app")
return
}
guard let completionHandler = completionHandler else {
Logger.global?.log(message: "Missing message completion handler")
log(.error, message: "Missing message completion handler")
return
}
guard let action = message[Constants.kMessageKeyAction] as? String else {
Logger.global?.log(message: "Missing action key in app message")
log(.error, message: "Missing action key in app message")
completionHandler(nil)
return
}
@ -112,7 +109,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
let activationAttemptId = options?[Constants.kActivationAttemptId] as? String
let errorNotifier = ErrorNotifier(activationAttemptId: activationAttemptId)
Logger.global?.log(message: "PacketTunnelProvider startTunnel")
log(.info, message: "PacketTunnelProvider startTunnel")
if let protocolConfiguration = self.protocolConfiguration as? NETunnelProviderProtocol {
let providerConfiguration = protocolConfiguration.providerConfiguration
@ -492,10 +489,10 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
wgAdapter.start(tunnelConfiguration: emptyTunnelConfiguration) { error in
self.dispatchQueue.async {
if let error {
Logger.global?.log(message: "Failed to start an empty tunnel")
log(.error, message: "Failed to start an empty tunnel")
completionHandler(error)
} else {
Logger.global?.log(message: "Started an empty tunnel")
log(.info, message: "Started an empty tunnel")
self.tunnelAdapterDidStart()
}
}