Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions Backtrace.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ Pod::Spec.new do |s|
s.osx.public_header_files = ["Backtrace-macOS/**/*.h*"]
s.tvos.public_header_files = ["Backtrace-tvOS/**/*.h*"]

s.ios.dependency "Cassette", '1.0.0-beta5'
Copy link
Contributor

@vlussenburg vlussenburg May 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check if there's any superfluous #if os(iOS) || os(OSX) left in prod/test code. I know there were a bunch of 'm

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll take a look :)

s.osx.dependency "Cassette", '1.0.0-beta5'
s.dependency "Backtrace-PLCrashReporter", '1.5.3'

s.resources = 'Sources/**/*.xcdatamodeld'
Expand Down
416 changes: 216 additions & 200 deletions Backtrace.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ end

def shared_ios_mac_pods
shared_pods
pod 'Cassette', '1.0.0-beta5'
end

def shared_test_ios_mac_pods
Expand Down
13 changes: 4 additions & 9 deletions Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
PODS:
- Backtrace (1.7.4-beta2):
- Backtrace (1.7.5):
- Backtrace-PLCrashReporter (= 1.5.3)
- Cassette (= 1.0.0-beta5)
- Backtrace-PLCrashReporter (1.5.3)
- Cassette (1.0.0-beta5)
- Nimble (10.0.0)
- Quick (5.0.1)

DEPENDENCIES:
- Backtrace (from `./Backtrace.podspec`)
- Backtrace-PLCrashReporter (= 1.5.3)
- Cassette (= 1.0.0-beta5)
- Nimble (~> 10.0.0)
- Quick (~> 5.0.1)

SPEC REPOS:
trunk:
- Backtrace-PLCrashReporter
- Cassette
- Nimble
- Quick

Expand All @@ -26,12 +22,11 @@ EXTERNAL SOURCES:
:path: "./Backtrace.podspec"

SPEC CHECKSUMS:
Backtrace: c0124ca7e1a84bc7a3b3407671fb99a90be474e9
Backtrace: 1b471570061cb4740b42663aaf3e381177a317ce
Backtrace-PLCrashReporter: 71ddeba11834d2bcc3c19f357aaec7bf87131f89
Cassette: 074c6991391733888990dba728b7ffe00299a0a6
Nimble: 5316ef81a170ce87baf72dd961f22f89a602ff84
Quick: 749aa754fd1e7d984f2000fe051e18a3a9809179

PODFILE CHECKSUM: 2045466adc5eebf2fa4652c2a2c73ec6a81b89b3
PODFILE CHECKSUM: ec560ea7bd4dba9a68a30ffbb0b25db5e3491921

COCOAPODS: 1.11.3
COCOAPODS: 1.12.1
105 changes: 105 additions & 0 deletions Sources/Features/Breadcrumb/BacktraceBreadcrumbFile.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import Foundation

enum BacktraceBreadcrumbFileError: Error {
case invalidFormat
}

@objc class BacktraceBreadcrumbFile: NSObject {

private static let minimumQueueFileSizeBytes = 4096
private let maximumIndividualBreadcrumbSize: Int
private let maxQueueFileSizeBytes: Int
private let queue: Queue<BreadcrumbRecord>
private let breadcrumbLogURL: URL
private let dispatchQueue = DispatchQueue(label: "io.backtrace.BacktraceBreadcrumbFile@\(UUID().uuidString)")

public init(_ breadcrumbSettings: BacktraceBreadcrumbSettings) throws {
self.breadcrumbLogURL = try breadcrumbSettings.getBreadcrumbLogPath()
self.queue = Queue<BreadcrumbRecord>()
self.maximumIndividualBreadcrumbSize = breadcrumbSettings.maxIndividualBreadcrumbSizeBytes
if breadcrumbSettings.maxQueueFileSizeBytes < BacktraceBreadcrumbFile.minimumQueueFileSizeBytes {
BacktraceLogger.warning("\(breadcrumbSettings.maxQueueFileSizeBytes) is smaller than the minimum of " +
"\(BacktraceBreadcrumbFile.minimumQueueFileSizeBytes)" +
", ignoring value and overriding with minimum.")
self.maxQueueFileSizeBytes = BacktraceBreadcrumbFile.minimumQueueFileSizeBytes
} else {
self.maxQueueFileSizeBytes = breadcrumbSettings.maxQueueFileSizeBytes
}

super.init()
}

func addBreadcrumb(_ breadcrumb: [String: Any]) -> Bool {
guard let breadcrumbJsonData = try? JSONSerialization.data(withJSONObject: breadcrumb) else {
BacktraceLogger.warning("Error when converting breadcrumb to data")
return false
}
guard let breadcrumbJsonString = String(data: breadcrumbJsonData, encoding: .utf8) else {
BacktraceLogger.warning("Error when converting breadcrumb to string")
return false
}
let breadcrumbSize = breadcrumbJsonData.count
// Check if breadcrumb size is larger than the maximum specified
if breadcrumbSize > maximumIndividualBreadcrumbSize {
BacktraceLogger.warning(
"Discarding breadcrumb that was larger than the maximum specified (\(maximumIndividualBreadcrumbSize).")
return false
}
dispatchQueue.sync {
let queueBreadcrumb = BreadcrumbRecord(size: breadcrumbSize, json: breadcrumbJsonString)
queue.enqueue(queueBreadcrumb)
let queuedBreadcrumbs = queue.allElements()
let queueSize = queue.count
var breadcrumbsArray = [String]()
var size = 0
for index in (0..<queueSize).reversed() {
guard index < queuedBreadcrumbs.count else {
continue
}
let queueBreadcrumb = queuedBreadcrumbs[index]
let breadcrumbSize = queueBreadcrumb.size
// Pop last element if size is greater than maxQueueFileSizeBytes
if size + breadcrumbSize > maxQueueFileSizeBytes && !queue.isEmpty {
while (index != 0) {
_ = queue.pop(at: index)
}
break
}
let breadcrumbJsonData = queueBreadcrumb.json
breadcrumbsArray.append(breadcrumbJsonData)
size += breadcrumbSize
}
let breadcrumbString = "[\(breadcrumbsArray.joined(separator: ","))]"
writeBreadcrumbToLogFile(breadcrumb: breadcrumbString, at: self.breadcrumbLogURL)
}

return true
}

func clear() -> Bool {
dispatchQueue.sync {
queue.clear()
clearBreadcrumbLogFile(at:self.breadcrumbLogURL)
}
return true
}
}

