Home | History | Annotate | Download | only in crash_reporting
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome_frame/crash_reporting/crash_metrics.h"
      6 
      7 #include "base/metrics/histogram.h"
      8 #include "base/win/registry.h"
      9 #include "chrome_frame/utils.h"
     10 
     11 static const wchar_t kChromeFrameMetricsKey[] =
     12     L"Software\\Google\\ChromeFrameMetrics";
     13 
     14 base::LazyInstance<CrashMetricsReporter>
     15     g_crash_metrics_instance_ = LAZY_INSTANCE_INITIALIZER;
     16 
     17 wchar_t* CrashMetricsReporter::g_metric_names[LAST_METRIC] = {
     18   L"navigationcount",
     19   L"crashcount",
     20   L"chrome_frame_navigationcount",
     21   L"sessionid",
     22   L"channel_error",
     23 };
     24 
     25 CrashMetricsReporter* CrashMetricsReporter::GetInstance() {
     26   return &g_crash_metrics_instance_.Get();
     27 }
     28 
     29 bool CrashMetricsReporter::SetMetric(Metric metric, int value) {
     30   DCHECK(metric >= NAVIGATION_COUNT && metric <= LAST_METRIC);
     31 
     32   base::win::RegKey metric_key;
     33   LONG result = metric_key.Create(HKEY_CURRENT_USER, kChromeFrameMetricsKey,
     34                                   KEY_SET_VALUE);
     35   if (result == ERROR_SUCCESS) {
     36     result = metric_key.WriteValue(g_metric_names[metric], value);
     37     if (result == ERROR_SUCCESS) {
     38       return true;
     39     } else {
     40       DLOG(ERROR) << "Failed to read ChromeFrame metric:"
     41         << g_metric_names[metric] << " error: " << result;
     42     }
     43   } else {
     44     DLOG(ERROR) << "Failed to create ChromeFrame metrics key. error: "
     45                 << result;
     46   }
     47   return false;
     48 }
     49 
     50 int CrashMetricsReporter::GetMetric(Metric metric) {
     51   DCHECK(metric >= NAVIGATION_COUNT && metric <= LAST_METRIC);
     52 
     53   int ret = 0;
     54   base::win::RegKey metric_key;
     55   if (metric_key.Open(HKEY_CURRENT_USER, kChromeFrameMetricsKey,
     56                       KEY_QUERY_VALUE) == ERROR_SUCCESS) {
     57     metric_key.ReadValueDW(g_metric_names[metric],
     58                            reinterpret_cast<DWORD*>(&ret));
     59   }
     60 
     61   return ret;
     62 }
     63 
     64 int CrashMetricsReporter::IncrementMetric(Metric metric) {
     65   DCHECK(metric >= NAVIGATION_COUNT && metric <= LAST_METRIC);
     66   int metric_value = GetMetric(metric);
     67   metric_value++;
     68   SetMetric(metric, metric_value);
     69   return metric_value;
     70 }
     71 
     72 void CrashMetricsReporter::RecordCrashMetrics() {
     73   int navigation_count = GetMetric(NAVIGATION_COUNT);
     74   if (navigation_count > 0) {
     75     UMA_HISTOGRAM_COUNTS("ChromeFrame.HostNavigationCount", navigation_count);
     76     SetMetric(NAVIGATION_COUNT, 0);
     77   }
     78 
     79   int chrome_frame_navigation_count = GetMetric(CHROME_FRAME_NAVIGATION_COUNT);
     80   if (chrome_frame_navigation_count > 0) {
     81     UMA_HISTOGRAM_COUNTS("ChromeFrame.CFNavigationCount",
     82                          chrome_frame_navigation_count);
     83     SetMetric(CHROME_FRAME_NAVIGATION_COUNT, 0);
     84   }
     85 
     86   int crash_count = GetMetric(CRASH_COUNT);
     87   if (crash_count > 0) {
     88     UMA_HISTOGRAM_COUNTS("ChromeFrame.HostCrashCount", crash_count);
     89     SetMetric(CRASH_COUNT, 0);
     90   }
     91 
     92   int channel_error_count = GetMetric(CHANNEL_ERROR_COUNT);
     93   if (channel_error_count > 0) {
     94     UMA_HISTOGRAM_COUNTS("ChromeFrame.ChannelErrorCount", channel_error_count);
     95     SetMetric(CHANNEL_ERROR_COUNT, 0);
     96   }
     97 }
     98