OLD | NEW |
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "metrics_daemon.h" | 5 #include "metrics_daemon.h" |
6 | 6 |
7 #include <dbus/dbus-glib-lowlevel.h> | 7 #include <dbus/dbus-glib-lowlevel.h> |
8 | 8 |
9 #include <base/file_util.h> | 9 #include <base/file_util.h> |
10 #include <base/logging.h> | 10 #include <base/logging.h> |
(...skipping 21 matching lines...) Expand all Loading... |
32 | 32 |
33 // The daily use monitor is scheduled to a 1-minute interval after | 33 // The daily use monitor is scheduled to a 1-minute interval after |
34 // initial user activity and then it's exponentially backed off to | 34 // initial user activity and then it's exponentially backed off to |
35 // 10-minute intervals. Although not required, the back off is | 35 // 10-minute intervals. Although not required, the back off is |
36 // implemented because the histogram buckets are spaced exponentially | 36 // implemented because the histogram buckets are spaced exponentially |
37 // anyway and to avoid too frequent metrics daemon process wake-ups | 37 // anyway and to avoid too frequent metrics daemon process wake-ups |
38 // and file I/O. | 38 // and file I/O. |
39 static const int kUseMonitorIntervalInit = 1 * kSecondsPerMinute; | 39 static const int kUseMonitorIntervalInit = 1 * kSecondsPerMinute; |
40 static const int kUseMonitorIntervalMax = 10 * kSecondsPerMinute; | 40 static const int kUseMonitorIntervalMax = 10 * kSecondsPerMinute; |
41 | 41 |
| 42 const char kKernelCrashDetectedFile[] = "/tmp/kernel-crash-detected"; |
| 43 static const char kUncleanShutdownDetectedFile[] = |
| 44 "/tmp/unclean-shutdown-detected"; |
| 45 |
42 // static metrics parameters. | 46 // static metrics parameters. |
43 const char MetricsDaemon::kMetricDailyUseTimeName[] = | 47 const char MetricsDaemon::kMetricDailyUseTimeName[] = |
44 "Logging.DailyUseTime"; | 48 "Logging.DailyUseTime"; |
45 const int MetricsDaemon::kMetricDailyUseTimeMin = 1; | 49 const int MetricsDaemon::kMetricDailyUseTimeMin = 1; |
46 const int MetricsDaemon::kMetricDailyUseTimeMax = kMinutesPerDay; | 50 const int MetricsDaemon::kMetricDailyUseTimeMax = kMinutesPerDay; |
47 const int MetricsDaemon::kMetricDailyUseTimeBuckets = 50; | 51 const int MetricsDaemon::kMetricDailyUseTimeBuckets = 50; |
48 | 52 |
49 const char MetricsDaemon::kMetricKernelCrashIntervalName[] = | |
50 "Logging.KernelCrashInterval"; | |
51 const int MetricsDaemon::kMetricKernelCrashIntervalMin = 1; | |
52 const int MetricsDaemon::kMetricKernelCrashIntervalMax = 4 * kSecondsPerWeek; | |
53 const int MetricsDaemon::kMetricKernelCrashIntervalBuckets = 50; | |
54 | |
55 const char MetricsDaemon::kMetricTimeToNetworkDropName[] = | 53 const char MetricsDaemon::kMetricTimeToNetworkDropName[] = |
56 "Network.TimeToDrop"; | 54 "Network.TimeToDrop"; |
57 const int MetricsDaemon::kMetricTimeToNetworkDropMin = 1; | 55 const int MetricsDaemon::kMetricTimeToNetworkDropMin = 1; |
58 const int MetricsDaemon::kMetricTimeToNetworkDropMax = | 56 const int MetricsDaemon::kMetricTimeToNetworkDropMax = |
59 8 /* hours */ * kMinutesPerHour * kSecondsPerMinute; | 57 8 /* hours */ * kMinutesPerHour * kSecondsPerMinute; |
60 const int MetricsDaemon::kMetricTimeToNetworkDropBuckets = 50; | 58 const int MetricsDaemon::kMetricTimeToNetworkDropBuckets = 50; |
61 | 59 |
| 60 // crash interval metrics |
| 61 const char MetricsDaemon::kMetricKernelCrashIntervalName[] = |
| 62 "Logging.KernelCrashInterval"; |
| 63 const char MetricsDaemon::kMetricUncleanShutdownIntervalName[] = |
| 64 "Logging.UncleanShutdownInterval"; |
62 const char MetricsDaemon::kMetricUserCrashIntervalName[] = | 65 const char MetricsDaemon::kMetricUserCrashIntervalName[] = |
63 "Logging.UserCrashInterval"; | 66 "Logging.UserCrashInterval"; |
64 const int MetricsDaemon::kMetricUserCrashIntervalMin = 1; | 67 |
65 const int MetricsDaemon::kMetricUserCrashIntervalMax = 4 * kSecondsPerWeek; | 68 const int MetricsDaemon::kMetricCrashIntervalMin = 1; |
66 const int MetricsDaemon::kMetricUserCrashIntervalBuckets = 50; | 69 const int MetricsDaemon::kMetricCrashIntervalMax = |
| 70 4 * kSecondsPerWeek; |
| 71 const int MetricsDaemon::kMetricCrashIntervalBuckets = 50; |
| 72 |
| 73 // crash frequency metrics |
| 74 const char MetricsDaemon::kMetricAnyCrashesDailyName[] = |
| 75 "Logging.AnyCrashesDaily"; |
| 76 const char MetricsDaemon::kMetricKernelCrashesDailyName[] = |
| 77 "Logging.KernelCrashesDaily"; |
| 78 const char MetricsDaemon::kMetricUncleanShutdownsDailyName[] = |
| 79 "Logging.UncleanShutdownsDaily"; |
| 80 const char MetricsDaemon::kMetricUserCrashesDailyName[] = |
| 81 "Logging.UserCrashesDaily"; |
| 82 const char MetricsDaemon::kMetricCrashesDailyMin = 1; |
| 83 const char MetricsDaemon::kMetricCrashesDailyMax = 100; |
| 84 const char MetricsDaemon::kMetricCrashesDailyBuckets = 50; |
| 85 |
| 86 |
67 | 87 |
68 // static | 88 // static |
69 const char* MetricsDaemon::kDBusMatches_[] = { | 89 const char* MetricsDaemon::kDBusMatches_[] = { |
70 "type='signal'," | 90 "type='signal'," |
71 "interface='" DBUS_IFACE_CRASH_REPORTER "'," | 91 "interface='" DBUS_IFACE_CRASH_REPORTER "'," |
72 "path='/'," | 92 "path='/'," |
73 "member='UserCrash'", | 93 "member='UserCrash'", |
74 | 94 |
75 "type='signal'," | 95 "type='signal'," |
76 "sender='org.chromium.flimflam'," | 96 "sender='org.chromium.flimflam'," |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 user_active_(false), | 181 user_active_(false), |
162 usemon_interval_(0), | 182 usemon_interval_(0), |
163 usemon_source_(NULL) {} | 183 usemon_source_(NULL) {} |
164 | 184 |
165 MetricsDaemon::~MetricsDaemon() {} | 185 MetricsDaemon::~MetricsDaemon() {} |
166 | 186 |
167 void MetricsDaemon::Run(bool run_as_daemon) { | 187 void MetricsDaemon::Run(bool run_as_daemon) { |
168 if (run_as_daemon && daemon(0, 0) != 0) | 188 if (run_as_daemon && daemon(0, 0) != 0) |
169 return; | 189 return; |
170 | 190 |
171 static const char kKernelCrashDetectedFile[] = "/tmp/kernel-crash-detected"; | 191 if (CheckSystemCrash(kKernelCrashDetectedFile)) { |
172 CheckKernelCrash(kKernelCrashDetectedFile); | 192 ProcessKernelCrash(); |
| 193 } |
| 194 |
| 195 if (CheckSystemCrash(kUncleanShutdownDetectedFile)) { |
| 196 ProcessUncleanShutdown(); |
| 197 } |
| 198 |
173 Loop(); | 199 Loop(); |
174 } | 200 } |
175 | 201 |
176 void MetricsDaemon::Init(bool testing, MetricsLibraryInterface* metrics_lib) { | 202 void MetricsDaemon::Init(bool testing, MetricsLibraryInterface* metrics_lib) { |
177 testing_ = testing; | 203 testing_ = testing; |
178 DCHECK(metrics_lib != NULL); | 204 DCHECK(metrics_lib != NULL); |
179 metrics_lib_ = metrics_lib; | 205 metrics_lib_ = metrics_lib; |
180 | 206 |
181 static const char kDailyUseRecordFile[] = "/var/log/metrics/daily-usage"; | 207 static const char kDailyUseRecordFile[] = "/var/log/metrics/daily-usage"; |
182 daily_use_.reset(new chromeos_metrics::TaggedCounter()); | 208 daily_use_.reset(new chromeos_metrics::TaggedCounter()); |
183 daily_use_->Init(kDailyUseRecordFile, &DailyUseReporter, this); | 209 daily_use_->Init(kDailyUseRecordFile, &ReportDailyUse, this); |
184 | 210 |
185 static const char kUserCrashIntervalRecordFile[] = | 211 static const char kUserCrashIntervalRecordFile[] = |
186 "/var/log/metrics/user-crash-interval"; | 212 "/var/log/metrics/user-crash-interval"; |
187 user_crash_interval_.reset(new chromeos_metrics::TaggedCounter()); | 213 user_crash_interval_.reset(new chromeos_metrics::TaggedCounter()); |
188 user_crash_interval_->Init(kUserCrashIntervalRecordFile, | 214 user_crash_interval_->Init(kUserCrashIntervalRecordFile, |
189 &UserCrashIntervalReporter, this); | 215 &ReportUserCrashInterval, this); |
190 | 216 |
191 static const char kKernelCrashIntervalRecordFile[] = | 217 static const char kKernelCrashIntervalRecordFile[] = |
192 "/var/log/metrics/kernel-crash-interval"; | 218 "/var/log/metrics/kernel-crash-interval"; |
193 kernel_crash_interval_.reset(new chromeos_metrics::TaggedCounter()); | 219 kernel_crash_interval_.reset(new chromeos_metrics::TaggedCounter()); |
194 kernel_crash_interval_->Init(kKernelCrashIntervalRecordFile, | 220 kernel_crash_interval_->Init(kKernelCrashIntervalRecordFile, |
195 &KernelCrashIntervalReporter, this); | 221 &ReportKernelCrashInterval, this); |
| 222 |
| 223 static const char kUncleanShutdownDetectedFile[] = |
| 224 "/var/log/metrics/unclean-shutdown-interval"; |
| 225 unclean_shutdown_interval_.reset(new chromeos_metrics::TaggedCounter()); |
| 226 unclean_shutdown_interval_->Init(kUncleanShutdownDetectedFile, |
| 227 &ReportUncleanShutdownInterval, this); |
| 228 |
| 229 static const char kUserCrashesDailyRecordFile[] = |
| 230 "/var/log/metrics/user-crashes-daily"; |
| 231 user_crashes_daily_.reset(new chromeos_metrics::FrequencyCounter()); |
| 232 user_crashes_daily_->Init(kUserCrashesDailyRecordFile, |
| 233 &ReportUserCrashesDaily, |
| 234 this, |
| 235 chromeos_metrics::kSecondsPerDay); |
| 236 |
| 237 static const char kKernelCrashesDailyRecordFile[] = |
| 238 "/var/log/metrics/kernel-crashes-daily"; |
| 239 kernel_crashes_daily_.reset(new chromeos_metrics::FrequencyCounter()); |
| 240 kernel_crashes_daily_->Init(kKernelCrashesDailyRecordFile, |
| 241 &ReportKernelCrashesDaily, |
| 242 this, |
| 243 chromeos_metrics::kSecondsPerDay); |
| 244 |
| 245 static const char kUncleanShutdownsDailyRecordFile[] = |
| 246 "/var/log/metrics/unclean-shutdowns-daily"; |
| 247 unclean_shutdowns_daily_.reset(new chromeos_metrics::FrequencyCounter()); |
| 248 unclean_shutdowns_daily_->Init(kUncleanShutdownsDailyRecordFile, |
| 249 &ReportUncleanShutdownsDaily, |
| 250 this, |
| 251 chromeos_metrics::kSecondsPerDay); |
| 252 |
| 253 static const char kAnyCrashesUserCrashDailyRecordFile[] = |
| 254 "/var/log/metrics/any-crashes-daily"; |
| 255 any_crashes_daily_.reset(new chromeos_metrics::FrequencyCounter()); |
| 256 any_crashes_daily_->Init(kAnyCrashesUserCrashDailyRecordFile, |
| 257 &ReportAnyCrashesDaily, |
| 258 this, |
| 259 chromeos_metrics::kSecondsPerDay); |
196 | 260 |
197 // Don't setup D-Bus and GLib in test mode. | 261 // Don't setup D-Bus and GLib in test mode. |
198 if (testing) | 262 if (testing) |
199 return; | 263 return; |
200 | 264 |
201 g_thread_init(NULL); | 265 g_thread_init(NULL); |
202 g_type_init(); | 266 g_type_init(); |
203 dbus_g_thread_init(); | 267 dbus_g_thread_init(); |
204 | 268 |
205 DBusError error; | 269 DBusError error; |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
401 user_active_ = active; | 465 user_active_ = active; |
402 user_active_last_ = now; | 466 user_active_last_ = now; |
403 } | 467 } |
404 | 468 |
405 void MetricsDaemon::ProcessUserCrash() { | 469 void MetricsDaemon::ProcessUserCrash() { |
406 // Counts the active use time up to now. | 470 // Counts the active use time up to now. |
407 SetUserActiveState(user_active_, Time::Now()); | 471 SetUserActiveState(user_active_, Time::Now()); |
408 | 472 |
409 // Reports the active use time since the last crash and resets it. | 473 // Reports the active use time since the last crash and resets it. |
410 user_crash_interval_->Flush(); | 474 user_crash_interval_->Flush(); |
| 475 |
| 476 user_crashes_daily_->Update(1); |
| 477 any_crashes_daily_->Update(1); |
411 } | 478 } |
412 | 479 |
413 void MetricsDaemon::ProcessKernelCrash() { | 480 void MetricsDaemon::ProcessKernelCrash() { |
414 // Counts the active use time up to now. | 481 // Counts the active use time up to now. |
415 SetUserActiveState(user_active_, Time::Now()); | 482 SetUserActiveState(user_active_, Time::Now()); |
416 | 483 |
417 // Reports the active use time since the last crash and resets it. | 484 // Reports the active use time since the last crash and resets it. |
418 kernel_crash_interval_->Flush(); | 485 kernel_crash_interval_->Flush(); |
| 486 |
| 487 kernel_crashes_daily_->Update(1); |
| 488 any_crashes_daily_->Update(1); |
419 } | 489 } |
420 | 490 |
421 void MetricsDaemon::CheckKernelCrash(const std::string& crash_file) { | 491 void MetricsDaemon::ProcessUncleanShutdown() { |
| 492 // Counts the active use time up to now. |
| 493 SetUserActiveState(user_active_, Time::Now()); |
| 494 |
| 495 // Reports the active use time since the last crash and resets it. |
| 496 unclean_shutdown_interval_->Flush(); |
| 497 |
| 498 unclean_shutdowns_daily_->Update(1); |
| 499 any_crashes_daily_->Update(1); |
| 500 } |
| 501 |
| 502 bool MetricsDaemon::CheckSystemCrash(const std::string& crash_file) { |
422 FilePath crash_detected(crash_file); | 503 FilePath crash_detected(crash_file); |
423 if (!file_util::PathExists(crash_detected)) | 504 if (!file_util::PathExists(crash_detected)) |
424 return; | 505 return false; |
425 | |
426 ProcessKernelCrash(); | |
427 | 506 |
428 // Deletes the crash-detected file so that the daemon doesn't report | 507 // Deletes the crash-detected file so that the daemon doesn't report |
429 // another kernel crash in case it's restarted. | 508 // another kernel crash in case it's restarted. |
430 file_util::Delete(crash_detected, | 509 file_util::Delete(crash_detected, |
431 false); // recursive | 510 false); // recursive |
| 511 return true; |
432 } | 512 } |
433 | 513 |
434 // static | 514 // static |
435 gboolean MetricsDaemon::UseMonitorStatic(gpointer data) { | 515 gboolean MetricsDaemon::UseMonitorStatic(gpointer data) { |
436 return static_cast<MetricsDaemon*>(data)->UseMonitor() ? TRUE : FALSE; | 516 return static_cast<MetricsDaemon*>(data)->UseMonitor() ? TRUE : FALSE; |
437 } | 517 } |
438 | 518 |
439 bool MetricsDaemon::UseMonitor() { | 519 bool MetricsDaemon::UseMonitor() { |
440 SetUserActiveState(user_active_, Time::Now()); | 520 SetUserActiveState(user_active_, Time::Now()); |
441 | 521 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
485 if (usemon_source_ == NULL) | 565 if (usemon_source_ == NULL) |
486 return; | 566 return; |
487 | 567 |
488 DLOG(INFO) << "destroying use monitor"; | 568 DLOG(INFO) << "destroying use monitor"; |
489 g_source_destroy(usemon_source_); | 569 g_source_destroy(usemon_source_); |
490 usemon_source_ = NULL; | 570 usemon_source_ = NULL; |
491 usemon_interval_ = 0; | 571 usemon_interval_ = 0; |
492 } | 572 } |
493 | 573 |
494 // static | 574 // static |
495 void MetricsDaemon::DailyUseReporter(void* handle, int tag, int count) { | 575 void MetricsDaemon::ReportDailyUse(void* handle, int tag, int count) { |
496 if (count <= 0) | 576 if (count <= 0) |
497 return; | 577 return; |
498 | 578 |
499 MetricsDaemon* daemon = static_cast<MetricsDaemon*>(handle); | 579 MetricsDaemon* daemon = static_cast<MetricsDaemon*>(handle); |
500 int minutes = (count + kSecondsPerMinute / 2) / kSecondsPerMinute; | 580 int minutes = (count + kSecondsPerMinute / 2) / kSecondsPerMinute; |
501 daemon->SendMetric(kMetricDailyUseTimeName, minutes, | 581 daemon->SendMetric(kMetricDailyUseTimeName, minutes, |
502 kMetricDailyUseTimeMin, | 582 kMetricDailyUseTimeMin, |
503 kMetricDailyUseTimeMax, | 583 kMetricDailyUseTimeMax, |
504 kMetricDailyUseTimeBuckets); | 584 kMetricDailyUseTimeBuckets); |
505 } | 585 } |
506 | 586 |
507 // static | 587 // static |
508 void MetricsDaemon::UserCrashIntervalReporter(void* handle, | 588 void MetricsDaemon::ReportCrashInterval(const char* histogram_name, |
509 int tag, int count) { | 589 void* handle, int count) { |
510 MetricsDaemon* daemon = static_cast<MetricsDaemon*>(handle); | 590 MetricsDaemon* daemon = static_cast<MetricsDaemon*>(handle); |
511 daemon->SendMetric(kMetricUserCrashIntervalName, count, | 591 daemon->SendMetric(histogram_name, count, |
512 kMetricUserCrashIntervalMin, | 592 kMetricCrashIntervalMin, |
513 kMetricUserCrashIntervalMax, | 593 kMetricCrashIntervalMax, |
514 kMetricUserCrashIntervalBuckets); | 594 kMetricCrashIntervalBuckets); |
515 } | 595 } |
516 | 596 |
517 // static | 597 // static |
518 void MetricsDaemon::KernelCrashIntervalReporter(void* handle, | 598 void MetricsDaemon::ReportUserCrashInterval(void* handle, |
| 599 int tag, int count) { |
| 600 ReportCrashInterval(kMetricUserCrashIntervalName, handle, count); |
| 601 } |
| 602 |
| 603 // static |
| 604 void MetricsDaemon::ReportKernelCrashInterval(void* handle, |
519 int tag, int count) { | 605 int tag, int count) { |
| 606 ReportCrashInterval(kMetricKernelCrashIntervalName, handle, count); |
| 607 } |
| 608 |
| 609 // static |
| 610 void MetricsDaemon::ReportUncleanShutdownInterval(void* handle, |
| 611 int tag, int count) { |
| 612 ReportCrashInterval(kMetricUncleanShutdownIntervalName, handle, count); |
| 613 } |
| 614 |
| 615 // static |
| 616 void MetricsDaemon::ReportCrashesDailyFrequency(const char* histogram_name, |
| 617 void* handle, |
| 618 int count) { |
520 MetricsDaemon* daemon = static_cast<MetricsDaemon*>(handle); | 619 MetricsDaemon* daemon = static_cast<MetricsDaemon*>(handle); |
521 daemon->SendMetric(kMetricKernelCrashIntervalName, count, | 620 daemon->SendMetric(histogram_name, count, |
522 kMetricKernelCrashIntervalMin, | 621 kMetricCrashesDailyMin, |
523 kMetricKernelCrashIntervalMax, | 622 kMetricCrashesDailyMax, |
524 kMetricKernelCrashIntervalBuckets); | 623 kMetricCrashesDailyBuckets); |
525 } | 624 } |
526 | 625 |
| 626 // static |
| 627 void MetricsDaemon::ReportUserCrashesDaily(void* handle, |
| 628 int tag, int count) { |
| 629 ReportCrashesDailyFrequency(kMetricUserCrashesDailyName, handle, count); |
| 630 } |
| 631 |
| 632 // static |
| 633 void MetricsDaemon::ReportKernelCrashesDaily(void* handle, |
| 634 int tag, int count) { |
| 635 ReportCrashesDailyFrequency(kMetricKernelCrashesDailyName, handle, count); |
| 636 } |
| 637 |
| 638 // static |
| 639 void MetricsDaemon::ReportUncleanShutdownsDaily(void* handle, |
| 640 int tag, int count) { |
| 641 ReportCrashesDailyFrequency(kMetricUncleanShutdownsDailyName, handle, count); |
| 642 } |
| 643 |
| 644 // static |
| 645 void MetricsDaemon::ReportAnyCrashesDaily(void* handle, int tag, int count) { |
| 646 ReportCrashesDailyFrequency(kMetricAnyCrashesDailyName, handle, count); |
| 647 } |
| 648 |
| 649 |
527 void MetricsDaemon::SendMetric(const string& name, int sample, | 650 void MetricsDaemon::SendMetric(const string& name, int sample, |
528 int min, int max, int nbuckets) { | 651 int min, int max, int nbuckets) { |
529 DLOG(INFO) << "received metric: " << name << " " << sample << " " | 652 DLOG(INFO) << "received metric: " << name << " " << sample << " " |
530 << min << " " << max << " " << nbuckets; | 653 << min << " " << max << " " << nbuckets; |
531 metrics_lib_->SendToUMA(name, sample, min, max, nbuckets); | 654 metrics_lib_->SendToUMA(name, sample, min, max, nbuckets); |
532 } | 655 } |
OLD | NEW |