| Index: metrics_daemon.cc
|
| diff --git a/metrics_daemon.cc b/metrics_daemon.cc
|
| index e93c9a8181d81cb576f27f49e42f067e8256041e..6cbe8e812be14064ad3b69204281a44c04890a86 100644
|
| --- a/metrics_daemon.cc
|
| +++ b/metrics_daemon.cc
|
| @@ -15,6 +15,7 @@ using base::TimeDelta;
|
| using base::TimeTicks;
|
|
|
| #define SAFE_MESSAGE(e) (e.message ? e.message : "unknown error")
|
| +#define DBUS_IFACE_CRASH_REPORTER "org.chromium.CrashReporter"
|
| #define DBUS_IFACE_FLIMFLAM_MANAGER "org.chromium.flimflam.Manager"
|
| #define DBUS_IFACE_POWER_MANAGER "org.chromium.PowerManager"
|
| #define DBUS_IFACE_SESSION_MANAGER "org.chromium.SessionManagerInterface"
|
| @@ -23,11 +24,16 @@ using base::TimeTicks;
|
| // TODO(petkov): This file should probably live in a user-specific stateful
|
| // location, e.g., /home/chronos/user.
|
| static const char kDailyUseRecordFile[] = "/var/log/metrics/daily-usage";
|
| +static const char kUserCrashIntervalRecordFile[] =
|
| + "/var/log/metrics/user-crash-interval";
|
|
|
| static const int kSecondsPerMinute = 60;
|
| static const int kMinutesPerHour = 60;
|
| static const int kHoursPerDay = 24;
|
| static const int kMinutesPerDay = kHoursPerDay * kMinutesPerHour;
|
| +static const int kSecondsPerDay = kSecondsPerMinute * kMinutesPerDay;
|
| +static const int kDaysPerWeek = 7;
|
| +static const int kSecondsPerWeek = kSecondsPerDay * kDaysPerWeek;
|
|
|
| // The daily use monitor is scheduled to a 1-minute interval after
|
| // initial user activity and then it's exponentially backed off to
|
| @@ -52,9 +58,20 @@ const int MetricsDaemon::kMetricTimeToNetworkDropMax =
|
| 8 /* hours */ * kMinutesPerHour * kSecondsPerMinute;
|
| const int MetricsDaemon::kMetricTimeToNetworkDropBuckets = 50;
|
|
|
| +const char MetricsDaemon::kMetricUserCrashIntervalName[] =
|
| + "Logging.UserCrashInterval";
|
| +const int MetricsDaemon::kMetricUserCrashIntervalMin = 1;
|
| +const int MetricsDaemon::kMetricUserCrashIntervalMax = 4 * kSecondsPerWeek;
|
| +const int MetricsDaemon::kMetricUserCrashIntervalBuckets = 50;
|
| +
|
| // static
|
| const char* MetricsDaemon::kDBusMatches_[] = {
|
| "type='signal',"
|
| + "interface='" DBUS_IFACE_CRASH_REPORTER "',"
|
| + "path='/',"
|
| + "member='UserCrash'",
|
| +
|
| + "type='signal',"
|
| "sender='org.chromium.flimflam',"
|
| "interface='" DBUS_IFACE_FLIMFLAM_MANAGER "',"
|
| "path='/',"
|
| @@ -111,6 +128,9 @@ void MetricsDaemon::Init(bool testing, MetricsLibraryInterface* metrics_lib) {
|
| metrics_lib_ = metrics_lib;
|
| daily_use_.reset(new chromeos_metrics::TaggedCounter());
|
| daily_use_->Init(kDailyUseRecordFile, &DailyUseReporter, this);
|
| + user_crash_interval_.reset(new chromeos_metrics::TaggedCounter());
|
| + user_crash_interval_->Init(kUserCrashIntervalRecordFile,
|
| + &UserCrashIntervalReporter, this);
|
|
|
| // Don't setup D-Bus and GLib in test mode.
|
| if (testing)
|
| @@ -130,7 +150,7 @@ void MetricsDaemon::Init(bool testing, MetricsLibraryInterface* metrics_lib) {
|
| dbus_connection_setup_with_g_main(connection, NULL);
|
|
|
| // Registers D-Bus matches for the signals we would like to catch.
|
| - for (unsigned int m = 0; m < sizeof(kDBusMatches_) / sizeof(char*); m++) {
|
| + for (unsigned int m = 0; m < arraysize(kDBusMatches_); m++) {
|
| const char* match = kDBusMatches_[m];
|
| DLOG(INFO) << "adding dbus match: " << match;
|
| dbus_bus_add_match(connection, match, &error);
|
| @@ -171,7 +191,11 @@ DBusHandlerResult MetricsDaemon::MessageFilter(DBusConnection* connection,
|
|
|
| DBusMessageIter iter;
|
| dbus_message_iter_init(message, &iter);
|
| - if (strcmp(interface, DBUS_IFACE_FLIMFLAM_MANAGER) == 0) {
|
| + if (strcmp(interface, DBUS_IFACE_CRASH_REPORTER) == 0) {
|
| + CHECK(strcmp(dbus_message_get_member(message),
|
| + "UserCrash") == 0);
|
| + daemon->ProcessUserCrash();
|
| + } else if (strcmp(interface, DBUS_IFACE_FLIMFLAM_MANAGER) == 0) {
|
| CHECK(strcmp(dbus_message_get_member(message),
|
| "StateChanged") == 0);
|
|
|
| @@ -295,6 +319,7 @@ void MetricsDaemon::SetUserActiveState(bool active, Time now) {
|
| TimeDelta since_epoch = now - Time();
|
| int day = since_epoch.InDays();
|
| daily_use_->Update(day, seconds);
|
| + user_crash_interval_->Update(0, seconds);
|
|
|
| // Schedules a use monitor on inactive->active transitions and
|
| // unschedules it on active->inactive transitions.
|
| @@ -309,6 +334,14 @@ void MetricsDaemon::SetUserActiveState(bool active, Time now) {
|
| user_active_last_ = now;
|
| }
|
|
|
| +void MetricsDaemon::ProcessUserCrash() {
|
| + // 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.
|
| + user_crash_interval_->Flush();
|
| +}
|
| +
|
| // static
|
| gboolean MetricsDaemon::UseMonitorStatic(gpointer data) {
|
| return static_cast<MetricsDaemon*>(data)->UseMonitor() ? TRUE : FALSE;
|
| @@ -371,6 +404,9 @@ void MetricsDaemon::UnscheduleUseMonitor() {
|
|
|
| // static
|
| void MetricsDaemon::DailyUseReporter(void* handle, int tag, int count) {
|
| + if (count <= 0)
|
| + return;
|
| +
|
| MetricsDaemon* daemon = static_cast<MetricsDaemon*>(handle);
|
| int minutes = (count + kSecondsPerMinute / 2) / kSecondsPerMinute;
|
| daemon->SendMetric(kMetricDailyUseTimeName, minutes,
|
| @@ -379,6 +415,16 @@ void MetricsDaemon::DailyUseReporter(void* handle, int tag, int count) {
|
| kMetricDailyUseTimeBuckets);
|
| }
|
|
|
| +// static
|
| +void MetricsDaemon::UserCrashIntervalReporter(void* handle,
|
| + int tag, int count) {
|
| + MetricsDaemon* daemon = static_cast<MetricsDaemon*>(handle);
|
| + daemon->SendMetric(kMetricUserCrashIntervalName, count,
|
| + kMetricUserCrashIntervalMin,
|
| + kMetricUserCrashIntervalMax,
|
| + kMetricUserCrashIntervalBuckets);
|
| +}
|
| +
|
| void MetricsDaemon::SendMetric(const std::string& name, int sample,
|
| int min, int max, int nbuckets) {
|
| DLOG(INFO) << "received metric: " << name << " " << sample << " "
|
|
|