summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/browser/indexed_db/leveldb/leveldb_database.cc21
-rw-r--r--third_party/leveldatabase/env_chromium.cc123
-rw-r--r--third_party/leveldatabase/env_chromium.h14
-rw-r--r--third_party/leveldatabase/env_chromium_unittest.cc21
-rw-r--r--tools/metrics/histograms/histograms.xml14
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>