diff --git a/cmds/statsd/Android.mk b/cmds/statsd/Android.mk index 929c3ccee6dc9..a1f5bb1a30f07 100644 --- a/cmds/statsd/Android.mk +++ b/cmds/statsd/Android.mk @@ -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 \ diff --git a/cmds/statsd/src/external/CpuTimePerUidFreqPuller.cpp b/cmds/statsd/src/external/CpuTimePerUidFreqPuller.cpp new file mode 100644 index 0000000000000..e004d217a9664 --- /dev/null +++ b/cmds/statsd/src/external/CpuTimePerUidFreqPuller.cpp @@ -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 +#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>* 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(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 diff --git a/cmds/statsd/src/external/CpuTimePerUidFreqPuller.h b/cmds/statsd/src/external/CpuTimePerUidFreqPuller.h new file mode 100644 index 0000000000000..839e5aab3dc2a --- /dev/null +++ b/cmds/statsd/src/external/CpuTimePerUidFreqPuller.h @@ -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 +#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>* data) override; +}; + +} // namespace statsd +} // namespace os +} // namespace android diff --git a/cmds/statsd/src/external/CpuTimePerUidPuller.cpp b/cmds/statsd/src/external/CpuTimePerUidPuller.cpp new file mode 100644 index 0000000000000..b84b877a0ee94 --- /dev/null +++ b/cmds/statsd/src/external/CpuTimePerUidPuller.cpp @@ -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 +#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>* 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(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 diff --git a/cmds/statsd/src/external/CpuTimePerUidPuller.h b/cmds/statsd/src/external/CpuTimePerUidPuller.h new file mode 100644 index 0000000000000..9bb89463725ec --- /dev/null +++ b/cmds/statsd/src/external/CpuTimePerUidPuller.h @@ -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 +#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>* data) override; +}; + +} // namespace statsd +} // namespace os +} // namespace android diff --git a/cmds/statsd/src/external/ResourcePowerManagerPuller.cpp b/cmds/statsd/src/external/ResourcePowerManagerPuller.cpp index 3608ee459611a..319feef49b35b 100644 --- a/cmds/statsd/src/external/ResourcePowerManagerPuller.cpp +++ b/cmds/statsd/src/external/ResourcePowerManagerPuller.cpp @@ -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 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(power_state_platform_sleep_state_tag, timestamp); + auto statePtr = make_shared( + 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(power_state_voter_tag, timestamp); + auto voterPtr = + make_shared(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( - 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; diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp index 43543cceeb1cf..5a05b453aa86e 100644 --- a/cmds/statsd/src/external/StatsPullerManager.cpp +++ b/cmds/statsd/src/external/StatsPullerManager.cpp @@ -21,6 +21,8 @@ #include #include #include +#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 statsCompanionServicePuller = - make_shared(); + shared_ptr statsCompanionServicePuller = make_shared(); shared_ptr resourcePowerManagerPuller = make_shared(); + shared_ptr cpuTimePerUidPuller = make_shared(); + shared_ptr cpuTimePerUidFreqPuller = make_shared(); - 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(); } diff --git a/cmds/statsd/src/stats_events.proto b/cmds/statsd/src/stats_events.proto index a516ca3a603a8..9ab07de96aa27 100644 --- a/cmds/statsd/src/stats_events.proto +++ b/cmds/statsd/src/stats_events.proto @@ -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; +}