Loading metrics/counter.cc +28 −0 Original line number Diff line number Diff line Loading @@ -183,4 +183,32 @@ void TaggedCounter::WriteRecord(int fd) { } } FrequencyCounter::FrequencyCounter() : cycle_duration_(1) { } FrequencyCounter::~FrequencyCounter() { } void FrequencyCounter::Init(const char* filename, TaggedCounterInterface::Reporter reporter, void* reporter_handle, time_t cycle_duration) { // Allow tests to inject tagged_counter_ dependency. if (tagged_counter_.get() == NULL) { tagged_counter_.reset(new TaggedCounter()); } tagged_counter_->Init(filename, reporter, reporter_handle); DCHECK(cycle_duration > 0); cycle_duration_ = cycle_duration; } void FrequencyCounter::UpdateInternal(int32 count, time_t now) { DCHECK(tagged_counter_.get() != NULL); tagged_counter_->Update(GetCycleNumber(now), count); } int32 FrequencyCounter::GetCycleNumber(time_t now) { return now / cycle_duration_; } } // namespace chromeos_metrics metrics/counter.h +46 −0 Original line number Diff line number Diff line Loading @@ -5,11 +5,18 @@ #ifndef METRICS_COUNTER_H_ #define METRICS_COUNTER_H_ #include <time.h> #include <base/basictypes.h> #include <base/scoped_ptr.h> #include <gtest/gtest_prod.h> // for FRIEND_TEST namespace chromeos_metrics { // Constants useful for frequency statistics. const int kSecondsPerDay = 60 * 60 * 24; const int kSecondsPerWeek = kSecondsPerDay * 7; // TaggedCounter maintains a persistent storage (i.e., a file) // aggregation counter for a given tag (e.g., day, hour) that survives // system shutdowns, reboots and crashes, as well as daemon process Loading Loading @@ -152,6 +159,45 @@ class TaggedCounter : public TaggedCounterInterface { RecordState record_state_; }; // FrequencyCounter uses TaggedCounter to maintain a persistent // storage of the number of events that occur in a given cycle // duration (in other words, a frequency count). For example, to // count the number of blips per day, initialize |cycle_duration| to // chromeos_metrics::kSecondsPerDay, and call Update with the number // of blips that happen concurrently (usually 1). Reporting of the // value is done through TaggedCounter's reporter function. class FrequencyCounter { public: // Create a new frequency counter. FrequencyCounter(); virtual ~FrequencyCounter(); // Initialize a frequency counter, which is necessary before first use. // |filename|, |reporter|, and |reporter_handle| are used as in // TaggedCounter::Init. |cycle_duration| is the number of seconds // in a cycle. virtual void Init(const char* filename, TaggedCounterInterface::Reporter reporter, void* reporter_handle, time_t cycle_duration); // Record that an event occurred. |count| is the number of concurrent // events that have occurred. The time is implicitly assumed to be the // time of the call. virtual void Update(int32 count) { UpdateInternal(count, time(NULL)); } private: friend class FrequencyCounterTest; FRIEND_TEST(FrequencyCounterTest, UpdateInternal); void UpdateInternal(int32 count, time_t now); int32 GetCycleNumber(time_t now); time_t cycle_duration_; scoped_ptr<TaggedCounterInterface> tagged_counter_; }; } // namespace chromeos_metrics #endif // METRICS_COUNTER_H_ metrics/counter_mock.h +9 −1 Original line number Diff line number Diff line Loading @@ -21,7 +21,15 @@ class TaggedCounterMock : public TaggedCounterInterface { MOCK_METHOD0(Flush, void()); }; class FrequencyCounterMock : public FrequencyCounter { public: MOCK_METHOD4(Init, void(const char* filename, TaggedCounterInterface::Reporter reporter, void* reporter_handle, time_t cycle_duration)); MOCK_METHOD1(Update, void(int32 count)); }; } // namespace chromeos_metrics #endif // METRICS_COUNTER_MOCK_H_ metrics/counter_test.cc +59 −0 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ #include <gtest/gtest.h> #include "counter.h" #include "counter_mock.h" // For TaggedCounterMock. using ::testing::_; using ::testing::MockFunction; Loading Loading @@ -255,6 +256,64 @@ TEST_F(TaggedCounterTest, Update) { EXPECT_EQ(TaggedCounter::kRecordValid, counter_.record_state_); } class FrequencyCounterTest : public testing::Test { protected: virtual void SetUp() { tagged_counter_ = new StrictMock<TaggedCounterMock>; frequency_counter_.tagged_counter_.reset(tagged_counter_); } static void FakeReporter(void *, int32, int32) { } void CheckInit(int32 cycle_duration); void CheckCycleNumber(int32 cycle_duration); FrequencyCounter frequency_counter_; StrictMock<TaggedCounterMock>* tagged_counter_; TaggedCounter::Reporter reporter_; }; void FrequencyCounterTest::CheckInit(int32 cycle_duration) { EXPECT_CALL(*tagged_counter_, Init(kTestRecordFile, FakeReporter, this)) .Times(1) .RetiresOnSaturation(); frequency_counter_.Init(kTestRecordFile, FakeReporter, this, cycle_duration); EXPECT_EQ(cycle_duration, frequency_counter_.cycle_duration_); } TEST_F(FrequencyCounterTest, Init) { CheckInit(100); } void FrequencyCounterTest::CheckCycleNumber(int32 cycle_duration) { CheckInit(cycle_duration); EXPECT_EQ(150, frequency_counter_.GetCycleNumber(cycle_duration * 150)); EXPECT_EQ(150, frequency_counter_.GetCycleNumber(cycle_duration * 150 + cycle_duration - 1)); EXPECT_EQ(151, frequency_counter_.GetCycleNumber(cycle_duration * 151 + 1)); EXPECT_EQ(0, frequency_counter_.GetCycleNumber(0)); } TEST_F(FrequencyCounterTest, GetCycleNumberForWeek) { CheckCycleNumber(kSecondsPerWeek); } TEST_F(FrequencyCounterTest, GetCycleNumberForDay) { CheckCycleNumber(kSecondsPerDay); } TEST_F(FrequencyCounterTest, UpdateInternal) { CheckInit(kSecondsPerWeek); EXPECT_CALL(*tagged_counter_, Update(150, 2)); frequency_counter_.UpdateInternal(2, kSecondsPerWeek * 150); } } // namespace chromeos_metrics int main(int argc, char** argv) { Loading metrics/metrics_daemon.cc +153 −30 Original line number Diff line number Diff line Loading @@ -39,6 +39,10 @@ static const int kSecondsPerWeek = kSecondsPerDay * kDaysPerWeek; static const int kUseMonitorIntervalInit = 1 * kSecondsPerMinute; static const int kUseMonitorIntervalMax = 10 * kSecondsPerMinute; const char kKernelCrashDetectedFile[] = "/tmp/kernel-crash-detected"; static const char kUncleanShutdownDetectedFile[] = "/tmp/unclean-shutdown-detected"; // static metrics parameters. const char MetricsDaemon::kMetricDailyUseTimeName[] = "Logging.DailyUseTime"; Loading @@ -46,12 +50,6 @@ const int MetricsDaemon::kMetricDailyUseTimeMin = 1; const int MetricsDaemon::kMetricDailyUseTimeMax = kMinutesPerDay; const int MetricsDaemon::kMetricDailyUseTimeBuckets = 50; const char MetricsDaemon::kMetricKernelCrashIntervalName[] = "Logging.KernelCrashInterval"; const int MetricsDaemon::kMetricKernelCrashIntervalMin = 1; const int MetricsDaemon::kMetricKernelCrashIntervalMax = 4 * kSecondsPerWeek; const int MetricsDaemon::kMetricKernelCrashIntervalBuckets = 50; const char MetricsDaemon::kMetricTimeToNetworkDropName[] = "Network.TimeToDrop"; const int MetricsDaemon::kMetricTimeToNetworkDropMin = 1; Loading @@ -59,11 +57,33 @@ const int MetricsDaemon::kMetricTimeToNetworkDropMax = 8 /* hours */ * kMinutesPerHour * kSecondsPerMinute; const int MetricsDaemon::kMetricTimeToNetworkDropBuckets = 50; // crash interval metrics const char MetricsDaemon::kMetricKernelCrashIntervalName[] = "Logging.KernelCrashInterval"; const char MetricsDaemon::kMetricUncleanShutdownIntervalName[] = "Logging.UncleanShutdownInterval"; const char MetricsDaemon::kMetricUserCrashIntervalName[] = "Logging.UserCrashInterval"; const int MetricsDaemon::kMetricUserCrashIntervalMin = 1; const int MetricsDaemon::kMetricUserCrashIntervalMax = 4 * kSecondsPerWeek; const int MetricsDaemon::kMetricUserCrashIntervalBuckets = 50; const int MetricsDaemon::kMetricCrashIntervalMin = 1; const int MetricsDaemon::kMetricCrashIntervalMax = 4 * kSecondsPerWeek; const int MetricsDaemon::kMetricCrashIntervalBuckets = 50; // crash frequency metrics const char MetricsDaemon::kMetricAnyCrashesDailyName[] = "Logging.AnyCrashesDaily"; const char MetricsDaemon::kMetricKernelCrashesDailyName[] = "Logging.KernelCrashesDaily"; const char MetricsDaemon::kMetricUncleanShutdownsDailyName[] = "Logging.UncleanShutdownsDaily"; const char MetricsDaemon::kMetricUserCrashesDailyName[] = "Logging.UserCrashesDaily"; const char MetricsDaemon::kMetricCrashesDailyMin = 1; const char MetricsDaemon::kMetricCrashesDailyMax = 100; const char MetricsDaemon::kMetricCrashesDailyBuckets = 50; // static const char* MetricsDaemon::kDBusMatches_[] = { Loading Loading @@ -168,8 +188,14 @@ void MetricsDaemon::Run(bool run_as_daemon) { if (run_as_daemon && daemon(0, 0) != 0) return; static const char kKernelCrashDetectedFile[] = "/tmp/kernel-crash-detected"; CheckKernelCrash(kKernelCrashDetectedFile); if (CheckSystemCrash(kKernelCrashDetectedFile)) { ProcessKernelCrash(); } if (CheckSystemCrash(kUncleanShutdownDetectedFile)) { ProcessUncleanShutdown(); } Loop(); } Loading @@ -180,19 +206,57 @@ void MetricsDaemon::Init(bool testing, MetricsLibraryInterface* metrics_lib) { static const char kDailyUseRecordFile[] = "/var/log/metrics/daily-usage"; daily_use_.reset(new chromeos_metrics::TaggedCounter()); daily_use_->Init(kDailyUseRecordFile, &DailyUseReporter, this); daily_use_->Init(kDailyUseRecordFile, &ReportDailyUse, this); static const char kUserCrashIntervalRecordFile[] = "/var/log/metrics/user-crash-interval"; user_crash_interval_.reset(new chromeos_metrics::TaggedCounter()); user_crash_interval_->Init(kUserCrashIntervalRecordFile, &UserCrashIntervalReporter, this); &ReportUserCrashInterval, this); static const char kKernelCrashIntervalRecordFile[] = "/var/log/metrics/kernel-crash-interval"; kernel_crash_interval_.reset(new chromeos_metrics::TaggedCounter()); kernel_crash_interval_->Init(kKernelCrashIntervalRecordFile, &KernelCrashIntervalReporter, this); &ReportKernelCrashInterval, this); static const char kUncleanShutdownDetectedFile[] = "/var/log/metrics/unclean-shutdown-interval"; unclean_shutdown_interval_.reset(new chromeos_metrics::TaggedCounter()); unclean_shutdown_interval_->Init(kUncleanShutdownDetectedFile, &ReportUncleanShutdownInterval, this); static const char kUserCrashesDailyRecordFile[] = "/var/log/metrics/user-crashes-daily"; user_crashes_daily_.reset(new chromeos_metrics::FrequencyCounter()); user_crashes_daily_->Init(kUserCrashesDailyRecordFile, &ReportUserCrashesDaily, this, chromeos_metrics::kSecondsPerDay); static const char kKernelCrashesDailyRecordFile[] = "/var/log/metrics/kernel-crashes-daily"; kernel_crashes_daily_.reset(new chromeos_metrics::FrequencyCounter()); kernel_crashes_daily_->Init(kKernelCrashesDailyRecordFile, &ReportKernelCrashesDaily, this, chromeos_metrics::kSecondsPerDay); static const char kUncleanShutdownsDailyRecordFile[] = "/var/log/metrics/unclean-shutdowns-daily"; unclean_shutdowns_daily_.reset(new chromeos_metrics::FrequencyCounter()); unclean_shutdowns_daily_->Init(kUncleanShutdownsDailyRecordFile, &ReportUncleanShutdownsDaily, this, chromeos_metrics::kSecondsPerDay); static const char kAnyCrashesUserCrashDailyRecordFile[] = "/var/log/metrics/any-crashes-daily"; any_crashes_daily_.reset(new chromeos_metrics::FrequencyCounter()); any_crashes_daily_->Init(kAnyCrashesUserCrashDailyRecordFile, &ReportAnyCrashesDaily, this, chromeos_metrics::kSecondsPerDay); // Don't setup D-Bus and GLib in test mode. if (testing) Loading Loading @@ -408,6 +472,9 @@ void MetricsDaemon::ProcessUserCrash() { // Reports the active use time since the last crash and resets it. user_crash_interval_->Flush(); user_crashes_daily_->Update(1); any_crashes_daily_->Update(1); } void MetricsDaemon::ProcessKernelCrash() { Loading @@ -416,19 +483,32 @@ void MetricsDaemon::ProcessKernelCrash() { // Reports the active use time since the last crash and resets it. kernel_crash_interval_->Flush(); kernel_crashes_daily_->Update(1); any_crashes_daily_->Update(1); } void MetricsDaemon::ProcessUncleanShutdown() { // Counts the active use time up to now. SetUserActiveState(user_active_, Time::Now()); // Reports the active use time since the last crash and resets it. unclean_shutdown_interval_->Flush(); unclean_shutdowns_daily_->Update(1); any_crashes_daily_->Update(1); } void MetricsDaemon::CheckKernelCrash(const std::string& crash_file) { bool MetricsDaemon::CheckSystemCrash(const std::string& crash_file) { FilePath crash_detected(crash_file); if (!file_util::PathExists(crash_detected)) return; ProcessKernelCrash(); return false; // Deletes the crash-detected file so that the daemon doesn't report // another kernel crash in case it's restarted. file_util::Delete(crash_detected, false); // recursive return true; } // static Loading Loading @@ -492,7 +572,7 @@ void MetricsDaemon::UnscheduleUseMonitor() { } // static void MetricsDaemon::DailyUseReporter(void* handle, int tag, int count) { void MetricsDaemon::ReportDailyUse(void* handle, int tag, int count) { if (count <= 0) return; Loading @@ -505,25 +585,68 @@ void MetricsDaemon::DailyUseReporter(void* handle, int tag, int count) { } // static void MetricsDaemon::UserCrashIntervalReporter(void* handle, int tag, int count) { void MetricsDaemon::ReportCrashInterval(const char* histogram_name, void* handle, int count) { MetricsDaemon* daemon = static_cast<MetricsDaemon*>(handle); daemon->SendMetric(kMetricUserCrashIntervalName, count, kMetricUserCrashIntervalMin, kMetricUserCrashIntervalMax, kMetricUserCrashIntervalBuckets); daemon->SendMetric(histogram_name, count, kMetricCrashIntervalMin, kMetricCrashIntervalMax, kMetricCrashIntervalBuckets); } // static void MetricsDaemon::ReportUserCrashInterval(void* handle, int tag, int count) { ReportCrashInterval(kMetricUserCrashIntervalName, handle, count); } // static void MetricsDaemon::ReportKernelCrashInterval(void* handle, int tag, int count) { ReportCrashInterval(kMetricKernelCrashIntervalName, handle, count); } // static void MetricsDaemon::KernelCrashIntervalReporter(void* handle, void MetricsDaemon::ReportUncleanShutdownInterval(void* handle, int tag, int count) { ReportCrashInterval(kMetricUncleanShutdownIntervalName, handle, count); } // static void MetricsDaemon::ReportCrashesDailyFrequency(const char* histogram_name, void* handle, int count) { MetricsDaemon* daemon = static_cast<MetricsDaemon*>(handle); daemon->SendMetric(kMetricKernelCrashIntervalName, count, kMetricKernelCrashIntervalMin, kMetricKernelCrashIntervalMax, kMetricKernelCrashIntervalBuckets); daemon->SendMetric(histogram_name, count, kMetricCrashesDailyMin, kMetricCrashesDailyMax, kMetricCrashesDailyBuckets); } // static void MetricsDaemon::ReportUserCrashesDaily(void* handle, int tag, int count) { ReportCrashesDailyFrequency(kMetricUserCrashesDailyName, handle, count); } // static void MetricsDaemon::ReportKernelCrashesDaily(void* handle, int tag, int count) { ReportCrashesDailyFrequency(kMetricKernelCrashesDailyName, handle, count); } // static void MetricsDaemon::ReportUncleanShutdownsDaily(void* handle, int tag, int count) { ReportCrashesDailyFrequency(kMetricUncleanShutdownsDailyName, handle, count); } // static void MetricsDaemon::ReportAnyCrashesDaily(void* handle, int tag, int count) { ReportCrashesDailyFrequency(kMetricAnyCrashesDailyName, handle, count); } void MetricsDaemon::SendMetric(const string& name, int sample, int min, int max, int nbuckets) { DLOG(INFO) << "received metric: " << name << " " << sample << " " Loading Loading
metrics/counter.cc +28 −0 Original line number Diff line number Diff line Loading @@ -183,4 +183,32 @@ void TaggedCounter::WriteRecord(int fd) { } } FrequencyCounter::FrequencyCounter() : cycle_duration_(1) { } FrequencyCounter::~FrequencyCounter() { } void FrequencyCounter::Init(const char* filename, TaggedCounterInterface::Reporter reporter, void* reporter_handle, time_t cycle_duration) { // Allow tests to inject tagged_counter_ dependency. if (tagged_counter_.get() == NULL) { tagged_counter_.reset(new TaggedCounter()); } tagged_counter_->Init(filename, reporter, reporter_handle); DCHECK(cycle_duration > 0); cycle_duration_ = cycle_duration; } void FrequencyCounter::UpdateInternal(int32 count, time_t now) { DCHECK(tagged_counter_.get() != NULL); tagged_counter_->Update(GetCycleNumber(now), count); } int32 FrequencyCounter::GetCycleNumber(time_t now) { return now / cycle_duration_; } } // namespace chromeos_metrics
metrics/counter.h +46 −0 Original line number Diff line number Diff line Loading @@ -5,11 +5,18 @@ #ifndef METRICS_COUNTER_H_ #define METRICS_COUNTER_H_ #include <time.h> #include <base/basictypes.h> #include <base/scoped_ptr.h> #include <gtest/gtest_prod.h> // for FRIEND_TEST namespace chromeos_metrics { // Constants useful for frequency statistics. const int kSecondsPerDay = 60 * 60 * 24; const int kSecondsPerWeek = kSecondsPerDay * 7; // TaggedCounter maintains a persistent storage (i.e., a file) // aggregation counter for a given tag (e.g., day, hour) that survives // system shutdowns, reboots and crashes, as well as daemon process Loading Loading @@ -152,6 +159,45 @@ class TaggedCounter : public TaggedCounterInterface { RecordState record_state_; }; // FrequencyCounter uses TaggedCounter to maintain a persistent // storage of the number of events that occur in a given cycle // duration (in other words, a frequency count). For example, to // count the number of blips per day, initialize |cycle_duration| to // chromeos_metrics::kSecondsPerDay, and call Update with the number // of blips that happen concurrently (usually 1). Reporting of the // value is done through TaggedCounter's reporter function. class FrequencyCounter { public: // Create a new frequency counter. FrequencyCounter(); virtual ~FrequencyCounter(); // Initialize a frequency counter, which is necessary before first use. // |filename|, |reporter|, and |reporter_handle| are used as in // TaggedCounter::Init. |cycle_duration| is the number of seconds // in a cycle. virtual void Init(const char* filename, TaggedCounterInterface::Reporter reporter, void* reporter_handle, time_t cycle_duration); // Record that an event occurred. |count| is the number of concurrent // events that have occurred. The time is implicitly assumed to be the // time of the call. virtual void Update(int32 count) { UpdateInternal(count, time(NULL)); } private: friend class FrequencyCounterTest; FRIEND_TEST(FrequencyCounterTest, UpdateInternal); void UpdateInternal(int32 count, time_t now); int32 GetCycleNumber(time_t now); time_t cycle_duration_; scoped_ptr<TaggedCounterInterface> tagged_counter_; }; } // namespace chromeos_metrics #endif // METRICS_COUNTER_H_
metrics/counter_mock.h +9 −1 Original line number Diff line number Diff line Loading @@ -21,7 +21,15 @@ class TaggedCounterMock : public TaggedCounterInterface { MOCK_METHOD0(Flush, void()); }; class FrequencyCounterMock : public FrequencyCounter { public: MOCK_METHOD4(Init, void(const char* filename, TaggedCounterInterface::Reporter reporter, void* reporter_handle, time_t cycle_duration)); MOCK_METHOD1(Update, void(int32 count)); }; } // namespace chromeos_metrics #endif // METRICS_COUNTER_MOCK_H_
metrics/counter_test.cc +59 −0 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ #include <gtest/gtest.h> #include "counter.h" #include "counter_mock.h" // For TaggedCounterMock. using ::testing::_; using ::testing::MockFunction; Loading Loading @@ -255,6 +256,64 @@ TEST_F(TaggedCounterTest, Update) { EXPECT_EQ(TaggedCounter::kRecordValid, counter_.record_state_); } class FrequencyCounterTest : public testing::Test { protected: virtual void SetUp() { tagged_counter_ = new StrictMock<TaggedCounterMock>; frequency_counter_.tagged_counter_.reset(tagged_counter_); } static void FakeReporter(void *, int32, int32) { } void CheckInit(int32 cycle_duration); void CheckCycleNumber(int32 cycle_duration); FrequencyCounter frequency_counter_; StrictMock<TaggedCounterMock>* tagged_counter_; TaggedCounter::Reporter reporter_; }; void FrequencyCounterTest::CheckInit(int32 cycle_duration) { EXPECT_CALL(*tagged_counter_, Init(kTestRecordFile, FakeReporter, this)) .Times(1) .RetiresOnSaturation(); frequency_counter_.Init(kTestRecordFile, FakeReporter, this, cycle_duration); EXPECT_EQ(cycle_duration, frequency_counter_.cycle_duration_); } TEST_F(FrequencyCounterTest, Init) { CheckInit(100); } void FrequencyCounterTest::CheckCycleNumber(int32 cycle_duration) { CheckInit(cycle_duration); EXPECT_EQ(150, frequency_counter_.GetCycleNumber(cycle_duration * 150)); EXPECT_EQ(150, frequency_counter_.GetCycleNumber(cycle_duration * 150 + cycle_duration - 1)); EXPECT_EQ(151, frequency_counter_.GetCycleNumber(cycle_duration * 151 + 1)); EXPECT_EQ(0, frequency_counter_.GetCycleNumber(0)); } TEST_F(FrequencyCounterTest, GetCycleNumberForWeek) { CheckCycleNumber(kSecondsPerWeek); } TEST_F(FrequencyCounterTest, GetCycleNumberForDay) { CheckCycleNumber(kSecondsPerDay); } TEST_F(FrequencyCounterTest, UpdateInternal) { CheckInit(kSecondsPerWeek); EXPECT_CALL(*tagged_counter_, Update(150, 2)); frequency_counter_.UpdateInternal(2, kSecondsPerWeek * 150); } } // namespace chromeos_metrics int main(int argc, char** argv) { Loading
metrics/metrics_daemon.cc +153 −30 Original line number Diff line number Diff line Loading @@ -39,6 +39,10 @@ static const int kSecondsPerWeek = kSecondsPerDay * kDaysPerWeek; static const int kUseMonitorIntervalInit = 1 * kSecondsPerMinute; static const int kUseMonitorIntervalMax = 10 * kSecondsPerMinute; const char kKernelCrashDetectedFile[] = "/tmp/kernel-crash-detected"; static const char kUncleanShutdownDetectedFile[] = "/tmp/unclean-shutdown-detected"; // static metrics parameters. const char MetricsDaemon::kMetricDailyUseTimeName[] = "Logging.DailyUseTime"; Loading @@ -46,12 +50,6 @@ const int MetricsDaemon::kMetricDailyUseTimeMin = 1; const int MetricsDaemon::kMetricDailyUseTimeMax = kMinutesPerDay; const int MetricsDaemon::kMetricDailyUseTimeBuckets = 50; const char MetricsDaemon::kMetricKernelCrashIntervalName[] = "Logging.KernelCrashInterval"; const int MetricsDaemon::kMetricKernelCrashIntervalMin = 1; const int MetricsDaemon::kMetricKernelCrashIntervalMax = 4 * kSecondsPerWeek; const int MetricsDaemon::kMetricKernelCrashIntervalBuckets = 50; const char MetricsDaemon::kMetricTimeToNetworkDropName[] = "Network.TimeToDrop"; const int MetricsDaemon::kMetricTimeToNetworkDropMin = 1; Loading @@ -59,11 +57,33 @@ const int MetricsDaemon::kMetricTimeToNetworkDropMax = 8 /* hours */ * kMinutesPerHour * kSecondsPerMinute; const int MetricsDaemon::kMetricTimeToNetworkDropBuckets = 50; // crash interval metrics const char MetricsDaemon::kMetricKernelCrashIntervalName[] = "Logging.KernelCrashInterval"; const char MetricsDaemon::kMetricUncleanShutdownIntervalName[] = "Logging.UncleanShutdownInterval"; const char MetricsDaemon::kMetricUserCrashIntervalName[] = "Logging.UserCrashInterval"; const int MetricsDaemon::kMetricUserCrashIntervalMin = 1; const int MetricsDaemon::kMetricUserCrashIntervalMax = 4 * kSecondsPerWeek; const int MetricsDaemon::kMetricUserCrashIntervalBuckets = 50; const int MetricsDaemon::kMetricCrashIntervalMin = 1; const int MetricsDaemon::kMetricCrashIntervalMax = 4 * kSecondsPerWeek; const int MetricsDaemon::kMetricCrashIntervalBuckets = 50; // crash frequency metrics const char MetricsDaemon::kMetricAnyCrashesDailyName[] = "Logging.AnyCrashesDaily"; const char MetricsDaemon::kMetricKernelCrashesDailyName[] = "Logging.KernelCrashesDaily"; const char MetricsDaemon::kMetricUncleanShutdownsDailyName[] = "Logging.UncleanShutdownsDaily"; const char MetricsDaemon::kMetricUserCrashesDailyName[] = "Logging.UserCrashesDaily"; const char MetricsDaemon::kMetricCrashesDailyMin = 1; const char MetricsDaemon::kMetricCrashesDailyMax = 100; const char MetricsDaemon::kMetricCrashesDailyBuckets = 50; // static const char* MetricsDaemon::kDBusMatches_[] = { Loading Loading @@ -168,8 +188,14 @@ void MetricsDaemon::Run(bool run_as_daemon) { if (run_as_daemon && daemon(0, 0) != 0) return; static const char kKernelCrashDetectedFile[] = "/tmp/kernel-crash-detected"; CheckKernelCrash(kKernelCrashDetectedFile); if (CheckSystemCrash(kKernelCrashDetectedFile)) { ProcessKernelCrash(); } if (CheckSystemCrash(kUncleanShutdownDetectedFile)) { ProcessUncleanShutdown(); } Loop(); } Loading @@ -180,19 +206,57 @@ void MetricsDaemon::Init(bool testing, MetricsLibraryInterface* metrics_lib) { static const char kDailyUseRecordFile[] = "/var/log/metrics/daily-usage"; daily_use_.reset(new chromeos_metrics::TaggedCounter()); daily_use_->Init(kDailyUseRecordFile, &DailyUseReporter, this); daily_use_->Init(kDailyUseRecordFile, &ReportDailyUse, this); static const char kUserCrashIntervalRecordFile[] = "/var/log/metrics/user-crash-interval"; user_crash_interval_.reset(new chromeos_metrics::TaggedCounter()); user_crash_interval_->Init(kUserCrashIntervalRecordFile, &UserCrashIntervalReporter, this); &ReportUserCrashInterval, this); static const char kKernelCrashIntervalRecordFile[] = "/var/log/metrics/kernel-crash-interval"; kernel_crash_interval_.reset(new chromeos_metrics::TaggedCounter()); kernel_crash_interval_->Init(kKernelCrashIntervalRecordFile, &KernelCrashIntervalReporter, this); &ReportKernelCrashInterval, this); static const char kUncleanShutdownDetectedFile[] = "/var/log/metrics/unclean-shutdown-interval"; unclean_shutdown_interval_.reset(new chromeos_metrics::TaggedCounter()); unclean_shutdown_interval_->Init(kUncleanShutdownDetectedFile, &ReportUncleanShutdownInterval, this); static const char kUserCrashesDailyRecordFile[] = "/var/log/metrics/user-crashes-daily"; user_crashes_daily_.reset(new chromeos_metrics::FrequencyCounter()); user_crashes_daily_->Init(kUserCrashesDailyRecordFile, &ReportUserCrashesDaily, this, chromeos_metrics::kSecondsPerDay); static const char kKernelCrashesDailyRecordFile[] = "/var/log/metrics/kernel-crashes-daily"; kernel_crashes_daily_.reset(new chromeos_metrics::FrequencyCounter()); kernel_crashes_daily_->Init(kKernelCrashesDailyRecordFile, &ReportKernelCrashesDaily, this, chromeos_metrics::kSecondsPerDay); static const char kUncleanShutdownsDailyRecordFile[] = "/var/log/metrics/unclean-shutdowns-daily"; unclean_shutdowns_daily_.reset(new chromeos_metrics::FrequencyCounter()); unclean_shutdowns_daily_->Init(kUncleanShutdownsDailyRecordFile, &ReportUncleanShutdownsDaily, this, chromeos_metrics::kSecondsPerDay); static const char kAnyCrashesUserCrashDailyRecordFile[] = "/var/log/metrics/any-crashes-daily"; any_crashes_daily_.reset(new chromeos_metrics::FrequencyCounter()); any_crashes_daily_->Init(kAnyCrashesUserCrashDailyRecordFile, &ReportAnyCrashesDaily, this, chromeos_metrics::kSecondsPerDay); // Don't setup D-Bus and GLib in test mode. if (testing) Loading Loading @@ -408,6 +472,9 @@ void MetricsDaemon::ProcessUserCrash() { // Reports the active use time since the last crash and resets it. user_crash_interval_->Flush(); user_crashes_daily_->Update(1); any_crashes_daily_->Update(1); } void MetricsDaemon::ProcessKernelCrash() { Loading @@ -416,19 +483,32 @@ void MetricsDaemon::ProcessKernelCrash() { // Reports the active use time since the last crash and resets it. kernel_crash_interval_->Flush(); kernel_crashes_daily_->Update(1); any_crashes_daily_->Update(1); } void MetricsDaemon::ProcessUncleanShutdown() { // Counts the active use time up to now. SetUserActiveState(user_active_, Time::Now()); // Reports the active use time since the last crash and resets it. unclean_shutdown_interval_->Flush(); unclean_shutdowns_daily_->Update(1); any_crashes_daily_->Update(1); } void MetricsDaemon::CheckKernelCrash(const std::string& crash_file) { bool MetricsDaemon::CheckSystemCrash(const std::string& crash_file) { FilePath crash_detected(crash_file); if (!file_util::PathExists(crash_detected)) return; ProcessKernelCrash(); return false; // Deletes the crash-detected file so that the daemon doesn't report // another kernel crash in case it's restarted. file_util::Delete(crash_detected, false); // recursive return true; } // static Loading Loading @@ -492,7 +572,7 @@ void MetricsDaemon::UnscheduleUseMonitor() { } // static void MetricsDaemon::DailyUseReporter(void* handle, int tag, int count) { void MetricsDaemon::ReportDailyUse(void* handle, int tag, int count) { if (count <= 0) return; Loading @@ -505,25 +585,68 @@ void MetricsDaemon::DailyUseReporter(void* handle, int tag, int count) { } // static void MetricsDaemon::UserCrashIntervalReporter(void* handle, int tag, int count) { void MetricsDaemon::ReportCrashInterval(const char* histogram_name, void* handle, int count) { MetricsDaemon* daemon = static_cast<MetricsDaemon*>(handle); daemon->SendMetric(kMetricUserCrashIntervalName, count, kMetricUserCrashIntervalMin, kMetricUserCrashIntervalMax, kMetricUserCrashIntervalBuckets); daemon->SendMetric(histogram_name, count, kMetricCrashIntervalMin, kMetricCrashIntervalMax, kMetricCrashIntervalBuckets); } // static void MetricsDaemon::ReportUserCrashInterval(void* handle, int tag, int count) { ReportCrashInterval(kMetricUserCrashIntervalName, handle, count); } // static void MetricsDaemon::ReportKernelCrashInterval(void* handle, int tag, int count) { ReportCrashInterval(kMetricKernelCrashIntervalName, handle, count); } // static void MetricsDaemon::KernelCrashIntervalReporter(void* handle, void MetricsDaemon::ReportUncleanShutdownInterval(void* handle, int tag, int count) { ReportCrashInterval(kMetricUncleanShutdownIntervalName, handle, count); } // static void MetricsDaemon::ReportCrashesDailyFrequency(const char* histogram_name, void* handle, int count) { MetricsDaemon* daemon = static_cast<MetricsDaemon*>(handle); daemon->SendMetric(kMetricKernelCrashIntervalName, count, kMetricKernelCrashIntervalMin, kMetricKernelCrashIntervalMax, kMetricKernelCrashIntervalBuckets); daemon->SendMetric(histogram_name, count, kMetricCrashesDailyMin, kMetricCrashesDailyMax, kMetricCrashesDailyBuckets); } // static void MetricsDaemon::ReportUserCrashesDaily(void* handle, int tag, int count) { ReportCrashesDailyFrequency(kMetricUserCrashesDailyName, handle, count); } // static void MetricsDaemon::ReportKernelCrashesDaily(void* handle, int tag, int count) { ReportCrashesDailyFrequency(kMetricKernelCrashesDailyName, handle, count); } // static void MetricsDaemon::ReportUncleanShutdownsDaily(void* handle, int tag, int count) { ReportCrashesDailyFrequency(kMetricUncleanShutdownsDailyName, handle, count); } // static void MetricsDaemon::ReportAnyCrashesDaily(void* handle, int tag, int count) { ReportCrashesDailyFrequency(kMetricAnyCrashesDailyName, handle, count); } void MetricsDaemon::SendMetric(const string& name, int sample, int min, int max, int nbuckets) { DLOG(INFO) << "received metric: " << name << " " << sample << " " Loading