add CpuTimePerUidPuller and CpuTimePerUidFreqPuller

Note: these pullers return monotonically increasing numbers.
The uids could include isolated uids that needs further translation in
statsd.

Test: manually tested on device and check print outs
Change-Id: I7097aec0417a3ac567b9b86149b757ac27cd58d8
This commit is contained in:
Chenjie Yu
2017-11-06 17:56:44 -08:00
parent 7f8def9d5a
commit e33bc3b967
8 changed files with 310 additions and 21 deletions

View File

@@ -31,6 +31,8 @@ statsd_common_src := \
src/config/ConfigManager.cpp \
src/external/StatsCompanionServicePuller.cpp \
src/external/ResourcePowerManagerPuller.cpp \
src/external/CpuTimePerUidPuller.cpp \
src/external/CpuTimePerUidFreqPuller.cpp \
src/external/StatsPullerManager.cpp \
src/logd/LogEvent.cpp \
src/logd/LogListener.cpp \

View File

@@ -0,0 +1,90 @@
/*
* Copyright (C) 2017 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.
*/
#define DEBUG true // STOPSHIP if true
#include "Log.h"
#include <fstream>
#include "external/CpuTimePerUidFreqPuller.h"
#include "logd/LogEvent.h"
#include "statslog.h"
using std::make_shared;
using std::shared_ptr;
using std::ifstream;
namespace android {
namespace os {
namespace statsd {
static const string sProcFile = "/proc/uid_cputime/show_uid_stat";
static const int kLineBufferSize = 1024;
/**
* Reads /proc/uid_time_in_state which has the format:
*
* uid: [freq1] [freq2] [freq3] ...
* [uid1]: [time in freq1] [time in freq2] [time in freq3] ...
* [uid2]: [time in freq1] [time in freq2] [time in freq3] ...
* ...
*
* This provides the times a UID's processes spent executing at each different cpu frequency.
* The file contains a monotonically increasing count of time for a single boot.
*/
bool CpuTimePerUidFreqPuller::Pull(const int tagId, vector<shared_ptr<LogEvent>>* data) {
data->clear();
ifstream fin;
fin.open(sProcFile);
if (!fin.good()) {
VLOG("Failed to read pseudo file %s", sProcFile.c_str());
return false;
}
uint64_t timestamp = time(nullptr) * NS_PER_SEC;
char buf[kLineBufferSize];
// first line prints the format and frequencies
fin.getline(buf, kLineBufferSize);
char * pch;
while(!fin.eof()){
fin.getline(buf, kLineBufferSize);
pch = strtok (buf, " :");
if (pch == NULL) break;
uint64_t uid = std::stoull(pch);
pch = strtok(NULL, " ");
uint64_t timeMs;
int idx = 0;
do {
timeMs = std::stoull(pch);
auto ptr = make_shared<LogEvent>(android::util::CPU_TIME_PER_UID_FREQ_PULLED, timestamp);
auto elemList = ptr->GetAndroidLogEventList();
*elemList << uid;
*elemList << idx;
*elemList << timeMs;
ptr->init();
data->push_back(ptr);
VLOG("uid %lld, freq idx %d, sys time %lld", (long long)uid, idx, (long long)timeMs);
idx ++;
pch = strtok(NULL, " ");
} while (pch != NULL);
}
return true;
}
} // namespace statsd
} // namespace os
} // namespace android

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C) 2017 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.
*/
#pragma once
#include <utils/String16.h>
#include "StatsPuller.h"
namespace android {
namespace os {
namespace statsd {
/**
* Reads /proc/uid_cputime/show_uid_stat which has the line format:
*
* uid: user_time_micro_seconds system_time_micro_seconds
*
* This provides the time a UID's processes spent executing in user-space and kernel-space.
* The file contains a monotonically increasing count of time for a single boot.
*/
class CpuTimePerUidFreqPuller : public StatsPuller {
public:
bool Pull(const int tagId, vector<std::shared_ptr<LogEvent>>* data) override;
};
} // namespace statsd
} // namespace os
} // namespace android

View File

