 Chromium Code Reviews
 Chromium Code Reviews Issue 7583049:
  Record UMA statistics for file_stream operations.  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src
    
  
    Issue 7583049:
  Record UMA statistics for file_stream operations.  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src| Index: net/base/file_stream.cc | 
| diff --git a/net/base/file_stream.cc b/net/base/file_stream.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..aae50c2d14ccb092f72b05fcbb4f8c61d776a44c | 
| --- /dev/null | 
| +++ b/net/base/file_stream.cc | 
| @@ -0,0 +1,251 @@ | 
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved. | 
| +// Use of this source code is governed by a BSD-style license that can be | 
| +// found in the LICENSE file. | 
| + | 
| +#include "net/base/file_stream.h" | 
| + | 
| +#include <string> | 
| +#if defined(OS_WIN) | 
| +#include <windows.h> | 
| +#endif | 
| + | 
| +#include "base/basictypes.h" | 
| +#include "base/logging.h" | 
| +#include "base/metrics/histogram.h" | 
| + | 
| +namespace net { | 
| + | 
| +namespace { | 
| + | 
| +int g_recording_class_mask = RECORDING_CLASS_NONE; | 
| + | 
| +#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*.*.
 | 
| + | 
| +struct Range { | 
| + int low; | 
| + int high; | 
| + bool record_individually; | 
| +}; | 
| + | 
| +// This must be higher than the largest value that isn't remapped into a bucket. | 
| +int kErrorBucketStart = 400; | 
| + | 
| +Range kErrorRangeList[] = { | 
| + { 0, 321, true }, // These are the ones we don't remap into buckets. | 
| + { 335, 371, false }, | 
| + { 383, 387, false }, | 
| + { 399, 404, false }, | 
| + { 415, 418, false }, | 
| + { 431, 433, false }, | 
| + { 447, 868, false }, | 
| + { 994, 1471, false }, | 
| + { 1500, 1513, false }, | 
| + { 1536, 1553, false }, | 
| + { 1601, 1654, false }, | 
| + { 1700, 1834, false }, | 
| + { 1898, 1938, false }, | 
| + { 2000, 2024, false }, | 
| + { 2048, 2085, false }, | 
| + { 2108, 2110, false }, | 
| + { 2202, 2203, false }, | 
| + { 2250, 2251, false }, | 
| + { 2401, 2405, false }, | 
| + { 3000, 3021, false }, | 
| + { 3950, 3951, false }, | 
| + { 4000, 4007, false }, | 
| + { 4050, 4066, false }, | 
| + { 4096, 4116, false }, | 
| + { 4200, 4215, false }, | 
| + { 4300, 4353, false }, | 
| + { 4390, 4395, false }, | 
| + { 4500, 4501, false }, | 
| + { 4864, 4905, false }, | 
| + { 5001, 5090, false }, | 
| + { 5890, 5953, false }, | 
| + { 6000, 6023, false }, | 
| + { 6118, 6119, false }, | 
| + { 6200, 6201, false }, | 
| + { 6600, 6649, false }, | 
| + { 6700, 6732, false }, | 
| + { 6800, 6856, false }, | 
| + { 7001, 7071, false }, | 
| + { 8001, 8018, false }, | 
| + { 8192, 8263, false }, | 
| + { 8301, 8640, false }, | 
| + { 8704, 8705, false }, | 
| + { 8960, 9053, false }, | 
| + { 9216, 9218, false }, | 
| + { 9263, 9276, false }, | 
| + { 9472, 9506, false }, | 
| + { 9550, 9573, false }, | 
| + { 9600, 9622, false }, | 
| + { 9650, 9656, false }, | 
| + { 9688, 9723, false }, | 
| + { 9750, 9754, false }, | 
| + { 9800, 9802, false }, | 
| + { 9850, 9853, false }, | 
| + { 9900, 9907, false }, | 
| + { 10000, 10072, false }, | 
| + { 10091, 10113, false }, | 
| + { 11001, 11034, false }, | 
| + { 12288, 12335, false }, | 
| + { 12544, 12559, false }, | 
| + { 12595, 12597, false }, | 
| + { 12801, 12803, false }, | 
| + { 13000, 13026, false }, | 
| + { 13800, 13933, false }, | 
| + { 14000, 14111, false }, | 
| + { 15000, 15039, false }, | 
| + { 15080, 15086, false }, | 
| + { 15100, 15109, false }, | 
| + { 15200, 15208, false }, | 
| + { 15250, 15251, false }, | 
| + { 15299, 15302, false }, | 
| + { 16385, 16436, false }, | 
| + { 18432, 18454, false }, | 
| + { 20480, 20486, false }, | 
| + { 24577, 24607, false }, | 
| + { 28673, 28698, false }, | 
| + { 32790, 32816, false }, | 
| + { 33281, 33322, false }, | 
| + { 35005, 35024, false }, | 
| + { 36000, 36004, false }, | 
| + { 40010, 40011, false }, | 
| + { 40067, 40069, false }, | 
| + { 53248, 53293, false }, | 
| + { 53376, 53382, false }, | 
| + { 57344, 57360, false }, | 
| + { 57377, 57394, false }, | 
| + { 65535, 65536 } | 
| +}; | 
| +size_t kNumErrorRanges = ARRAYSIZE_UNSAFE(kErrorRangeList); | 
| + | 
| +// Windows has very many errors. We're not interested in most of them, but we | 
| +// don't know which ones are significant. | 
| +// This function maps error ranges we think we don't care about to specific | 
| +// buckets, and leaves the others alone. If we get hits on the buckets, | 
| +// we can add those values to the values we leave alone. | 
| +// If we get values *between* the buckets, we record those as buckets too. | 
| +// The range list is extracted from WinError.h. | 
| +int ReduceErrorRange(int error) { | 
| + error = HRESULT_CODE(error); | 
| + | 
| + for (size_t n = 0; n < kNumErrorRanges; ++n) { | 
| + if (kErrorRangeList[n].record_individually) { | 
| + if (error < kErrorRangeList[n].low) | 
| + return kErrorBucketStart + (2 * n) - 1; // In gap before the bucket. | 
| + if (error <= kErrorRangeList[n].high) | 
| + return error; // Record individually. | 
| + } else { | 
| + if (error < kErrorRangeList[n].low) | 
| + return kErrorBucketStart + (2 * n) - 1; // In gap before the bucket. | 
| + if (error <= kErrorRangeList[n].high) | 
| + return kErrorBucketStart + 2 * n; // In bucket. | 
| + } | 
| + } | 
| + | 
| + // After the last bucket. | 
| + return kErrorBucketStart + 2 * kNumErrorRanges; | 
| +} | 
| + | 
| +#endif // defined(OS_WIN) | 
| + | 
| +void RecordFileErrorTypeCount(FileErrorTypes type) { | 
| + UMA_HISTOGRAM_ENUMERATION( | 
| + "FileErrorType.Counts", type, FILE_ERROR_TYPES_COUNT); | 
| +} | 
| + | 
| +std::string RecordUmaName(FileErrorTypes type, int class_flags) { | 
| + std::string s; | 
| + static const char* names[] = { | 
| + "FileErrorTypes.NotOpenError", | 
| + "FileErrorTypes.OpenError", | 
| + "FileErrorTypes.WriteError", | 
| + "FileErrorTypes.ReadError", | 
| + "FileErrorTypes.SeekError", | 
| + "FileErrorTypes.FlushError", | 
| + "FileErrorTypes.SetEofError", | 
| + "FileErrorTypes.GetSizeError", | 
| + }; | 
| + static const char* classes[] = { | 
| + ".Download", | 
| + // Add more strings here as necessary to match |RecordingClass| items. | 
| + }; | 
| + static const int num_classes = ARRAYSIZE_UNSAFE(classes); | 
| + | 
| + s = names[type]; | 
| + | 
| + int i; | 
| + int mask; | 
| + int start = RECORDING_CLASS_NONE + 1; | 
| + for (i = start, mask = 1 << (start - 1); | 
| + i < (num_classes + start); | 
| + mask <<= 1, i++) { | 
| + if (class_flags & mask) { | 
| + s += classes[i - start]; | 
| + break; | 
| + } | 
| + } | 
| + | 
| + return s; | 
| +} | 
| + | 
| +} // namespace | 
| + | 
| +void EnableRecordingForClass(int class_flags) { | 
| + g_recording_class_mask = class_flags; | 
| +} | 
| + | 
| +#define UMA_HISTOGRAM_CLASS(c) \ | 
| + if (class_flags & (1 << RECORDING_CLASS_##c) & g_recording_class_mask) { \ | 
| + UMA_HISTOGRAM_ENUMERATION(name.c_str(), error, max_error); \ | 
| + break; \ | 
| + } | 
| + | 
| +#define UMA_HISTOGRAM_CLASSES() \ | 
| + for (int i = 0; i < RECORDING_CLASS_MAX; ++i) { \ | 
| + UMA_HISTOGRAM_CLASS(DOWNLOADS) \ | 
| + } | 
| + | 
| +#define UMA_HISTOGRAM_TYPE(t) \ | 
| + case FILE_ERROR_TYPES_##t: \ | 
| + UMA_HISTOGRAM_CLASSES() \ | 
| + break; | 
| + | 
| +void RecordFileError(int error, FileErrorTypes type, int class_flags) { | 
| + if (class_flags == RECORDING_CLASS_NONE) | 
| + return; | 
| + | 
| + RecordFileErrorTypeCount(type); | 
| + | 
| + std::string name = RecordUmaName(type, class_flags); | 
| + | 
| + DLOG(WARNING) << "() " << "Recording error " << error | 
| + << " of type " << type << " with flags " << class_flags | 
| + << ". Name = '" << name << "'"; | 
| + | 
| + unsigned int max_error = (1U << 14) - 2; // Histogram limit. | 
| + | 
| +#if defined(OS_WIN) | 
| + error = ReduceErrorRange(error); | 
| + max_error = kErrorBucketStart + 2 * kNumErrorRanges + 1; | 
| +#elif defined(OS_POSIX) | 
| + // Posix errors seem to have only low positive values. | 
| + max_error = 160; | 
| +#endif | 
| + | 
| + switch(type) { | 
| + UMA_HISTOGRAM_TYPE(IS_NOT_OPEN) | 
| + UMA_HISTOGRAM_TYPE(OPEN) | 
| + UMA_HISTOGRAM_TYPE(WRITE) | 
| + UMA_HISTOGRAM_TYPE(READ) | 
| + UMA_HISTOGRAM_TYPE(SEEK) | 
| + UMA_HISTOGRAM_TYPE(FLUSH) | 
| + UMA_HISTOGRAM_TYPE(SET_EOF) | 
| + UMA_HISTOGRAM_TYPE(GET_SIZE) | 
| + default: | 
| + break; | 
| + } | 
| +} | 
| + | 
| +} // namespace net |