From ddf45332890330a232521e22e45ddd6e35f13aae Mon Sep 17 00:00:00 2001 From: Antoine van der Lee <4329185+AvdLee@users.noreply.github.com> Date: Fri, 1 Mar 2024 14:24:08 +0100 Subject: [PATCH 1/6] Remove legacy code --- Sources/Logging/Loggable.swift | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Sources/Logging/Loggable.swift b/Sources/Logging/Loggable.swift index 87a840d..87853e8 100644 --- a/Sources/Logging/Loggable.swift +++ b/Sources/Logging/Loggable.swift @@ -55,9 +55,7 @@ struct NewSession: Loggable { let system = "\(Device.systemName) \(Device.systemVersion)" let locale = Locale.preferredLanguages[0] - /// We start with `\n\n---\n\n` for backwards compatibility since it's - /// used for splitting the log into sections. - var message = "\n\n---\n\n
" + var message = "
" message += "

Date: \(date)

" message += "

System: \(system)

" message += "

Locale: \(locale)

" From ab7d58e95b67fad947d457d38c92ef9596863b38 Mon Sep 17 00:00:00 2001 From: Antoine van der Lee <4329185+AvdLee@users.noreply.github.com> Date: Fri, 1 Mar 2024 15:21:16 +0100 Subject: [PATCH 2/6] Reverse legacy commit --- Sources/Logging/Loggable.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Sources/Logging/Loggable.swift b/Sources/Logging/Loggable.swift index 87853e8..87a840d 100644 --- a/Sources/Logging/Loggable.swift +++ b/Sources/Logging/Loggable.swift @@ -55,7 +55,9 @@ struct NewSession: Loggable { let system = "\(Device.systemName) \(Device.systemVersion)" let locale = Locale.preferredLanguages[0] - var message = "
" + /// We start with `\n\n---\n\n` for backwards compatibility since it's + /// used for splitting the log into sections. + var message = "\n\n---\n\n
" message += "

Date: \(date)

" message += "

System: \(system)

" message += "

Locale: \(locale)

" From 90891220134d722921255d2b99a6f2168d06706c Mon Sep 17 00:00:00 2001 From: Antoine van der Lee <4329185+AvdLee@users.noreply.github.com> Date: Fri, 1 Mar 2024 15:21:38 +0100 Subject: [PATCH 3/6] Fix trimming log files based on log lines instead of data count --- .../Reporters/LogsReporterTests.swift | 1 - .../Reporters/LogsTrimmerTests.swift | 62 +++++++++++++++++++ Sources/Logging/DiagnosticsLogger.swift | 15 ++--- Sources/Logging/LogsTrimmer.swift | 47 ++++++++++++++ 4 files changed, 114 insertions(+), 11 deletions(-) create mode 100644 DiagnosticsTests/Reporters/LogsTrimmerTests.swift create mode 100644 Sources/Logging/LogsTrimmer.swift diff --git a/DiagnosticsTests/Reporters/LogsReporterTests.swift b/DiagnosticsTests/Reporters/LogsReporterTests.swift index 1fe7d74..37c8d01 100644 --- a/DiagnosticsTests/Reporters/LogsReporterTests.swift +++ b/DiagnosticsTests/Reporters/LogsReporterTests.swift @@ -62,5 +62,4 @@ final class LogsReporterTests: XCTestCase { let secondIndex = try XCTUnwrap(diagnostics.range(of: "second")?.lowerBound) XCTAssertTrue(firstIndex > secondIndex) } - } diff --git a/DiagnosticsTests/Reporters/LogsTrimmerTests.swift b/DiagnosticsTests/Reporters/LogsTrimmerTests.swift new file mode 100644 index 0000000..2cd8f01 --- /dev/null +++ b/DiagnosticsTests/Reporters/LogsTrimmerTests.swift @@ -0,0 +1,62 @@ +// +// LogsTrimmerTests.swift +// +// +// Created by Antoine van der Lee on 01/03/2024. +// + +import XCTest +@testable import Diagnostics + +final class LogsTrimmerTests: XCTestCase { + + /// It should trim the oldest line and skip session headers. + func testTrimmingSessionsSingleLine() { + let expectedOutput = """ +

Date: 2024-02-20 10:33:47

System: iOS 16.3

Locale: en-GB

Version: 6.2.8 (17000)

+

2024-02-20 10:33:47 | SYSTEM: 2024-02-20 10:33:47.086 Collect[32949:1669571] Reachability Flag Status: -R t------ reachabilityStatusForFlags

+ """ + + /// Store the maximum size to match the expected output. + let maximumSize = Int64(Data(expectedOutput.utf8).count) + var input = expectedOutput + input += """ +

2024-02-20 10:33:47 | SYSTEM: 2024-02-20 10:33:47.101 Collect[32949:1669571] [Firebase/Crashlytics] Version 8.15.0

+ """ + + var inputData = Data(input.utf8) + let trimmer = LogsTrimmer( + numberOfLinesToTrim: 1 + ) + + trimmer.trim(data: &inputData) + + let outputString = String(data: inputData, encoding: .utf8) + XCTAssertEqual(outputString, expectedOutput) + } + + /// It should trim the oldest lines and skip session headers. + func testTrimmingSessionsMultipleLines() { + let expectedOutput = """ +

Date: 2024-02-20 10:33:47

System: iOS 16.3

Locale: en-GB

Version: 6.2.8 (17000)

+ """ + + /// Store the maximum size to match the expected output. + let maximumSize = Int64(Data(expectedOutput.utf8).count) + var input = expectedOutput + input += """ +

2024-02-20 10:33:47 | SYSTEM: 2024-02-20 10:33:47.086 Collect[32949:1669571] Reachability Flag Status: -R t------ reachabilityStatusForFlags

+

2024-02-20 10:33:47 | SYSTEM: 2024-02-20 10:33:47.101 Collect[32949:1669571] [Firebase/Crashlytics] Version 8.15.0

+ """ + + var inputData = Data(input.utf8) + let trimmer = LogsTrimmer( + numberOfLinesToTrim: 10 + ) + + trimmer.trim(data: &inputData) + + let outputString = String(data: inputData, encoding: .utf8) + XCTAssertEqual(outputString, expectedOutput) + } +} diff --git a/Sources/Logging/DiagnosticsLogger.swift b/Sources/Logging/DiagnosticsLogger.swift index a20e61e..59a1b63 100644 --- a/Sources/Logging/DiagnosticsLogger.swift +++ b/Sources/Logging/DiagnosticsLogger.swift @@ -223,19 +223,14 @@ extension DiagnosticsLogger { guard var data = try? Data(contentsOf: self.logFileLocation, options: .mappedIfSafe), - !data.isEmpty, - let newline = "\n".data(using: .utf8) else { - return assertionFailure("Trimming the current log file failed") + !data.isEmpty else { + return assertionFailure("Trimming the current log file failed") } - var position: Int = 0 - while (logSize - Int64(position)) > (maximumSize - trimSize) { - guard let range = data.firstRange(of: newline, in: position ..< data.count) else { break } - position = range.startIndex.advanced(by: 1) - } + let trimmer = LogsTrimmer(numberOfLinesToTrim: 10) + trimmer.trim(data: &data) - logSize -= Int64(position) - data.removeSubrange(0 ..< position) + logSize = Int64(data.count) guard (try? data.write(to: logFileLocation, options: .atomic)) != nil else { return assertionFailure("Could not write trimmed log to target file location: \(logFileLocation)") diff --git a/Sources/Logging/LogsTrimmer.swift b/Sources/Logging/LogsTrimmer.swift new file mode 100644 index 0000000..ba0a2a4 --- /dev/null +++ b/Sources/Logging/LogsTrimmer.swift @@ -0,0 +1,47 @@ +// +// LogsTrimmer.swift +// +// +// Created by Antoine van der Lee on 01/03/2024. +// + +import Foundation + +struct LogsTrimmer { + let numberOfLinesToTrim: Int + + func trim(data: inout Data) { + guard let logs = String(data: data, encoding: .utf8) else { + return + } + + // Define the regular expression pattern + let pattern = "

(.*?)

" + + // Create a regular expression object + guard let regex = try? NSRegularExpression(pattern: pattern) else { + return + } + + // Find all matches in the input string + let matches = regex.matches( + in: logs, + range: NSRange(location: 0, length: logs.utf16.count) + ).suffix(numberOfLinesToTrim) + + guard let firstMatch = matches.first, let lastMatch = matches.last else { + return + } + + let range = NSRange( + location: firstMatch.range.location, + length: lastMatch.range.upperBound - firstMatch.range.location + ) + guard let range = Range(range, in: logs) else { + return + } + + let trimmedLogs = logs.replacingCharacters(in: range, with: "") + data = Data(trimmedLogs.utf8) + } +} From 5e1eab44f45ca6d49a9a7fd9d2439a96f650977d Mon Sep 17 00:00:00 2001 From: Antoine van der Lee <4329185+AvdLee@users.noreply.github.com> Date: Fri, 1 Mar 2024 15:30:01 +0100 Subject: [PATCH 4/6] Apple SwiftFormat --- Sources/Logging/LogsTrimmer.swift | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Sources/Logging/LogsTrimmer.swift b/Sources/Logging/LogsTrimmer.swift index ba0a2a4..c28afee 100644 --- a/Sources/Logging/LogsTrimmer.swift +++ b/Sources/Logging/LogsTrimmer.swift @@ -24,10 +24,12 @@ struct LogsTrimmer { } // Find all matches in the input string - let matches = regex.matches( - in: logs, - range: NSRange(location: 0, length: logs.utf16.count) - ).suffix(numberOfLinesToTrim) + let matches = regex + .matches( + in: logs, + range: NSRange(location: 0, length: logs.utf16.count) + ) + .suffix(numberOfLinesToTrim) guard let firstMatch = matches.first, let lastMatch = matches.last else { return From b4fe49e8d815e87a90c4bc2e58be029a4489ae07 Mon Sep 17 00:00:00 2001 From: Antoine van der Lee <4329185+AvdLee@users.noreply.github.com> Date: Mon, 4 Mar 2024 09:26:22 +0100 Subject: [PATCH 5/6] Fix SwiftLint warnings --- DiagnosticsTests/Reporters/LogsTrimmerTests.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/DiagnosticsTests/Reporters/LogsTrimmerTests.swift b/DiagnosticsTests/Reporters/LogsTrimmerTests.swift index 2cd8f01..794cd05 100644 --- a/DiagnosticsTests/Reporters/LogsTrimmerTests.swift +++ b/DiagnosticsTests/Reporters/LogsTrimmerTests.swift @@ -4,9 +4,10 @@ // // Created by Antoine van der Lee on 01/03/2024. // +// swiftlint:disable line_length -import XCTest @testable import Diagnostics +import XCTest final class LogsTrimmerTests: XCTestCase { @@ -60,3 +61,4 @@ final class LogsTrimmerTests: XCTestCase { XCTAssertEqual(outputString, expectedOutput) } } +// swiftlint:enable line_length From 10306350de53e70fa47958c68f36d29c7b49bae4 Mon Sep 17 00:00:00 2001 From: Antoine van der Lee <4329185+AvdLee@users.noreply.github.com> Date: Mon, 4 Mar 2024 09:26:56 +0100 Subject: [PATCH 6/6] Remove unused property --- DiagnosticsTests/Reporters/LogsTrimmerTests.swift | 4 ---- 1 file changed, 4 deletions(-) diff --git a/DiagnosticsTests/Reporters/LogsTrimmerTests.swift b/DiagnosticsTests/Reporters/LogsTrimmerTests.swift index 794cd05..d875091 100644 --- a/DiagnosticsTests/Reporters/LogsTrimmerTests.swift +++ b/DiagnosticsTests/Reporters/LogsTrimmerTests.swift @@ -18,8 +18,6 @@ final class LogsTrimmerTests: XCTestCase {

2024-02-20 10:33:47 | SYSTEM: 2024-02-20 10:33:47.086 Collect[32949:1669571] Reachability Flag Status: -R t------ reachabilityStatusForFlags

""" - /// Store the maximum size to match the expected output. - let maximumSize = Int64(Data(expectedOutput.utf8).count) var input = expectedOutput input += """

2024-02-20 10:33:47 | SYSTEM: 2024-02-20 10:33:47.101 Collect[32949:1669571] [Firebase/Crashlytics] Version 8.15.0

@@ -42,8 +40,6 @@ final class LogsTrimmerTests: XCTestCase {

Date: 2024-02-20 10:33:47

System: iOS 16.3

Locale: en-GB

Version: 6.2.8 (17000)

""" - /// Store the maximum size to match the expected output. - let maximumSize = Int64(Data(expectedOutput.utf8).count) var input = expectedOutput input += """

2024-02-20 10:33:47 | SYSTEM: 2024-02-20 10:33:47.086 Collect[32949:1669571] Reachability Flag Status: -R t------ reachabilityStatusForFlags