| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 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 "net/base/file_stream.h" | 
|  | 6 | 
|  | 7 #include <string> | 
|  | 8 #if defined(OS_WIN) | 
|  | 9 #include <windows.h> | 
|  | 10 #endif | 
|  | 11 | 
|  | 12 #include "base/basictypes.h" | 
|  | 13 #include "base/logging.h" | 
|  | 14 #include "base/metrics/histogram.h" | 
|  | 15 | 
|  | 16 namespace net { | 
|  | 17 | 
|  | 18 namespace { | 
|  | 19 | 
|  | 20 int g_recording_class_mask = RECORDING_CLASS_NONE; | 
|  | 21 | 
|  | 22 #if  defined(OS_WIN) | 
|  | 23 | 
|  | 24 struct Range { | 
|  | 25   int low; | 
|  | 26   int high; | 
|  | 27   bool record_individually; | 
|  | 28 }; | 
|  | 29 | 
|  | 30 // This must be higher than the largest value that isn't remapped into a bucket. | 
|  | 31 int kErrorBucketStart = 400; | 
|  | 32 | 
|  | 33 Range kErrorRangeList[] = { | 
|  | 34   { 0, 321, true },  // These are the ones we don't remap into buckets. | 
|  | 35   { 335, 371, false }, | 
|  | 36   { 383, 387, false }, | 
|  | 37   { 399, 404, false }, | 
|  | 38   { 415, 418, false }, | 
|  | 39   { 431, 433, false }, | 
|  | 40   { 447, 868, false }, | 
|  | 41   { 994, 1471, false }, | 
|  | 42   { 1500, 1513, false }, | 
|  | 43   { 1536, 1553, false }, | 
|  | 44   { 1601, 1654, false }, | 
|  | 45   { 1700, 1834, false }, | 
|  | 46   { 1898, 1938, false }, | 
|  | 47   { 2000, 2024, false }, | 
|  | 48   { 2048, 2085, false }, | 
|  | 49   { 2108, 2110, false }, | 
|  | 50   { 2202, 2203, false }, | 
|  | 51   { 2250, 2251, false }, | 
|  | 52   { 2401, 2405, false }, | 
|  | 53   { 3000, 3021, false }, | 
|  | 54   { 3950, 3951, false }, | 
|  | 55   { 4000, 4007, false }, | 
|  | 56   { 4050, 4066, false }, | 
|  | 57   { 4096, 4116, false }, | 
|  | 58   { 4200, 4215, false }, | 
|  | 59   { 4300, 4353, false }, | 
|  | 60   { 4390, 4395, false }, | 
|  | 61   { 4500, 4501, false }, | 
|  | 62   { 4864, 4905, false }, | 
|  | 63   { 5001, 5090, false }, | 
|  | 64   { 5890, 5953, false }, | 
|  | 65   { 6000, 6023, false }, | 
|  | 66   { 6118, 6119, false }, | 
|  | 67   { 6200, 6201, false }, | 
|  | 68   { 6600, 6649, false }, | 
|  | 69   { 6700, 6732, false }, | 
|  | 70   { 6800, 6856, false }, | 
|  | 71   { 7001, 7071, false }, | 
|  | 72   { 8001, 8018, false }, | 
|  | 73   { 8192, 8263, false }, | 
|  | 74   { 8301, 8640, false }, | 
|  | 75   { 8704, 8705, false }, | 
|  | 76   { 8960, 9053, false }, | 
|  | 77   { 9216, 9218, false }, | 
|  | 78   { 9263, 9276, false }, | 
|  | 79   { 9472, 9506, false }, | 
|  | 80   { 9550, 9573, false }, | 
|  | 81   { 9600, 9622, false }, | 
|  | 82   { 9650, 9656, false }, | 
|  | 83   { 9688, 9723, false }, | 
|  | 84   { 9750, 9754, false }, | 
|  | 85   { 9800, 9802, false }, | 
|  | 86   { 9850, 9853, false }, | 
|  | 87   { 9900, 9907, false }, | 
|  | 88   { 10000, 10072, false }, | 
|  | 89   { 10091, 10113, false }, | 
|  | 90   { 11001, 11034, false }, | 
|  | 91   { 12288, 12335, false }, | 
|  | 92   { 12544, 12559, false }, | 
|  | 93   { 12595, 12597, false }, | 
|  | 94   { 12801, 12803, false }, | 
|  | 95   { 13000, 13026, false }, | 
|  | 96   { 13800, 13933, false }, | 
|  | 97   { 14000, 14111, false }, | 
|  | 98   { 15000, 15039, false }, | 
|  | 99   { 15080, 15086, false }, | 
|  | 100   { 15100, 15109, false }, | 
|  | 101   { 15200, 15208, false }, | 
|  | 102   { 15250, 15251, false }, | 
|  | 103   { 15299, 15302, false }, | 
|  | 104   { 16385, 16436, false }, | 
|  | 105   { 18432, 18454, false }, | 
|  | 106   { 20480, 20486, false }, | 
|  | 107   { 24577, 24607, false }, | 
|  | 108   { 28673, 28698, false }, | 
|  | 109   { 32790, 32816, false }, | 
|  | 110   { 33281, 33322, false }, | 
|  | 111   { 35005, 35024, false }, | 
|  | 112   { 36000, 36004, false }, | 
|  | 113   { 40010, 40011, false }, | 
|  | 114   { 40067, 40069, false }, | 
|  | 115   { 53248, 53293, false }, | 
|  | 116   { 53376, 53382, false }, | 
|  | 117   { 57344, 57360, false }, | 
|  | 118   { 57377, 57394, false }, | 
|  | 119   { 65535, 65536 } | 
|  | 120 }; | 
|  | 121 size_t kNumErrorRanges = ARRAYSIZE_UNSAFE(kErrorRangeList); | 
|  | 122 | 
|  | 123 // Windows has very many errors.  We're not interested in most of them, but we | 
|  | 124 // don't know which ones are significant. | 
|  | 125 // This function maps error ranges we think we don't care about to specific | 
|  | 126 // buckets, and leaves the others alone.  If we get hits on the buckets, | 
|  | 127 // we can add those values to the values we leave alone. | 
|  | 128 // If we get values *between* the buckets, we record those as buckets too. | 
|  | 129 // The range list is extracted from WinError.h. | 
|  | 130 int ReduceErrorRange(int error) { | 
|  | 131   error = HRESULT_CODE(error); | 
|  | 132 | 
|  | 133   for (size_t n = 0; n < kNumErrorRanges; ++n) { | 
|  | 134     if (kErrorRangeList[n].record_individually) { | 
|  | 135       if (error < kErrorRangeList[n].low) | 
|  | 136         return kErrorBucketStart + (2 * n) - 1;  // In gap before the bucket. | 
|  | 137       if (error <= kErrorRangeList[n].high) | 
|  | 138         return error;  // Record individually. | 
|  | 139     } else { | 
|  | 140       if (error < kErrorRangeList[n].low) | 
|  | 141         return kErrorBucketStart + (2 * n) - 1;  // In gap before the bucket. | 
|  | 142       if (error <= kErrorRangeList[n].high) | 
|  | 143         return kErrorBucketStart + 2 * n;  // In bucket. | 
|  | 144     } | 
|  | 145   } | 
|  | 146 | 
|  | 147   // After the last bucket. | 
|  | 148   return kErrorBucketStart + 2 * kNumErrorRanges; | 
|  | 149 } | 
|  | 150 | 
|  | 151 #endif  // defined(OS_WIN) | 
|  | 152 | 
|  | 153 void RecordFileErrorTypeCount(FileErrorTypes type) { | 
|  | 154   UMA_HISTOGRAM_ENUMERATION( | 
|  | 155       "FileErrorType.Counts", type, FILE_ERROR_TYPES_COUNT); | 
|  | 156 } | 
|  | 157 | 
|  | 158 std::string RecordUmaName(FileErrorTypes type, int class_flags) { | 
|  | 159   std::string s; | 
|  | 160   static const char* names[] = { | 
|  | 161     "FileErrorTypes.NotOpenError", | 
|  | 162     "FileErrorTypes.OpenError", | 
|  | 163     "FileErrorTypes.WriteError", | 
|  | 164     "FileErrorTypes.ReadError", | 
|  | 165     "FileErrorTypes.SeekError", | 
|  | 166     "FileErrorTypes.FlushError", | 
|  | 167     "FileErrorTypes.SetEofError", | 
|  | 168     "FileErrorTypes.GetSizeError", | 
|  | 169   }; | 
|  | 170   static const char* classes[] = { | 
|  | 171     ".Download", | 
|  | 172     // Add more strings here as necessary to match |RecordingClass| items. | 
|  | 173   }; | 
|  | 174   static const int num_classes = ARRAYSIZE_UNSAFE(classes); | 
|  | 175 | 
|  | 176   s = names[type]; | 
|  | 177 | 
|  | 178   int i; | 
|  | 179   int mask; | 
|  | 180   int start = RECORDING_CLASS_NONE + 1; | 
|  | 181   for (i = start, mask = 1 << (start - 1); | 
|  | 182        i < (num_classes + start); | 
|  | 183        mask <<= 1, i++) { | 
|  | 184     if (class_flags & mask) { | 
|  | 185       s += classes[i - start]; | 
|  | 186       break; | 
|  | 187     } | 
|  | 188   } | 
|  | 189 | 
|  | 190   return s; | 
|  | 191 } | 
|  | 192 | 
|  | 193 }  // namespace | 
|  | 194 | 
|  | 195 void EnableRecordingForClass(int class_flags) { | 
|  | 196   g_recording_class_mask = class_flags; | 
|  | 197 } | 
|  | 198 | 
|  | 199 #define UMA_HISTOGRAM_CLASS(c) \ | 
|  | 200   if (class_flags & (1 << RECORDING_CLASS_##c) & g_recording_class_mask) { \ | 
|  | 201     UMA_HISTOGRAM_ENUMERATION(name.c_str(), error, max_error); \ | 
|  | 202     break; \ | 
|  | 203   } | 
|  | 204 | 
|  | 205 #define UMA_HISTOGRAM_CLASSES() \ | 
|  | 206   for (int i = 0; i < RECORDING_CLASS_MAX; ++i) { \ | 
|  | 207     UMA_HISTOGRAM_CLASS(DOWNLOADS) \ | 
|  | 208   } | 
|  | 209 | 
|  | 210 #define UMA_HISTOGRAM_TYPE(t) \ | 
|  | 211   case FILE_ERROR_TYPES_##t: \ | 
|  | 212     UMA_HISTOGRAM_CLASSES() \ | 
|  | 213     break; | 
|  | 214 | 
|  | 215 void RecordFileError(int error, FileErrorTypes type, int class_flags) { | 
|  | 216   if (class_flags == RECORDING_CLASS_NONE) | 
|  | 217     return; | 
|  | 218 | 
|  | 219   RecordFileErrorTypeCount(type); | 
|  | 220 | 
|  | 221   std::string name = RecordUmaName(type, class_flags); | 
|  | 222 | 
|  | 223   DLOG(WARNING) << "() " << "Recording error " << error | 
|  | 224                 << " of type " << type << " with flags " << class_flags | 
|  | 225                 << ". Name = '" << name << "'"; | 
|  | 226 | 
|  | 227   unsigned int max_error = (1U << 14) - 2;  // Histogram limit. | 
|  | 228 | 
|  | 229 #if  defined(OS_WIN) | 
|  | 230   error = ReduceErrorRange(error); | 
|  | 231   max_error = kErrorBucketStart + 2 * kNumErrorRanges + 1; | 
|  | 232 #elif  defined(OS_POSIX) | 
|  | 233   // Posix errors seem to have only low positive values. | 
|  | 234   max_error = 160; | 
|  | 235 #endif | 
|  | 236 | 
|  | 237   switch(type) { | 
|  | 238     UMA_HISTOGRAM_TYPE(IS_NOT_OPEN) | 
|  | 239     UMA_HISTOGRAM_TYPE(OPEN) | 
|  | 240     UMA_HISTOGRAM_TYPE(WRITE) | 
|  | 241     UMA_HISTOGRAM_TYPE(READ) | 
|  | 242     UMA_HISTOGRAM_TYPE(SEEK) | 
|  | 243     UMA_HISTOGRAM_TYPE(FLUSH) | 
|  | 244     UMA_HISTOGRAM_TYPE(SET_EOF) | 
|  | 245     UMA_HISTOGRAM_TYPE(GET_SIZE) | 
|  | 246     default: | 
|  | 247       break; | 
|  | 248   } | 
|  | 249 } | 
|  | 250 | 
|  | 251 }  // namespace net | 
| OLD | NEW | 
|---|