Structured logging (#831)

* Structured logging support

* Bump the SDK, fix breaking changes

* Enabled more logging of timeline diffs

* Keep only source file last path components in logs

* Bump the SDK, tweaks following code review
This commit is contained in:
Stefan Ceriu 2023-04-25 14:48:20 +03:00 committed by GitHub
parent 0d3e823b69
commit be8adb19b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 286 additions and 252 deletions

View File

@ -111,8 +111,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/matrix-org/matrix-rust-components-swift",
"state" : {
"revision" : "8ce08eb804c449f4e7472e66edd7e80b4e8e9ded",
"version" : "1.0.54-alpha"
"revision" : "1febfb02005fca9cf99264be72c6383c103085c5",
"version" : "1.0.56-alpha"
}
},
{
@ -214,15 +214,6 @@
"version" : "0.2.3"
}
},
{
"identity" : "swiftybeaver",
"kind" : "remoteSourceControl",
"location" : "https://github.com/SwiftyBeaver/SwiftyBeaver",
"state" : {
"revision" : "1080914828ef1c9ca9cd2bad50667b3d847dabff",
"version" : "2.0.0"
}
},
{
"identity" : "version",
"kind" : "remoteSourceControl",

View File

@ -51,10 +51,11 @@ class AppCoordinator: AppCoordinatorProtocol {
@Consumable private var storedAppRoute: AppRoute?
init() {
MXLog.configure()
navigationRootCoordinator = NavigationRootCoordinator()
Self.setupServiceLocator(navigationRootCoordinator: navigationRootCoordinator)
Self.setupLogging()
ServiceLocator.shared.analytics.startIfEnabled()
@ -118,26 +119,6 @@ class AppCoordinator: AppCoordinatorProtocol {
ServiceLocator.shared.register(analytics: Analytics(client: PostHogAnalyticsClient()))
}
private static func setupLogging() {
let loggerConfiguration = MXLogConfiguration()
loggerConfiguration.maxLogFilesCount = 10
#if DEBUG
setupTracing(configuration: .debug)
loggerConfiguration.logLevel = .debug
#else
setupTracing(configuration: .release)
loggerConfiguration.logLevel = .info
#endif
// Avoid redirecting NSLogs to files if we are attached to a debugger.
if isatty(STDERR_FILENO) == 0 {
loggerConfiguration.redirectLogsToFiles = true
}
MXLog.configure(loggerConfiguration)
}
/// Perform any required migrations for the app to function correctly.
private func performMigrationsIfNecessary(from oldVersion: Version, to newVersion: Version) {
guard oldVersion != newVersion else { return }

View File

@ -19,13 +19,15 @@ import SwiftUI
@main
struct Application: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) private var applicationDelegate
private let applicationCoordinator: AppCoordinatorProtocol
private let appCoordinator: AppCoordinatorProtocol!
init() {
if Tests.isRunningUITests {
applicationCoordinator = UITestsAppCoordinator()
appCoordinator = UITestsAppCoordinator()
} else if Tests.isRunningUnitTests {
appCoordinator = nil
} else {
applicationCoordinator = AppCoordinator()
appCoordinator = AppCoordinator()
}
}
@ -34,9 +36,9 @@ struct Application: App {
if Tests.isRunningUnitTests {
EmptyView()
} else {
applicationCoordinator.toPresentable()
appCoordinator.toPresentable()
.task {
applicationCoordinator.start()
appCoordinator.start()
}
.statusBarHidden(shouldHideStatusBar)
}

View File

@ -15,87 +15,119 @@
//
import Foundation
import SwiftyBeaver
/// Various MXLog configuration options. Used in conjunction with `MXLog.configure()`
public class MXLogConfiguration: NSObject {
/// the desired log level. `.verbose` by default.
public var logLevel = MXLogLevel.verbose
/// whether logs should be written directly to files. `false` by default.
public var redirectLogsToFiles = false
/// the maximum total space to use for log files in bytes. `100MB` by default.
public var logFilesSizeLimit: UInt = 100 * 1024 * 1024 // 100MB
/// the maximum number of log files to use before rolling. `50` by default.
public var maxLogFilesCount: UInt = 50
/// the subname for log files. Files will be named as 'console-[subLogName].log'. `nil` by default
public var subLogName: String?
}
/// MXLog logging levels. Use .none to disable logging entirely.
public enum MXLogLevel: UInt {
case none
case verbose
case debug
case info
case warning
case error
}
private var logger: SwiftyBeaver.Type = {
let logger = SwiftyBeaver.self
MXLog.configureLogger(logger, withConfiguration: MXLogConfiguration())
return logger
}()
import MatrixRustSDK
/**
Logging utility that provies multiple logging levels as well as file output and rolling.
Its purpose is to provide a common entry for customizing logging and should be used throughout the code.
Please see `MXLog.h` for Objective-C options.
*/
public class MXLog: NSObject {
/// Method used to customize MXLog's behavior.
/// Called automatically when first accessing the logger with the default values.
/// Please see `MXLogConfiguration` for all available options.
/// - Parameters:
/// - configuration: the `MXLogConfiguration` instance to use
public static func configure(_ configuration: MXLogConfiguration) {
configureLogger(logger, withConfiguration: configuration)
enum MXLog {
private enum Constants {
static let target = "elementx"
// Avoid redirecting NSLogs to files if we are attached to a debugger.
static let redirectToFiles = isatty(STDERR_FILENO) == 0
/// the maximum number of log files to use before rolling. `10` by default.
static let maxLogFileCount: UInt = 10
/// the maximum total space to use for log files in bytes. `100MB` by default.
static let logFilesSizeLimit: UInt = 100 * 1024 * 1024 // 100MB
}
public static func verbose(_ message: @autoclosure () -> Any,
file: String = #file,
function: String = #function,
line: Int = #line,
context: Any? = nil) {
logger.verbose(message(), file: file, function: function, line: line, context: context)
// Rust side crashes if invoking setupTracing multiple times
private static var didConfigureOnce = false
private static var rootSpan: Span!
private static var target: String!
static func configure(target: String? = nil,
logLevel: TracingConfiguration.LogLevel? = nil,
redirectToFiles: Bool = Constants.redirectToFiles,
maxLogFileCount: UInt = Constants.maxLogFileCount,
logFileSizeLimit: UInt = Constants.logFilesSizeLimit) {
guard didConfigureOnce == false else {
if let target {
MXLogger.setSubLogName(target)
}
// SubLogName needs to be set before calling configure in order to be applied
MXLogger.configure(redirectToFiles: redirectToFiles,
maxLogFileCount: maxLogFileCount,
logFileSizeLimit: logFileSizeLimit)
return
}
if let logLevel {
setupTracing(configuration: .custom(logLevel: logLevel))
} else {
#if DEBUG
setupTracing(configuration: .debug)
#else
setupTracing(configuration: .release)
#endif
}
if let target {
self.target = target
MXLogger.setSubLogName(target)
} else {
self.target = Constants.target
}
rootSpan = Span(file: #file, line: #line, column: #column, level: .info, target: self.target, name: "root")
rootSpan.enter()
MXLogger.configure(redirectToFiles: redirectToFiles,
maxLogFileCount: maxLogFileCount,
logFileSizeLimit: logFileSizeLimit)
didConfigureOnce = true
}
public static func debug(_ message: @autoclosure () -> Any,
file: String = #file,
function: String = #function,
line: Int = #line,
context: Any? = nil) {
logger.debug(message(), file: file, function: function, line: line, context: context)
static func createSpan(_ name: String,
file: String = #file,
function: String = #function,
line: Int = #line,
column: Int = #column) -> Span {
createSpan(name, level: .info, file: file, function: function, line: line, column: column)
}
public static func info(_ message: @autoclosure () -> Any,
file: String = #file,
function: String = #function,
line: Int = #line,
context: Any? = nil) {
logger.info(message(), file: file, function: function, line: line, context: context)
static func verbose(_ message: Any,
file: String = #file,
function: String = #function,
line: Int = #line,
column: Int = #column,
context: Any? = nil) {
log(message, level: .trace, file: file, function: function, line: line, column: column, context: context)
}
public static func warning(_ message: @autoclosure () -> Any,
file: String = #file,
function: String = #function,
line: Int = #line,
context: Any? = nil) {
logger.warning(message(), file: file, function: function, line: line, context: context)
static func debug(_ message: Any,
file: String = #file,
function: String = #function,
line: Int = #line,
column: Int = #column,
context: Any? = nil) {
log(message, level: .debug, file: file, function: function, line: line, column: column, context: context)
}
static func info(_ message: Any,
file: String = #file,
function: String = #function,
line: Int = #line,
column: Int = #column,
context: Any? = nil) {
log(message, level: .info, file: file, function: function, line: line, column: column, context: context)
}
static func warning(_ message: Any,
file: String = #file,
function: String = #function,
line: Int = #line,
column: Int = #column,
context: Any? = nil) {
log(message, level: .warn, file: file, function: function, line: line, column: column, context: context)
}
/// Log error with additional details
@ -103,12 +135,13 @@ public class MXLog: NSObject {
/// - Parameters:
/// - message: Description of the error without any variables (this is to improve error aggregations by type)
/// - context: Additional context-dependent details about the issue
public static func error(_ message: @autoclosure () -> Any,
file: String = #file,
function: String = #function,
line: Int = #line,
context: Any? = nil) {
logger.error(message(), file: file, function: function, line: line, context: context)
static func error(_ message: Any,
file: String = #file,
function: String = #function,
line: Int = #line,
column: Int = #column,
context: Any? = nil) {
log(message, level: .error, file: file, function: function, line: line, column: column, context: context)
}
/// Log failure with additional details
@ -119,12 +152,14 @@ public class MXLog: NSObject {
/// - Parameters:
/// - message: Description of the error without any variables (this is to improve error aggregations by type)
/// - context: Additional context-dependent details about the issue
public static func failure(_ message: String,
file: String = #file,
function: String = #function,
line: Int = #line,
context: Any? = nil) {
logger.error(message, file: file, function: function, line: line, context: context)
static func failure(_ message: Any,
file: String = #file,
function: String = #function,
line: Int = #line,
column: Int = #column,
context: Any? = nil) {
log(message, level: .error, file: file, function: function, line: line, column: column, context: context)
#if DEBUG
assertionFailure("\(message)")
#endif
@ -132,46 +167,38 @@ public class MXLog: NSObject {
// MARK: - Private
fileprivate static func configureLogger(_ logger: SwiftyBeaver.Type, withConfiguration configuration: MXLogConfiguration) {
if let subLogName = configuration.subLogName {
MXLogger.setSubLogName(subLogName)
private static func createSpan(_ name: String,
level: LogLevel,
file: String = #file,
function: String = #function,
line: Int = #line,
column: Int = #column) -> Span {
guard didConfigureOnce else {
fatalError()
}
MXLogger.redirectNSLog(toFiles: configuration.redirectLogsToFiles,
numberOfFiles: configuration.maxLogFilesCount,
sizeLimit: configuration.logFilesSizeLimit)
if Span.current().isNone() {
rootSpan.enter()
}
guard configuration.logLevel != .none else {
logger.removeAllDestinations()
return Span(file: file, line: UInt32(line), column: UInt32(column), level: level, target: target, name: name)
}
private static func log(_ message: Any,
level: LogLevel,
file: String = #file,
function: String = #function,
line: Int = #line,
column: Int = #column,
context: Any? = nil) {
guard didConfigureOnce else {
return
}
logger.removeAllDestinations()
let consoleDestination = ConsoleDestination()
consoleDestination.useNSLog = true
consoleDestination.asynchronously = false
consoleDestination.format = "$C$N.$F:$l $M $X$c" // See https://docs.swiftybeaver.com/article/20-custom-format
consoleDestination.levelColor.verbose = ""
consoleDestination.levelColor.debug = ""
consoleDestination.levelColor.info = ""
consoleDestination.levelColor.warning = "⚠️ "
consoleDestination.levelColor.error = "🚨 "
switch configuration.logLevel {
case .verbose:
consoleDestination.minLevel = .verbose
case .debug:
consoleDestination.minLevel = .debug
case .info:
consoleDestination.minLevel = .info
case .warning:
consoleDestination.minLevel = .warning
case .error:
consoleDestination.minLevel = .error
case .none:
break
if Span.current().isNone() {
rootSpan.enter()
}
logger.addDestination(consoleDestination)
logEvent(file: (file as NSString).lastPathComponent, line: UInt32(line), column: UInt32(column), level: level, target: target, message: "\(message)")
}
}

View File

@ -37,14 +37,16 @@ class MXLogger {
///
/// - Parameters:
/// - redirectToFiles: `true` to enable the redirection.
/// - numberOfFiles: number of files to keep (default is 10).
/// - sizeLimit: size limit of log files in bytes. 0 means no limitation, the default value for other methods
static func redirectNSLog(toFiles redirectToFiles: Bool, numberOfFiles: UInt = 10, sizeLimit: UInt = 0) {
/// - maxLogFileCount: number of files to keep (default is 10).
/// - logFileSizeLimit: size limit of log files in bytes. 0 means no limitation, the default value for other methods
static func configure(redirectToFiles: Bool,
maxLogFileCount: UInt,
logFileSizeLimit: UInt) {
if redirectToFiles {
var tempLog = ""
// Do a circular buffer based on X files
for index in (0...(numberOfFiles - 2)).reversed() {
for index in (0...(maxLogFileCount - 2)).reversed() {
rotateLog(at: index, tempLog: &tempLog)
}
@ -60,10 +62,10 @@ class MXLogger {
MXLog.info(tempLog)
}
removeExtraFiles(from: numberOfFiles)
removeExtraFiles(from: maxLogFileCount)
if sizeLimit > 0 {
removeFiles(after: sizeLimit)
if logFileSizeLimit > 0 {
removeFiles(after: logFileSizeLimit)
}
} else if stderrSave > 0 {
// Flush before restoring stderr

View File

@ -22,11 +22,30 @@ import MatrixRustSDK
// https://docs.rs/tracing-subscriber/0.2.7/tracing_subscriber/filter/struct.EnvFilter.html#examples
struct TracingConfiguration {
static var release = TracingConfiguration(overrides: [.common: .info])
static var debug = TracingConfiguration(overrides: [.common: .info])
static var debug = TracingConfiguration(overrides: [.matrix_sdk_crypto: .info,
.matrix_sdk_http_client: .info,
.matrix_sdk_sliding_sync: .info,
.matrix_sdk_base_sliding_sync: .info])
/// Configure tracing with certain overrides in place
/// - Parameter overrides: the desired overrides
/// - Returns: a custom tracing configuration
static func custom(overrides: [Target: LogLevel]) -> TracingConfiguration {
TracingConfiguration(overrides: overrides)
}
/// Sets the same log level for all Targets
/// - Parameter logLevel: the desired log level
/// - Returns: a custom tracing configuration
static func custom(logLevel: LogLevel) -> TracingConfiguration {
let overrides = targets.keys.reduce(into: [Target: LogLevel]()) { partialResult, target in
partialResult[target] = logLevel
}
return TracingConfiguration(overrides: overrides)
}
enum LogLevel: String { case error, warn, info, debug, trace }
enum Target: String {
@ -41,8 +60,8 @@ struct TracingConfiguration {
case matrix_sdk_room_timeline = "matrix_sdk::room::timeline"
}
let targets: OrderedDictionary<Target, LogLevel> = [
.common: .warn,
static let targets: OrderedDictionary<Target, LogLevel> = [
.common: .info,
.hyper: .warn,
.sled: .warn,
.matrix_sdk_sled: .warn,
@ -56,7 +75,7 @@ struct TracingConfiguration {
var overrides = [Target: LogLevel]()
var filter: String {
var newTargets = targets
var newTargets = Self.targets
for (target, logLevel) in overrides {
newTargets.updateValue(logLevel, forKey: target)
}

View File

@ -93,7 +93,7 @@ class AuthenticationServiceProxy: AuthenticationServiceProxyProtocol {
let client = try authenticationService.restoreWithAccessToken(token: token, deviceId: deviceID)
return await userSession(for: client)
} catch {
MXLog.error(error)
MXLog.error("Failed restoring with access token: \(error)")
return .failure(.failedLoggingIn)
}
}

View File

@ -48,7 +48,7 @@ actor MediaLoader: MediaLoaderProtocol {
func loadMediaFileForSource(_ source: MediaSourceProxy) async throws -> MediaFileHandleProxy {
let result = try await Task.dispatch(on: clientQueue) {
try self.client.getMediaFile(source: source.underlyingSource, mimeType: source.mimeType ?? "application/octet-stream")
try self.client.getMediaFile(mediaSource: source.underlyingSource, mimeType: source.mimeType ?? "application/octet-stream")
}
return MediaFileHandleProxy(handle: result)

View File

@ -80,7 +80,13 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
// MARK: - Private
fileprivate func updateRoomsWithDiffs(_ diffs: [SlidingSyncListRoomsListDiff]) {
MXLog.info("Received \(diffs.count) diffs")
let span = MXLog.createSpan("process_room_list_diffs")
span.enter()
defer {
span.exit()
}
MXLog.verbose("Received \(diffs.count) diffs")
rooms = diffs
.reduce(rooms) { currentItems, diff in
@ -101,7 +107,7 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
detectDuplicatesInRoomList(rooms)
MXLog.info("Finished applying \(diffs.count) diffs, new count: \(rooms.count)")
MXLog.verbose("Finished applying \(diffs.count) diffs, new count: \(rooms.count)")
}
private func buildRoomSummaryForIdentifier(_ identifier: String, invalidated: Bool) -> RoomSummary {

View File

@ -60,6 +60,7 @@ class RoomTimelineProvider: RoomTimelineProviderProtocol {
switch await roomProxy.addTimelineListener(listener: roomTimelineListener) {
case .success(let items):
itemProxies = items.map(TimelineItemProxy.init)
MXLog.info("Added timeline listener, current items (\(items.count)) : \(items.map(\.debugIdentifier))")
case .failure:
let roomID = await roomProxy.id
MXLog.error("Failed adding timeline listener on room with identifier: \(roomID)")
@ -70,7 +71,13 @@ class RoomTimelineProvider: RoomTimelineProviderProtocol {
// MARK: - Private
private func updateItemsWithDiffs(_ diffs: [TimelineDiff]) {
MXLog.verbose("Received timeline diff")
let span = MXLog.createSpan("process_timeline_list_diffs")
span.enter()
defer {
span.exit()
}
MXLog.info("Received timeline diff")
itemProxies = diffs
.reduce(itemProxies) { currentItems, diff in
@ -84,12 +91,10 @@ class RoomTimelineProvider: RoomTimelineProviderProtocol {
return currentItems
}
MXLog.verbose("Applied diff \(collectionDiff), new count: \(updatedItems.count)")
return updatedItems
}
MXLog.verbose("Finished applying diff")
MXLog.info("Finished applying diffs, current items (\(itemProxies.count)) : \(itemProxies.map(\.debugIdentifier))")
}
// swiftlint:disable:next cyclomatic_complexity function_body_length
@ -100,60 +105,64 @@ class RoomTimelineProvider: RoomTimelineProviderProtocol {
case .pushFront:
guard let item = diff.pushFront() else { fatalError() }
MXLog.verbose("Push Front")
MXLog.info("Push Front: \(item.debugIdentifier)")
let itemProxy = TimelineItemProxy(item: item)
changes.append(.insert(offset: 0, element: itemProxy, associatedWith: nil))
case .pushBack:
guard let item = diff.pushBack() else { fatalError() }
MXLog.verbose("Push Back")
MXLog.info("Push Back \(item.debugIdentifier)")
let itemProxy = TimelineItemProxy(item: item)
changes.append(.insert(offset: Int(itemProxies.count), element: itemProxy, associatedWith: nil))
case .insert:
guard let update = diff.insert() else { fatalError() }
MXLog.verbose("Insert at \(update.index), current total count: \(itemProxies.count)")
MXLog.info("Insert \(update.item.debugIdentifier) at \(update.index)")
let itemProxy = TimelineItemProxy(item: update.item)
changes.append(.insert(offset: Int(update.index), element: itemProxy, associatedWith: nil))
case .append:
guard let items = diff.append() else { fatalError() }
MXLog.verbose("Append new items with count: \(items.count), to current total count: \(itemProxies.count)")
MXLog.info("Append \(items.map(\.debugIdentifier))")
for (index, item) in items.enumerated() {
changes.append(.insert(offset: Int(itemProxies.count) + index, element: TimelineItemProxy(item: item), associatedWith: nil))
}
case .set:
guard let update = diff.set() else { fatalError() }
MXLog.verbose("Update \(update.index), current total count: \(itemProxies.count)")
MXLog.info("Set \(update.item.debugIdentifier) at index \(update.index)")
let itemProxy = TimelineItemProxy(item: update.item)
changes.append(.remove(offset: Int(update.index), element: itemProxy, associatedWith: nil))
changes.append(.insert(offset: Int(update.index), element: itemProxy, associatedWith: nil))
case .popFront:
MXLog.verbose("Pop Front, current total count: \(itemProxies.count)")
guard let itemProxy = itemProxies.first else { fatalError() }
MXLog.info("Pop Front \(itemProxy.debugIdentifier)")
changes.append(.remove(offset: 0, element: itemProxy, associatedWith: nil))
case .popBack:
MXLog.verbose("Pop Back, current total count: \(itemProxies.count)")
guard let itemProxy = itemProxies.last else { fatalError() }
MXLog.info("Pop Back \(itemProxy.debugIdentifier)")
changes.append(.remove(offset: itemProxies.count - 1, element: itemProxy, associatedWith: nil))
case .remove:
guard let index = diff.remove() else { fatalError() }
MXLog.verbose("Remove item at: \(index), current total count: \(itemProxies.count)")
let itemProxy = itemProxies[Int(index)]
MXLog.info("Remove \(itemProxy.debugIdentifier) at: \(index)")
changes.append(.remove(offset: Int(index), element: itemProxy, associatedWith: nil))
case .clear:
MXLog.verbose("Clear all items, current total count: \(itemProxies.count)")
MXLog.info("Clear all items")
for (index, itemProxy) in itemProxies.enumerated() {
changes.append(.remove(offset: index, element: itemProxy, associatedWith: nil))
}
case .reset:
guard let items = diff.reset() else { fatalError() }
MXLog.verbose("Replace all items with new count: \(items.count), current total count: \(itemProxies.count)")
MXLog.info("Replace all items with \(items.map(\.debugIdentifier))")
for (index, itemProxy) in itemProxies.enumerated() {
changes.append(.remove(offset: index, element: itemProxy, associatedWith: nil))
}
@ -166,3 +175,43 @@ class RoomTimelineProvider: RoomTimelineProviderProtocol {
return CollectionDifference(changes)
}
}
private extension TimelineItem {
var debugIdentifier: String {
if let virtualTimelineItem = asVirtual() {
return virtualTimelineItem.debugIdentifier
} else if let eventTimelineItem = asEvent() {
return eventTimelineItem.uniqueIdentifier()
}
return "UnknownTimelineItem"
}
}
private extension TimelineItemProxy {
var debugIdentifier: String {
switch self {
case .event(let eventTimelineItem):
return eventTimelineItem.item.uniqueIdentifier()
case .virtual(let virtualTimelineItem):
return virtualTimelineItem.debugIdentifier
case .unknown:
return "UnknownTimelineItem"
}
}
}
private extension VirtualTimelineItem {
var debugIdentifier: String {
switch self {
case .dayDivider(let timestamp):
return "DayDiviver(\(timestamp))"
case .loadingIndicator:
return "LoadingIndicator"
case .readMarker:
return "ReadMarker"
case .timelineStart:
return "TimelineStart"
}
}
}

View File

@ -106,7 +106,7 @@ struct EventTimelineItemProxy {
}
var reactions: [Reaction] {
item.reactions() ?? []
item.reactions()
}
var timestamp: Date {

View File

@ -140,7 +140,6 @@ targets:
- package: Kingfisher
- package: KZFileWatchers
- package: PostHog
- package: SwiftyBeaver
- package: SwiftState
- package: GZIP
- package: Sentry

View File

@ -36,7 +36,6 @@ targets:
- package: DTCoreText
- package: KeychainAccess
- package: Kingfisher
- package: SwiftyBeaver
- package: SwiftState
- package: GZIP
- package: Sentry

View File

@ -81,24 +81,7 @@ class NSELogger {
}
isConfigured = true
let configuration = MXLogConfiguration()
configuration.maxLogFilesCount = 10
configuration.subLogName = "nse"
#if DEBUG
setupTracing(configuration: .debug)
configuration.logLevel = .debug
#else
setupTracing(configuration: .release)
configuration.logLevel = .info
#endif
// Avoid redirecting NSLogs to files if we are attached to a debugger.
if isatty(STDERR_FILENO) == 0 {
configuration.redirectLogsToFiles = true
}
MXLog.configure(configuration)
MXLog.configure(target: "nse")
}
static func logMemory(with tag: String) {

View File

@ -33,7 +33,6 @@ targets:
dependencies:
- package: MatrixRustSDK
- package: SwiftyBeaver
- package: KeychainAccess
- package: Kingfisher
- package: Collections

View File

@ -36,7 +36,6 @@ targets:
- package: Kingfisher
- package: KZFileWatchers
- package: PostHog
- package: SwiftyBeaver
- package: SwiftState
- package: GZIP
- package: Sentry

View File

@ -36,9 +36,8 @@ class LoggingTests: XCTestCase {
let log = UUID().uuidString
let configuration = MXLogConfiguration()
configuration.redirectLogsToFiles = true
MXLog.configure(configuration)
MXLog.configure(redirectToFiles: true)
MXLog.info(log)
guard let logFile = MXLogger.logFiles.first else {
XCTFail(Constants.genericFailure)
@ -56,9 +55,7 @@ class LoggingTests: XCTestCase {
// When launching the app 5 times.
let launchCount = 5
for index in 0..<launchCount {
let configuration = MXLogConfiguration()
configuration.redirectLogsToFiles = true
MXLog.configure(configuration) // This call is only made at app launch.
MXLog.configure(redirectToFiles: true)
MXLog.info("Launch \(index + 1)")
}
@ -77,10 +74,7 @@ class LoggingTests: XCTestCase {
let launchCount = 10
let logFileCount = 5
for index in 0..<launchCount {
let configuration = MXLogConfiguration()
configuration.maxLogFilesCount = UInt(logFileCount)
configuration.redirectLogsToFiles = true
MXLog.configure(configuration) // This call is only made at app launch.
MXLog.configure(redirectToFiles: true, maxLogFileCount: UInt(logFileCount))
MXLog.info("Launch \(index + 1)")
}
@ -97,12 +91,9 @@ class LoggingTests: XCTestCase {
// When launching the app 10 times, with a max total log size of 25KB and logging ~5KB data each time.
let launchCount = 10
let logFileSizeLimit = 25 * 1024
let logFileSizeLimit: UInt = 25 * 1024
for index in 0..<launchCount {
let configuration = MXLogConfiguration()
configuration.logFilesSizeLimit = UInt(logFileSizeLimit)
configuration.redirectLogsToFiles = true
MXLog.configure(configuration) // This call is only made at app launch.
MXLog.configure(redirectToFiles: true, logFileSizeLimit: logFileSizeLimit)
MXLog.info("Launch \(index + 1)")
// Add ~5KB of logs
@ -142,11 +133,9 @@ class LoggingTests: XCTestCase {
let log = UUID().uuidString
let configuration = MXLogConfiguration()
configuration.logLevel = .error
configuration.redirectLogsToFiles = true
MXLog.configure(configuration)
MXLog.info(log)
MXLog.configure(redirectToFiles: true)
MXLog.verbose(log)
guard let logFile = MXLogger.logFiles.first else {
XCTFail(Constants.genericFailure)
return
@ -159,19 +148,17 @@ class LoggingTests: XCTestCase {
func testSubLogName() {
XCTAssert(MXLogger.logFiles.isEmpty)
let subLogName = "nse"
let target = "nse"
let configuration = MXLogConfiguration()
configuration.subLogName = subLogName
configuration.redirectLogsToFiles = true
MXLog.configure(configuration)
MXLog.configure(target: target, redirectToFiles: true)
MXLog.info(UUID().uuidString)
guard let logFile = MXLogger.logFiles.first else {
XCTFail(Constants.genericFailure)
return
}
XCTAssertTrue(logFile.lastPathComponent.contains(subLogName))
XCTAssertTrue(logFile.lastPathComponent.contains(target))
}
func testRoomSummaryContentIsRedacted() throws {
@ -189,10 +176,9 @@ class LoggingTests: XCTestCase {
// When logging that value
XCTAssert(MXLogger.logFiles.isEmpty)
let configuration = MXLogConfiguration()
configuration.logLevel = .info
configuration.redirectLogsToFiles = true
MXLog.configure(configuration)
MXLog.configure(redirectToFiles: true)
MXLog.info(roomSummary)
// Then the log file should not include the sensitive information
@ -207,7 +193,6 @@ class LoggingTests: XCTestCase {
XCTAssertFalse(content.contains(lastMessage))
}
// swiftlint:disable:next function_body_length
func testTimelineContentIsRedacted() throws {
// Given timeline items that contain text
let textAttributedString = "TextAttributed"
@ -235,10 +220,9 @@ class LoggingTests: XCTestCase {
// When logging that value
XCTAssert(MXLogger.logFiles.isEmpty)
let configuration = MXLogConfiguration()
configuration.logLevel = .info
configuration.redirectLogsToFiles = true
MXLog.configure(configuration)
MXLog.configure(redirectToFiles: true)
MXLog.info(textMessage)
MXLog.info(noticeMessage)
MXLog.info(emoteMessage)
@ -294,10 +278,9 @@ class LoggingTests: XCTestCase {
// When logging that value
XCTAssert(MXLogger.logFiles.isEmpty)
let configuration = MXLogConfiguration()
configuration.logLevel = .info
configuration.redirectLogsToFiles = true
MXLog.configure(configuration)
MXLog.configure(redirectToFiles: true)
MXLog.info(textMessage)
MXLog.info(noticeMessage)
MXLog.info(emoteMessage)

View File

@ -95,7 +95,7 @@ private class MockMediaLoadingClient: ClientProtocol {
func uploadMedia(mimeType: String, data content: [UInt8]) throws -> String { fatalError() }
func getMediaFile(source: MatrixRustSDK.MediaSource, mimeType: String) throws -> MatrixRustSDK.MediaFileHandle { fatalError() }
func getMediaFile(mediaSource: MatrixRustSDK.MediaSource, mimeType: String) throws -> MatrixRustSDK.MediaFileHandle { fatalError() }
func getProfile(userId: String) throws -> MatrixRustSDK.UserProfile { fatalError() }
@ -129,10 +129,6 @@ private class MockMediaLoadingClient: ClientProtocol {
fatalError()
}
func searchUsers(searchTerm: String, limit: UInt64) throws -> MatrixRustSDK.SearchUsersResults {
fatalError()
}
func unignoreUser(userId: String) throws {
fatalError()
}
@ -146,4 +142,6 @@ private class MockMediaLoadingClient: ClientProtocol {
lang: String) throws {
fatalError()
}
func searchUsers(searchTerm: String, limit: UInt64) throws -> MatrixRustSDK.SearchUsersResults { fatalError() }
}

View File

@ -156,7 +156,7 @@ private struct MockEventTimelineItem: EventTimelineItemProtocol {
func raw() -> String? { nil }
func reactions() -> [MatrixRustSDK.Reaction]? { nil }
func reactions() -> [MatrixRustSDK.Reaction] { [] }
func sender() -> String { "@user:server.com" }

View File

@ -42,7 +42,7 @@ include:
packages:
MatrixRustSDK:
url: https://github.com/matrix-org/matrix-rust-components-swift
exactVersion: 1.0.54-alpha
exactVersion: 1.0.56-alpha
# path: ../matrix-rust-sdk
DesignKit:
path: DesignKit
@ -83,9 +83,6 @@ packages:
PostHog:
url: https://github.com/PostHog/posthog-ios
minorVersion: 2.0.0
SwiftyBeaver:
url: https://github.com/SwiftyBeaver/SwiftyBeaver
minorVersion: 2.0.0
SwiftState:
url: https://github.com/ReactKit/SwiftState
minorVersion: 6.0.0