Skip to content

Conversation

@rebello95
Copy link
Collaborator

@rebello95 rebello95 commented Mar 3, 2023

Adds the ability for interceptors to receive metrics data via a new closure. This is helpful for tracing, i.e., when building an interceptor that:

  • Creates a trace span when a request is sent, stores that span on itself, and optionally alters the request headers
  • Closes the span when a response is received
  • Adds additional information to the span when metrics are provided

Ideally, this information would be included in the response callback itself (i.e., within the HTTPResponse), but URLSession does not provide URLSessionTaskMetrics at the same time that it provides the response. Furthermore, metrics tend to arrive after the response completes, and blocking the response from being passed back to the caller while waiting for metrics does not make sense. Instead, a new callback is being added to unary interceptors.

Example:

private final class SampleInterceptor: Interceptor {
    func unaryFunction() -> Connect.UnaryFunction {
        return .init(
            requestFunction: { $0 },
            responseFunction: { $0 },
            responseMetricsFunction: { metrics in
                print("**Metrics: \(metrics)")
                return metrics
            }
        )
    }

    func streamFunction() -> Connect.StreamFunction {
        fatalError()
    }
}

Which prints something like this:

**Metrics: HTTPMetrics(taskMetrics: (Task Interval) <_NSConcreteDateInterval: 0x600003654e20> (Start Date) 2023-03-03 23:19:10 +0000 + (Duration) 0.326617 seconds = (End Date) 2023-03-03 23:19:10 +0000
(Redirect Count) 0
(Transaction Metrics) (Request) <NSMutableURLRequest: 0x6000034bb4c0> { URL: https://demo.connect.build/buf.connect.demo.eliza.v1.ElizaService/Say }
(Response) <NSHTTPURLResponse: 0x6000037a6a60> { URL: https://demo.connect.build/buf.connect.demo.eliza.v1.ElizaService/Say } { Status Code: 200, Headers {
    "Accept-Encoding" =     (
        gzip
    );
    "Alt-Svc" =     (
        "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000"
    );
    "Content-Length" =     (
        55
    );
    "Content-Type" =     (
        "application/proto"
    );
    Date =     (
        "Fri, 03 Mar 2023 23:18:54 GMT"
    );
    Server =     (
        "Google Frontend"
    );
    Vary =     (
        Origin
    );
    Via =     (
        "1.1 google"
    );
    traceparent =     (
        "00-9241f673bcbbcd032a5916609af966dc-8c76b9eb554865b1-01"
    );
    "x-cloud-trace-context" =     (
        "9241f673bcbbcd032a5916609af966dc/10121481632961029553;o=1"
    );
} }
(Fetch Start) 2023-03-03 23:19:10 +0000
(Domain Lookup Start) (null)
(Domain Lookup End) (null)
(Connect Start) (null)
(Secure Connection Start) (null)
(Secure Connection End) (null)
(Connect End) (null)
(Request Start) 2023-03-03 23:19:10 +0000
(Request End) 2023-03-03 23:19:10 +0000
(Response Start) 2023-03-03 23:19:10 +0000
(Response End) 2023-03-03 23:19:10 +0000
(Protocol Name) (null)
(Proxy Connection) NO
(Reused Connection) NO
(Fetch Type) Local Cache
(Request Header Bytes) 0
(Request Body Transfer Bytes) 0
(Request Body Bytes) 0
(Response Header Bytes) 0
(Response Body Transfer Bytes) 0
(Response Body Bytes) 0
(Local Address) (null)
(Local Port) (null)
(Remote Address) (null)
(Remote Port) (null)
(TLS Protocol Version) 0x0000
(TLS Cipher Suite) 0x0000
(Cellular) NO
(Expensive) NO
(Constrained) NO
(Multipath) NO

(Request) <NSURLRequest: 0x6000034bb480> { URL: https://demo.connect.build/buf.connect.demo.eliza.v1.ElizaService/Say }
(Response) <NSHTTPURLResponse: 0x6000037afa60> { URL: https://demo.connect.build/buf.connect.demo.eliza.v1.ElizaService/Say } { Status Code: 200, Headers {
    "Accept-Encoding" =     (
        gzip
    );
    "Alt-Svc" =     (
        "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000"
    );
    "Content-Length" =     (
        55
    );
    "Content-Type" =     (
        "application/proto"
    );
    Date =     (
        "Fri, 03 Mar 2023 23:19:10 GMT"
    );
    Server =     (
        "Google Frontend"
    );
    Vary =     (
        Origin
    );
    Via =     (
        "1.1 google"
    );
    traceparent =     (
        "00-ae364b402513689f7fec0ca19ec0e48c-58203dacb495c785-01"
    );
    "x-cloud-trace-context" =     (
        "ae364b402513689f7fec0ca19ec0e48c/6350143286565783429;o=1"
    );
} }
(Fetch Start) 2023-03-03 23:19:10 +0000
(Domain Lookup Start) 2023-03-03 23:19:10 +0000
(Domain Lookup End) 2023-03-03 23:19:10 +0000
(Connect Start) 2023-03-03 23:19:10 +0000
(Secure Connection Start) 2023-03-03 23:19:10 +0000
(Secure Connection End) 2023-03-03 23:19:10 +0000
(Connect End) 2023-03-03 23:19:10 +0000
(Request Start) 2023-03-03 23:19:10 +0000
(Request End) 2023-03-03 23:19:10 +0000
(Response Start) 2023-03-03 23:19:10 +0000
(Response End) 2023-03-03 23:19:10 +0000
(Protocol Name) h3
(Proxy Connection) NO
(Reused Connection) NO
(Fetch Type) Network Load
(Request Header Bytes) 170
(Request Body Transfer Bytes) 0
(Request Body Bytes) 6
(Response Header Bytes) 243
(Response Body Transfer Bytes) 57
(Response Body Bytes) 55
(Local Address) 192.168.13.223
(Local Port) 64004
(Remote Address) 35.227.208.237
(Remote Port) 443
(TLS Protocol Version) 0x0304
(TLS Cipher Suite) 0x1301
(Cellular) NO
(Expensive) NO
(Constrained) NO
(Multipath) NO

)

@rebello95 rebello95 marked this pull request as ready for review March 6, 2023 18:11
@rebello95 rebello95 requested a review from buildbreaker March 6, 2023 18:13
@rebello95 rebello95 merged commit 9e3d90a into main Mar 6, 2023
@rebello95 rebello95 deleted the interceptors-metrics branch March 6, 2023 23:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants