Chromium Code Reviews| 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) | |
|
cbentzel
2011/08/15 19:49:11
This would be a lot clearer and fewer #if defined
ahendrickson
2011/08/15 23:42:26
Moved the code to file_stream_metrics*.*.
| |
| 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 |