| 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 "counter.h" | 5 #include "counter.h" | 
| 6 | 6 | 
| 7 #include <fcntl.h> | 7 #include <fcntl.h> | 
| 8 | 8 | 
| 9 #include <base/eintr_wrapper.h> | 9 #include <base/eintr_wrapper.h> | 
| 10 #include <base/logging.h> | 10 #include <base/logging.h> | 
|  | 11 #include "metrics_library.h" | 
| 11 | 12 | 
| 12 namespace chromeos_metrics { | 13 namespace chromeos_metrics { | 
| 13 | 14 | 
| 14 // TaggedCounter::Record implementation. | 15 // TaggedCounter::Record implementation. | 
| 15 void TaggedCounter::Record::Init(int32 tag, int32 count) { | 16 void TaggedCounter::Record::Init(int32 tag, int32 count) { | 
| 16   tag_ = tag; | 17   tag_ = tag; | 
| 17   count_ = (count > 0) ? count : 0; | 18   count_ = (count > 0) ? count : 0; | 
| 18 } | 19 } | 
| 19 | 20 | 
| 20 void TaggedCounter::Record::Add(int32 count) { | 21 void TaggedCounter::Record::Add(int32 count) { | 
| 21   if (count <= 0) | 22   if (count <= 0) | 
| 22     return; | 23     return; | 
| 23 | 24 | 
| 24   // Saturates on positive overflow. | 25   // Saturates on positive overflow. | 
| 25   int64 new_count = static_cast<int64>(count_) + static_cast<int64>(count); | 26   int64 new_count = static_cast<int64>(count_) + static_cast<int64>(count); | 
| 26   if (new_count > kint32max) | 27   if (new_count > kint32max) | 
| 27     count_ = kint32max; | 28     count_ = kint32max; | 
| 28   else | 29   else | 
| 29     count_ = static_cast<int32>(new_count); | 30     count_ = static_cast<int32>(new_count); | 
| 30 } | 31 } | 
| 31 | 32 | 
| 32 // TaggedCounter implementation. | 33 // TaggedCounter implementation. | 
| 33 TaggedCounter::TaggedCounter() | 34 TaggedCounter::TaggedCounter() | 
| 34     : filename_(NULL), | 35     : reporter_(NULL), | 
| 35       reporter_(NULL), |  | 
| 36       reporter_handle_(NULL), | 36       reporter_handle_(NULL), | 
| 37       record_state_(kRecordInvalid) {} | 37       record_state_(kRecordInvalid) {} | 
| 38 | 38 | 
| 39 TaggedCounter::~TaggedCounter() {} | 39 TaggedCounter::~TaggedCounter() {} | 
| 40 | 40 | 
| 41 void TaggedCounter::Init(const char* filename, | 41 void TaggedCounter::Init(const char* filename, | 
| 42                          Reporter reporter, void* reporter_handle) { | 42                          Reporter reporter, void* reporter_handle) { | 
| 43   DCHECK(filename); | 43   DCHECK(filename); | 
| 44   filename_ = filename; | 44   filename_ = filename; | 
| 45   reporter_ = reporter; | 45   reporter_ = reporter; | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
| 65     if (record_state_ == kRecordNull) | 65     if (record_state_ == kRecordNull) | 
| 66       return; | 66       return; | 
| 67   } else { | 67   } else { | 
| 68     // If there's no new data and the last record in the aggregation | 68     // If there's no new data and the last record in the aggregation | 
| 69     // file is with the same tag, there's nothing to do. | 69     // file is with the same tag, there's nothing to do. | 
| 70     if (count <= 0 && record_state_ == kRecordValid && record_.tag() == tag) | 70     if (count <= 0 && record_state_ == kRecordValid && record_.tag() == tag) | 
| 71       return; | 71       return; | 
| 72   } | 72   } | 
| 73 | 73 | 
| 74   DLOG(INFO) << "tag: " << tag << " count: " << count << " flush: " << flush; | 74   DLOG(INFO) << "tag: " << tag << " count: " << count << " flush: " << flush; | 
| 75   DCHECK(filename_); | 75   DCHECK(!filename_.empty()); | 
| 76 | 76 | 
| 77   // NOTE: The assumption is that this TaggedCounter object is the | 77   // NOTE: The assumption is that this TaggedCounter object is the | 
| 78   // sole owner of the persistent storage file so no locking is | 78   // sole owner of the persistent storage file so no locking is | 
| 79   // necessary. | 79   // necessary. | 
| 80   int fd = HANDLE_EINTR(open(filename_, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)); | 80   int fd = HANDLE_EINTR(open(filename_.c_str(), | 
|  | 81                              O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)); | 
| 81   if (fd < 0) { | 82   if (fd < 0) { | 
| 82     PLOG(WARNING) << "Unable to open the persistent counter file"; | 83     PLOG(WARNING) << "Unable to open the persistent counter file"; | 
| 83     return; | 84     return; | 
| 84   } | 85   } | 
| 85 | 86 | 
| 86   ReadRecord(fd); | 87   ReadRecord(fd); | 
| 87   ReportRecord(tag, flush); | 88   ReportRecord(tag, flush); | 
| 88   UpdateRecord(tag, count, flush); | 89   UpdateRecord(tag, count, flush); | 
| 89   WriteRecord(fd); | 90   WriteRecord(fd); | 
| 90 | 91 | 
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 176     case kRecordNull: | 177     case kRecordNull: | 
| 177     case kRecordValid: | 178     case kRecordValid: | 
| 178       // Nothing to do. | 179       // Nothing to do. | 
| 179       break; | 180       break; | 
| 180 | 181 | 
| 181     default: | 182     default: | 
| 182       NOTREACHED(); | 183       NOTREACHED(); | 
| 183   } | 184   } | 
| 184 } | 185 } | 
| 185 | 186 | 
|  | 187 MetricsLibraryInterface* TaggedCounterReporter::metrics_lib_ = NULL; | 
|  | 188 | 
|  | 189 TaggedCounterReporter::TaggedCounterReporter() | 
|  | 190     : tagged_counter_(new TaggedCounter()), | 
|  | 191       min_(0), | 
|  | 192       max_(0), | 
|  | 193       buckets_(0) { | 
|  | 194 } | 
|  | 195 | 
|  | 196 TaggedCounterReporter::~TaggedCounterReporter() { | 
|  | 197 } | 
|  | 198 | 
|  | 199 void TaggedCounterReporter::Init(const char* filename, | 
|  | 200                                  const char* histogram_name, | 
|  | 201                                  int min, | 
|  | 202                                  int max, | 
|  | 203                                  int buckets) { | 
|  | 204   tagged_counter_->Init(filename, Report, this); | 
|  | 205   histogram_name_ = histogram_name; | 
|  | 206   min_ = min; | 
|  | 207   max_ = max; | 
|  | 208   buckets_ = buckets; | 
|  | 209   CHECK(min_ >= 0); | 
|  | 210   CHECK(max_ > min_); | 
|  | 211   CHECK(buckets_ > 0); | 
|  | 212 } | 
|  | 213 | 
|  | 214 void TaggedCounterReporter::Report(void* handle, int32 tag, int32 count) { | 
|  | 215   TaggedCounterReporter* this_reporter = | 
|  | 216       reinterpret_cast<TaggedCounterReporter*>(handle); | 
|  | 217   DLOG(INFO) << "received metric: " << this_reporter->histogram_name_ | 
|  | 218              << " " << count << " " << this_reporter->min_ << " " | 
|  | 219              << this_reporter->max_ << " " << this_reporter->buckets_; | 
|  | 220   CHECK(metrics_lib_ != NULL); | 
|  | 221   CHECK(this_reporter->buckets_ > 0); | 
|  | 222   metrics_lib_->SendToUMA(this_reporter->histogram_name_, | 
|  | 223                           count, | 
|  | 224                           this_reporter->min_, | 
|  | 225                           this_reporter->max_, | 
|  | 226                           this_reporter->buckets_); | 
|  | 227 } | 
|  | 228 | 
| 186 FrequencyCounter::FrequencyCounter() : cycle_duration_(1) { | 229 FrequencyCounter::FrequencyCounter() : cycle_duration_(1) { | 
| 187 } | 230 } | 
| 188 | 231 | 
| 189 FrequencyCounter::~FrequencyCounter() { | 232 FrequencyCounter::~FrequencyCounter() { | 
| 190 } | 233 } | 
| 191 | 234 | 
| 192 void FrequencyCounter::Init(const char* filename, | 235 void FrequencyCounter::Init(TaggedCounterInterface* tagged_counter, | 
| 193                             TaggedCounterInterface::Reporter reporter, |  | 
| 194                             void* reporter_handle, |  | 
| 195                             time_t cycle_duration) { | 236                             time_t cycle_duration) { | 
| 196   // Allow tests to inject tagged_counter_ dependency. | 237   tagged_counter_.reset(tagged_counter); | 
| 197   if (tagged_counter_.get() == NULL) { |  | 
| 198     tagged_counter_.reset(new TaggedCounter()); |  | 
| 199   } |  | 
| 200   tagged_counter_->Init(filename, reporter, reporter_handle); |  | 
| 201   DCHECK(cycle_duration > 0); | 238   DCHECK(cycle_duration > 0); | 
| 202   cycle_duration_ = cycle_duration; | 239   cycle_duration_ = cycle_duration; | 
| 203 } | 240 } | 
| 204 | 241 | 
| 205 void FrequencyCounter::UpdateInternal(int32 count, time_t now) { | 242 void FrequencyCounter::UpdateInternal(int32 count, time_t now) { | 
| 206   DCHECK(tagged_counter_.get() != NULL); | 243   DCHECK(tagged_counter_.get() != NULL); | 
| 207   tagged_counter_->Update(GetCycleNumber(now), count); | 244   tagged_counter_->Update(GetCycleNumber(now), count); | 
| 208 } | 245 } | 
| 209 | 246 | 
| 210 int32 FrequencyCounter::GetCycleNumber(time_t now) { | 247 int32 FrequencyCounter::GetCycleNumber(time_t now) { | 
| 211   return now / cycle_duration_; | 248   return now / cycle_duration_; | 
| 212 } | 249 } | 
| 213 | 250 | 
| 214 }  // namespace chromeos_metrics | 251 }  // namespace chromeos_metrics | 
| OLD | NEW | 
|---|