Skip to content

Commit

Permalink
Merge pull request #166 from WeTransfer/feature/tmob-5115-trimming
Browse files Browse the repository at this point in the history
[TMOB 5115] Trim using lines instead of bytes
  • Loading branch information
AvdLee authored Mar 4, 2024
2 parents 4a362cc + 1030635 commit f5c4c56
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 11 deletions.
1 change: 0 additions & 1 deletion DiagnosticsTests/Reporters/LogsReporterTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,4 @@ final class LogsReporterTests: XCTestCase {
let secondIndex = try XCTUnwrap(diagnostics.range(of: "second")?.lowerBound)
XCTAssertTrue(firstIndex > secondIndex)
}

}
60 changes: 60 additions & 0 deletions DiagnosticsTests/Reporters/LogsTrimmerTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//
// LogsTrimmerTests.swift
//
//
// Created by Antoine van der Lee on 01/03/2024.
//
// swiftlint:disable line_length

@testable import Diagnostics
import XCTest

final class LogsTrimmerTests: XCTestCase {

/// It should trim the oldest line and skip session headers.
func testTrimmingSessionsSingleLine() {
let expectedOutput = """
<summary><div class="session-header"><p><span>Date: </span>2024-02-20 10:33:47</p><p><span>System: </span>iOS 16.3</p><p><span>Locale: </span>en-GB</p><p><span>Version: </span>6.2.8 (17000)</p></div></summary>
<p class="system"><span class="log-date">2024-02-20 10:33:47</span><span class="log-separator"> | </span><span class="log-message">SYSTEM: 2024-02-20 10:33:47.086 Collect[32949:1669571] Reachability Flag Status: -R t------ reachabilityStatusForFlags</span></p>
"""

var input = expectedOutput
input += """
<p class="system"><span class="log-date">2024-02-20 10:33:47</span><span class="log-separator"> | </span><span class="log-message">SYSTEM: 2024-02-20 10:33:47.101 Collect[32949:1669571] [Firebase/Crashlytics] Version 8.15.0</span></p>
"""

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 = """
<summary><div class="session-header"><p><span>Date: </span>2024-02-20 10:33:47</p><p><span>System: </span>iOS 16.3</p><p><span>Locale: </span>en-GB</p><p><span>Version: </span>6.2.8 (17000)</p></div></summary>
"""

var input = expectedOutput
input += """
<p class="system"><span class="log-date">2024-02-20 10:33:47</span><span class="log-separator"> | </span><span class="log-message">SYSTEM: 2024-02-20 10:33:47.086 Collect[32949:1669571] Reachability Flag Status: -R t------ reachabilityStatusForFlags</span></p>
<p class="system"><span class="log-date">2024-02-20 10:33:47</span><span class="log-separator"> | </span><span class="log-message">SYSTEM: 2024-02-20 10:33:47.101 Collect[32949:1669571] [Firebase/Crashlytics] Version 8.15.0</span></p>
"""

var inputData = Data(input.utf8)
let trimmer = LogsTrimmer(
numberOfLinesToTrim: 10
)

trimmer.trim(data: &inputData)

let outputString = String(data: inputData, encoding: .utf8)
XCTAssertEqual(outputString, expectedOutput)
}
}
// swiftlint:enable line_length
15 changes: 5 additions & 10 deletions Sources/Logging/DiagnosticsLogger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)")
Expand Down
49 changes: 49 additions & 0 deletions Sources/Logging/LogsTrimmer.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//
// 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 = "<p class=\"system\"><span class=\"log-date\">(.*?)</span></p>"

// 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)
}
}

0 comments on commit f5c4c56

Please sign in to comment.