Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(310)

Unified Diff: base/files/important_file_writer.cc

Issue 2920223002: Add additional histograms with suffixes to ImportantFileWriter. (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: base/files/important_file_writer.cc
diff --git a/base/files/important_file_writer.cc b/base/files/important_file_writer.cc
index 0696c96b6c955e388dcb0f6af8398ccb9033f8cb..25626abdee134766b33dc3fa53a998fe57100fb4 100644
--- a/base/files/important_file_writer.cc
+++ b/base/files/important_file_writer.cc
@@ -49,10 +49,35 @@ enum TempFileFailure {
TEMP_FILE_FAILURE_MAX
};
-void LogFailure(const FilePath& path, TempFileFailure failure_code,
+// Helper function to write samples to a histogram with a dynamically assigned
+// histogram name. Works with different error code types convertible to
+// HistogramBase::Sample.
+template <typename SampleType>
+typename std::enable_if<
+ std::is_convertible<SampleType, HistogramBase::Sample>::value>::type
+DynamicUmaHistogramEnumeration(const char* histogram_name,
rkaplow 2017/06/05 18:17:30 can you use the function version from https://cs.c
xaerox 2017/06/07 09:32:54 Acknowledged.
+ const std::string& histogram_suffix,
+ SampleType add_sample,
+ SampleType max_sample) {
+ constexpr auto one_sample = HistogramBase::Sample(1);
+ const auto histogram_full_name =
+ std::string(histogram_name).append(histogram_suffix);
+ auto* histogram = Histogram::FactoryGet(
+ histogram_full_name, one_sample,
+ static_cast<HistogramBase::Sample>(max_sample),
+ static_cast<HistogramBase::Sample>(max_sample) + one_sample,
+ HistogramBase::kUmaTargetedHistogramFlag);
+ if (histogram)
+ histogram->Add(static_cast<HistogramBase::Sample>(add_sample));
+}
+
+void LogFailure(const FilePath& path,
+ const std::string& histogram_suffix,
+ TempFileFailure failure_code,
StringPiece message) {
- UMA_HISTOGRAM_ENUMERATION("ImportantFile.TempFileFailures", failure_code,
- TEMP_FILE_FAILURE_MAX);
+ DynamicUmaHistogramEnumeration("ImportantFile.TempFileFailures",
+ histogram_suffix, failure_code,
+ TEMP_FILE_FAILURE_MAX);
DPLOG(WARNING) << "temp file failure: " << path.value() << " : " << message;
}
@@ -62,21 +87,43 @@ void WriteScopedStringToFileAtomically(
const FilePath& path,
std::unique_ptr<std::string> data,
Closure before_write_callback,
- Callback<void(bool success)> after_write_callback) {
+ Callback<void(bool success)> after_write_callback,
+ std::string histogram_suffix) {
if (!before_write_callback.is_null())
before_write_callback.Run();
- bool result = ImportantFileWriter::WriteFileAtomically(path, *data);
+ bool result = ImportantFileWriter::WriteFileAtomically(
+ path, *data, std::move(histogram_suffix));
if (!after_write_callback.is_null())
after_write_callback.Run(result);
}
+base::File::Error GetLastFileError() {
+#if defined(OS_WIN)
+ return base::File::OSErrorToFileError(::GetLastError());
+#elif defined(OS_POSIX)
+ return base::File::OSErrorToFileError(errno);
+#else
+ return base::File::FILE_OK;
+#endif
+}
+
+void DeleteTmpFile(const FilePath& tmp_file_path,
+ const std::string& histogram_suffix) {
+ if (!DeleteFile(tmp_file_path, false)) {
+ DynamicUmaHistogramEnumeration("ImportantFile.FileDeleteError",
+ histogram_suffix, -GetLastFileError(),
+ -base::File::FILE_ERROR_MAX);
+ }
+}
+
} // namespace
// static
bool ImportantFileWriter::WriteFileAtomically(const FilePath& path,
- StringPiece data) {
+ StringPiece data,
+ std::string histogram_suffix) {
#if defined(OS_CHROMEOS)
// On Chrome OS, chrome gets killed when it cannot finish shutdown quickly,
// and this function seems to be one of the slowest shutdown steps.
@@ -97,13 +144,21 @@ bool ImportantFileWriter::WriteFileAtomically(const FilePath& path,
// is securely created.
FilePath tmp_file_path;
if (!CreateTemporaryFileInDir(path.DirName(), &tmp_file_path)) {
- LogFailure(path, FAILED_CREATING, "could not create temporary file");
+ DynamicUmaHistogramEnumeration("ImportantFile.FileCreateError",
+ histogram_suffix, -GetLastFileError(),
+ -base::File::FILE_ERROR_MAX);
+ LogFailure(path, histogram_suffix, FAILED_CREATING,
+ "could not create temporary file");
return false;
}
File tmp_file(tmp_file_path, File::FLAG_OPEN | File::FLAG_WRITE);
if (!tmp_file.IsValid()) {
- LogFailure(path, FAILED_OPENING, "could not open temporary file");
+ DynamicUmaHistogramEnumeration("ImportantFile.FileOpenError",
+ histogram_suffix, -tmp_file.error_details(),
+ -base::File::FILE_ERROR_MAX);
+ LogFailure(path, histogram_suffix, FAILED_OPENING,
+ "could not open temporary file");
DeleteFile(tmp_file_path, false);
return false;
}
@@ -111,25 +166,35 @@ bool ImportantFileWriter::WriteFileAtomically(const FilePath& path,
// If this fails in the wild, something really bad is going on.
const int data_length = checked_cast<int32_t>(data.length());
int bytes_written = tmp_file.Write(0, data.data(), data_length);
+ if (bytes_written < data_length) {
+ DynamicUmaHistogramEnumeration("ImportantFile.FileWriteError",
+ histogram_suffix, -GetLastFileError(),
+ -base::File::FILE_ERROR_MAX);
+ }
bool flush_success = tmp_file.Flush();
tmp_file.Close();
if (bytes_written < data_length) {
- LogFailure(path, FAILED_WRITING, "error writing, bytes_written=" +
- IntToString(bytes_written));
- DeleteFile(tmp_file_path, false);
+ LogFailure(path, histogram_suffix, FAILED_WRITING,
+ "error writing, bytes_written=" + IntToString(bytes_written));
+ DeleteTmpFile(tmp_file_path, histogram_suffix);
return false;
}
if (!flush_success) {
- LogFailure(path, FAILED_FLUSHING, "error flushing");
- DeleteFile(tmp_file_path, false);
+ LogFailure(path, histogram_suffix, FAILED_FLUSHING, "error flushing");
+ DeleteTmpFile(tmp_file_path, histogram_suffix);
return false;
}
- if (!ReplaceFile(tmp_file_path, path, nullptr)) {
- LogFailure(path, FAILED_RENAMING, "could not rename temporary file");
- DeleteFile(tmp_file_path, false);
+ base::File::Error replace_file_error = base::File::FILE_OK;
+ if (!ReplaceFile(tmp_file_path, path, &replace_file_error)) {
+ DynamicUmaHistogramEnumeration("ImportantFile.FileRenameError",
+ histogram_suffix, -replace_file_error,
+ -base::File::FILE_ERROR_MAX);
+ LogFailure(path, histogram_suffix, FAILED_RENAMING,
+ "could not rename temporary file");
+ DeleteTmpFile(tmp_file_path, histogram_suffix);
return false;
}
@@ -138,19 +203,23 @@ bool ImportantFileWriter::WriteFileAtomically(const FilePath& path,
ImportantFileWriter::ImportantFileWriter(
const FilePath& path,
- scoped_refptr<SequencedTaskRunner> task_runner)
+ scoped_refptr<SequencedTaskRunner> task_runner,
+ std::string histogram_suffix)
: ImportantFileWriter(path,
std::move(task_runner),
- kDefaultCommitInterval) {}
+ kDefaultCommitInterval,
+ std::move(histogram_suffix)) {}
ImportantFileWriter::ImportantFileWriter(
const FilePath& path,
scoped_refptr<SequencedTaskRunner> task_runner,
- TimeDelta interval)
+ TimeDelta interval,
+ std::string histogram_suffix)
: path_(path),
task_runner_(std::move(task_runner)),
serializer_(nullptr),
commit_interval_(interval),
+ histogram_suffix_(std::move(histogram_suffix)),
weak_factory_(this) {
DCHECK(task_runner_);
}
@@ -178,7 +247,7 @@ void ImportantFileWriter::WriteNow(std::unique_ptr<std::string> data) {
Closure task = AdaptCallbackForRepeating(
BindOnce(&WriteScopedStringToFileAtomically, path_, std::move(data),
std::move(before_next_write_callback_),
- std::move(after_next_write_callback_)));
+ std::move(after_next_write_callback_), histogram_suffix_));
if (!task_runner_->PostTask(FROM_HERE, MakeCriticalClosure(task))) {
// Posting the task to background message loop is not expected

Powered by Google App Engine
This is Rietveld 408576698