Chromium Code Reviews| Index: client/prune_crash_reports.cc |
| diff --git a/client/prune_crash_reports.cc b/client/prune_crash_reports.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..88f72c8cdfed9b35017430a8a4e5f7e6243cefa2 |
| --- /dev/null |
| +++ b/client/prune_crash_reports.cc |
| @@ -0,0 +1,115 @@ |
| +// Copyright 2015 The Crashpad Authors. All rights reserved. |
| +// |
| +// Licensed under the Apache License, Version 2.0 (the "License"); |
| +// you may not use this file except in compliance with the License. |
| +// You may obtain a copy of the License at |
| +// |
| +// http://www.apache.org/licenses/LICENSE-2.0 |
| +// |
| +// Unless required by applicable law or agreed to in writing, software |
| +// distributed under the License is distributed on an "AS IS" BASIS, |
| +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| +// See the License for the specific language governing permissions and |
| +// limitations under the License. |
| + |
| +#include "client/prune_crash_reports.h" |
| + |
| +#include <sys/stat.h> |
| + |
| +#include <algorithm> |
| +#include <vector> |
| + |
| +#include "base/logging.h" |
| + |
| +namespace crashpad { |
| + |
| +void PruneCrashReportDatabase(CrashReportDatabase* database, |
| + PruneCondition* condition) { |
| + std::vector<CrashReportDatabase::Report> all_reports, temp; |
| + CrashReportDatabase::OperationStatus status; |
| + |
| + status = database->GetPendingReports(&temp); |
|
Mark Mentovai
2015/10/07 03:54:27
Why don’t you fetch this right into all_reports? T
Robert Sesek
2015/10/07 16:24:34
Must be empty on entry. http://docs.crashpad.googl
Mark Mentovai
2015/10/07 16:40:13
It will be.
1. Fetch pending into all_reports.
2.
Robert Sesek
2015/10/07 17:16:28
Done.
|
| + if (status != CrashReportDatabase::kNoError) { |
| + LOG(ERROR) << "Database Pruning: Failed to get pending reports"; |
|
Mark Mentovai
2015/10/07 03:54:27
Local style is predominantly “PruneCrashReportData
Robert Sesek
2015/10/07 16:24:34
Done.
|
| + return; |
| + } |
| + all_reports.insert(all_reports.end(), temp.begin(), temp.end()); |
| + temp.clear(); |
| + |
| + status = database->GetCompletedReports(&temp); |
| + if (status != CrashReportDatabase::kNoError) { |
| + LOG(ERROR) << "Database Pruning: Failed to get completed reports"; |
| + return; |
| + } |
| + all_reports.insert(all_reports.end(), temp.begin(), temp.end()); |
| + |
| + std::sort(all_reports.begin(), all_reports.end(), |
| + [](const CrashReportDatabase::Report& lhs, |
| + const CrashReportDatabase::Report& rhs) { |
| + return lhs.creation_time > rhs.creation_time; |
| + }); |
| + |
| + for (const auto& report : all_reports) { |
| + if (condition->ShouldPruneReport(report)) { |
| + status = database->DeleteReport(report.uuid); |
| + if (status != CrashReportDatabase::kNoError) { |
| + LOG(ERROR) << "Database Pruning: Failed to remove report " |
| + << report.uuid.ToString(); |
| + } |
| + } |
| + } |
| +} |
| + |
| +scoped_ptr<PruneCondition> GetDefaultDatabasePruneCondition() { |
| + return make_scoped_ptr(new BinaryPruneCondition(BinaryPruneCondition::OR, |
| + new AgePruneCondition(365), new DatabaseSizePruneCondition(1024 * 128))); |
| +} |
| + |
| +AgePruneCondition::AgePruneCondition(int max_age_in_days) |
| + : oldest_report_time_(time(nullptr) - (max_age_in_days * 60 * 60 * 24)) {} |
|
Mark Mentovai
2015/10/07 03:54:27
mod this whole thing to a round UTC day?
Robert Sesek
2015/10/07 16:24:34
Done.
|
| + |
| +AgePruneCondition::~AgePruneCondition() {} |
| + |
| +bool AgePruneCondition::ShouldPruneReport( |
| + const CrashReportDatabase::Report& report) { |
| + return report.creation_time < oldest_report_time_; |
| +} |
| + |
| +DatabaseSizePruneCondition::DatabaseSizePruneCondition(size_t max_size_in_bytes) |
| + : max_size_in_bytes_(max_size_in_bytes), measured_size_(0) {} |
| + |
| +DatabaseSizePruneCondition::~DatabaseSizePruneCondition() {} |
| + |
| +bool DatabaseSizePruneCondition::ShouldPruneReport( |
| + const CrashReportDatabase::Report& report) { |
| +#if defined(OS_POSIX) |
| + struct stat statbuf; |
| + if (stat(report.file_path.value().c_str(), &statbuf) == 0) { |
| +#elif defined(OS_WIN) |
| + struct _stat statbuf; |
|
Mark Mentovai
2015/10/07 03:54:27
_stati64 for a full-sized st_size.
Robert Sesek
2015/10/07 16:24:34
Done.
|
| + if (_wstat(report.file_path.value().c_str(), &statbuf) == 0) { |
|
Mark Mentovai
2015/10/07 03:54:27
_wstati64
Robert Sesek
2015/10/07 16:24:34
Done.
|
| +#else |
| +#error "Not implemented" |
| +#endif |
| + measured_size_ += statbuf.st_size; |
| + } |
| + return measured_size_ > max_size_in_bytes_; |
| +} |
| + |
| +BinaryPruneCondition::BinaryPruneCondition( |
| + Operator op, PruneCondition* lhs, PruneCondition* rhs) |
| + : op_(op), lhs_(lhs), rhs_(rhs) {} |
| + |
| +BinaryPruneCondition::~BinaryPruneCondition() {} |
| + |
| +bool BinaryPruneCondition::ShouldPruneReport( |
| + const CrashReportDatabase::Report& report) { |
| + switch (op_) { |
| + case AND: |
| + return lhs_->ShouldPruneReport(report) && rhs_->ShouldPruneReport(report); |
| + case OR: |
| + return lhs_->ShouldPruneReport(report) || rhs_->ShouldPruneReport(report); |
| + } |
| +} |
|
scottmg
2015/10/06 22:22:07
On Windows:
d:\src\crashpad\crashpad\client\prune
Robert Sesek
2015/10/07 16:24:34
Done.
|
| + |
| +} // namespace crashpad |