summaryrefslogtreecommitdiff
path: root/perfstatsd/perfstatsd.cpp
diff options
context:
space:
mode:
authorCharles(Yen-Cheng) Chan <charleschan@google.com>2019-01-02 12:26:16 +0800
committerCharles(Yen-Cheng) Chan <charleschan@google.com>2019-01-04 18:07:20 +0800
commit08bfed87cbeab2d2949ea0ad0b90c8e813a7ecf2 (patch)
tree119fd737f6d08fd9564c2870f135dacd1faf1b91 /perfstatsd/perfstatsd.cpp
parent90ea5f3bb9b7c67f45b2d7f184f9dd56eec3170d (diff)
downloadpixel-08bfed87cbeab2d2949ea0ad0b90c8e813a7ecf2.tar.gz
Add perfstatsd to collect perf stats history
Refer to go/perfstatsd-design for detail. Bug: 117587967 Test: verify daemon run on boot and dump data triggered by dumpstate Change-Id: I4f0258c8ab220649f19d0ee960fc6bcbc790c6e1
Diffstat (limited to 'perfstatsd/perfstatsd.cpp')
-rw-r--r--perfstatsd/perfstatsd.cpp80
1 files changed, 80 insertions, 0 deletions
diff --git a/perfstatsd/perfstatsd.cpp b/perfstatsd/perfstatsd.cpp
new file mode 100644
index 00000000..1f51aa79
--- /dev/null
+++ b/perfstatsd/perfstatsd.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2018 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 LOG_TAG "perfstatsd"
+
+#include <perfstatsd.h>
+
+using namespace android::pixel::perfstatsd;
+
+perfstatsd_t::perfstatsd_t(void) {
+ mRefreshPeriod = DEFAULT_DATA_COLLECT_PERIOD;
+}
+
+void perfstatsd_t::refresh(void) {
+ for (auto const &stats : mStats) {
+ stats->refresh();
+ }
+ return;
+}
+
+void perfstatsd_t::get_history(std::string *ret) {
+ std::priority_queue<statsdata, std::vector<statsdata>, StatsdataCompare> mergedQueue;
+ for (auto const &stats : mStats) {
+ stats->dump(&mergedQueue);
+ }
+
+ while (!mergedQueue.empty()) {
+ statsdata data = mergedQueue.top();
+ auto raw_time = data.getTime();
+ auto seconds = std::chrono::time_point_cast<std::chrono::seconds>(raw_time);
+ auto d = raw_time - seconds;
+ auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(d);
+ std::string content = data.getData();
+
+ time_t t = std::chrono::system_clock::to_time_t(raw_time);
+ char buff[20];
+ strftime(buff, sizeof(buff), "%m-%d %H:%M:%S", localtime(&t));
+
+ ret->append(std::string(buff) + ".");
+ ret->append(std::to_string(milliseconds.count()) + "\n");
+ ret->append(content + "\n");
+ mergedQueue.pop();
+ }
+
+ if (ret->size() > 400_KiB)
+ LOG_TO(SYSTEM, WARNING) << "Data might be too large. size: " << ret->size() << " bytes\n"
+ << *ret;
+}
+
+void perfstatsd_t::setOptions(const std::string &key, const std::string &value) {
+ if (key == PERFSTATSD_PERIOD) {
+ uint32_t val = 0;
+ if (!base::ParseUint(value, &val) || val < 1) {
+ LOG_TO(SYSTEM, ERROR) << "Invalid value. Minimum refresh period is 1 second";
+ } else {
+ mRefreshPeriod = val;
+ LOG_TO(SYSTEM, INFO) << "set period to " << value << " seconds";
+ }
+ return;
+ }
+
+ for (auto const &stats : mStats) {
+ stats->setOptions(std::forward<const std::string>(key),
+ std::forward<const std::string>(value));
+ }
+ return;
+}