Home | History | Annotate | Download | only in metrics
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.net.metrics;
     18 
     19 import android.net.NetworkCapabilities;
     20 
     21 import com.android.internal.util.BitUtils;
     22 
     23 import java.util.Arrays;
     24 
     25 /**
     26  * A batch of DNS events recorded by NetdEventListenerService for a specific network.
     27  * {@hide}
     28  */
     29 final public class DnsEvent {
     30 
     31     private static final int SIZE_LIMIT = 20000;
     32 
     33     // Network id of the network associated with the event, or 0 if unspecified.
     34     public final int netId;
     35     // Transports of the network associated with the event, as defined in NetworkCapabilities.
     36     // It is the caller responsability to ensure the value of transports does not change between
     37     // calls to addResult.
     38     public final long transports;
     39     // The number of DNS queries recorded. Queries are stored in the structure-of-array style where
     40     // the eventTypes, returnCodes, and latenciesMs arrays have the same length and the i-th event
     41     // is spread across the three array at position i.
     42     public int eventCount;
     43     // The number of successful DNS queries recorded.
     44     public int successCount;
     45     // The types of DNS queries as defined in INetdEventListener.
     46     public byte[] eventTypes;
     47     // Current getaddrinfo codes go from 1 to EAI_MAX = 15. gethostbyname returns errno, but there
     48     // are fewer than 255 errno values. So we store the result code in a byte as well.
     49     public byte[] returnCodes;
     50     // Latencies in milliseconds of queries, stored as ints.
     51     public int[] latenciesMs;
     52 
     53     public DnsEvent(int netId, long transports, int initialCapacity) {
     54         this.netId = netId;
     55         this.transports = transports;
     56         eventTypes = new byte[initialCapacity];
     57         returnCodes = new byte[initialCapacity];
     58         latenciesMs = new int[initialCapacity];
     59     }
     60 
     61     boolean addResult(byte eventType, byte returnCode, int latencyMs) {
     62         boolean isSuccess = (returnCode == 0);
     63         if (eventCount >= SIZE_LIMIT) {
     64             // TODO: implement better rate limiting that does not biases metrics.
     65             return isSuccess;
     66         }
     67         if (eventCount == eventTypes.length) {
     68             resize((int) (1.4 * eventCount));
     69         }
     70         eventTypes[eventCount] = eventType;
     71         returnCodes[eventCount] = returnCode;
     72         latenciesMs[eventCount] = latencyMs;
     73         eventCount++;
     74         if (isSuccess) {
     75             successCount++;
     76         }
     77         return isSuccess;
     78     }
     79 
     80     public void resize(int newLength) {
     81         eventTypes = Arrays.copyOf(eventTypes, newLength);
     82         returnCodes = Arrays.copyOf(returnCodes, newLength);
     83         latenciesMs = Arrays.copyOf(latenciesMs, newLength);
     84     }
     85 
     86     @Override
     87     public String toString() {
     88         StringBuilder builder =
     89                 new StringBuilder("DnsEvent(").append("netId=").append(netId).append(", ");
     90         for (int t : BitUtils.unpackBits(transports)) {
     91             builder.append(NetworkCapabilities.transportNameOf(t)).append(", ");
     92         }
     93         builder.append(String.format("%d events, ", eventCount));
     94         builder.append(String.format("%d success)", successCount));
     95         return builder.toString();
     96     }
     97 }
     98