Update the RustSDK and adopt the new tracing configuration that allows maximum size and age limits on all logs.

Set that 100Mb and a week and remove previous rageshake uploading checks as they are no longer required.
This commit is contained in:
Stefan Ceriu
2026-02-13 14:24:51 +02:00
committed by Stefan Ceriu
parent 2ee095554b
commit 8f9d507e28
10 changed files with 25 additions and 82 deletions
+1 -1
View File
@@ -9841,7 +9841,7 @@
repositoryURL = "https://github.com/element-hq/matrix-rust-components-swift"; repositoryURL = "https://github.com/element-hq/matrix-rust-components-swift";
requirement = { requirement = {
kind = exactVersion; kind = exactVersion;
version = 26.02.10; version = 26.02.13;
}; };
}; };
701C7BEF8F70F7A83E852DCC /* XCRemoteSwiftPackageReference "GZIP" */ = { 701C7BEF8F70F7A83E852DCC /* XCRemoteSwiftPackageReference "GZIP" */ = {
@@ -158,8 +158,8 @@
"kind" : "remoteSourceControl", "kind" : "remoteSourceControl",
"location" : "https://github.com/element-hq/matrix-rust-components-swift", "location" : "https://github.com/element-hq/matrix-rust-components-swift",
"state" : { "state" : {
"revision" : "b4a065799c4b73d3c7c345ab13e701344568bd91", "revision" : "113131fa5f779a22319b61525c3126ba63045fa0",
"version" : "26.2.10" "version" : "26.2.13"
} }
}, },
{ {
@@ -134,7 +134,6 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
bugReportService = BugReportService(rageshakeURLPublisher: appSettings.bugReportRageshakeURL.publisher, bugReportService = BugReportService(rageshakeURLPublisher: appSettings.bugReportRageshakeURL.publisher,
applicationID: appSettings.bugReportApplicationID, applicationID: appSettings.bugReportApplicationID,
sdkGitSHA: sdkGitSha(), sdkGitSHA: sdkGitSha(),
maxUploadSize: appSettings.bugReportMaxUploadSize,
appHooks: appHooks) appHooks: appHooks)
Self.setupSentry(bugReportService: bugReportService, appSettings: appSettings) Self.setupSentry(bugReportService: bugReportService, appSettings: appSettings)
@@ -313,8 +313,6 @@ final class AppSettings {
let bugReportSentryRustURL: URL? = Secrets.sentryRustDSN.map { URL(string: $0)! } // swiftlint:disable:this force_unwrapping let bugReportSentryRustURL: URL? = Secrets.sentryRustDSN.map { URL(string: $0)! } // swiftlint:disable:this force_unwrapping
/// The name allocated by the bug report server /// The name allocated by the bug report server
private(set) var bugReportApplicationID = "element-x-ios" private(set) var bugReportApplicationID = "element-x-ios"
/// The maximum size of the upload request. Default value is just below CloudFlare's max request size.
let bugReportMaxUploadSize = 50 * 1024 * 1024
// MARK: - Analytics // MARK: - Analytics
@@ -25,10 +25,12 @@ enum Target: String {
} }
} }
var logFilePrefix: String? { var logFilePrefix: String {
switch self { switch self {
case .mainApp: nil case .mainApp:
default: rawValue "console"
default:
rawValue
} }
} }
+9 -19
View File
@@ -10,9 +10,6 @@ import Foundation
import MatrixRustSDK import MatrixRustSDK
enum Tracing { enum Tracing {
/// The base filename used for log files. This may be suffixed by the target
/// name and other log management metadata during rotation.
static let filePrefix = "console"
/// The directory that stores all of the log files. /// The directory that stores all of the log files.
static var logsDirectory: URL { static var logsDirectory: URL {
if ProcessInfo.isRunningIntegrationTests { if ProcessInfo.isRunningIntegrationTests {
@@ -30,22 +27,13 @@ enum Tracing {
.appGroupContainerDirectory .appGroupContainerDirectory
} }
static let fileExtension = "log" static let fileExtension = ".log"
static func buildConfiguration(logLevel: LogLevel, traceLogPacks: Set<TraceLogPack>, static func buildConfiguration(logLevel: LogLevel,
traceLogPacks: Set<TraceLogPack>,
currentTarget: String, currentTarget: String,
filePrefix: String?, filePrefix: String,
sentryURL: URL?) -> TracingConfiguration { sentryURL: URL?) -> TracingConfiguration {
let fileName = if let filePrefix {
"\(Tracing.filePrefix)-\(filePrefix)"
} else {
Tracing.filePrefix
}
// Keep a minimum of 1 week of log files. In reality it will be longer
// as the app is unlikely to be running continuously.
let maxFiles: UInt64 = 24 * 7
// Log everything on integration tests to check whether // Log everything on integration tests to check whether
// the logs contain any sensitive data. See `integration-tests.yml` // the logs contain any sensitive data. See `integration-tests.yml`
let level: LogLevel = ProcessInfo.isRunningIntegrationTests ? .trace : logLevel let level: LogLevel = ProcessInfo.isRunningIntegrationTests ? .trace : logLevel
@@ -55,9 +43,11 @@ enum Tracing {
extraTargets: [currentTarget], extraTargets: [currentTarget],
writeToStdoutOrSystem: true, writeToStdoutOrSystem: true,
writeToFiles: .init(path: logsDirectory.path(percentEncoded: false), writeToFiles: .init(path: logsDirectory.path(percentEncoded: false),
filePrefix: fileName, filePrefix: filePrefix,
fileSuffix: fileExtension, fileSuffix: fileExtension,
maxFiles: maxFiles), // Total compressed size needs to be under CloudFlare's max request size of 50Mb
maxTotalSizeBytes: 100 * 1024 * 1024, // 100Mb
maxAgeSeconds: 7 * 24 * 60 * 60), // One week
sentryDsn: sentryURL?.absoluteString) sentryDsn: sentryURL?.absoluteString)
} }
@@ -81,7 +71,7 @@ enum Tracing {
let modificationDate = resourceValues.contentModificationDate let modificationDate = resourceValues.contentModificationDate
else { continue } else { continue }
if logURL.lastPathComponent.hasPrefix(filePrefix) { if logURL.lastPathComponent.hasSuffix(fileExtension) {
logFiles.append((logURL, modificationDate)) logFiles.append((logURL, modificationDate))
} }
} }
@@ -16,7 +16,6 @@ class BugReportService: NSObject, BugReportServiceProtocol {
private var rageshakeURL: RageshakeConfiguration private var rageshakeURL: RageshakeConfiguration
private let applicationID: String private let applicationID: String
private let sdkGitSHA: String private let sdkGitSHA: String
private let maxUploadSize: Int
private let session: URLSession private let session: URLSession
private let appHooks: AppHooks private let appHooks: AppHooks
@@ -32,13 +31,11 @@ class BugReportService: NSObject, BugReportServiceProtocol {
init(rageshakeURLPublisher: CurrentValuePublisher<RageshakeConfiguration, Never>, init(rageshakeURLPublisher: CurrentValuePublisher<RageshakeConfiguration, Never>,
applicationID: String, applicationID: String,
sdkGitSHA: String, sdkGitSHA: String,
maxUploadSize: Int,
session: URLSession = .shared, session: URLSession = .shared,
appHooks: AppHooks) { appHooks: AppHooks) {
rageshakeURL = rageshakeURLPublisher.value rageshakeURL = rageshakeURLPublisher.value
self.applicationID = applicationID self.applicationID = applicationID
self.sdkGitSHA = sdkGitSHA self.sdkGitSHA = sdkGitSHA
self.maxUploadSize = maxUploadSize
self.session = session self.session = session
self.appHooks = appHooks self.appHooks = appHooks
@@ -210,7 +207,7 @@ class BugReportService: NSObject, BugReportServiceProtocol {
private func zipFiles(_ logFiles: [URL]) async -> Logs { private func zipFiles(_ logFiles: [URL]) async -> Logs {
MXLog.info("zipFiles") MXLog.info("zipFiles")
var compressedLogs = Logs(maxFileSize: maxUploadSize) var compressedLogs = Logs()
for url in logFiles { for url in logFiles {
do { do {
@@ -228,15 +225,6 @@ class BugReportService: NSObject, BugReportServiceProtocol {
/// Zips a file creating chunks based on 10MB inputs. /// Zips a file creating chunks based on 10MB inputs.
private func attachFile(at url: URL, to zippedFiles: inout Logs) throws { private func attachFile(at url: URL, to zippedFiles: inout Logs) throws {
// We check the compressed size to determine whether or not to attach the files.
// **However:** given our gzip library compresses in memory it is possible to OOM
// on files that will obviously be thrown away, so check the uncompressed size too.
let uncompressedSizeThreshold = maxUploadSize * 5
if try FileManager.default.sizeForItem(at: url) > uncompressedSizeThreshold {
MXLog.error("Uncompressed logs too large, skipping attachment: \(url.lastPathComponent)")
return
}
let fileHandle = try FileHandle(forReadingFrom: url) let fileHandle = try FileHandle(forReadingFrom: url)
while let data = try fileHandle.readToEnd() { while let data = try fileHandle.readToEnd() {
@@ -254,9 +242,6 @@ class BugReportService: NSObject, BugReportServiceProtocol {
/// A collection of logs to be uploaded to the bug report service. /// A collection of logs to be uploaded to the bug report service.
struct Logs { struct Logs {
/// The maximum total size of all the files.
let maxFileSize: Int
/// The files included. /// The files included.
private(set) var files: [URL] = [] private(set) var files: [URL] = []
/// The total size of the files after compression. /// The total size of the files after compression.
@@ -265,10 +250,6 @@ class BugReportService: NSObject, BugReportServiceProtocol {
private(set) var originalSize = 0 private(set) var originalSize = 0
mutating func appendFile(at url: URL, zippedSize: Int, originalSize: Int) { mutating func appendFile(at url: URL, zippedSize: Int, originalSize: Int) {
guard self.zippedSize + zippedSize < maxFileSize else {
MXLog.error("Logs too large, skipping attachment: \(url.lastPathComponent)")
return
}
files.append(url) files.append(url)
self.originalSize += originalSize self.originalSize += originalSize
self.zippedSize += zippedSize self.zippedSize += zippedSize
@@ -55,7 +55,6 @@ class BugReportServiceTests: XCTestCase {
let service = BugReportService(rageshakeURLPublisher: urlPublisher.asCurrentValuePublisher(), let service = BugReportService(rageshakeURLPublisher: urlPublisher.asCurrentValuePublisher(),
applicationID: "mock_app_id", applicationID: "mock_app_id",
sdkGitSHA: "1234", sdkGitSHA: "1234",
maxUploadSize: ServiceLocator.shared.settings.bugReportMaxUploadSize,
session: .mock, session: .mock,
appHooks: AppHooks()) appHooks: AppHooks())
XCTAssertTrue(service.isEnabled) XCTAssertTrue(service.isEnabled)
@@ -67,7 +66,6 @@ class BugReportServiceTests: XCTestCase {
let service = BugReportService(rageshakeURLPublisher: urlPublisher.asCurrentValuePublisher(), let service = BugReportService(rageshakeURLPublisher: urlPublisher.asCurrentValuePublisher(),
applicationID: "mock_app_id", applicationID: "mock_app_id",
sdkGitSHA: "1234", sdkGitSHA: "1234",
maxUploadSize: ServiceLocator.shared.settings.bugReportMaxUploadSize,
session: .mock, session: .mock,
appHooks: AppHooks()) appHooks: AppHooks())
XCTAssertFalse(service.isEnabled) XCTAssertFalse(service.isEnabled)
@@ -79,7 +77,6 @@ class BugReportServiceTests: XCTestCase {
let service = BugReportService(rageshakeURLPublisher: urlPublisher.asCurrentValuePublisher(), let service = BugReportService(rageshakeURLPublisher: urlPublisher.asCurrentValuePublisher(),
applicationID: "mock_app_id", applicationID: "mock_app_id",
sdkGitSHA: "1234", sdkGitSHA: "1234",
maxUploadSize: ServiceLocator.shared.settings.bugReportMaxUploadSize,
session: .mock, session: .mock,
appHooks: AppHooks()) appHooks: AppHooks())
@@ -107,7 +104,6 @@ class BugReportServiceTests: XCTestCase {
let service = BugReportService(rageshakeURLPublisher: appSettings.bugReportRageshakeURL.publisher, let service = BugReportService(rageshakeURLPublisher: appSettings.bugReportRageshakeURL.publisher,
applicationID: "mock_app_id", applicationID: "mock_app_id",
sdkGitSHA: "1234", sdkGitSHA: "1234",
maxUploadSize: ServiceLocator.shared.settings.bugReportMaxUploadSize,
session: .mock, session: .mock,
appHooks: AppHooks()) appHooks: AppHooks())
XCTAssertTrue(service.isEnabled) XCTAssertTrue(service.isEnabled)
@@ -139,31 +135,6 @@ class BugReportServiceTests: XCTestCase {
XCTAssertEqual(defaultConfigurationResponse.reportURL, initialURL.absoluteString.replacingOccurrences(of: "submit", with: "123")) XCTAssertEqual(defaultConfigurationResponse.reportURL, initialURL.absoluteString.replacingOccurrences(of: "submit", with: "123"))
} }
func testLogsMaxSize() {
// Given a new set of logs
var logs = BugReportService.Logs(maxFileSize: 1000)
XCTAssertEqual(logs.zippedSize, 0)
XCTAssertEqual(logs.originalSize, 0)
XCTAssertTrue(logs.files.isEmpty)
// When adding new files within the size limit
logs.appendFile(at: .homeDirectory, zippedSize: 250, originalSize: 1000)
logs.appendFile(at: .picturesDirectory, zippedSize: 500, originalSize: 2000)
// Then the logs should be included
XCTAssertEqual(logs.zippedSize, 750)
XCTAssertEqual(logs.originalSize, 3000)
XCTAssertEqual(logs.files, [.homeDirectory, .picturesDirectory])
// When adding a new file larger that will exceed the size limit
logs.appendFile(at: .homeDirectory, zippedSize: 500, originalSize: 2000)
// Then the files shouldn't be included.
XCTAssertEqual(logs.zippedSize, 750)
XCTAssertEqual(logs.originalSize, 3000)
XCTAssertEqual(logs.files, [.homeDirectory, .picturesDirectory])
}
} }
private class MockURLProtocol: URLProtocol { private class MockURLProtocol: URLProtocol {
+6 -4
View File
@@ -19,8 +19,9 @@ class LoggingTests: XCTestCase {
Tracing.logsDirectoryOverride = nil Tracing.logsDirectoryOverride = nil
try reloadTracingFileWriter(configuration: .init(path: URL.appGroupLogsDirectory.path(percentEncoded: false), try reloadTracingFileWriter(configuration: .init(path: URL.appGroupLogsDirectory.path(percentEncoded: false),
filePrefix: "console-tests", filePrefix: "console-tests",
fileSuffix: "log", fileSuffix: ".log",
maxFiles: 100)) maxTotalSizeBytes: 1000,
maxAgeSeconds: 1000))
} }
func testFileLogging() throws { func testFileLogging() throws {
@@ -343,8 +344,9 @@ class LoggingTests: XCTestCase {
if redirectTracingFileWriter { if redirectTracingFileWriter {
try reloadTracingFileWriter(configuration: .init(path: testDirectory.path(percentEncoded: false), try reloadTracingFileWriter(configuration: .init(path: testDirectory.path(percentEncoded: false),
filePrefix: "console", filePrefix: "console",
fileSuffix: "log", fileSuffix: ".log",
maxFiles: 100)) maxTotalSizeBytes: 1000,
maxAgeSeconds: 1000))
} }
} }
} }
+1 -1
View File
@@ -73,7 +73,7 @@ packages:
# Element/Matrix dependencies # Element/Matrix dependencies
MatrixRustSDK: MatrixRustSDK:
url: https://github.com/element-hq/matrix-rust-components-swift url: https://github.com/element-hq/matrix-rust-components-swift
exactVersion: 26.02.10 exactVersion: 26.02.13
# path: ../matrix-rust-sdk # path: ../matrix-rust-sdk
Compound: Compound:
path: compound-ios path: compound-ios