Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(260)

Side by Side Diff: metrics_daemon.cc

Issue 6486021: Collect some disk statistics. (Closed) Base URL: http://git.chromium.org/git/metrics.git@master
Patch Set: remove duplicate log and close file Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« metrics_daemon.h ('K') | « metrics_daemon.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <fcntl.h>
7 #include <string.h> 8 #include <string.h>
8 9
9 #include <base/file_util.h> 10 #include <base/file_util.h>
10 #include <base/logging.h> 11 #include <base/logging.h>
11 #include <dbus/dbus-glib-lowlevel.h> 12 #include <dbus/dbus-glib-lowlevel.h>
12 13
13 #include "counter.h" 14 #include "counter.h"
14 15
15 using base::Time; 16 using base::Time;
16 using base::TimeDelta; 17 using base::TimeDelta;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 const char MetricsDaemon::kMetricUncleanShutdownsWeeklyName[] = 78 const char MetricsDaemon::kMetricUncleanShutdownsWeeklyName[] =
78 "Logging.UncleanShutdownsWeekly"; 79 "Logging.UncleanShutdownsWeekly";
79 const char MetricsDaemon::kMetricUserCrashesDailyName[] = 80 const char MetricsDaemon::kMetricUserCrashesDailyName[] =
80 "Logging.UserCrashesDaily"; 81 "Logging.UserCrashesDaily";
81 const char MetricsDaemon::kMetricUserCrashesWeeklyName[] = 82 const char MetricsDaemon::kMetricUserCrashesWeeklyName[] =
82 "Logging.UserCrashesWeekly"; 83 "Logging.UserCrashesWeekly";
83 const char MetricsDaemon::kMetricCrashFrequencyMin = 1; 84 const char MetricsDaemon::kMetricCrashFrequencyMin = 1;
84 const char MetricsDaemon::kMetricCrashFrequencyMax = 100; 85 const char MetricsDaemon::kMetricCrashFrequencyMax = 100;
85 const char MetricsDaemon::kMetricCrashFrequencyBuckets = 50; 86 const char MetricsDaemon::kMetricCrashFrequencyBuckets = 50;
86 87
88 // disk stats metrics
89 const char MetricsDaemon::kMetricReadSectorsLongName[] =
90 "Platform.ReadSectorsLong";
petkov 2011/02/11 06:42:30 maybe add a comment about the units -- sectors/sec
91 const char MetricsDaemon::kMetricWriteSectorsLongName[] =
92 "Platform.WriteSectorsLong";
93 const char MetricsDaemon::kMetricReadSectorsShortName[] =
94 "Platform.ReadSectorsShort";
95 const char MetricsDaemon::kMetricWriteSectorsShortName[] =
96 "Platform.WriteSectorsShort";
97
98 const int MetricsDaemon::kMetricDiskStatsShortInterval = 1; // seconds
petkov 2011/02/11 06:42:30 just two spaces before //
99 const int MetricsDaemon::kMetricDiskStatsLongInterval = 30; // seconds
100
101 // Assume a max rate of 250Mb/s for reads, worse for writes.
102 const int MetricsDaemon::kMetricSectorsIOMax = 500000;
103 const int MetricsDaemon::kMetricSectorsBuckets = 50;
104
105 // Path to disk stats.
106 const char MetricsDaemon::kMetricsDiskStatsPath[] = "/sys/class/block/sda/stat";
petkov 2011/02/11 06:42:30 x86 specific... is it easy to make this work for A
Luigi Semenzato 2011/02/12 00:33:02 ARM uses the same path, at least on my machine.
107
87 // persistent metrics path 108 // persistent metrics path
88 const char MetricsDaemon::kMetricsPath[] = "/var/log/metrics"; 109 const char MetricsDaemon::kMetricsPath[] = "/var/log/metrics";
89 110
90 111
91 // static 112 // static
92 const char* MetricsDaemon::kDBusMatches_[] = { 113 const char* MetricsDaemon::kDBusMatches_[] = {
93 "type='signal'," 114 "type='signal',"
94 "interface='" DBUS_IFACE_CRASH_REPORTER "'," 115 "interface='" DBUS_IFACE_CRASH_REPORTER "',"
95 "path='/'," 116 "path='/',"
96 "member='UserCrash'", 117 "member='UserCrash'",
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 DeleteFrequencyCounters(); 232 DeleteFrequencyCounters();
212 ConfigureCrashFrequencyReporter(kMetricAnyCrashesDailyName); 233 ConfigureCrashFrequencyReporter(kMetricAnyCrashesDailyName);
213 ConfigureCrashFrequencyReporter(kMetricAnyCrashesWeeklyName); 234 ConfigureCrashFrequencyReporter(kMetricAnyCrashesWeeklyName);
214 ConfigureCrashFrequencyReporter(kMetricKernelCrashesDailyName); 235 ConfigureCrashFrequencyReporter(kMetricKernelCrashesDailyName);
215 ConfigureCrashFrequencyReporter(kMetricKernelCrashesWeeklyName); 236 ConfigureCrashFrequencyReporter(kMetricKernelCrashesWeeklyName);
216 ConfigureCrashFrequencyReporter(kMetricUncleanShutdownsDailyName); 237 ConfigureCrashFrequencyReporter(kMetricUncleanShutdownsDailyName);
217 ConfigureCrashFrequencyReporter(kMetricUncleanShutdownsWeeklyName); 238 ConfigureCrashFrequencyReporter(kMetricUncleanShutdownsWeeklyName);
218 ConfigureCrashFrequencyReporter(kMetricUserCrashesDailyName); 239 ConfigureCrashFrequencyReporter(kMetricUserCrashesDailyName);
219 ConfigureCrashFrequencyReporter(kMetricUserCrashesWeeklyName); 240 ConfigureCrashFrequencyReporter(kMetricUserCrashesWeeklyName);
220 241
242 DiskStatsReporterInit();
243
221 // Don't setup D-Bus and GLib in test mode. 244 // Don't setup D-Bus and GLib in test mode.
222 if (testing) 245 if (testing)
223 return; 246 return;
224 247
225 g_thread_init(NULL); 248 g_thread_init(NULL);
226 g_type_init(); 249 g_type_init();
227 dbus_g_thread_init(); 250 dbus_g_thread_init();
228 251
229 DBusError error; 252 DBusError error;
230 dbus_error_init(&error); 253 dbus_error_init(&error);
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 // If there's a use monitor scheduled already, destroys it. 510 // If there's a use monitor scheduled already, destroys it.
488 if (usemon_source_ == NULL) 511 if (usemon_source_ == NULL)
489 return; 512 return;
490 513
491 DLOG(INFO) << "destroying use monitor"; 514 DLOG(INFO) << "destroying use monitor";
492 g_source_destroy(usemon_source_); 515 g_source_destroy(usemon_source_);
493 usemon_source_ = NULL; 516 usemon_source_ = NULL;
494 usemon_interval_ = 0; 517 usemon_interval_ = 0;
495 } 518 }
496 519
520 void MetricsDaemon::DiskStatsReporterInit() {
521 diskstats_source_ = NULL;
522 DiskStatsReadStats(&read_sectors_, &write_sectors_);
523 // The first time around just run the long stat, so we don't delay boot.
524 diskstats_state_ = kDiskStatsLong;
525 ScheduleDiskStatsCallback(kMetricDiskStatsLongInterval);
526 }
527
528 void MetricsDaemon::ScheduleDiskStatsCallback(int wait) {
529 diskstats_source_ = g_timeout_source_new_seconds(wait);
petkov 2011/02/11 06:42:30 You don't really need to store the source for this
Luigi Semenzato 2011/02/12 00:33:02 Splendid, thanks!
530 g_source_set_callback(diskstats_source_, DiskStatsCallbackStatic, this, NULL);
531 g_source_attach(diskstats_source_, NULL);
532 }
533
534 void MetricsDaemon::DiskStatsReadStats(long int* read_sectors,
535 long int* write_sectors) {
536 int nchars;
537 int nitems;
538 char line[200];
539 int file = open(kMetricsDiskStatsPath, O_RDONLY);
petkov 2011/02/11 06:42:30 want to use HANDLE_EINTR macro here and below for
Luigi Semenzato 2011/02/12 00:33:02 Thanks, good suggestion.
540 LOG_IF(FATAL, file < 0) << "cannot open " << kMetricsDiskStatsPath << ": "
petkov 2011/02/11 06:42:30 FATAL? This would cause the process to crash every
Luigi Semenzato 2011/02/12 00:33:02 You are completely right. Making non-fatal.
541 << strerror(errno);
542 nchars = read(file, line, sizeof(line));
543 LOG_IF(FATAL, nchars == sizeof(line)) << "line too long in "
544 << kMetricsDiskStatsPath;
545 line[nchars] = '\0';
546 nitems = sscanf(line, "%*d %*d %ld %*d %*d %*d %ld",
547 read_sectors, write_sectors);
548 LOG_IF(FATAL, nitems != 2) << "found " << nitems << " in "
549 << kMetricsDiskStatsPath << ", expected 2";
550 close(file);
551 }
552
553 // static
554 gboolean MetricsDaemon::DiskStatsCallbackStatic(void* handle) {
555 (static_cast<MetricsDaemon*>(handle))->DiskStatsCallback();
556 return false; // destroy this source instance
petkov 2011/02/11 06:42:30 just 2 spaces before //
557 }
558
559 void MetricsDaemon::DiskStatsCallback() {
560 long int read_sectors_now, write_sectors_now;
561 DiskStatsReadStats(&read_sectors_now, &write_sectors_now);
562
563 switch (diskstats_state_) {
564
565 case kDiskStatsShort:
petkov 2011/02/11 06:42:30 per style, case needs to be 2-space indented relat
Luigi Semenzato 2011/02/12 00:33:02 I was overriding some indentation variables by mis
566 SendMetric(kMetricReadSectorsShortName,
567 (int) (read_sectors_now - read_sectors_) /
568 kMetricDiskStatsShortInterval,
569 0,
570 kMetricSectorsIOMax,
571 kMetricSectorsBuckets);
572 SendMetric(kMetricWriteSectorsShortName,
573 (int) (write_sectors_now - write_sectors_) /
574 kMetricDiskStatsShortInterval,
575 0,
576 kMetricSectorsIOMax,
577 kMetricSectorsBuckets);
578 // Schedule long callback.
579 diskstats_state_ = kDiskStatsLong;
580 ScheduleDiskStatsCallback(kMetricDiskStatsLongInterval -
581 kMetricDiskStatsShortInterval);
582 break;
583
584 case kDiskStatsLong:
585 SendMetric(kMetricReadSectorsLongName,
586 (int) (read_sectors_now - read_sectors_) /
587 kMetricDiskStatsLongInterval,
588 0,
589 kMetricSectorsIOMax,
590 kMetricSectorsBuckets);
591 SendMetric(kMetricWriteSectorsLongName,
592 (int) (write_sectors_now - write_sectors_) /
593 kMetricDiskStatsLongInterval,
594 0,
595 kMetricSectorsIOMax,
596 kMetricSectorsBuckets);
597 // Reset sector counters
598 read_sectors_ = read_sectors_now;
599 write_sectors_ = write_sectors_now;
600
601 // Schedule short callback.
602 diskstats_state_ = kDiskStatsShort;
603 ScheduleDiskStatsCallback(kMetricDiskStatsShortInterval);
604 break;
605
606 default:
607 LOG(FATAL) << "Invalid disk stats state";
608 }
609 }
610
497 // static 611 // static
498 void MetricsDaemon::ReportDailyUse(void* handle, int tag, int count) { 612 void MetricsDaemon::ReportDailyUse(void* handle, int tag, int count) {
499 if (count <= 0) 613 if (count <= 0)
500 return; 614 return;
501 615
502 MetricsDaemon* daemon = static_cast<MetricsDaemon*>(handle); 616 MetricsDaemon* daemon = static_cast<MetricsDaemon*>(handle);
503 int minutes = (count + kSecondsPerMinute / 2) / kSecondsPerMinute; 617 int minutes = (count + kSecondsPerMinute / 2) / kSecondsPerMinute;
504 daemon->SendMetric(kMetricDailyUseTimeName, minutes, 618 daemon->SendMetric(kMetricDailyUseTimeName, minutes,
505 kMetricDailyUseTimeMin, 619 kMetricDailyUseTimeMin,
506 kMetricDailyUseTimeMax, 620 kMetricDailyUseTimeMax,
507 kMetricDailyUseTimeBuckets); 621 kMetricDailyUseTimeBuckets);
508 } 622 }
509 623
510 void MetricsDaemon::SendMetric(const string& name, int sample, 624 void MetricsDaemon::SendMetric(const string& name, int sample,
511 int min, int max, int nbuckets) { 625 int min, int max, int nbuckets) {
512 DLOG(INFO) << "received metric: " << name << " " << sample << " " 626 DLOG(INFO) << "received metric: " << name << " " << sample << " "
513 << min << " " << max << " " << nbuckets; 627 << min << " " << max << " " << nbuckets;
514 metrics_lib_->SendToUMA(name, sample, min, max, nbuckets); 628 metrics_lib_->SendToUMA(name, sample, min, max, nbuckets);
515 } 629 }
OLDNEW
« metrics_daemon.h ('K') | « metrics_daemon.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698