diff options
-rw-r--r-- | content/browser/indexed_db/leveldb/leveldb_database.cc | 21 | ||||
-rw-r--r-- | third_party/leveldatabase/env_chromium.cc | 123 | ||||
-rw-r--r-- | third_party/leveldatabase/env_chromium.h | 14 | ||||
-rw-r--r-- | third_party/leveldatabase/env_chromium_unittest.cc | 21 | ||||
-rw-r--r-- | tools/metrics/histograms/histograms.xml | 14 |
5 files changed, 124 insertions, 69 deletions
diff --git a/content/browser/indexed_db/leveldb/leveldb_database.cc b/content/browser/indexed_db/leveldb/leveldb_database.cc index 6fedec1..88dc47e 100644 --- a/content/browser/indexed_db/leveldb/leveldb_database.cc +++ b/content/browser/indexed_db/leveldb/leveldb_database.cc @@ -17,6 +17,7 @@ #include "content/browser/indexed_db/leveldb/leveldb_iterator.h" #include "content/browser/indexed_db/leveldb/leveldb_slice.h" #include "content/browser/indexed_db/leveldb/leveldb_write_batch.h" +#include "third_party/leveldatabase/env_chromium.h" #include "third_party/leveldatabase/env_idb.h" #include "third_party/leveldatabase/src/helpers/memenv/memenv.h" #include "third_party/leveldatabase/src/include/leveldb/comparator.h" @@ -138,7 +139,7 @@ static int CheckFreeSpace(const char* type, const base::FilePath& file_name) { return clamped_disk_space_k_bytes; } -static void HistogramLevelDBError(const char* histogram_name, +static void HistogramLevelDBError(const std::string& histogram_name, const leveldb::Status& s) { DCHECK(!s.ok()); enum { @@ -161,6 +162,24 @@ static void HistogramLevelDBError(const char* histogram_name, LEVEL_DB_MAX_ERROR + 1, base::HistogramBase::kUmaTargetedHistogramFlag) ->Add(leveldb_error); + + // The code above histograms the type of error. The code below tries to + // histogram the method where the error occurred in ChromiumEnv and, in most + // cases, the exact error encountered. + leveldb_env::MethodID method; + int error = -1; + leveldb_env::ErrorParsingResult result = + leveldb_env::ParseMethodAndError(s.ToString().c_str(), &method, &error); + if (result == leveldb_env::NONE) + return; + std::string method_histogram_name(histogram_name); + method_histogram_name.append(".EnvMethod"); + base::LinearHistogram::FactoryGet( + method_histogram_name, + 1, + leveldb_env::kNumEntries, + leveldb_env::kNumEntries + 1, + base::HistogramBase::kUmaTargetedHistogramFlag)->Add(method); } scoped_ptr<LevelDBDatabase> LevelDBDatabase::Open( diff --git a/third_party/leveldatabase/env_chromium.cc b/third_party/leveldatabase/env_chromium.cc index 71a5c88..8d74569 100644 --- a/third_party/leveldatabase/env_chromium.cc +++ b/third_party/leveldatabase/env_chromium.cc @@ -129,56 +129,6 @@ base::FilePath CreateFilePath(const std::string& file_path) { #endif } -const char* MethodIDToString(MethodID method) { - switch (method) { - case kSequentialFileRead: - return "SequentialFileRead"; - case kSequentialFileSkip: - return "SequentialFileSkip"; - case kRandomAccessFileRead: - return "RandomAccessFileRead"; - case kWritableFileAppend: - return "WritableFileAppend"; - case kWritableFileClose: - return "WritableFileClose"; - case kWritableFileFlush: - return "WritableFileFlush"; - case kWritableFileSync: - return "WritableFileSync"; - case kNewSequentialFile: - return "NewSequentialFile"; - case kNewRandomAccessFile: - return "NewRandomAccessFile"; - case kNewWritableFile: - return "NewWritableFile"; - case kDeleteFile: - return "DeleteFile"; - case kCreateDir: - return "CreateDir"; - case kDeleteDir: - return "DeleteDir"; - case kGetFileSize: - return "GetFileSize"; - case kRenameFile: - return "RenameFile"; - case kLockFile: - return "LockFile"; - case kUnlockFile: - return "UnlockFile"; - case kGetTestDirectory: - return "GetTestDirectory"; - case kNewLogger: - return "NewLogger"; - case kSyncParent: - return "SyncParent"; - case kNumEntries: - NOTREACHED(); - return "kNumEntries"; - } - NOTREACHED(); - return "Unknown"; -} - static const base::FilePath::CharType kLevelDBTestDirectoryPrefix[] = FILE_PATH_LITERAL("leveldb-test-"); @@ -351,6 +301,56 @@ class IDBEnv : public ChromiumEnv { } // unnamed namespace +const char* MethodIDToString(MethodID method) { + switch (method) { + case kSequentialFileRead: + return "SequentialFileRead"; + case kSequentialFileSkip: + return "SequentialFileSkip"; + case kRandomAccessFileRead: + return "RandomAccessFileRead"; + case kWritableFileAppend: + return "WritableFileAppend"; + case kWritableFileClose: + return "WritableFileClose"; + case kWritableFileFlush: + return "WritableFileFlush"; + case kWritableFileSync: + return "WritableFileSync"; + case kNewSequentialFile: + return "NewSequentialFile"; + case kNewRandomAccessFile: + return "NewRandomAccessFile"; + case kNewWritableFile: + return "NewWritableFile"; + case kDeleteFile: + return "DeleteFile"; + case kCreateDir: + return "CreateDir"; + case kDeleteDir: + return "DeleteDir"; + case kGetFileSize: + return "GetFileSize"; + case kRenameFile: + return "RenameFile"; + case kLockFile: + return "LockFile"; + case kUnlockFile: + return "UnlockFile"; + case kGetTestDirectory: + return "GetTestDirectory"; + case kNewLogger: + return "NewLogger"; + case kSyncParent: + return "SyncParent"; + case kNumEntries: + NOTREACHED(); + return "kNumEntries"; + } + NOTREACHED(); + return "Unknown"; +} + Status MakeIOError(Slice filename, const char* message, MethodID method, @@ -393,19 +393,26 @@ Status MakeIOError(Slice filename, const char* message, MethodID method) { return Status::IOError(filename, buf); } -bool ParseMethodAndError(const char* string, int* method, int* error) { - if (RE2::PartialMatch(string, "ChromeMethodOnly: (\\d+)", method)) - return true; +ErrorParsingResult ParseMethodAndError(const char* string, + MethodID* method_param, + int* error) { + int method; + if (RE2::PartialMatch(string, "ChromeMethodOnly: (\\d+)", &method)) { + *method_param = static_cast<MethodID>(method); + return METHOD_ONLY; + } if (RE2::PartialMatch( - string, "ChromeMethodPFE: (\\d+)::.*::(\\d+)", method, error)) { + string, "ChromeMethodPFE: (\\d+)::.*::(\\d+)", &method, error)) { *error = -*error; - return true; + *method_param = static_cast<MethodID>(method); + return METHOD_AND_PFE; } if (RE2::PartialMatch( - string, "ChromeMethodErrno: (\\d+)::.*::(\\d+)", method, error)) { - return true; + string, "ChromeMethodErrno: (\\d+)::.*::(\\d+)", &method, error)) { + *method_param = static_cast<MethodID>(method); + return METHOD_AND_ERRNO; } - return false; + return NONE; } std::string FilePathToString(const base::FilePath& file_path) { diff --git a/third_party/leveldatabase/env_chromium.h b/third_party/leveldatabase/env_chromium.h index 38a3759..168d180 100644 --- a/third_party/leveldatabase/env_chromium.h +++ b/third_party/leveldatabase/env_chromium.h @@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_LEVELDATABASE_ENV_CHROMIUM_H_ #define THIRD_PARTY_LEVELDATABASE_ENV_CHROMIUM_H_ +#include <deque> #include <map> #include "base/metrics/histogram.h" @@ -40,6 +41,8 @@ enum MethodID { kNumEntries }; +const char* MethodIDToString(MethodID method); + leveldb::Status MakeIOError(leveldb::Slice filename, const char* message, MethodID method, @@ -52,7 +55,16 @@ leveldb::Status MakeIOError(leveldb::Slice filename, const char* message, MethodID method); -bool ParseMethodAndError(const char* string, int* method, int* error); +enum ErrorParsingResult { + METHOD_ONLY, + METHOD_AND_PFE, + METHOD_AND_ERRNO, + NONE, +}; + +ErrorParsingResult ParseMethodAndError(const char* string, + MethodID* method, + int* error); std::string FilePathToString(const base::FilePath& file_path); class UMALogger { diff --git a/third_party/leveldatabase/env_chromium_unittest.cc b/third_party/leveldatabase/env_chromium_unittest.cc index eae2d6a..e7b0bba 100644 --- a/third_party/leveldatabase/env_chromium_unittest.cc +++ b/third_party/leveldatabase/env_chromium_unittest.cc @@ -14,9 +14,10 @@ using namespace leveldb; TEST(ErrorEncoding, OnlyAMethod) { const MethodID in_method = kSequentialFileRead; const Status s = MakeIOError("Somefile.txt", "message", in_method); - int method = -50; + MethodID method; int error = -75; - EXPECT_TRUE(ParseMethodAndError(s.ToString().c_str(), &method, &error)); + EXPECT_EQ(METHOD_ONLY, + ParseMethodAndError(s.ToString().c_str(), &method, &error)); EXPECT_EQ(in_method, method); EXPECT_EQ(-75, error); } @@ -26,9 +27,10 @@ TEST(ErrorEncoding, PlatformFileError) { const base::PlatformFileError pfe = base::PLATFORM_FILE_ERROR_INVALID_OPERATION; const Status s = MakeIOError("Somefile.txt", "message", in_method, pfe); - int method; + MethodID method; int error; - EXPECT_TRUE(ParseMethodAndError(s.ToString().c_str(), &method, &error)); + EXPECT_EQ(METHOD_AND_PFE, + ParseMethodAndError(s.ToString().c_str(), &method, &error)); EXPECT_EQ(in_method, method); EXPECT_EQ(pfe, error); } @@ -38,19 +40,20 @@ TEST(ErrorEncoding, Errno) { const int some_errno = ENOENT; const Status s = MakeIOError("Somefile.txt", "message", in_method, some_errno); - int method; + MethodID method; int error; - EXPECT_TRUE(ParseMethodAndError(s.ToString().c_str(), &method, &error)); + EXPECT_EQ(METHOD_AND_ERRNO, + ParseMethodAndError(s.ToString().c_str(), &method, &error)); EXPECT_EQ(in_method, method); EXPECT_EQ(some_errno, error); } TEST(ErrorEncoding, NoEncodedMessage) { Status s = Status::IOError("Some message", "from leveldb itself"); - int method = 3; + MethodID method = kRandomAccessFileRead; int error = 4; - EXPECT_FALSE(ParseMethodAndError(s.ToString().c_str(), &method, &error)); - EXPECT_EQ(3, method); + EXPECT_EQ(NONE, ParseMethodAndError(s.ToString().c_str(), &method, &error)); + EXPECT_EQ(kRandomAccessFileRead, method); EXPECT_EQ(4, error); } diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 6b7594c..4c6289d 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml @@ -11651,12 +11651,26 @@ other types of suffix sets. </summary> </histogram> +<histogram name="WebCore.IndexedDB.LevelDBOpenErrors.EnvMethod" + enum="LevelDBIOErrorMethods"> + <summary> + LevelDBEnv methods that generated IO errors when opening a database. + </summary> +</histogram> + <histogram name="WebCore.IndexedDB.LevelDBWriteErrors" enum="LevelDBErrorTypes"> <summary> Error classes returned by LevelDB when it failed to write to a database. </summary> </histogram> +<histogram name="WebCore.IndexedDB.LevelDBWriteErrors.EnvMethod" + enum="LevelDBIOErrorMethods"> + <summary> + LevelDBEnv methods that generated IO errors when writing to a database. + </summary> +</histogram> + <histogram name="WebCore.V8DOMWindowShell.createContext.IsolatedWorld" units="milliseconds"> <summary> |