Merge "Pull process cpu stats into statsd"

This commit is contained in:
Chenjie Yu
2018-10-16 20:48:57 +00:00
committed by Android (Google) Code Review
3 changed files with 92 additions and 37 deletions

View File

@@ -183,6 +183,7 @@ message Atom {
DiskIo disk_io = 10032;
PowerProfile power_profile = 10033;
ProcStats proc_stats_pkg_proc = 10034;
ProcessCpuTime process_cpu_time = 10035;
}
// DO NOT USE field numbers above 100,000 in AOSP.
@@ -3006,3 +3007,19 @@ message PowerProfileProto {
message PowerProfile {
optional PowerProfileProto power_profile = 1;
}
/**
* Pulls process user time and system time. Puller takes a snapshot of all pids
* in the system and returns cpu stats for those that are working at the time.
* Dead pids will be dropped. Kernel processes are excluded.
* Min cool-down is 5 sec.
*/
message ProcessCpuTime {
optional int32 uid = 1 [(is_uid) = true];
optional string process_name = 2;
// Process cpu time in user space, cumulative from boot/process start
optional int64 user_time_millis = 3;
// Process cpu time in system space, cumulative from boot/process start
optional int64 system_time_millis = 4;
}

View File

@@ -223,6 +223,9 @@ const std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = {
// PowerProfile constants for power model calculations.
{android::util::POWER_PROFILE,
{{}, {}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::POWER_PROFILE)}},
// Process cpu stats. Min cool-down is 5 sec, inline with what AcitivityManagerService uses.
{android::util::PROCESS_CPU_TIME,
{{}, {}, 5 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::PROCESS_CPU_TIME)}},
};
StatsPullerManager::StatsPullerManager() : mNextPullTimeNs(NO_ALARM_UPDATE) {

View File

@@ -88,6 +88,7 @@ import com.android.internal.os.KernelWakelockReader;
import com.android.internal.os.KernelWakelockStats;
import com.android.internal.os.LooperStats;
import com.android.internal.os.PowerProfile;
import com.android.internal.os.ProcessCpuTracker;
import com.android.internal.os.StoragedUidIoStatsReader;
import com.android.internal.util.DumpUtils;
import com.android.server.BinderCallsStatsService;
@@ -174,11 +175,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats();
private IWifiManager mWifiManager = null;
private TelephonyManager mTelephony = null;
private final StatFs mStatFsData = new StatFs(Environment.getDataDirectory().getAbsolutePath());
private final StatFs mStatFsSystem =
new StatFs(Environment.getRootDirectory().getAbsolutePath());
private final StatFs mStatFsTemp =
new StatFs(Environment.getDownloadCacheDirectory().getAbsolutePath());
@GuardedBy("sStatsdLock")
private final HashSet<Long> mDeathTimeMillis = new HashSet<>();
@GuardedBy("sStatsdLock")
@@ -199,6 +195,8 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
private static IThermalService sThermalService;
private File mBaseDir =
new File(SystemServiceManager.ensureSystemDir(), "stats_companion");
@GuardedBy("this")
ProcessCpuTracker mProcessCpuTracker = null;
public StatsCompanionService(Context context) {
super();
@@ -772,7 +770,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
private void pullBluetoothBytesTransfer(
int tagId, long elapsedNanos, long wallClockNanos,
List<StatsLogEventWrapper> pulledData) {
BluetoothActivityEnergyInfo info = pullBluetoothData();
BluetoothActivityEnergyInfo info = fetchBluetoothData();
if (info.getUidTraffic() != null) {
for (UidTraffic traffic : info.getUidTraffic()) {
StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos,
@@ -884,9 +882,12 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
int tagId, long elapsedNanos, long wallClockNanos,
List<StatsLogEventWrapper> pulledData) {
long token = Binder.clearCallingIdentity();
if (mWifiManager == null) {
mWifiManager =
IWifiManager.Stub.asInterface(ServiceManager.getService(Context.WIFI_SERVICE));
synchronized (this) {
if (mWifiManager == null) {
mWifiManager =
IWifiManager.Stub.asInterface(
ServiceManager.getService(Context.WIFI_SERVICE));
}
}
if (mWifiManager != null) {
try {
@@ -916,8 +917,10 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
int tagId, long elapsedNanos, long wallClockNanos,
List<StatsLogEventWrapper> pulledData) {
long token = Binder.clearCallingIdentity();
if (mTelephony == null) {
mTelephony = TelephonyManager.from(mContext);
synchronized (this) {
if (mTelephony == null) {
mTelephony = TelephonyManager.from(mContext);
}
}
if (mTelephony != null) {
SynchronousResultReceiver modemReceiver = new SynchronousResultReceiver("telephony");
@@ -941,7 +944,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
private void pullBluetoothActivityInfo(
int tagId, long elapsedNanos, long wallClockNanos,
List<StatsLogEventWrapper> pulledData) {
BluetoothActivityEnergyInfo info = pullBluetoothData();
BluetoothActivityEnergyInfo info = fetchBluetoothData();
StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
e.writeLong(info.getTimeStamp());
e.writeInt(info.getBluetoothStackState());
@@ -952,7 +955,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
pulledData.add(e);
}
private synchronized BluetoothActivityEnergyInfo pullBluetoothData() {
private synchronized BluetoothActivityEnergyInfo fetchBluetoothData() {
final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter != null) {
SynchronousResultReceiver bluetoothReceiver = new SynchronousResultReceiver(
@@ -1306,30 +1309,35 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
private void pullProcessStats(int section, int tagId, long elapsedNanos, long wallClockNanos,
List<StatsLogEventWrapper> pulledData) {
try {
long lastHighWaterMark = readProcStatsHighWaterMark(section);
List<ParcelFileDescriptor> statsFiles = new ArrayList<>();
long highWaterMark = mProcessStats.getCommittedStats(
lastHighWaterMark, section, true, statsFiles);
if (statsFiles.size() != 1) {
return;
synchronized (this) {
try {
long lastHighWaterMark = readProcStatsHighWaterMark(section);
List<ParcelFileDescriptor> statsFiles = new ArrayList<>();
long highWaterMark = mProcessStats.getCommittedStats(
lastHighWaterMark, section, true, statsFiles);
if (statsFiles.size() != 1) {
return;
}
InputStream stream = new ParcelFileDescriptor.AutoCloseInputStream(
statsFiles.get(0));
int[] len = new int[1];
byte[] stats = readFully(stream, len);
StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos,
wallClockNanos);
e.writeStorage(Arrays.copyOf(stats, len[0]));
pulledData.add(e);
new File(mBaseDir.getAbsolutePath() + "/" + section + "_"
+ lastHighWaterMark).delete();
new File(
mBaseDir.getAbsolutePath() + "/" + section + "_"
+ highWaterMark).createNewFile();
} catch (IOException e) {
Log.e(TAG, "Getting procstats failed: ", e);
} catch (RemoteException e) {
Log.e(TAG, "Getting procstats failed: ", e);
} catch (SecurityException e) {
Log.e(TAG, "Getting procstats failed: ", e);
}
InputStream stream = new ParcelFileDescriptor.AutoCloseInputStream(statsFiles.get(0));
int[] len = new int[1];
byte[] stats = readFully(stream, len);
StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
e.writeStorage(Arrays.copyOf(stats, len[0]));
pulledData.add(e);
new File(mBaseDir.getAbsolutePath() + "/" + section + "_" + lastHighWaterMark).delete();
new File(
mBaseDir.getAbsolutePath() + "/" + section + "_"
+ highWaterMark).createNewFile();
} catch (IOException e) {
Log.e(TAG, "Getting procstats failed: ", e);
} catch (RemoteException e) {
Log.e(TAG, "Getting procstats failed: ", e);
} catch (SecurityException e) {
Log.e(TAG, "Getting procstats failed: ", e);
}
}
@@ -1398,12 +1406,34 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
});
}
private void pullProcessCpuTime(int tagId, long elapsedNanos, final long wallClockNanos,
List<StatsLogEventWrapper> pulledData) {
synchronized (this) {
if (mProcessCpuTracker == null) {
mProcessCpuTracker = new ProcessCpuTracker(false);
mProcessCpuTracker.init();
}
mProcessCpuTracker.update();
for (int i = 0; i < mProcessCpuTracker.countStats(); i++) {
ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos,
wallClockNanos);
e.writeInt(st.uid);
e.writeString(st.name);
e.writeLong(st.base_utime);
e.writeLong(st.base_stime);
pulledData.add(e);
}
}
}
/**
* Pulls various data.
*/
@Override // Binder call
public StatsLogEventWrapper[] pullData(int tagId) {
enforceCallingPermission();
if (DEBUG) {
Slog.d(TAG, "Pulling " + tagId);
}
@@ -1512,7 +1542,8 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
break;
}
case StatsLog.PROC_STATS: {
pullProcessStats(ProcessStats.REPORT_ALL, tagId, elapsedNanos, wallClockNanos, ret);
pullProcessStats(ProcessStats.REPORT_ALL, tagId, elapsedNanos, wallClockNanos,
ret);
break;
}
case StatsLog.PROC_STATS_PKG_PROC: {
@@ -1528,6 +1559,10 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
pullPowerProfile(tagId, elapsedNanos, wallClockNanos, ret);
break;
}
case StatsLog.PROCESS_CPU_TIME: {
pullProcessCpuTime(tagId, elapsedNanos, wallClockNanos, ret);
break;
}
default:
Slog.w(TAG, "No such tagId data as " + tagId);
return null;