@@ -0,0 +1,82 @@
/*
* Copyright (C) 2017 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.
*/
#define DEBUG true // STOPSHIP if true
#include "Log.h"
#include <fstream>
#include "external/CpuTimePerUidPuller.h"
#include "logd/LogEvent.h"
#include "statslog.h"
using std::make_shared;
using std::shared_ptr;
using std::ifstream;
namespace android {
namespace os {
namespace statsd {
static const string sProcFile = "/proc/uid_cputime/show_uid_stat";
static const int kLineBufferSize = 1024;
/**
* Reads /proc/uid_cputime/show_uid_stat which has the line format:
*
* uid: user_time_micro_seconds system_time_micro_seconds power_in_milli-amp-micro_seconds
*
* This provides the time a UID's processes spent executing in user-space and kernel-space.
* The file contains a monotonically increasing count of time for a single boot.
*/
bool CpuTimePerUidPuller::Pull(const int tagId, vector<shared_ptr<LogEvent>>* data) {
data->clear();
ifstream fin;
fin.open(sProcFile);
if (!fin.good()) {
VLOG("Failed to read pseudo file %s", sProcFile.c_str());
return false;
}
uint64_t timestamp = time(nullptr) * NS_PER_SEC;
char buf[kLineBufferSize];
char * pch;
while(!fin.eof()){
fin.getline(buf, kLineBufferSize);
pch = strtok(buf, " :");
if (pch == NULL) break;
uint64_t uid = std::stoull(pch);
pch = strtok(buf, " ");
uint64_t userTimeMs = std::stoull(pch);
pch = strtok(buf, " ");
uint64_t sysTimeMs = std::stoull(pch);
auto ptr = make_shared<LogEvent>(android::util::CPU_TIME_PER_UID_PULLED, timestamp);
auto elemList = ptr->GetAndroidLogEventList();
*elemList << uid;
*elemList << userTimeMs;
*elemList << sysTimeMs;
ptr->init();
data->push_back(ptr);
VLOG("uid %lld, user time %lld, sys time %lld", (long long)uid, (long long)userTimeMs, (long long)sysTimeMs);
}
return true;
}
} // namespace statsd
} // namespace os
} // namespace android

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C) 2017 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.
*/
#pragma once
#include <utils/String16.h>
#include "StatsPuller.h"
namespace android {
namespace os {
namespace statsd {
/**
* Reads /proc/uid_cputime/show_uid_stat which has the line format:
*
* uid: user_time_micro_seconds system_time_micro_seconds
*
* This provides the time a UID's processes spent executing in user-space and kernel-space.
* The file contains a monotonically increasing count of time for a single boot.
*/
class CpuTimePerUidPuller : public StatsPuller {
public:
bool Pull(const int tagId, vector<std::shared_ptr<LogEvent>>* data) override;
};
} // namespace statsd
} // namespace os
} // namespace android

View File

