Add stats puller for aggregated procstats
Implement puller code in StatsPullAtomService & ProcessStats that will output new pre-aggregated proto form of ProcStats data. Change-Id: Id3d28b0ec135b1b25f3b70a5eb29bec67d71805d Test: local debugging, see b/152397079 Bug: b/152397079 Bug: b/145203981
This commit is contained in:
@@ -534,16 +534,31 @@ public final class DumpUtils {
|
||||
int procStateIndex = curState % STATE_COUNT;
|
||||
|
||||
// Remap process state per array above.
|
||||
procStateIndex = PROCESS_STATS_STATE_TO_AGGREGATED_STATE[procStateIndex];
|
||||
try {
|
||||
procStateIndex = PROCESS_STATS_STATE_TO_AGGREGATED_STATE[procStateIndex];
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
procStateIndex = ProcessStatsEnums.AGGREGATED_PROCESS_STATE_UNKNOWN;
|
||||
}
|
||||
|
||||
// Pack screen & process state using bit shifting
|
||||
return (procStateIndex << 8) | screenStateIndex;
|
||||
return (procStateIndex << 0xf) | screenStateIndex;
|
||||
}
|
||||
|
||||
/** Print aggregated tags generated via {@code #aggregateCurrentProcessState}. */
|
||||
public static void printAggregatedProcStateTagProto(ProtoOutputStream proto, long screenId,
|
||||
long stateId, int state) {
|
||||
proto.write(screenId, ADJ_SCREEN_PROTO_ENUMS[state >> 8]);
|
||||
proto.write(stateId, STATE_PROTO_ENUMS[state]);
|
||||
// screen state is in lowest 0xf bits, process state is in next 0xf bits up
|
||||
|
||||
try {
|
||||
proto.write(stateId, STATE_PROTO_ENUMS[state >> 0xf]);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
proto.write(stateId, ProcessStatsEnums.PROCESS_STATE_UNKNOWN);
|
||||
}
|
||||
|
||||
try {
|
||||
proto.write(screenId, ADJ_SCREEN_PROTO_ENUMS[state & 0xf]);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
proto.write(screenId, ProcessStatsEnums.SCREEN_STATE_UNKNOWN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1436,7 +1436,7 @@ public final class ProcessState {
|
||||
}
|
||||
int index = durationByState.indexOfKey(aggregatedType);
|
||||
if (index >= 0) {
|
||||
durationByState.put(aggregatedType, time + durationByState.valueAt(aggregatedType));
|
||||
durationByState.put(aggregatedType, time + durationByState.valueAt(index));
|
||||
} else {
|
||||
durationByState.put(aggregatedType, time);
|
||||
}
|
||||
@@ -1502,14 +1502,15 @@ public final class ProcessState {
|
||||
proto.write(ProcessStatsProto.UID, uid);
|
||||
|
||||
for (int i = 0; i < durationByState.size(); i++) {
|
||||
final int aggregatedKey = mPssTable.getKeyAt(i);
|
||||
|
||||
final long stateToken = proto.start(ProcessStatsProto.STATES);
|
||||
|
||||
final int aggregatedKey = durationByState.keyAt(i);
|
||||
|
||||
DumpUtils.printAggregatedProcStateTagProto(proto,
|
||||
ProcessStatsStateProto.SCREEN_STATE,
|
||||
ProcessStatsStateProto.PROCESS_STATE,
|
||||
durationByState.keyAt(i));
|
||||
proto.write(ProcessStatsStateProto.DURATION_MS, durationByState.valueAt(i));
|
||||
aggregatedKey);
|
||||
proto.write(ProcessStatsStateProto.DURATION_MS, durationByState.get(aggregatedKey));
|
||||
|
||||
ProtoUtils.toAggStatsProto(proto, ProcessStatsStateProto.RSS,
|
||||
0, /* do not output a minimum value */
|
||||
|
||||
@@ -2178,29 +2178,7 @@ public final class ProcessStats implements Parcelable {
|
||||
* Writes to ProtoOutputStream.
|
||||
*/
|
||||
public void dumpDebug(ProtoOutputStream proto, long now, int section) {
|
||||
proto.write(ProcessStatsSectionProto.START_REALTIME_MS, mTimePeriodStartRealtime);
|
||||
proto.write(ProcessStatsSectionProto.END_REALTIME_MS,
|
||||
mRunning ? SystemClock.elapsedRealtime() : mTimePeriodEndRealtime);
|
||||
proto.write(ProcessStatsSectionProto.START_UPTIME_MS, mTimePeriodStartUptime);
|
||||
proto.write(ProcessStatsSectionProto.END_UPTIME_MS, mTimePeriodEndUptime);
|
||||
proto.write(ProcessStatsSectionProto.RUNTIME, mRuntime);
|
||||
proto.write(ProcessStatsSectionProto.HAS_SWAPPED_PSS, mHasSwappedOutPss);
|
||||
boolean partial = true;
|
||||
if ((mFlags & FLAG_SHUTDOWN) != 0) {
|
||||
proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_SHUTDOWN);
|
||||
partial = false;
|
||||
}
|
||||
if ((mFlags & FLAG_SYSPROPS) != 0) {
|
||||
proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_SYSPROPS);
|
||||
partial = false;
|
||||
}
|
||||
if ((mFlags & FLAG_COMPLETE) != 0) {
|
||||
proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_COMPLETE);
|
||||
partial = false;
|
||||
}
|
||||
if (partial) {
|
||||
proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_PARTIAL);
|
||||
}
|
||||
dumpProtoPreamble(proto);
|
||||
|
||||
final int NPAGETYPES = mPageTypeLabels.size();
|
||||
for (int i = 0; i < NPAGETYPES; i++) {
|
||||
@@ -2247,6 +2225,49 @@ public final class ProcessStats implements Parcelable {
|
||||
}
|
||||
}
|
||||
|
||||
/** Similar to {@code #dumpDebug}, but with a reduced/aggregated subset of states. */
|
||||
public void dumpAggregatedProtoForStatsd(ProtoOutputStream proto) {
|
||||
dumpProtoPreamble(proto);
|
||||
final ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
|
||||
for (int ip = 0; ip < procMap.size(); ip++) {
|
||||
final String procName = procMap.keyAt(ip);
|
||||
final SparseArray<ProcessState> uids = procMap.valueAt(ip);
|
||||
for (int iu = 0; iu < uids.size(); iu++) {
|
||||
final int uid = uids.keyAt(iu);
|
||||
final ProcessState procState = uids.valueAt(iu);
|
||||
procState.dumpAggregatedProtoForStatsd(proto,
|
||||
ProcessStatsSectionProto.PROCESS_STATS,
|
||||
procName, uid, mTimePeriodEndRealtime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void dumpProtoPreamble(ProtoOutputStream proto) {
|
||||
proto.write(ProcessStatsSectionProto.START_REALTIME_MS, mTimePeriodStartRealtime);
|
||||
proto.write(ProcessStatsSectionProto.END_REALTIME_MS,
|
||||
mRunning ? SystemClock.elapsedRealtime() : mTimePeriodEndRealtime);
|
||||
proto.write(ProcessStatsSectionProto.START_UPTIME_MS, mTimePeriodStartUptime);
|
||||
proto.write(ProcessStatsSectionProto.END_UPTIME_MS, mTimePeriodEndUptime);
|
||||
proto.write(ProcessStatsSectionProto.RUNTIME, mRuntime);
|
||||
proto.write(ProcessStatsSectionProto.HAS_SWAPPED_PSS, mHasSwappedOutPss);
|
||||
boolean partial = true;
|
||||
if ((mFlags & FLAG_SHUTDOWN) != 0) {
|
||||
proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_SHUTDOWN);
|
||||
partial = false;
|
||||
}
|
||||
if ((mFlags & FLAG_SYSPROPS) != 0) {
|
||||
proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_SYSPROPS);
|
||||
partial = false;
|
||||
}
|
||||
if ((mFlags & FLAG_COMPLETE) != 0) {
|
||||
proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_COMPLETE);
|
||||
partial = false;
|
||||
}
|
||||
if (partial) {
|
||||
proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_PARTIAL);
|
||||
}
|
||||
}
|
||||
|
||||
final public static class ProcessStateHolder {
|
||||
public final long appVersion;
|
||||
public ProcessState state;
|
||||
|
||||
@@ -2041,32 +2041,35 @@ public class StatsPullAtomService extends SystemService {
|
||||
synchronized (mProcessStatsLock) {
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
// force procstats to flush & combine old files into one store
|
||||
long lastHighWaterMark = readProcStatsHighWaterMark(section);
|
||||
List<ParcelFileDescriptor> statsFiles = new ArrayList<>();
|
||||
long highWaterMark = processStatsService.getCommittedStats(
|
||||
lastHighWaterMark, section, true, statsFiles);
|
||||
if (statsFiles.size() != 1) {
|
||||
return StatsManager.PULL_SKIP;
|
||||
}
|
||||
unpackStreamedData(atomTag, pulledData, statsFiles);
|
||||
|
||||
ProcessStats procStats = new ProcessStats(false);
|
||||
long highWaterMark = processStatsService.getCommittedStatsMerged(
|
||||
lastHighWaterMark, section, true, statsFiles, procStats);
|
||||
|
||||
// aggregate the data together for westworld consumption
|
||||
ProtoOutputStream proto = new ProtoOutputStream();
|
||||
procStats.dumpAggregatedProtoForStatsd(proto);
|
||||
|
||||
StatsEvent e = StatsEvent.newBuilder()
|
||||
.setAtomId(atomTag)
|
||||
.writeByteArray(proto.getBytes())
|
||||
.build();
|
||||
pulledData.add(e);
|
||||
|
||||
new File(mBaseDir.getAbsolutePath() + "/" + section + "_" + lastHighWaterMark)
|
||||
.delete();
|
||||
new File(mBaseDir.getAbsolutePath() + "/" + section + "_" + highWaterMark)
|
||||
.createNewFile();
|
||||
} catch (IOException e) {
|
||||
Slog.e(TAG, "Getting procstats failed: ", e);
|
||||
return StatsManager.PULL_SKIP;
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Getting procstats failed: ", e);
|
||||
return StatsManager.PULL_SKIP;
|
||||
} catch (SecurityException e) {
|
||||
} catch (RemoteException | IOException e) {
|
||||
Slog.e(TAG, "Getting procstats failed: ", e);
|
||||
return StatsManager.PULL_SKIP;
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
|
||||
return StatsManager.PULL_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user