Skip to content

Commit

Permalink
Add scoped attributes to plcrashreport (#125)
Browse files Browse the repository at this point in the history
* Add scoped attributes to plcrashreport

* Use +=
  • Loading branch information
konraddysput authored Jun 21, 2024
1 parent 41814ae commit b6823f9
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 10 deletions.
13 changes: 8 additions & 5 deletions Sources/Features/Attributes/AttributesProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,24 +44,27 @@ extension AttributesProvider: SignalContext {
self.faultInfo.faultMessage = faultMessage
}

func set(errorType: String?) {
self.attributes["error.type"] = errorType
}

var attachmentPaths: [String] {
return allAttachments.map(\.path)
}

var allAttachments: Attachments {
attachments + attributesSources.map(\.attachments).reduce([], +)
}

var scopedAttributes: Attributes {
return immutable + attributes;
}
var dynamicAttributes: Attributes {
return attributesSources.map(\.mutable).merging()
}

var allAttributes: Attributes {
return attributes + defaultAttributes
}

var defaultAttributes: Attributes {
return immutable + attributesSources.map(\.mutable).merging()
return immutable + dynamicAttributes
}
}

Expand Down
4 changes: 4 additions & 0 deletions Sources/Features/Attributes/DefaultAttributes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import UIKit

final class FaultInfo: AttributesSource {
var faultMessage: String?

var immutable: [String : Any?] {
return ["error.type": "Crash"]
}
var mutable: [String: Any?] {
return ["error.message": faultMessage]
}
Expand Down
9 changes: 8 additions & 1 deletion Sources/Features/Client/BacktraceReporter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ extension BacktraceReporter: BacktraceClientCustomizing {
return attributesProvider.attributes
} set {
attributesProvider.attributes = newValue

guard let attributeData = try? JSONSerialization.data(withJSONObject: attributesProvider.scopedAttributes) else {
return
}
self.reporter.setCustomData(data: attributeData)

}
}

Expand Down Expand Up @@ -111,10 +117,11 @@ extension BacktraceReporter {
func generate(exception: NSException? = nil, attachmentPaths: [String] = [],
faultMessage: String? = nil) throws -> BacktraceReport {
attributesProvider.set(faultMessage: faultMessage)
attributesProvider.set(errorType: "Exception")
let resource = try reporter.generateLiveReport(exception: exception,
attributes: attributesProvider.allAttributes,
attachmentPaths: attachmentPaths + attributesProvider.attachmentPaths)

resource.attributes["error.type"] = "Exception"
return resource
}
}
Expand Down
6 changes: 6 additions & 0 deletions Sources/Features/Extensions/Foundation+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ extension Dictionary {
static func + (lhs: Dictionary, rhs: Dictionary) -> Dictionary {
return lhs.merging(rhs, uniquingKeysWith: {_, new in new})
}

static func += (left: inout Dictionary, right: Dictionary) {
for (key, value) in right {
left[key] = value
}
}
}

// From: https://stackoverflow.com/a/57886995
Expand Down
21 changes: 20 additions & 1 deletion Sources/Features/Repository/Model/BacktraceReport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ import CrashReporter
self.attachmentPaths = attachmentPaths
self.attributes = attributes
super.init()

self.extendCrashAttributes()
}

init(managedObject: Crash) throws {
guard let reportData = managedObject.reportData,
let identifierString = managedObject.hashProperty,
Expand All @@ -37,7 +39,10 @@ import CrashReporter
self.identifier = identifier
self.attachmentPaths = attachmentPaths
self.attributes = (try? AttributesStorage.retrieve(fileName: identifier.uuidString)) ?? [:]

super.init()

self.extendCrashAttributes()
}
}

Expand All @@ -46,4 +51,18 @@ extension BacktraceReport: PersistentStorable {
typealias ManagedObjectType = Crash

static var entityName: String { return "Crash" }

private func extendCrashAttributes() {
guard let customData = self.plCrashReport.customData else {
return
}

if let attributes = try? JSONSerialization.jsonObject(with: customData, options: []) as? [String: Any] {
self.attributes += attributes
} else {
return
}
}


}
9 changes: 7 additions & 2 deletions Sources/Public/BacktraceCrashReporter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ extension BacktraceCrashReporter: CrashReporting {
let signalInfo = signalInfoPointer?.pointee else {
return
}
attributesProvider.set(errorType: "Crash")

attributesProvider.set(faultMessage: "siginfo_t.si_signo: \(signalInfo.si_signo)")

try? AttributesStorage.store(attributesProvider.allAttributes, fileName: BacktraceCrashReporter.crashName)
try? AttributesStorage.store(attributesProvider.dynamicAttributes, fileName: BacktraceCrashReporter.crashName)
try? AttachmentsStorage.store(attributesProvider.allAttachments, fileName: BacktraceCrashReporter.crashName)
}

Expand All @@ -60,10 +60,15 @@ extension BacktraceCrashReporter: CrashReporting {
// This function retrieves, constructs, and sends the pending crash report
func pendingCrashReport() throws -> BacktraceReport {
let reportData = try reporter.loadPendingCrashReportDataAndReturnError()

let attributes = (try? AttributesStorage.retrieve(fileName: BacktraceCrashReporter.crashName)) ?? [:]
let attachmentPaths = copiedFileAttachments.map(\.path)
return try BacktraceReport(report: reportData, attributes: attributes, attachmentPaths: attachmentPaths)
}

func setCustomData(data: Data) {
self.reporter.customData = data
}

// This function is called to copy stored file attachments
// from pending crashes so that they are not overwritten by the
Expand Down
1 change: 1 addition & 0 deletions Sources/Public/Internal/CrashReporting.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ protocol CrashReporting {
func hasPendingCrashes() -> Bool
func enableCrashReporting() throws
func signalContext(_ mutableContext: inout SignalContext)
func setCustomData(data: Data) -> Void
}
3 changes: 2 additions & 1 deletion Sources/Public/Internal/SignalContext.swift
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import Foundation

protocol SignalContext: CustomStringConvertible {
var scopedAttributes: Attributes { get }
var allAttributes: Attributes { get }
var dynamicAttributes: Attributes { get }
var allAttachments: Attachments { get }
var attributes: Attributes { get set }
// File attachments are stored to disk as URLs
var attachments: Attachments { get set }
// File attachments are used in `BacktraceReport` as string paths
var attachmentPaths: [String] { get }
func set(faultMessage: String?)
func set(errorType: String?)
}

0 comments on commit b6823f9

Please sign in to comment.