@@ -34,6 +34,7 @@
#include "external/StatsPuller.h"
#include "logd/LogEvent.h"
#include "statslog.h"
using android::hardware::hidl_vec;
using android::hardware::power::V1_0::IPower;
@@ -57,10 +58,6 @@ sp<android::hardware::power::V1_1::IPower> gPowerHalV1_1 = nullptr;
std::mutex gPowerHalMutex;
bool gPowerHalExists = true;
static const int power_state_platform_sleep_state_tag = 1011;
static const int power_state_voter_tag = 1012;
static const int power_state_subsystem_state_tag = 1013;
bool getPowerHal() {
if (gPowerHalExists && gPowerHalV1_0 == nullptr) {
gPowerHalV1_0 = android::hardware::power::V1_0::IPower::getService();
@@ -94,8 +91,8 @@ bool ResourcePowerManagerPuller::Pull(const int tagId, vector<shared_ptr<LogEven
for (size_t i = 0; i < states.size(); i++) {
const PowerStatePlatformSleepState& state = states[i];
auto statePtr =
make_shared<LogEvent>(power_state_platform_sleep_state_tag, timestamp);
auto statePtr = make_shared<LogEvent>(
android::util::POWER_STATE_PLATFORM_SLEEP_STATE_PULLED, timestamp);
auto elemList = statePtr->GetAndroidLogEventList();
*elemList << state.name;
*elemList << state.residencyInMsecSinceBoot;
@@ -107,12 +104,14 @@ bool ResourcePowerManagerPuller::Pull(const int tagId, vector<shared_ptr<LogEven
(long long)state.residencyInMsecSinceBoot,
(long long)state.totalTransitions, state.supportedOnlyInSuspend ? 1 : 0);
for (auto voter : state.voters) {
auto voterPtr = make_shared<LogEvent>(power_state_voter_tag, timestamp);
auto voterPtr =
make_shared<LogEvent>(android::util::POWER_STATE_VOTER_PULLED, timestamp);
auto elemList = voterPtr->GetAndroidLogEventList();
*elemList << state.name;
*elemList << voter.name;
*elemList << voter.totalTimeInMsecVotedForSinceBoot;
*elemList << voter.totalNumberOfTimesVotedSinceBoot;
voterPtr->init();
data->push_back(voterPtr);
VLOG("powerstatevoter: %s, %s, %lld, %lld", state.name.c_str(),
voter.name.c_str(), (long long)voter.totalTimeInMsecVotedForSinceBoot,
@@ -141,7 +140,7 @@ bool ResourcePowerManagerPuller::Pull(const int tagId, vector<shared_ptr<LogEven
for (size_t j = 0; j < subsystem.states.size(); j++) {
const PowerStateSubsystemSleepState& state = subsystem.states[j];
auto subsystemStatePtr = make_shared<LogEvent>(
power_state_subsystem_state_tag, timestamp);
android::util::POWER_STATE_SUBSYSTEM_SLEEP_STATE_PULLED, timestamp);
auto elemList = subsystemStatePtr->GetAndroidLogEventList();
*elemList << subsystem.name;
*elemList << state.name;

View File

@@ -21,6 +21,8 @@
#include <cutils/log.h>
#include <algorithm>
#include <climits>
#include "CpuTimePerUidFreqPuller.h"
#include "CpuTimePerUidPuller.h"
#include "ResourcePowerManagerPuller.h"
#include "StatsCompanionServicePuller.h"
#include "StatsPullerManager.h"
@@ -42,21 +44,29 @@ namespace statsd {
StatsPullerManager::StatsPullerManager()
: mCurrentPullingInterval(LONG_MAX), mPullStartTimeMs(get_pull_start_time_ms()) {
shared_ptr<StatsPuller> statsCompanionServicePuller =
make_shared<StatsCompanionServicePuller>();
shared_ptr<StatsPuller> statsCompanionServicePuller = make_shared<StatsCompanionServicePuller>();
shared_ptr<StatsPuller> resourcePowerManagerPuller = make_shared<ResourcePowerManagerPuller>();
shared_ptr<StatsPuller> cpuTimePerUidPuller = make_shared<CpuTimePerUidPuller>();
shared_ptr<StatsPuller> cpuTimePerUidFreqPuller = make_shared<CpuTimePerUidFreqPuller>();
mPullers.insert({android::util::KERNEL_WAKELOCK_PULLED, statsCompanionServicePuller});
mPullers.insert({android::util::WIFI_BYTES_TRANSFERRED, statsCompanionServicePuller});
mPullers.insert({android::util::MOBILE_BYTES_TRANSFERRED, statsCompanionServicePuller});
mPullers.insert({android::util::WIFI_BYTES_TRANSFERRED_BY_FG_BG, statsCompanionServicePuller});
mPullers.insert(
{android::util::MOBILE_BYTES_TRANSFERRED_BY_FG_BG, statsCompanionServicePuller});
mPullers.insert(
{android::util::POWER_STATE_PLATFORM_SLEEP_STATE_PULLED, resourcePowerManagerPuller});
mPullers.insert({android::util::POWER_STATE_VOTER_PULLED, resourcePowerManagerPuller});
mPullers.insert(
{android::util::POWER_STATE_SUBSYSTEM_SLEEP_STATE_PULLED, resourcePowerManagerPuller});
mPullers.insert({android::util::KERNEL_WAKELOCK_PULLED,
statsCompanionServicePuller});
mPullers.insert({android::util::WIFI_BYTES_TRANSFERRED,
statsCompanionServicePuller});
mPullers.insert({android::util::MOBILE_BYTES_TRANSFERRED,
statsCompanionServicePuller});
mPullers.insert({android::util::WIFI_BYTES_TRANSFERRED_BY_FG_BG,
statsCompanionServicePuller});
mPullers.insert({android::util::MOBILE_BYTES_TRANSFERRED_BY_FG_BG,
statsCompanionServicePuller});
mPullers.insert({android::util::POWER_STATE_PLATFORM_SLEEP_STATE_PULLED,
resourcePowerManagerPuller});
mPullers.insert({android::util::POWER_STATE_VOTER_PULLED,
resourcePowerManagerPuller});
mPullers.insert({android::util::POWER_STATE_SUBSYSTEM_SLEEP_STATE_PULLED,
resourcePowerManagerPuller});
mPullers.insert({android::util::CPU_TIME_PER_UID_PULLED, cpuTimePerUidPuller});
mPullers.insert({android::util::CPU_TIME_PER_UID_FREQ_PULLED, cpuTimePerUidFreqPuller});
mStatsCompanionService = StatsService::getStatsCompanionService();
}

View File

@@ -87,6 +87,8 @@ message StatsEvent {
PowerStateVoterPulled power_state_voter_pulled = 1006;
PowerStateSubsystemSleepStatePulled power_state_subsystem_sleep_state_pulled = 1007;
CpuTimePerFreqPulled cpu_time_per_freq_pulled = 1008;
CpuTimePerUidPulled cpu_time_per_uid_pulled = 1009;
CpuTimePerUidFreqPulled cpu_time_per_uid_freq_pulled = 1010;
}
}
@@ -870,6 +872,7 @@ message IsolatedUidChanged {
}
/*
<<<<<<< HEAD
* Pulls Cpu time per frequency.
* Note: this should be pulled for gauge metric only, without condition.
* The puller keeps internal state of last values. It should not be pulled by
@@ -885,3 +888,24 @@ message CpuTimePerFreqPulled {
optional uint32 freq_index = 2;
optional uint64 time = 3;
}
/*
* Pulls Cpu Time Per Uid.
* Note that isolated process uid time should be attributed to host uids.
*/
message CpuTimePerUidPulled {
optional uint64 uid = 1;
optional uint64 user_time_ms = 2;
optional uint64 sys_time_ms = 3;
}
/**
* Pulls Cpu Time Per Uid per frequency.
* Note that isolated process uid time should be attributed to host uids.
* For each uid, we order the time by descending frequencies.
*/
message CpuTimePerUidFreqPulled {
optional uint64 uid = 1;
optional uint64 freq_idx = 2;
optional uint64 time_ms = 3;
}