/*
 * Copyright (C) 2017 Square, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package okhttp3;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.List;
import javax.annotation.Nullable;

Listener for metrics events. Extend this class to monitor the quantity, size, and duration of your application's HTTP calls.

All start/connect/acquire events will eventually receive a matching end/release event, either successful (non-null parameters), or failed (non-null throwable). The first common parameters of each event pair are used to link the event in case of concurrent or repeated events e.g. dnsStart(call, domainName) -> dnsEnd(call, domainName, inetAddressList).

Nesting is as follows

  • call -> (dns -> connect -> secure connect)* -> request events
  • call -> (connection acquire/release)*

Request events are ordered: requestHeaders -> requestBody -> responseHeaders -> responseBody

Since connections may be reused, the dns and connect events may not be present for a call, or may be repeated in case of failure retries, even concurrently in case of happy eyeballs type scenarios. A redirect cross domain, or to use https may cause additional connection and request events.

All event methods must execute fast, without external locking, cannot throw exceptions, attempt to mutate the event parameters, or be reentrant back into the client. Any IO - writing to files or network should be done asynchronously.

/** * Listener for metrics events. Extend this class to monitor the quantity, size, and duration of * your application's HTTP calls. * * <p>All start/connect/acquire events will eventually receive a matching end/release event, * either successful (non-null parameters), or failed (non-null throwable). The first common * parameters of each event pair are used to link the event in case of concurrent or repeated * events e.g. dnsStart(call, domainName) -&gt; dnsEnd(call, domainName, inetAddressList). * * <p>Nesting is as follows * <ul> * <li>call -&gt; (dns -&gt; connect -&gt; secure connect)* -&gt; request events</li> * <li>call -&gt; (connection acquire/release)*</li> * </ul> * * <p>Request events are ordered: * requestHeaders -&gt; requestBody -&gt; responseHeaders -&gt; responseBody * * <p>Since connections may be reused, the dns and connect events may not be present for a call, * or may be repeated in case of failure retries, even concurrently in case of happy eyeballs type * scenarios. A redirect cross domain, or to use https may cause additional connection and request * events. * * <p>All event methods must execute fast, without external locking, cannot throw exceptions, * attempt to mutate the event parameters, or be reentrant back into the client. * Any IO - writing to files or network should be done asynchronously. */
public abstract class EventListener { public static final EventListener NONE = new EventListener() { }; static EventListener.Factory factory(final EventListener listener) { return new EventListener.Factory() { public EventListener create(Call call) { return listener; } }; }
Invoked as soon as a call is enqueued or executed by a client. In case of thread or stream limits, this call may be executed well before processing the request is able to begin.

This will be invoked only once for a single Call. Retries of different routes or redirects will be handled within the boundaries of a single callStart and callEnd/callFailed pair.

/** * Invoked as soon as a call is enqueued or executed by a client. In case of thread or stream * limits, this call may be executed well before processing the request is able to begin. * * <p>This will be invoked only once for a single {@link Call}. Retries of different routes * or redirects will be handled within the boundaries of a single callStart and {@link * #callEnd}/{@link #callFailed} pair. */
public void callStart(Call call) { }
Invoked just prior to a DNS lookup. See Dns.lookup(String).

This can be invoked more than 1 time for a single Call. For example, if the response to the Call.request() is a redirect to a different host.

If the Call is able to reuse an existing pooled connection, this method will not be invoked. See ConnectionPool.

/** * Invoked just prior to a DNS lookup. See {@link Dns#lookup(String)}. * * <p>This can be invoked more than 1 time for a single {@link Call}. For example, if the response * to the {@link Call#request()} is a redirect to a different host. * * <p>If the {@link Call} is able to reuse an existing pooled connection, this method will not be * invoked. See {@link ConnectionPool}. */
public void dnsStart(Call call, String domainName) { }
Invoked immediately after a DNS lookup.

This method is invoked after dnsStart.

/** * Invoked immediately after a DNS lookup. * * <p>This method is invoked after {@link #dnsStart}. */
public void dnsEnd(Call call, String domainName, List<InetAddress> inetAddressList) { }
Invoked just prior to initiating a socket connection.

This method will be invoked if no existing connection in the ConnectionPool can be reused.

This can be invoked more than 1 time for a single Call. For example, if the response to the Call.request() is a redirect to a different address, or a connection is retried.

/** * Invoked just prior to initiating a socket connection. * * <p>This method will be invoked if no existing connection in the {@link ConnectionPool} can be * reused. * * <p>This can be invoked more than 1 time for a single {@link Call}. For example, if the response * to the {@link Call#request()} is a redirect to a different address, or a connection is retried. */
public void connectStart(Call call, InetSocketAddress inetSocketAddress, Proxy proxy) { }
Invoked just prior to initiating a TLS connection.

This method is invoked if the following conditions are met:

This can be invoked more than 1 time for a single Call. For example, if the response to the Call.request() is a redirect to a different address, or a connection is retried.

/** * Invoked just prior to initiating a TLS connection. * * <p>This method is invoked if the following conditions are met: * <ul> * <li>The {@link Call#request()} requires TLS.</li> * <li>No existing connection from the {@link ConnectionPool} can be reused.</li> * </ul> * * <p>This can be invoked more than 1 time for a single {@link Call}. For example, if the response * to the {@link Call#request()} is a redirect to a different address, or a connection is retried. */
public void secureConnectStart(Call call) { }
Invoked immediately after a TLS connection was attempted.

This method is invoked after secureConnectStart.

/** * Invoked immediately after a TLS connection was attempted. * * <p>This method is invoked after {@link #secureConnectStart}. */
public void secureConnectEnd(Call call, @Nullable Handshake handshake) { }
Invoked immediately after a socket connection was attempted.

If the call uses HTTPS, this will be invoked after secureConnectEnd(Call, Handshake), otherwise it will invoked after connectStart(Call, InetSocketAddress, Proxy).

/** * Invoked immediately after a socket connection was attempted. * * <p>If the {@code call} uses HTTPS, this will be invoked after * {@link #secureConnectEnd(Call, Handshake)}, otherwise it will invoked after * {@link #connectStart(Call, InetSocketAddress, Proxy)}. */
public void connectEnd(Call call, InetSocketAddress inetSocketAddress, Proxy proxy, @Nullable Protocol protocol) { }
Invoked when a connection attempt fails. This failure is not terminal if further routes are available and failure recovery is enabled.

If the call uses HTTPS, this will be invoked after secureConnectEnd(Call, Handshake), otherwise it will invoked after connectStart(Call, InetSocketAddress, Proxy).

/** * Invoked when a connection attempt fails. This failure is not terminal if further routes are * available and failure recovery is enabled. * * <p>If the {@code call} uses HTTPS, this will be invoked after {@link #secureConnectEnd(Call, * Handshake)}, otherwise it will invoked after {@link #connectStart(Call, InetSocketAddress, * Proxy)}. */
public void connectFailed(Call call, InetSocketAddress inetSocketAddress, Proxy proxy, @Nullable Protocol protocol, IOException ioe) { }
Invoked after a connection has been acquired for the call.

This can be invoked more than 1 time for a single Call. For example, if the response to the Call.request() is a redirect to a different address.

/** * Invoked after a connection has been acquired for the {@code call}. * * <p>This can be invoked more than 1 time for a single {@link Call}. For example, if the response * to the {@link Call#request()} is a redirect to a different address. */
public void connectionAcquired(Call call, Connection connection) { }
Invoked after a connection has been released for the call.

This method is always invoked after connectionAcquired(Call, Connection).

This can be invoked more than 1 time for a single Call. For example, if the response to the Call.request() is a redirect to a different address.

/** * Invoked after a connection has been released for the {@code call}. * * <p>This method is always invoked after {@link #connectionAcquired(Call, Connection)}. * * <p>This can be invoked more than 1 time for a single {@link Call}. For example, if the response * to the {@link Call#request()} is a redirect to a different address. */
public void connectionReleased(Call call, Connection connection) { }
Invoked just prior to sending request headers.

The connection is implicit, and will generally relate to the last connectionAcquired(Call, Connection) event.

This can be invoked more than 1 time for a single Call. For example, if the response to the Call.request() is a redirect to a different address.

/** * Invoked just prior to sending request headers. * * <p>The connection is implicit, and will generally relate to the last * {@link #connectionAcquired(Call, Connection)} event. * * <p>This can be invoked more than 1 time for a single {@link Call}. For example, if the response * to the {@link Call#request()} is a redirect to a different address. */
public void requestHeadersStart(Call call) { }
Invoked immediately after sending request headers.

This method is always invoked after requestHeadersStart(Call).

Params:
  • request – the request sent over the network. It is an error to access the body of this request.
/** * Invoked immediately after sending request headers. * * <p>This method is always invoked after {@link #requestHeadersStart(Call)}. * * @param request the request sent over the network. It is an error to access the body of this * request. */
public void requestHeadersEnd(Call call, Request request) { }
Invoked just prior to sending a request body. Will only be invoked for request allowing and having a request body to send.

The connection is implicit, and will generally relate to the last connectionAcquired(Call, Connection) event.

This can be invoked more than 1 time for a single Call. For example, if the response to the Call.request() is a redirect to a different address.

/** * Invoked just prior to sending a request body. Will only be invoked for request allowing and * having a request body to send. * * <p>The connection is implicit, and will generally relate to the last * {@link #connectionAcquired(Call, Connection)} event. * * <p>This can be invoked more than 1 time for a single {@link Call}. For example, if the response * to the {@link Call#request()} is a redirect to a different address. */
public void requestBodyStart(Call call) { }
Invoked immediately after sending a request body.

This method is always invoked after requestBodyStart(Call).

/** * Invoked immediately after sending a request body. * * <p>This method is always invoked after {@link #requestBodyStart(Call)}. */
public void requestBodyEnd(Call call, long byteCount) { }
Invoked just prior to receiving response headers.

The connection is implicit, and will generally relate to the last connectionAcquired(Call, Connection) event.

This can be invoked more than 1 time for a single Call. For example, if the response to the Call.request() is a redirect to a different address.

/** * Invoked just prior to receiving response headers. * * <p>The connection is implicit, and will generally relate to the last * {@link #connectionAcquired(Call, Connection)} event. * * <p>This can be invoked more than 1 time for a single {@link Call}. For example, if the response * to the {@link Call#request()} is a redirect to a different address. */
public void responseHeadersStart(Call call) { }
Invoked immediately after receiving response headers.

This method is always invoked after responseHeadersStart.

Params:
  • response – the response received over the network. It is an error to access the body of this response.
/** * Invoked immediately after receiving response headers. * * <p>This method is always invoked after {@link #responseHeadersStart}. * * @param response the response received over the network. It is an error to access the body of * this response. */
public void responseHeadersEnd(Call call, Response response) { }
Invoked just prior to receiving the response body.

The connection is implicit, and will generally relate to the last connectionAcquired(Call, Connection) event.

This will usually be invoked only 1 time for a single Call, exceptions are a limited set of cases including failure recovery.

/** * Invoked just prior to receiving the response body. * * <p>The connection is implicit, and will generally relate to the last * {@link #connectionAcquired(Call, Connection)} event. * * <p>This will usually be invoked only 1 time for a single {@link Call}, * exceptions are a limited set of cases including failure recovery. */
public void responseBodyStart(Call call) { }
Invoked immediately after receiving a response body and completing reading it.

Will only be invoked for requests having a response body e.g. won't be invoked for a websocket upgrade.

This method is always invoked after requestBodyStart(Call).

/** * Invoked immediately after receiving a response body and completing reading it. * * <p>Will only be invoked for requests having a response body e.g. won't be invoked for a * websocket upgrade. * * <p>This method is always invoked after {@link #requestBodyStart(Call)}. */
public void responseBodyEnd(Call call, long byteCount) { }
Invoked immediately after a call has completely ended. This includes delayed consumption of response body by the caller.

This method is always invoked after callStart(Call).

/** * Invoked immediately after a call has completely ended. This includes delayed consumption * of response body by the caller. * * <p>This method is always invoked after {@link #callStart(Call)}. */
public void callEnd(Call call) { }
Invoked when a call fails permanently.

This method is always invoked after callStart(Call).

/** * Invoked when a call fails permanently. * * <p>This method is always invoked after {@link #callStart(Call)}. */
public void callFailed(Call call, IOException ioe) { } public interface Factory {
Creates an instance of the EventListener for a particular Call. The returned EventListener instance will be used during the lifecycle of the call.

This method is invoked after the call is created. See OkHttpClient.newCall(Request).

It is an error for implementations to issue any mutating operations on the call instance from this method.

/** * Creates an instance of the {@link EventListener} for a particular {@link Call}. The returned * {@link EventListener} instance will be used during the lifecycle of the {@code call}. * * <p>This method is invoked after the {@code call} is created. See * {@link OkHttpClient#newCall(Request)}. * * <p><strong>It is an error for implementations to issue any mutating operations on the * {@code call} instance from this method.</strong> */
EventListener create(Call call); } }