Charles(Yen-Cheng) Chan | 08bfed8 | 2019-01-02 12:26:16 +0800 | [diff] [blame] | 1 | /* |
Charles(Yen-Cheng) Chan | a78dcb9 | 2019-01-10 16:39:54 +0800 | [diff] [blame] | 2 | * Copyright (C) 2019 The Android Open Source Project |
Charles(Yen-Cheng) Chan | 08bfed8 | 2019-01-02 12:26:16 +0800 | [diff] [blame] | 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | #define LOG_TAG "perfstatsd" |
| 18 | |
| 19 | #include <perfstatsd.h> |
| 20 | |
| 21 | using namespace android::pixel::perfstatsd; |
| 22 | |
Charles(Yen-Cheng) Chan | a78dcb9 | 2019-01-10 16:39:54 +0800 | [diff] [blame] | 23 | Perfstatsd::Perfstatsd(void) { |
Charles(Yen-Cheng) Chan | 08bfed8 | 2019-01-02 12:26:16 +0800 | [diff] [blame] | 24 | mRefreshPeriod = DEFAULT_DATA_COLLECT_PERIOD; |
Charles(Yen-Cheng) Chan | 5d34251 | 2019-01-02 12:33:03 +0800 | [diff] [blame] | 25 | |
Charles(Yen-Cheng) Chan | a78dcb9 | 2019-01-10 16:39:54 +0800 | [diff] [blame] | 26 | std::unique_ptr<StatsType> cpuUsage(new CpuUsage); |
Charles(Yen-Cheng) Chan | 5d34251 | 2019-01-02 12:33:03 +0800 | [diff] [blame] | 27 | cpuUsage->setBufferSize(CPU_USAGE_BUFFER_SIZE); |
| 28 | mStats.emplace_back(std::move(cpuUsage)); |
Jimmy Shiu | c441013 | 2019-01-02 13:32:47 +0800 | [diff] [blame] | 29 | |
Jimmy Shiu | 2656ca3 | 2019-01-09 13:05:09 +0800 | [diff] [blame] | 30 | std::unique_ptr<StatsType> ioUsage(new IoUsage); |
Jimmy Shiu | c441013 | 2019-01-02 13:32:47 +0800 | [diff] [blame] | 31 | ioUsage->setBufferSize(IO_USAGE_BUFFER_SIZE); |
| 32 | mStats.emplace_back(std::move(ioUsage)); |
Charles(Yen-Cheng) Chan | 08bfed8 | 2019-01-02 12:26:16 +0800 | [diff] [blame] | 33 | } |
| 34 | |
Charles(Yen-Cheng) Chan | a78dcb9 | 2019-01-10 16:39:54 +0800 | [diff] [blame] | 35 | void Perfstatsd::refresh(void) { |
Charles(Yen-Cheng) Chan | 08bfed8 | 2019-01-02 12:26:16 +0800 | [diff] [blame] | 36 | for (auto const &stats : mStats) { |
| 37 | stats->refresh(); |
| 38 | } |
| 39 | return; |
| 40 | } |
| 41 | |
Charles(Yen-Cheng) Chan | a78dcb9 | 2019-01-10 16:39:54 +0800 | [diff] [blame] | 42 | void Perfstatsd::getHistory(std::string *ret) { |
| 43 | std::priority_queue<StatsData, std::vector<StatsData>, StatsdataCompare> mergedQueue; |
Charles(Yen-Cheng) Chan | 08bfed8 | 2019-01-02 12:26:16 +0800 | [diff] [blame] | 44 | for (auto const &stats : mStats) { |
| 45 | stats->dump(&mergedQueue); |
| 46 | } |
| 47 | |
| 48 | while (!mergedQueue.empty()) { |
Charles(Yen-Cheng) Chan | a78dcb9 | 2019-01-10 16:39:54 +0800 | [diff] [blame] | 49 | StatsData data = mergedQueue.top(); |
Charles(Yen-Cheng) Chan | 08bfed8 | 2019-01-02 12:26:16 +0800 | [diff] [blame] | 50 | auto raw_time = data.getTime(); |
| 51 | auto seconds = std::chrono::time_point_cast<std::chrono::seconds>(raw_time); |
| 52 | auto d = raw_time - seconds; |
| 53 | auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(d); |
| 54 | std::string content = data.getData(); |
| 55 | |
| 56 | time_t t = std::chrono::system_clock::to_time_t(raw_time); |
| 57 | char buff[20]; |
| 58 | strftime(buff, sizeof(buff), "%m-%d %H:%M:%S", localtime(&t)); |
| 59 | |
| 60 | ret->append(std::string(buff) + "."); |
| 61 | ret->append(std::to_string(milliseconds.count()) + "\n"); |
| 62 | ret->append(content + "\n"); |
| 63 | mergedQueue.pop(); |
| 64 | } |
| 65 | |
| 66 | if (ret->size() > 400_KiB) |
Tom Cherry | 4a2c84c | 2020-01-10 17:09:45 -0800 | [diff] [blame] | 67 | LOG(WARNING) << "Data might be too large. size: " << ret->size() << " bytes\n" << *ret; |
Charles(Yen-Cheng) Chan | 08bfed8 | 2019-01-02 12:26:16 +0800 | [diff] [blame] | 68 | } |
| 69 | |
Charles(Yen-Cheng) Chan | a78dcb9 | 2019-01-10 16:39:54 +0800 | [diff] [blame] | 70 | void Perfstatsd::setOptions(const std::string &key, const std::string &value) { |
Charles(Yen-Cheng) Chan | 08bfed8 | 2019-01-02 12:26:16 +0800 | [diff] [blame] | 71 | if (key == PERFSTATSD_PERIOD) { |
| 72 | uint32_t val = 0; |
| 73 | if (!base::ParseUint(value, &val) || val < 1) { |
Tom Cherry | 4a2c84c | 2020-01-10 17:09:45 -0800 | [diff] [blame] | 74 | LOG(ERROR) << "Invalid value. Minimum refresh period is 1 second"; |
Charles(Yen-Cheng) Chan | 08bfed8 | 2019-01-02 12:26:16 +0800 | [diff] [blame] | 75 | } else { |
| 76 | mRefreshPeriod = val; |
Tom Cherry | 4a2c84c | 2020-01-10 17:09:45 -0800 | [diff] [blame] | 77 | LOG(INFO) << "set period to " << value << " seconds"; |
Charles(Yen-Cheng) Chan | 08bfed8 | 2019-01-02 12:26:16 +0800 | [diff] [blame] | 78 | } |
| 79 | return; |
| 80 | } |
| 81 | |
| 82 | for (auto const &stats : mStats) { |
| 83 | stats->setOptions(std::forward<const std::string>(key), |
| 84 | std::forward<const std::string>(value)); |
| 85 | } |
| 86 | return; |
| 87 | } |