Loading bootstat/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ bootstat_test_src_files := \ bootstat_shared_libs := \ libbase \ libcutils \ liblog bootstat_cflags := \ Loading bootstat/README.md +5 −4 Original line number Diff line number Diff line Loading @@ -7,10 +7,11 @@ analysis. Usage: bootstat [options] options include: -d Dump the boot event records to the console. -h Show this help. -l Log all metrics to logstorage. -r Record the relative time of a named boot event. -h, --help Show this help -l, --log Log all metrics to logstorage -p, --print Dump the boot event records to the console -r, --record Record the timestamp of a named boot event --record_boot_reason Record the reason why the device booted ## Relative time ## Loading bootstat/boot_event_record_store.cpp +15 −3 Original line number Diff line number Diff line Loading @@ -56,19 +56,31 @@ void BootEventRecordStore::AddBootEvent(const std::string& name) { LOG(ERROR) << "Failed to read /proc/uptime"; } // Cast intentionally rounds down. int32_t uptime = static_cast<int32_t>(strtod(uptime_str.c_str(), NULL)); AddBootEventWithValue(name, uptime); } // The implementation of AddBootEventValue makes use of the mtime file // attribute to store the value associated with a boot event in order to // optimize on-disk size requirements and small-file thrashing. void BootEventRecordStore::AddBootEventWithValue( const std::string& name, int32_t value) { std::string record_path = GetBootEventPath(name); if (creat(record_path.c_str(), S_IRUSR | S_IWUSR) == -1) { PLOG(ERROR) << "Failed to create " << record_path; } // Fill out the stat structure for |record_path| in order to get the atime to // set in the utime() call. struct stat file_stat; if (stat(record_path.c_str(), &file_stat) == -1) { PLOG(ERROR) << "Failed to read " << record_path; } // Cast intentionally rounds down. time_t uptime = static_cast<time_t>(strtod(uptime_str.c_str(), NULL)); struct utimbuf times = {file_stat.st_atime, uptime}; // Set the |modtime| of the file to store the value of the boot event while // preserving the |actime| (as read by stat). struct utimbuf times = {/* actime */ file_stat.st_atime, /* modtime */ value}; if (utime(record_path.c_str(), ×) == -1) { PLOG(ERROR) << "Failed to set mtime for " << record_path; } Loading bootstat/boot_event_record_store.h +5 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,10 @@ class BootEventRecordStore { // Persists the boot event named |name| in the record store. void AddBootEvent(const std::string& name); // Persists the boot event named |name| with the associated |value| in the // record store. void AddBootEventWithValue(const std::string& name, int32_t value); // Returns a list of all of the boot events persisted in the record store. std::vector<BootEventRecord> GetAllBootEvents() const; Loading @@ -45,6 +49,7 @@ class BootEventRecordStore { // more test-friendly path. FRIEND_TEST(BootEventRecordStoreTest, AddSingleBootEvent); FRIEND_TEST(BootEventRecordStoreTest, AddMultipleBootEvents); FRIEND_TEST(BootEventRecordStoreTest, AddBootEventWithValue); // Sets the filesystem path of the record store. void SetStorePath(const std::string& path); Loading bootstat/boot_event_record_store_test.cpp +12 −0 Original line number Diff line number Diff line Loading @@ -154,3 +154,15 @@ TEST_F(BootEventRecordStoreTest, AddMultipleBootEvents) { EXPECT_TRUE(FuzzUptimeEquals(uptime, *i)); } } TEST_F(BootEventRecordStoreTest, AddBootEventWithValue) { BootEventRecordStore store; store.SetStorePath(GetStorePathForTesting()); store.AddBootEventWithValue("permian", 42); auto events = store.GetAllBootEvents(); ASSERT_EQ(1U, events.size()); EXPECT_EQ("permian", events[0].first); EXPECT_EQ(42, events[0].second); } No newline at end of file Loading
bootstat/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ bootstat_test_src_files := \ bootstat_shared_libs := \ libbase \ libcutils \ liblog bootstat_cflags := \ Loading
bootstat/README.md +5 −4 Original line number Diff line number Diff line Loading @@ -7,10 +7,11 @@ analysis. Usage: bootstat [options] options include: -d Dump the boot event records to the console. -h Show this help. -l Log all metrics to logstorage. -r Record the relative time of a named boot event. -h, --help Show this help -l, --log Log all metrics to logstorage -p, --print Dump the boot event records to the console -r, --record Record the timestamp of a named boot event --record_boot_reason Record the reason why the device booted ## Relative time ## Loading
bootstat/boot_event_record_store.cpp +15 −3 Original line number Diff line number Diff line Loading @@ -56,19 +56,31 @@ void BootEventRecordStore::AddBootEvent(const std::string& name) { LOG(ERROR) << "Failed to read /proc/uptime"; } // Cast intentionally rounds down. int32_t uptime = static_cast<int32_t>(strtod(uptime_str.c_str(), NULL)); AddBootEventWithValue(name, uptime); } // The implementation of AddBootEventValue makes use of the mtime file // attribute to store the value associated with a boot event in order to // optimize on-disk size requirements and small-file thrashing. void BootEventRecordStore::AddBootEventWithValue( const std::string& name, int32_t value) { std::string record_path = GetBootEventPath(name); if (creat(record_path.c_str(), S_IRUSR | S_IWUSR) == -1) { PLOG(ERROR) << "Failed to create " << record_path; } // Fill out the stat structure for |record_path| in order to get the atime to // set in the utime() call. struct stat file_stat; if (stat(record_path.c_str(), &file_stat) == -1) { PLOG(ERROR) << "Failed to read " << record_path; } // Cast intentionally rounds down. time_t uptime = static_cast<time_t>(strtod(uptime_str.c_str(), NULL)); struct utimbuf times = {file_stat.st_atime, uptime}; // Set the |modtime| of the file to store the value of the boot event while // preserving the |actime| (as read by stat). struct utimbuf times = {/* actime */ file_stat.st_atime, /* modtime */ value}; if (utime(record_path.c_str(), ×) == -1) { PLOG(ERROR) << "Failed to set mtime for " << record_path; } Loading
bootstat/boot_event_record_store.h +5 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,10 @@ class BootEventRecordStore { // Persists the boot event named |name| in the record store. void AddBootEvent(const std::string& name); // Persists the boot event named |name| with the associated |value| in the // record store. void AddBootEventWithValue(const std::string& name, int32_t value); // Returns a list of all of the boot events persisted in the record store. std::vector<BootEventRecord> GetAllBootEvents() const; Loading @@ -45,6 +49,7 @@ class BootEventRecordStore { // more test-friendly path. FRIEND_TEST(BootEventRecordStoreTest, AddSingleBootEvent); FRIEND_TEST(BootEventRecordStoreTest, AddMultipleBootEvents); FRIEND_TEST(BootEventRecordStoreTest, AddBootEventWithValue); // Sets the filesystem path of the record store. void SetStorePath(const std::string& path); Loading
bootstat/boot_event_record_store_test.cpp +12 −0 Original line number Diff line number Diff line Loading @@ -154,3 +154,15 @@ TEST_F(BootEventRecordStoreTest, AddMultipleBootEvents) { EXPECT_TRUE(FuzzUptimeEquals(uptime, *i)); } } TEST_F(BootEventRecordStoreTest, AddBootEventWithValue) { BootEventRecordStore store; store.SetStorePath(GetStorePathForTesting()); store.AddBootEventWithValue("permian", 42); auto events = store.GetAllBootEvents(); ASSERT_EQ(1U, events.size()); EXPECT_EQ("permian", events[0].first); EXPECT_EQ(42, events[0].second); } No newline at end of file