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..af00be3999a4be091b6e0c93eb777c17ce530880 |
| --- /dev/null |
| +++ b/client/prune_crash_reports.cc |
| @@ -0,0 +1,125 @@ |
| +// 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; |
| + CrashReportDatabase::OperationStatus status; |
| + |
| + status = database->GetPendingReports(&all_reports); |
| + if (status != CrashReportDatabase::kNoError) { |
| + LOG(ERROR) << "PruneCrashReportDatabase: Failed to get pending reports"; |
| + return; |
| + } |
| + |
| + std::vector<CrashReportDatabase::Report> completed_reports; |
| + status = database->GetCompletedReports(&completed_reports); |
| + if (status != CrashReportDatabase::kNoError) { |
| + LOG(ERROR) << "PruneCrashReportDatabase: Failed to get completed reports"; |
| + return; |
| + } |
| + all_reports.insert(all_reports.end(), completed_reports.begin(), |
| + completed_reports.end()); |
| + |
| + std::sort(all_reports.begin(), all_reports.end(), |
|
Mark Mentovai
2015/10/07 19:13:05
Just noting it here so that there’s evidence that
|
| + [](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(); |
| + } |
| + } |
| + } |
| +} |
| + |
| +// static |
| +scoped_ptr<PruneCondition> PruneCondition::GetDefault() { |
| + // DatabaseSizePruneCondition must be the LHS so that it is always evaluated, |
| + // due to the short-circuting behavior of BinaryPruneCondition. |
| + return make_scoped_ptr(new BinaryPruneCondition(BinaryPruneCondition::OR, |
| + new DatabaseSizePruneCondition(1024 * 128), new AgePruneCondition(365))); |
| +} |
| + |
| +const time_t kSecondsInDay = 60 * 60 * 24; |
|
Mark Mentovai
2015/10/07 19:13:05
namespace {}
Robert Sesek
2015/10/07 20:34:52
static
Mark Mentovai
2015/10/07 20:58:23
Robert Sesek wrote:
|
| + |
| +AgePruneCondition::AgePruneCondition(int max_age_in_days) |
| + : oldest_report_time_( |
| + ((time(nullptr) - (max_age_in_days * kSecondsInDay)) |
| + / kSecondsInDay) * kSecondsInDay) {} |
| + |
| +AgePruneCondition::~AgePruneCondition() {} |
| + |
| +bool AgePruneCondition::ShouldPruneReport( |
| + const CrashReportDatabase::Report& report) { |
| + return report.creation_time < oldest_report_time_; |
| +} |
| + |
| +DatabaseSizePruneCondition::DatabaseSizePruneCondition(size_t max_size_in_kb) |
| + : max_size_in_kb_(max_size_in_kb), 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 _stati64 statbuf; |
| + if (_wstat64(report.file_path.value().c_str(), &statbuf) == 0) { |
| +#else |
| +#error "Not implemented" |
| +#endif |
| + measured_size_ += statbuf.st_size; |
| + } |
| + return (measured_size_ / 1024.0f) > max_size_in_kb_; |
|
Mark Mentovai
2015/10/07 19:13:05
What’s with the floating-point domain?
How about
Robert Sesek
2015/10/07 20:34:52
Floating point was to promote to float before to r
|
| +} |
| + |
| +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); |
| + default: |
| + NOTREACHED(); |
| + return false; |
| + } |
| +} |
| + |
| +} // namespace crashpad |