Add # daily crashes metrics and separate kernel crashes out.
BUG=5340 Review URL: http://codereview.chromium.org/3181015
This commit is contained in:
parent
3fd74748a7
commit
ccd84c03d2
7 changed files with 452 additions and 79 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
@ -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_
|
||||
|
|
|
@ -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_
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <gtest/gtest.h>
|
||||
|
||||
#include "counter.h"
|
||||
#include "counter_mock.h" // For TaggedCounterMock.
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::MockFunction;
|
||||
|
@ -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) {
|
||||
|
|
|
@ -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";
|
||||
|
@ -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;
|
||||
|
@ -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_[] = {
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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() {
|
||||
|
@ -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::CheckKernelCrash(const std::string& crash_file) {
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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::KernelCrashIntervalReporter(void* handle,
|
||||
int tag, int count) {
|
||||
MetricsDaemon* daemon = static_cast<MetricsDaemon*>(handle);
|
||||
daemon->SendMetric(kMetricKernelCrashIntervalName, count,
|
||||
kMetricKernelCrashIntervalMin,
|
||||
kMetricKernelCrashIntervalMax,
|
||||
kMetricKernelCrashIntervalBuckets);
|
||||
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::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(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 << " "
|
||||
|
|
|
@ -14,7 +14,10 @@
|
|||
|
||||
#include "metrics_library.h"
|
||||
|
||||
namespace chromeos_metrics { class TaggedCounterInterface; }
|
||||
namespace chromeos_metrics {
|
||||
class FrequencyCounter;
|
||||
class TaggedCounterInterface;
|
||||
}
|
||||
|
||||
class MetricsDaemon {
|
||||
|
||||
|
@ -31,9 +34,7 @@ class MetricsDaemon {
|
|||
|
||||
private:
|
||||
friend class MetricsDaemonTest;
|
||||
FRIEND_TEST(MetricsDaemonTest, CheckKernelCrash);
|
||||
FRIEND_TEST(MetricsDaemonTest, DailyUseReporter);
|
||||
FRIEND_TEST(MetricsDaemonTest, KernelCrashIntervalReporter);
|
||||
FRIEND_TEST(MetricsDaemonTest, CheckSystemCrash);
|
||||
FRIEND_TEST(MetricsDaemonTest, LookupNetworkState);
|
||||
FRIEND_TEST(MetricsDaemonTest, LookupPowerState);
|
||||
FRIEND_TEST(MetricsDaemonTest, LookupScreenSaverState);
|
||||
|
@ -43,13 +44,18 @@ class MetricsDaemon {
|
|||
FRIEND_TEST(MetricsDaemonTest, NetStateChangedSuspend);
|
||||
FRIEND_TEST(MetricsDaemonTest, PowerStateChanged);
|
||||
FRIEND_TEST(MetricsDaemonTest, ProcessKernelCrash);
|
||||
FRIEND_TEST(MetricsDaemonTest, ProcessUncleanShutdown);
|
||||
FRIEND_TEST(MetricsDaemonTest, ProcessUserCrash);
|
||||
FRIEND_TEST(MetricsDaemonTest, ReportCrashesDailyFrequency);
|
||||
FRIEND_TEST(MetricsDaemonTest, ReportDailyUse);
|
||||
FRIEND_TEST(MetricsDaemonTest, ReportKernelCrashInterval);
|
||||
FRIEND_TEST(MetricsDaemonTest, ReportUncleanShutdownInterval);
|
||||
FRIEND_TEST(MetricsDaemonTest, ReportUserCrashInterval);
|
||||
FRIEND_TEST(MetricsDaemonTest, ScreenSaverStateChanged);
|
||||
FRIEND_TEST(MetricsDaemonTest, SendMetric);
|
||||
FRIEND_TEST(MetricsDaemonTest, SessionStateChanged);
|
||||
FRIEND_TEST(MetricsDaemonTest, SetUserActiveState);
|
||||
FRIEND_TEST(MetricsDaemonTest, SetUserActiveStateTimeJump);
|
||||
FRIEND_TEST(MetricsDaemonTest, UserCrashIntervalReporter);
|
||||
|
||||
// The network states (see network_states.h).
|
||||
enum NetworkState {
|
||||
|
@ -84,22 +90,27 @@ class MetricsDaemon {
|
|||
};
|
||||
|
||||
// Metric parameters.
|
||||
static const char kMetricAnyCrashesDailyName[];
|
||||
static const char kMetricCrashesDailyBuckets;
|
||||
static const char kMetricCrashesDailyMax;
|
||||
static const char kMetricCrashesDailyMin;
|
||||
static const int kMetricCrashIntervalBuckets;
|
||||
static const int kMetricCrashIntervalMax;
|
||||
static const int kMetricCrashIntervalMin;
|
||||
static const int kMetricDailyUseTimeBuckets;
|
||||
static const int kMetricDailyUseTimeMax;
|
||||
static const int kMetricDailyUseTimeMin;
|
||||
static const char kMetricDailyUseTimeName[];
|
||||
static const int kMetricDailyUseTimeMin;
|
||||
static const int kMetricDailyUseTimeMax;
|
||||
static const int kMetricDailyUseTimeBuckets;
|
||||
static const char kMetricKernelCrashesDailyName[];
|
||||
static const char kMetricKernelCrashIntervalName[];
|
||||
static const int kMetricKernelCrashIntervalMin;
|
||||
static const int kMetricKernelCrashIntervalMax;
|
||||
static const int kMetricKernelCrashIntervalBuckets;
|
||||
static const int kMetricTimeToNetworkDropBuckets;
|
||||
static const int kMetricTimeToNetworkDropMax;
|
||||
static const int kMetricTimeToNetworkDropMin;
|
||||
static const char kMetricTimeToNetworkDropName[];
|
||||
static const int kMetricTimeToNetworkDropMin;
|
||||
static const int kMetricTimeToNetworkDropMax;
|
||||
static const int kMetricTimeToNetworkDropBuckets;
|
||||
static const char kMetricUncleanShutdownIntervalName[];
|
||||
static const char kMetricUncleanShutdownsDailyName[];
|
||||
static const char kMetricUserCrashesDailyName[];
|
||||
static const char kMetricUserCrashIntervalName[];
|
||||
static const int kMetricUserCrashIntervalMin;
|
||||
static const int kMetricUserCrashIntervalMax;
|
||||
static const int kMetricUserCrashIntervalBuckets;
|
||||
|
||||
// D-Bus message match strings.
|
||||
static const char* kDBusMatches_[];
|
||||
|
@ -162,10 +173,14 @@ class MetricsDaemon {
|
|||
// Updates the active use time and logs time between kernel crashes.
|
||||
void ProcessKernelCrash();
|
||||
|
||||
// Checks if a kernel crash has been detected and processes if so.
|
||||
// The method assumes that a kernel crash has happened if
|
||||
// |crash_file| exists.
|
||||
void CheckKernelCrash(const std::string& crash_file);
|
||||
// Updates the active use time and logs time between unclean shutdowns.
|
||||
void ProcessUncleanShutdown();
|
||||
|
||||
// Checks if a kernel crash has been detected and returns true if
|
||||
// so. The method assumes that a kernel crash has happened if
|
||||
// |crash_file| exists. It removes the file immediately if it
|
||||
// exists, so it must not be called more than once.
|
||||
bool CheckSystemCrash(const std::string& crash_file);
|
||||
|
||||
// Callbacks for the daily use monitor. The daily use monitor uses
|
||||
// LogDailyUseRecord to aggregate current usage data and send it to
|
||||
|
@ -196,15 +211,39 @@ class MetricsDaemon {
|
|||
|
||||
// TaggedCounter callback to process aggregated daily usage data and
|
||||
// send to UMA.
|
||||
static void DailyUseReporter(void* data, int tag, int count);
|
||||
static void ReportDailyUse(void* data, int tag, int count);
|
||||
|
||||
// Helper to report a crash interval to UMA.
|
||||
static void ReportCrashInterval(const char* histogram_name,
|
||||
void* handle, int count);
|
||||
|
||||
// TaggedCounter callback to process time between user-space process
|
||||
// crashes and send to UMA.
|
||||
static void UserCrashIntervalReporter(void* data, int tag, int count);
|
||||
static void ReportUserCrashInterval(void* data, int tag, int count);
|
||||
|
||||
// TaggedCounter callback to process time between kernel crashes and
|
||||
// send to UMA.
|
||||
static void KernelCrashIntervalReporter(void* data, int tag, int count);
|
||||
static void ReportKernelCrashInterval(void* data, int tag, int count);
|
||||
|
||||
// TaggedCounter callback to process time between unclean shutdowns and
|
||||
// send to UMA.
|
||||
static void ReportUncleanShutdownInterval(void* data, int tag, int count);
|
||||
|
||||
// Helper to report a daily crash frequency to UMA.
|
||||
static void ReportCrashesDailyFrequency(const char* histogram_name,
|
||||
void* handle, int count);
|
||||
|
||||
// TaggedCounter callback to report daily crash frequency to UMA.
|
||||
static void ReportUserCrashesDaily(void* handle, int tag, int count);
|
||||
|
||||
// TaggedCounter callback to report kernel crash frequency to UMA.
|
||||
static void ReportKernelCrashesDaily(void* handle, int tag, int count);
|
||||
|
||||
// TaggedCounter callback to report unclean shutdown frequency to UMA.
|
||||
static void ReportUncleanShutdownsDaily(void* handle, int tag, int count);
|
||||
|
||||
// TaggedCounter callback to report frequency of any crashes to UMA.
|
||||
static void ReportAnyCrashesDaily(void* handle, int tag, int count);
|
||||
|
||||
// Test mode.
|
||||
bool testing_;
|
||||
|
@ -244,6 +283,23 @@ class MetricsDaemon {
|
|||
// Active use time between kernel crashes.
|
||||
scoped_ptr<chromeos_metrics::TaggedCounterInterface> kernel_crash_interval_;
|
||||
|
||||
// Active use time between unclean shutdowns crashes.
|
||||
scoped_ptr<chromeos_metrics::TaggedCounterInterface>
|
||||
unclean_shutdown_interval_;
|
||||
|
||||
// Daily count of user-space process crashes.
|
||||
scoped_ptr<chromeos_metrics::FrequencyCounter> user_crashes_daily_;
|
||||
|
||||
// Daily count of kernel crashes.
|
||||
scoped_ptr<chromeos_metrics::FrequencyCounter> kernel_crashes_daily_;
|
||||
|
||||
// Daily count of unclean shutdowns.
|
||||
scoped_ptr<chromeos_metrics::FrequencyCounter> unclean_shutdowns_daily_;
|
||||
|
||||
// Daily count of any crashes (user-space processes, kernel, or
|
||||
// unclean shutdowns).
|
||||
scoped_ptr<chromeos_metrics::FrequencyCounter> any_crashes_daily_;
|
||||
|
||||
// Sleep period until the next daily usage aggregation performed by
|
||||
// the daily use monitor (see ScheduleUseMonitor).
|
||||
int usemon_interval_;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
using base::Time;
|
||||
using base::TimeTicks;
|
||||
using chromeos_metrics::FrequencyCounterMock;
|
||||
using chromeos_metrics::TaggedCounterMock;
|
||||
using ::testing::_;
|
||||
using ::testing::Return;
|
||||
|
@ -59,6 +60,16 @@ class MetricsDaemonTest : public testing::Test {
|
|||
daemon_.kernel_crash_interval_.reset(kernel_crash_interval_);
|
||||
user_crash_interval_ = new StrictMock<TaggedCounterMock>();
|
||||
daemon_.user_crash_interval_.reset(user_crash_interval_);
|
||||
unclean_shutdown_interval_ = new StrictMock<TaggedCounterMock>();
|
||||
daemon_.unclean_shutdown_interval_.reset(unclean_shutdown_interval_);
|
||||
kernel_crashes_daily_ = new StrictMock<FrequencyCounterMock>();
|
||||
daemon_.kernel_crashes_daily_.reset(kernel_crashes_daily_);
|
||||
user_crashes_daily_ = new StrictMock<FrequencyCounterMock>();
|
||||
daemon_.user_crashes_daily_.reset(user_crashes_daily_);
|
||||
unclean_shutdowns_daily_ = new StrictMock<FrequencyCounterMock>();
|
||||
daemon_.unclean_shutdowns_daily_.reset(unclean_shutdowns_daily_);
|
||||
any_crashes_daily_ = new StrictMock<FrequencyCounterMock>();
|
||||
daemon_.any_crashes_daily_.reset(any_crashes_daily_);
|
||||
|
||||
EXPECT_FALSE(daemon_.user_active_);
|
||||
EXPECT_TRUE(daemon_.user_active_last_.is_null());
|
||||
|
@ -172,40 +183,54 @@ class MetricsDaemonTest : public testing::Test {
|
|||
StrictMock<TaggedCounterMock>* daily_use_;
|
||||
StrictMock<TaggedCounterMock>* kernel_crash_interval_;
|
||||
StrictMock<TaggedCounterMock>* user_crash_interval_;
|
||||
StrictMock<TaggedCounterMock>* unclean_shutdown_interval_;
|
||||
|
||||
StrictMock<FrequencyCounterMock>* kernel_crashes_daily_;
|
||||
StrictMock<FrequencyCounterMock>* user_crashes_daily_;
|
||||
StrictMock<FrequencyCounterMock>* unclean_shutdowns_daily_;
|
||||
StrictMock<FrequencyCounterMock>* any_crashes_daily_;
|
||||
};
|
||||
|
||||
TEST_F(MetricsDaemonTest, CheckKernelCrash) {
|
||||
TEST_F(MetricsDaemonTest, CheckSystemCrash) {
|
||||
static const char kKernelCrashDetected[] = "test-kernel-crash-detected";
|
||||
daemon_.CheckKernelCrash(kKernelCrashDetected);
|
||||
EXPECT_FALSE(daemon_.CheckSystemCrash(kKernelCrashDetected));
|
||||
|
||||
FilePath crash_detected(kKernelCrashDetected);
|
||||
file_util::WriteFile(crash_detected, "", 0);
|
||||
IgnoreActiveUseUpdate();
|
||||
EXPECT_CALL(*kernel_crash_interval_, Flush())
|
||||
.Times(1)
|
||||
.RetiresOnSaturation();
|
||||
daemon_.CheckKernelCrash(kKernelCrashDetected);
|
||||
EXPECT_TRUE(file_util::PathExists(crash_detected));
|
||||
EXPECT_TRUE(daemon_.CheckSystemCrash(kKernelCrashDetected));
|
||||
EXPECT_FALSE(file_util::PathExists(crash_detected));
|
||||
EXPECT_FALSE(daemon_.CheckSystemCrash(kKernelCrashDetected));
|
||||
EXPECT_FALSE(file_util::PathExists(crash_detected));
|
||||
file_util::Delete(crash_detected, false);
|
||||
}
|
||||
|
||||
TEST_F(MetricsDaemonTest, DailyUseReporter) {
|
||||
TEST_F(MetricsDaemonTest, ReportDailyUse) {
|
||||
ExpectDailyUseTimeMetric(/* sample */ 2);
|
||||
MetricsDaemon::DailyUseReporter(&daemon_, /* tag */ 20, /* count */ 90);
|
||||
MetricsDaemon::ReportDailyUse(&daemon_, /* tag */ 20, /* count */ 90);
|
||||
|
||||
ExpectDailyUseTimeMetric(/* sample */ 1);
|
||||
MetricsDaemon::DailyUseReporter(&daemon_, /* tag */ 23, /* count */ 89);
|
||||
MetricsDaemon::ReportDailyUse(&daemon_, /* tag */ 23, /* count */ 89);
|
||||
|
||||
// There should be no metrics generated for the calls below.
|
||||
MetricsDaemon::DailyUseReporter(&daemon_, /* tag */ 50, /* count */ 0);
|
||||
MetricsDaemon::DailyUseReporter(&daemon_, /* tag */ 60, /* count */ -5);
|
||||
MetricsDaemon::ReportDailyUse(&daemon_, /* tag */ 50, /* count */ 0);
|
||||
MetricsDaemon::ReportDailyUse(&daemon_, /* tag */ 60, /* count */ -5);
|
||||
}
|
||||
|
||||
TEST_F(MetricsDaemonTest, KernelCrashIntervalReporter) {
|
||||
TEST_F(MetricsDaemonTest, ReportKernelCrashInterval) {
|
||||
ExpectMetric(MetricsDaemon::kMetricKernelCrashIntervalName, 50,
|
||||
MetricsDaemon::kMetricKernelCrashIntervalMin,
|
||||
MetricsDaemon::kMetricKernelCrashIntervalMax,
|
||||
MetricsDaemon::kMetricKernelCrashIntervalBuckets);
|
||||
MetricsDaemon::KernelCrashIntervalReporter(&daemon_, 0, 50);
|
||||
MetricsDaemon::kMetricCrashIntervalMin,
|
||||
MetricsDaemon::kMetricCrashIntervalMax,
|
||||
MetricsDaemon::kMetricCrashIntervalBuckets);
|
||||
MetricsDaemon::ReportKernelCrashInterval(&daemon_, 0, 50);
|
||||
}
|
||||
|
||||
TEST_F(MetricsDaemonTest, ReportUncleanShutdownInterval) {
|
||||
ExpectMetric(MetricsDaemon::kMetricUncleanShutdownIntervalName, 50,
|
||||
MetricsDaemon::kMetricCrashIntervalMin,
|
||||
MetricsDaemon::kMetricCrashIntervalMax,
|
||||
MetricsDaemon::kMetricCrashIntervalBuckets);
|
||||
MetricsDaemon::ReportUncleanShutdownInterval(&daemon_, 0, 50);
|
||||
}
|
||||
|
||||
TEST_F(MetricsDaemonTest, LookupNetworkState) {
|
||||
|
@ -246,6 +271,12 @@ TEST_F(MetricsDaemonTest, MessageFilter) {
|
|||
EXPECT_CALL(*user_crash_interval_, Flush())
|
||||
.Times(1)
|
||||
.RetiresOnSaturation();
|
||||
EXPECT_CALL(*user_crashes_daily_, Update(1))
|
||||
.Times(1)
|
||||
.RetiresOnSaturation();
|
||||
EXPECT_CALL(*any_crashes_daily_, Update(1))
|
||||
.Times(1)
|
||||
.RetiresOnSaturation();
|
||||
msg = NewDBusSignalString("/",
|
||||
"org.chromium.CrashReporter",
|
||||
"UserCrash",
|
||||
|
@ -379,14 +410,28 @@ TEST_F(MetricsDaemonTest, ProcessKernelCrash) {
|
|||
EXPECT_CALL(*kernel_crash_interval_, Flush())
|
||||
.Times(1)
|
||||
.RetiresOnSaturation();
|
||||
EXPECT_CALL(*kernel_crashes_daily_, Update(1));
|
||||
EXPECT_CALL(*any_crashes_daily_, Update(1));
|
||||
daemon_.ProcessKernelCrash();
|
||||
}
|
||||
|
||||
TEST_F(MetricsDaemonTest, ProcessUncleanShutdown) {
|
||||
IgnoreActiveUseUpdate();
|
||||
EXPECT_CALL(*unclean_shutdown_interval_, Flush())
|
||||
.Times(1)
|
||||
.RetiresOnSaturation();
|
||||
EXPECT_CALL(*unclean_shutdowns_daily_, Update(1));
|
||||
EXPECT_CALL(*any_crashes_daily_, Update(1));
|
||||
daemon_.ProcessUncleanShutdown();
|
||||
}
|
||||
|
||||
TEST_F(MetricsDaemonTest, ProcessUserCrash) {
|
||||
IgnoreActiveUseUpdate();
|
||||
EXPECT_CALL(*user_crash_interval_, Flush())
|
||||
.Times(1)
|
||||
.RetiresOnSaturation();
|
||||
EXPECT_CALL(*user_crashes_daily_, Update(1));
|
||||
EXPECT_CALL(*any_crashes_daily_, Update(1));
|
||||
daemon_.ProcessUserCrash();
|
||||
}
|
||||
|
||||
|
@ -469,12 +514,20 @@ TEST_F(MetricsDaemonTest, SetUserActiveStateTimeJump) {
|
|||
EXPECT_EQ(TestTime(10 * kSecondsPerDay + 1000), daemon_.user_active_last_);
|
||||
}
|
||||
|
||||
TEST_F(MetricsDaemonTest, UserCrashIntervalReporter) {
|
||||
TEST_F(MetricsDaemonTest, ReportUserCrashInterval) {
|
||||
ExpectMetric(MetricsDaemon::kMetricUserCrashIntervalName, 50,
|
||||
MetricsDaemon::kMetricUserCrashIntervalMin,
|
||||
MetricsDaemon::kMetricUserCrashIntervalMax,
|
||||
MetricsDaemon::kMetricUserCrashIntervalBuckets);
|
||||
MetricsDaemon::UserCrashIntervalReporter(&daemon_, 0, 50);
|
||||
MetricsDaemon::kMetricCrashIntervalMin,
|
||||
MetricsDaemon::kMetricCrashIntervalMax,
|
||||
MetricsDaemon::kMetricCrashIntervalBuckets);
|
||||
MetricsDaemon::ReportUserCrashInterval(&daemon_, 0, 50);
|
||||
}
|
||||
|
||||
TEST_F(MetricsDaemonTest, ReportCrashesDailyFrequency) {
|
||||
ExpectMetric("foobar", 50,
|
||||
MetricsDaemon::kMetricCrashesDailyMin,
|
||||
MetricsDaemon::kMetricCrashesDailyMax,
|
||||
MetricsDaemon::kMetricCrashesDailyBuckets);
|
||||
MetricsDaemon::ReportCrashesDailyFrequency("foobar", &daemon_, 50);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
|
Loading…
Reference in a new issue