extension BacktraceBreadcrumbFile {

func writeBreadcrumbToLogFile(breadcrumb: String, at breadcrumbLogURL: URL) {
do {
try breadcrumb.write(to: breadcrumbLogURL, atomically: true, encoding: .utf8)
} catch {
BacktraceLogger.warning("Error writing breadcrumb to log file at: \(breadcrumbLogURL) - \(error.localizedDescription)")
}
}

func clearBreadcrumbLogFile(at breadcrumbLogURL: URL) {
do {
try "".write(to: breadcrumbLogURL, atomically: false, encoding: .utf8)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if someone deletes a file when you're generating breadcrumbs?

} catch {
BacktraceLogger.warning("Error clearing breadcrumb log file at: \(breadcrumbLogURL) - \(error.localizedDescription)")
}
}
}
113 changes: 0 additions & 113 deletions Sources/Features/Breadcrumb/BacktraceBreadcrumbFileHelper.swift

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import Foundation
@objc class BacktraceBreadcrumbsLogManager: NSObject {

private var breadcrumbId: Int
private let backtraceBreadcrumbFileHelper: BacktraceBreadcrumbFileHelper
private let backtraceBreadcrumbFile: BacktraceBreadcrumbFile

init(breadcrumbSettings: BacktraceBreadcrumbSettings) throws {
self.backtraceBreadcrumbFileHelper = try BacktraceBreadcrumbFileHelper(breadcrumbSettings)
self.backtraceBreadcrumbFile = try BacktraceBreadcrumbFile(breadcrumbSettings)

self.breadcrumbId = Date().millisecondsSince1970
BreadcrumbsInfo.currentBreadcrumbsId = breadcrumbId
Expand All @@ -29,11 +29,11 @@ import Foundation
"message": message]
breadcrumb["attributes"] = attributes

return backtraceBreadcrumbFileHelper.addBreadcrumb(breadcrumb)
return backtraceBreadcrumbFile.addBreadcrumb(breadcrumb)
}

func clear() -> Bool {
let result = backtraceBreadcrumbFileHelper.clear()
let result = backtraceBreadcrumbFile.clear()
if result {
breadcrumbId = Date().millisecondsSince1970
BreadcrumbsInfo.currentBreadcrumbsId = breadcrumbId
Expand Down
11 changes: 11 additions & 0 deletions Sources/Features/Breadcrumb/BreadcrumbRecord.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Foundation

struct BreadcrumbRecord {
let size: Int
let json: String

init(size: Int, json: String) {
self.size = size
self.json = json
}
}
66 changes: 66 additions & 0 deletions Sources/Features/Breadcrumb/Queue.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import Foundation

@objcMembers
public class Queue<T>: NSObject {
private var elements: [T] = []

func enqueue(_ element: T) {
elements.append(element)
}

func dequeue() -> T? {
if elements.isEmpty {
return nil
} else {
return elements.removeFirst()
}
}

func peek() -> T? {
return elements.first
}

func remove(at index: Int) -> T? {
guard index < elements.count else {
return nil
}
return elements.remove(at: index)
}

func pop(at index: Int) -> T? {
guard !elements.isEmpty else {
return nil
}
return remove(at: index)
}

func element(at index: Int) -> T? {
guard index >= 0 && index < elements.count else {
return nil
}
return elements[index]
}

func pop() -> T? {
guard !elements.isEmpty else {
return nil
}
return elements.popLast()
}

public func allElements() -> [T] {
return elements
}

func clear() {
elements.removeAll()
}

var isEmpty: Bool {
return elements.isEmpty
}

var count: Int {
return elements.count
}
}
Loading