`RUM.ResourceAttributesProvider` not providing `data` information in URLSession tracking
Describe the bug
ResourceAttributesProvider in the urlSessionTracking initializer for RUM is not providing data information for network requests made with data(for:) methods. It provides URLRequest and URLResponse information, but data always comes back as nil and does not populate for resources. This seems to be limiting the automatic tracking experience.
Reproduction
Configure Datadog RUM and enable urlSessionTracking with the resourceAttributesProvider. Create a network request using async await and data(for:). Call the request and observe that neither the closure for the attributes, nor the resource in the RUM dashboard will show data.
RUM.enable(
with: RUM.Configuration(
applicationID: appID,
urlSessionTracking: RUM.Configuration.URLSessionTracking(resourceAttributesProvider: { req, resp, data, err in
return ["dataInfo": data]
})
)
)
Datadog SDK version:
SDK V 2.7.0
Dependency Manager:
Which dependency manager do you use? e.g. Cocoapods / Carthage / SPM / ... SPM
Deployment Target:
What is the Deployment Target of your app? e.g. iOS 12, iPhone + iPad
ios 17
Hello @a-benavente 👋. Thanks for reporting this. I confirm, we can reproduce the wrong behaviour on our side, sorry.
This will require priority fix on our side, stay tuned. The bug was introduced in 2.5.0 with adding support to async/await URLSession APIs. The behaviour is correct in 2.4.0 and below, but async/await is not supported there.
Problem is not limited to async/await APIs tho, I can see no data with regular task API, hence I updated the title.
Reproduction code:
rumConfig.urlSessionTracking = .init(
resourceAttributesProvider: { request, response, data, error in
print("⭐️ [Attributes Provider] data: \(data)")
return [:]
}
)
class InstrumentedSessionDelegate: NSObject, URLSessionDataDelegate {}
URLSessionInstrumentation.enable(
with: .init(
delegateClass: InstrumentedSessionDelegate.self
)
)
let session = URLSession(configuration: .ephemeral, delegate: InstrumentedSessionDelegate(), delegateQueue: nil)
var request = URLRequest(url: URL(string: "https://httpbin.org/ip")!)
request.httpMethod = "GET"
let task = session.dataTask(with: request) { data, _, _ in
print("⭐️ [Task] data: \(data)")
}
task.resume()
Output:
⭐️ [Task] data: Optional(31 bytes)
⭐️ [Attributes Provider] data: nil
Thank you! I will keep an eye out for the fix @ncreated
We have merged the related PR #1696 which fixes the regression.
However, this doesn't address the async-await APIs because lack of completion handler and swizzling of APIs.
I'm going to keep the issue opened until we figure out the async-await API fix.
On the fix side, I'm skeptical given the fact, we can't swizzle async-await APIs. The only delegate method we can trust is urlSession(_:task:didFinishCollecting:) which doesn't provide access to response (error or data). Hence, the solution that we have for other APIs can't be applied here.
Keep an eye on the issue, we will update it as soon as we have something to share.