Add # daily crashes metrics and separate kernel crashes out.

BUG=5340

Review URL: http://codereview.chromium.org/3181015
This commit is contained in:
Ken Mixter 2010-08-16 19:57:13 -07:00
parent 3fd74748a7
commit ccd84c03d2
7 changed files with 452 additions and 79 deletions

View file

@ -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

View file

@ -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_

View file

@ -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_

View file

@ -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) {

View file

@ -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 << " "

View file

@ -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_;

View file

@ -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) {