open-telemetry / opentelemetry-swift

OpenTelemetry API for Swift
https://opentelemetry.io/docs/instrumentation/swift/
Apache License 2.0
224 stars 148 forks source link

URLSession Metrics Instrumentation #150

Open Sherlouk opened 3 years ago

Sherlouk commented 3 years ago

Hey there ๐Ÿ‘‹

Recently saw PR #119 which is currently on it's own branch which looks really nice and starts progress into instrumenting apps automatically.

I wonder how you would feel supporting task metrics?

optional func urlSession(_ session: URLSession, 
                         task: URLSessionTask, 
                         didFinishCollecting metrics: URLSessionTaskMetrics)

These metrics give us access to a lot more information about the network request including information the request characteristics, host details, TLS security information but most importantly for me it includes detailed network timings.

image

I've currently got my own OpenTelemetry instrumentation which outputs something like this:

Captured 2021-03-31 at 10 30 36

Currently I use a URLSession proxy delegate which requires some manual changes to the network stack, but it should (though I have been unable to confirm this) be possible to swizzle the above function call in the same way you have other methods.

I believe there to be quite a lot of value both in terms of the spans but also the metadata that can be achieved by adding metrics support ๐Ÿ˜„

Thanks!

nachoBonafonte commented 3 years ago

Yes, having exact timings and the possibility of this level of detail in network calls would be great. But I am not sure that it would work automatically for all calls just by swizzling this method. The API will probably check if it has a delegate before calling the method, so sessions without delegate would not recover this information. But definitely deserves some investigation and evaluate the possibilities.

nachoBonafonte commented 3 years ago

I have been doing some investigation here, and as expected, we need the URLSession to have a delegate so we can swizzle the method. I have uploaded some code to the network branch for capturing session task metrics, it swizzles the method if exists or adds the method if the session has a delegate. We cannot set a delegate ourselves though. Also added some more code to the network example for easier testing The code just captures the method, still doesn't create spans or anything like that. We should also think what to do when we have both ways of creating spans for the network, probably add some user configuration and things like that.