Merge "[AF05] Fill NetworkStatsRecorderFileReading metrics" into main
This commit is contained in:
commit
59583789e9
3 changed files with 209 additions and 0 deletions
125
service-t/src/com/android/metrics/NetworkStatsMetricsLogger.java
Normal file
125
service-t/src/com/android/metrics/NetworkStatsMetricsLogger.java
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* 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 com.android.metrics;
|
||||
|
||||
import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_UID;
|
||||
import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_UID_TAG;
|
||||
import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_XT;
|
||||
|
||||
import static com.android.server.ConnectivityStatsLog.NETWORK_STATS_RECORDER_FILE_OPERATED;
|
||||
import static com.android.server.ConnectivityStatsLog.NETWORK_STATS_RECORDER_FILE_OPERATED__FAST_DATA_INPUT_STATE__FDIS_DISABLED;
|
||||
import static com.android.server.ConnectivityStatsLog.NETWORK_STATS_RECORDER_FILE_OPERATED__OPERATION_TYPE__ROT_READ;
|
||||
import static com.android.server.ConnectivityStatsLog.NETWORK_STATS_RECORDER_FILE_OPERATED__RECORDER_PREFIX__PREFIX_UID;
|
||||
import static com.android.server.ConnectivityStatsLog.NETWORK_STATS_RECORDER_FILE_OPERATED__RECORDER_PREFIX__PREFIX_UIDTAG;
|
||||
import static com.android.server.ConnectivityStatsLog.NETWORK_STATS_RECORDER_FILE_OPERATED__RECORDER_PREFIX__PREFIX_UNKNOWN;
|
||||
import static com.android.server.ConnectivityStatsLog.NETWORK_STATS_RECORDER_FILE_OPERATED__RECORDER_PREFIX__PREFIX_XT;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.net.NetworkStatsCollection;
|
||||
import android.net.NetworkStatsHistory;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.server.ConnectivityStatsLog;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Helper class to log NetworkStats related metrics.
|
||||
*
|
||||
* This class does not provide thread-safe.
|
||||
*/
|
||||
public class NetworkStatsMetricsLogger {
|
||||
final Dependencies mDeps;
|
||||
int mReadIndex = 1;
|
||||
|
||||
/** Dependency class */
|
||||
@VisibleForTesting
|
||||
public static class Dependencies {
|
||||
/**
|
||||
* Writes a NETWORK_STATS_RECORDER_FILE_OPERATION_REPORTED event to ConnectivityStatsLog.
|
||||
*/
|
||||
public void writeRecorderFileReadingStats(int recorderType, int readIndex,
|
||||
int readLatencyMillis,
|
||||
int fileCount, int totalFileSize,
|
||||
int keys, int uids, int totalHistorySize) {
|
||||
ConnectivityStatsLog.write(NETWORK_STATS_RECORDER_FILE_OPERATED,
|
||||
NETWORK_STATS_RECORDER_FILE_OPERATED__OPERATION_TYPE__ROT_READ,
|
||||
recorderType,
|
||||
readIndex,
|
||||
readLatencyMillis,
|
||||
fileCount,
|
||||
totalFileSize,
|
||||
keys,
|
||||
uids,
|
||||
totalHistorySize,
|
||||
NETWORK_STATS_RECORDER_FILE_OPERATED__FAST_DATA_INPUT_STATE__FDIS_DISABLED);
|
||||
}
|
||||
}
|
||||
|
||||
public NetworkStatsMetricsLogger() {
|
||||
mDeps = new Dependencies();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public NetworkStatsMetricsLogger(Dependencies deps) {
|
||||
mDeps = deps;
|
||||
}
|
||||
|
||||
private static int prefixToRecorderType(@NonNull String prefix) {
|
||||
switch (prefix) {
|
||||
case PREFIX_XT:
|
||||
return NETWORK_STATS_RECORDER_FILE_OPERATED__RECORDER_PREFIX__PREFIX_XT;
|
||||
case PREFIX_UID:
|
||||
return NETWORK_STATS_RECORDER_FILE_OPERATED__RECORDER_PREFIX__PREFIX_UID;
|
||||
case PREFIX_UID_TAG:
|
||||
return NETWORK_STATS_RECORDER_FILE_OPERATED__RECORDER_PREFIX__PREFIX_UIDTAG;
|
||||
default:
|
||||
return NETWORK_STATS_RECORDER_FILE_OPERATED__RECORDER_PREFIX__PREFIX_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log statistics from the NetworkStatsRecorder file reading process into statsd.
|
||||
*/
|
||||
public void logRecorderFileReading(@NonNull String prefix, int readLatencyMillis,
|
||||
@NonNull NetworkStatsCollection collection) {
|
||||
final Set<Integer> uids = new HashSet<>();
|
||||
final Map<NetworkStatsCollection.Key, NetworkStatsHistory> entries =
|
||||
collection.getEntries();
|
||||
|
||||
for (final NetworkStatsCollection.Key key : entries.keySet()) {
|
||||
uids.add(key.uid);
|
||||
}
|
||||
|
||||
int totalHistorySize = 0;
|
||||
for (final NetworkStatsHistory history : entries.values()) {
|
||||
totalHistorySize += history.size();
|
||||
}
|
||||
|
||||
// TODO: Fill file characteristics.
|
||||
mDeps.writeRecorderFileReadingStats(prefixToRecorderType(prefix),
|
||||
mReadIndex++,
|
||||
readLatencyMillis,
|
||||
0 /* fileCount */,
|
||||
0 /* totalFileSize */,
|
||||
entries.size(),
|
||||
uids.size(),
|
||||
totalHistorySize);
|
||||
}
|
||||
}
|
||||
|
|
@ -32,12 +32,14 @@ import android.net.NetworkTemplate;
|
|||
import android.net.TrafficStats;
|
||||
import android.os.Binder;
|
||||
import android.os.DropBoxManager;
|
||||
import android.os.SystemClock;
|
||||
import android.service.NetworkStatsRecorderProto;
|
||||
import android.util.IndentingPrintWriter;
|
||||
import android.util.Log;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
|
||||
import com.android.internal.util.FileRotator;
|
||||
import com.android.metrics.NetworkStatsMetricsLogger;
|
||||
import com.android.net.module.util.NetworkStatsUtils;
|
||||
|
||||
import libcore.io.IoUtils;
|
||||
|
|
@ -90,6 +92,7 @@ public class NetworkStatsRecorder {
|
|||
private final CombiningRewriter mPendingRewriter;
|
||||
|
||||
private WeakReference<NetworkStatsCollection> mComplete;
|
||||
private final NetworkStatsMetricsLogger mMetricsLogger = new NetworkStatsMetricsLogger();
|
||||
|
||||
/**
|
||||
* Non-persisted recorder, with only one bucket. Used by {@link NetworkStatsObservers}.
|
||||
|
|
@ -182,8 +185,15 @@ public class NetworkStatsRecorder {
|
|||
Objects.requireNonNull(mRotator, "missing FileRotator");
|
||||
NetworkStatsCollection res = mComplete != null ? mComplete.get() : null;
|
||||
if (res == null) {
|
||||
final long readStart = SystemClock.elapsedRealtime();
|
||||
res = loadLocked(Long.MIN_VALUE, Long.MAX_VALUE);
|
||||
mComplete = new WeakReference<NetworkStatsCollection>(res);
|
||||
final long readEnd = SystemClock.elapsedRealtime();
|
||||
// For legacy recorders which are used for data integrity check, which
|
||||
// have wipeOnError flag unset, skip reporting metrics.
|
||||
if (mWipeOnError) {
|
||||
mMetricsLogger.logRecorderFileReading(mCookie, (int) (readEnd - readStart), res);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,15 @@
|
|||
|
||||
package com.android.server.net;
|
||||
|
||||
import static android.net.NetworkStats.SET_DEFAULT;
|
||||
import static android.net.NetworkStats.SET_FOREGROUND;
|
||||
import static android.net.NetworkStats.TAG_NONE;
|
||||
import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_UID;
|
||||
import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_XT;
|
||||
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
|
||||
|
||||
import static com.android.server.ConnectivityStatsLog.NETWORK_STATS_RECORDER_FILE_OPERATED__RECORDER_PREFIX__PREFIX_UID;
|
||||
import static com.android.server.ConnectivityStatsLog.NETWORK_STATS_RECORDER_FILE_OPERATED__RECORDER_PREFIX__PREFIX_XT;
|
||||
import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
|
||||
|
||||
import static org.mockito.Mockito.any;
|
||||
|
|
@ -29,12 +36,16 @@ import static org.mockito.Mockito.reset;
|
|||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.net.NetworkIdentity;
|
||||
import android.net.NetworkIdentitySet;
|
||||
import android.net.NetworkStats;
|
||||
import android.net.NetworkStatsCollection;
|
||||
import android.os.DropBoxManager;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.internal.util.FileRotator;
|
||||
import com.android.metrics.NetworkStatsMetricsLogger;
|
||||
import com.android.testutils.DevSdkIgnoreRule;
|
||||
import com.android.testutils.DevSdkIgnoreRunner;
|
||||
|
||||
|
|
@ -53,6 +64,8 @@ public final class NetworkStatsRecorderTest {
|
|||
private static final String TAG = NetworkStatsRecorderTest.class.getSimpleName();
|
||||
|
||||
private static final String TEST_PREFIX = "test";
|
||||
private static final int TEST_UID1 = 1234;
|
||||
private static final int TEST_UID2 = 1235;
|
||||
|
||||
@Mock private DropBoxManager mDropBox;
|
||||
@Mock private NetworkStats.NonMonotonicObserver mObserver;
|
||||
|
|
@ -86,4 +99,65 @@ public final class NetworkStatsRecorderTest {
|
|||
// Verify that the rotator won't delete files.
|
||||
verify(rotator, never()).deleteAll();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFileReadingMetrics_empty() {
|
||||
final NetworkStatsCollection collection = new NetworkStatsCollection(30);
|
||||
final NetworkStatsMetricsLogger.Dependencies deps =
|
||||
mock(NetworkStatsMetricsLogger.Dependencies.class);
|
||||
final NetworkStatsMetricsLogger logger = new NetworkStatsMetricsLogger(deps);
|
||||
logger.logRecorderFileReading(PREFIX_XT, 888, collection);
|
||||
verify(deps).writeRecorderFileReadingStats(
|
||||
NETWORK_STATS_RECORDER_FILE_OPERATED__RECORDER_PREFIX__PREFIX_XT,
|
||||
1 /* readIndex */,
|
||||
888 /* readLatencyMillis */,
|
||||
0 /* fileCount */,
|
||||
0 /* totalFileSize */,
|
||||
0 /* keys */,
|
||||
0 /* uids */,
|
||||
0 /* totalHistorySize */
|
||||
);
|
||||
|
||||
// Write second time, verify the index increases.
|
||||
logger.logRecorderFileReading(PREFIX_XT, 567, collection);
|
||||
verify(deps).writeRecorderFileReadingStats(
|
||||
NETWORK_STATS_RECORDER_FILE_OPERATED__RECORDER_PREFIX__PREFIX_XT,
|
||||
2 /* readIndex */,
|
||||
567 /* readLatencyMillis */,
|
||||
0 /* fileCount */,
|
||||
0 /* totalFileSize */,
|
||||
0 /* keys */,
|
||||
0 /* uids */,
|
||||
0 /* totalHistorySize */
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFileReadingMetrics() {
|
||||
final NetworkStatsCollection collection = new NetworkStatsCollection(30);
|
||||
final NetworkStats.Entry entry = new NetworkStats.Entry();
|
||||
final NetworkIdentitySet identSet = new NetworkIdentitySet();
|
||||
identSet.add(new NetworkIdentity.Builder().build());
|
||||
// Empty entries will be skipped, put some ints to make sure they can be recorded.
|
||||
entry.rxBytes = 1;
|
||||
|
||||
collection.recordData(identSet, TEST_UID1, SET_DEFAULT, TAG_NONE, 0, 60, entry);
|
||||
collection.recordData(identSet, TEST_UID2, SET_DEFAULT, TAG_NONE, 0, 60, entry);
|
||||
collection.recordData(identSet, TEST_UID2, SET_FOREGROUND, TAG_NONE, 30, 60, entry);
|
||||
|
||||
final NetworkStatsMetricsLogger.Dependencies deps =
|
||||
mock(NetworkStatsMetricsLogger.Dependencies.class);
|
||||
final NetworkStatsMetricsLogger logger = new NetworkStatsMetricsLogger(deps);
|
||||
logger.logRecorderFileReading(PREFIX_UID, 123, collection);
|
||||
verify(deps).writeRecorderFileReadingStats(
|
||||
NETWORK_STATS_RECORDER_FILE_OPERATED__RECORDER_PREFIX__PREFIX_UID,
|
||||
1 /* readIndex */,
|
||||
123 /* readLatencyMillis */,
|
||||
0 /* fileCount */,
|
||||
0 /* totalFileSize */,
|
||||
3 /* keys */,
|
||||
2 /* uids */,
|
||||
5 /* totalHistorySize */
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue